Skip to content

Commit

Permalink
[#82] Added FROM clause to update builder (#256)
Browse files Browse the repository at this point in the history
  • Loading branch information
mlaflamm authored Mar 17, 2023
1 parent e1c3903 commit d8eb51b
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 0 deletions.
22 changes: 22 additions & 0 deletions update.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type updateData struct {
Prefixes []Sqlizer
Table string
SetClauses []setClause
From Sqlizer
WhereParts []Sqlizer
OrderBys []string
Limit string
Expand Down Expand Up @@ -100,6 +101,14 @@ func (d *updateData) ToSql() (sqlStr string, args []interface{}, err error) {
}
sql.WriteString(strings.Join(setSqls, ", "))

if d.From != nil {
sql.WriteString(" FROM ")
args, err = appendToSql([]Sqlizer{d.From}, sql, "", args)
if err != nil {
return
}
}

if len(d.WhereParts) > 0 {
sql.WriteString(" WHERE ")
args, err = appendToSql(d.WhereParts, sql, " AND ", args)
Expand Down Expand Up @@ -233,6 +242,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.Set(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.Set(b, "From", Alias(from, alias)).(UpdateBuilder)
}

// Where adds WHERE expressions to the query.
//
// See SelectBuilder.Where for more information.
Expand Down
23 changes: 23 additions & 0 deletions update_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,26 @@ func TestUpdateBuilderNoRunner(t *testing.T) {
_, err := b.Exec()
assert.Equal(t, RunnerNotSet, err)
}

func TestUpdateBuilderFrom(t *testing.T) {
sql, _, err := Update("employees").Set("sales_count", 100).From("accounts").Where("accounts.name = ?", "ACME").ToSql()
assert.NoError(t, err)
assert.Equal(t, "UPDATE employees SET sales_count = ? FROM accounts WHERE accounts.name = ?", sql)
}

func TestUpdateBuilderFromSelect(t *testing.T) {
sql, _, err := Update("employees").
Set("sales_count", 100).
FromSelect(Select("id").
From("accounts").
Where("accounts.name = ?", "ACME"), "subquery").
Where("employees.account_id = subquery.id").ToSql()
assert.NoError(t, err)

expectedSql :=
"UPDATE employees " +
"SET sales_count = ? " +
"FROM (SELECT id FROM accounts WHERE accounts.name = ?) AS subquery " +
"WHERE employees.account_id = subquery.id"
assert.Equal(t, expectedSql, sql)
}

0 comments on commit d8eb51b

Please sign in to comment.