adopt forked squirrel supporting from UPDATE FROM (#19896)

Fork https://github.com/Masterminds/squirrel as https://github.com/lieut-data/squirrel with the following changes:
* https://github.com/Masterminds/squirrel/pull/256 supporting FROM clause to update builder (Postgres)
* Extension of above to support multiple FROM in UPDATE (Postgres)
* Support for multiple tables in UPDATE (MySQL)

This PR then leverages those changes to simplify a query that previously had to be coded by hand and duplicate for each of MySQL and Postgres.
Этот коммит содержится в:
Jesse Hallam
2022-04-04 09:30:59 -03:00
коммит произвёл GitHub
родитель 3f5eb5f6f7
Коммит 7b5ac343f0
7 изменённых файлов: 64 добавлений и 36 удалений

2
go.mod
Просмотреть файл

@@ -126,6 +126,8 @@ require (
gopkg.in/yaml.v2 v2.4.0
)
replace github.com/Masterminds/squirrel v1.5.2 => github.com/lieut-data/squirrel v1.5.4
// Hack to prevent the willf/bitset module from being upgraded to 1.2.0.
// They changed the module path from github.com/willf/bitset to
// github.com/bits-and-blooms/bitset and a couple of dependent repos are yet

4
go.sum
Просмотреть файл

@@ -978,6 +978,10 @@ github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lib/pq v1.10.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lib/pq v1.10.4 h1:SO9z7FRPzA03QhHKJrH5BXA6HU1rS4V2nIVrrNC1iYk=
github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lieut-data/squirrel v1.5.3 h1:c6RI29VQOkUvqjpUsa45HeZ+wShtzDcSrmTUom/F65g=
github.com/lieut-data/squirrel v1.5.3/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=
github.com/lieut-data/squirrel v1.5.4 h1:OGzJNl0/ZxdjLEHuFzDo797zB2V7i8wQXBVThcOzbHE=
github.com/lieut-data/squirrel v1.5.4/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=
github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=

Просмотреть файл

@@ -571,36 +571,28 @@ func (s *SqlThreadStore) MarkAllAsReadByChannels(userID string, channelIDs []str
now := model.GetMillis()
// TODO: Fork squirrel to include https://github.com/Masterminds/squirrel/pull/256 and
// support FROM in an UPDATE query.
channelIDsSql, channelIDsArgs := constructArrayArgs(channelIDs)
var query string
var query sq.UpdateBuilder
if s.DriverName() == model.DatabaseDriverPostgres {
query = `
UPDATE ThreadMemberships
SET LastViewed = ?, UnreadMentions = ?, LastUpdated = ?
FROM Threads
WHERE ThreadMemberships.UserId = ?
AND Threads.PostId = ThreadMemberships.PostId
AND Threads.ChannelID IN ` + channelIDsSql + `
AND Threads.LastReplyAt > ThreadMemberships.LastViewed
`
query = s.getQueryBuilder().Update("ThreadMemberships").From("Threads")
} else {
query = `
UPDATE ThreadMemberships, Threads
SET ThreadMemberships.LastViewed = ?, ThreadMemberships.UnreadMentions = ?, ThreadMemberships.LastUpdated = ?
WHERE ThreadMemberships.UserId = ?
AND Threads.PostId = ThreadMemberships.PostId
AND Threads.ChannelID IN ` + channelIDsSql + `
AND Threads.LastReplyAt > ThreadMemberships.LastViewed
`
query = s.getQueryBuilder().Update("ThreadMemberships", "Threads")
}
args := []interface{}{now, 0, now, userID}
args = append(args, channelIDsArgs...)
query = query.Set("LastViewed", now).
Set("UnreadMentions", 0).
Set("LastUpdated", now).
Where(sq.Eq{"ThreadMemberships.UserId": userID}).
Where(sq.Expr("Threads.PostId = ThreadMemberships.PostId")).
Where(sq.Eq{"Threads.ChannelId": channelIDs}).
Where(sq.Expr("Threads.LastReplyAt > ThreadMemberships.LastViewed"))
if _, err := s.GetMasterX().Exec(query, args...); err != nil {
sql, args, err := query.ToSql()
if err != nil {
return errors.Wrapf(err, "failed to build query to mark all as read by %d channels for user id=%s", len(channelIDs), userID)
}
if _, err := s.GetMasterX().Exec(sql, args...); err != nil {
return errors.Wrapf(err, "failed to mark all threads as read by channels for user id=%s", userID)
}

2
vendor/github.com/Masterminds/squirrel/squirrel_ctx.go сгенерированный поставляемый
Просмотреть файл

@@ -32,7 +32,7 @@ type QueryRowerContext interface {
QueryRowContext(ctx context.Context, query string, args ...interface{}) RowScanner
}
// RunnerContext groups the Runner interface, along with the Contect versions of each of
// RunnerContext groups the Runner interface, along with the Context versions of each of
// its methods
type RunnerContext interface {
Runner

8
vendor/github.com/Masterminds/squirrel/statement.go сгенерированный поставляемый
Просмотреть файл

@@ -22,8 +22,8 @@ func (b StatementBuilderType) Replace(into string) InsertBuilder {
}
// Update returns a UpdateBuilder for this StatementBuilderType.
func (b StatementBuilderType) Update(table string) UpdateBuilder {
return UpdateBuilder(b).Table(table)
func (b StatementBuilderType) Update(tables ...string) UpdateBuilder {
return UpdateBuilder(b).Table(tables...)
}
// Delete returns a DeleteBuilder for this StatementBuilderType.
@@ -76,8 +76,8 @@ func Replace(into string) InsertBuilder {
// Update returns a new UpdateBuilder with the given table name.
//
// See UpdateBuilder.Table.
func Update(table string) UpdateBuilder {
return StatementBuilder.Update(table)
func Update(tables ...string) UpdateBuilder {
return StatementBuilder.Update(tables...)
}
// Delete returns a new DeleteBuilder with the given table name.

40
vendor/github.com/Masterminds/squirrel/update.go сгенерированный поставляемый
Просмотреть файл

@@ -14,8 +14,9 @@ type updateData struct {
PlaceholderFormat PlaceholderFormat
RunWith BaseRunner
Prefixes []Sqlizer
Table string
Tables []string
SetClauses []setClause
From []Sqlizer
WhereParts []Sqlizer
OrderBys []string
Limit string
@@ -54,7 +55,7 @@ func (d *updateData) QueryRow() RowScanner {
}
func (d *updateData) ToSql() (sqlStr string, args []interface{}, err error) {
if len(d.Table) == 0 {
if len(d.Tables) == 0 {
err = fmt.Errorf("update statements must specify a table")
return
}
@@ -75,7 +76,7 @@ func (d *updateData) ToSql() (sqlStr string, args []interface{}, err error) {
}
sql.WriteString("UPDATE ")
sql.WriteString(d.Table)
sql.WriteString(strings.Join(d.Tables, ", "))
sql.WriteString(" SET ")
setSqls := make([]string, len(d.SetClauses))
@@ -100,6 +101,14 @@ func (d *updateData) ToSql() (sqlStr string, args []interface{}, err error) {
}
sql.WriteString(strings.Join(setSqls, ", "))
if len(d.From) > 0 {
sql.WriteString(" FROM ")
args, err = appendToSql(d.From, sql, ", ", args)
if err != nil {
return
}
}
if len(d.WhereParts) > 0 {
sql.WriteString(" WHERE ")
args, err = appendToSql(d.WhereParts, sql, " AND ", args)
@@ -208,8 +217,16 @@ func (b UpdateBuilder) PrefixExpr(expr Sqlizer) UpdateBuilder {
}
// Table sets the table to be updated.
func (b UpdateBuilder) Table(table string) UpdateBuilder {
return builder.Set(b, "Table", table).(UpdateBuilder)
// Additional tables are used with supporting databases to implicitly join.
func (b UpdateBuilder) Table(tables ...string) UpdateBuilder {
nonEmptyTables := make([]string, 0, len(tables))
for _, table := range tables {
if table != "" {
nonEmptyTables = append(nonEmptyTables, table)
}
}
return builder.Set(b, "Tables", nonEmptyTables).(UpdateBuilder)
}
// Set adds SET clauses to the query.
@@ -233,6 +250,19 @@ func (b UpdateBuilder) SetMap(clauses map[string]interface{}) UpdateBuilder {
return b
}
// From adds FROM clause to the query
// FROM is valid construct in postgresql only.
func (b UpdateBuilder) From(from string) UpdateBuilder {
return builder.Append(b, "From", newPart(from)).(UpdateBuilder)
}
// FromSelect sets a subquery into the FROM clause of the query.
func (b UpdateBuilder) FromSelect(from SelectBuilder, alias string) UpdateBuilder {
// Prevent misnumbered parameters in nested selects (#183).
from = from.PlaceholderFormat(Question)
return builder.Append(b, "From", Alias(from, alias)).(UpdateBuilder)
}
// Where adds WHERE expressions to the query.
//
// See SelectBuilder.Where for more information.

2
vendor/modules.txt поставляемый
Просмотреть файл

@@ -10,7 +10,7 @@ github.com/JalfResi/justext
# github.com/Masterminds/semver/v3 v3.1.1
## explicit
github.com/Masterminds/semver/v3
# github.com/Masterminds/squirrel v1.5.2
# github.com/Masterminds/squirrel v1.5.2 => github.com/lieut-data/squirrel v1.5.4
## explicit
github.com/Masterminds/squirrel
# github.com/PuerkitoBio/goquery v1.8.0