Skip to content

Commit 9b757d6

Browse files
author
José Carlos
authored
Merge pull request #317 from upper/issue-316
Issue 316
2 parents 51cf352 + 2c780be commit 9b757d6

File tree

5 files changed

+97
-26
lines changed

5 files changed

+97
-26
lines changed

internal/sqladapter/exql/column_value.go

+6-3
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,12 @@ func (c *ColumnValue) Compile(layout *Template) (compiled string) {
3131
}
3232

3333
data := columnValueT{
34-
c.Column.Compile(layout),
35-
c.Operator,
36-
c.Value.Compile(layout),
34+
Column: c.Column.Compile(layout),
35+
Operator: c.Operator,
36+
}
37+
38+
if c.Value != nil {
39+
data.Value = c.Value.Compile(layout)
3740
}
3841

3942
compiled = mustParse(layout.ColumnValue, data)

lib/sqlbuilder/builder.go

+4
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,10 @@ func Map(item interface{}, options *MapOptions) ([]string, []interface{}, error)
301301
return nil, nil, ErrExpectingPointerToEitherMapOrStruct
302302
}
303303

304+
if len(fv.fields) == 0 {
305+
return nil, nil, errors.New("No values mapped.")
306+
}
307+
304308
sort.Sort(&fv)
305309

306310
return fv.fields, fv.values, nil

lib/sqlbuilder/builder_test.go

+44
Original file line numberDiff line numberDiff line change
@@ -959,6 +959,50 @@ func TestUpdate(t *testing.T) {
959959
"id = id + ?", 10,
960960
).Where("id > ?", 0).String(),
961961
)
962+
963+
{
964+
q := b.Update("posts").Set("column = ?", "foo")
965+
966+
assert.Equal(
967+
`UPDATE "posts" SET "column" = $1`,
968+
q.String(),
969+
)
970+
971+
assert.Equal(
972+
[]interface{}{"foo"},
973+
q.Arguments(),
974+
)
975+
}
976+
977+
{
978+
q := b.Update("posts").Set(db.Raw("column = ?", "foo"))
979+
980+
assert.Equal(
981+
`UPDATE "posts" SET column = $1`,
982+
q.String(),
983+
)
984+
985+
assert.Equal(
986+
[]interface{}{"foo"},
987+
q.Arguments(),
988+
)
989+
}
990+
991+
{
992+
q := b.Update("posts").Set(
993+
db.Cond{"tags": db.Raw("array_remove(tags, ?)", "foo")},
994+
).Where(db.Raw("hub_id = ? AND ? = ANY(tags) AND ? = ANY(tags)", 1, "bar", "baz"))
995+
996+
assert.Equal(
997+
`UPDATE "posts" SET "tags" = array_remove(tags, $1) WHERE (hub_id = $2 AND $3 = ANY(tags) AND $4 = ANY(tags))`,
998+
q.String(),
999+
)
1000+
1001+
assert.Equal(
1002+
[]interface{}{"foo", 1, "bar", "baz"},
1003+
q.Arguments(),
1004+
)
1005+
}
9621006
}
9631007

9641008
func TestDelete(t *testing.T) {

lib/sqlbuilder/convert.go

+18-2
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ func (tu *templateWithUtils) ToWhereWithArguments(term interface{}) (where exql.
172172
func (tu *templateWithUtils) PlaceholderValue(in interface{}) (exql.Fragment, []interface{}) {
173173
switch t := in.(type) {
174174
case db.RawValue:
175-
return exql.RawValue(t.String()), nil
175+
return exql.RawValue(t.String()), t.Arguments()
176176
case db.Function:
177177
fnName := t.Name()
178178
fnArgs := []interface{}{}
@@ -230,7 +230,14 @@ func (tu *templateWithUtils) ToColumnValues(term interface{}) (cv exql.ColumnVal
230230
case []interface{}:
231231
l := len(t)
232232
for i := 0; i < l; i++ {
233-
column := t[i].(string)
233+
column, ok := t[i].(string)
234+
235+
if !ok {
236+
p, q := tu.ToColumnValues(t[i])
237+
cv.ColumnValues = append(cv.ColumnValues, p.ColumnValues...)
238+
args = append(args, q...)
239+
continue
240+
}
234241

235242
if !strings.ContainsAny(column, "=") {
236243
column = fmt.Sprintf("%s = ?", column)
@@ -337,6 +344,15 @@ func (tu *templateWithUtils) ToColumnValues(term interface{}) (cv exql.ColumnVal
337344

338345
cv.ColumnValues = append(cv.ColumnValues, &columnValue)
339346

347+
return cv, args
348+
case db.RawValue:
349+
columnValue := exql.ColumnValue{}
350+
p, q := Preprocess(t.Raw(), t.Arguments())
351+
352+
columnValue.Column = exql.RawValue(p)
353+
args = append(args, q...)
354+
355+
cv.ColumnValues = append(cv.ColumnValues, &columnValue)
340356
return cv, args
341357
case db.Constraints:
342358
for _, c := range t.Constraints() {

lib/sqlbuilder/update.go

+25-21
Original file line numberDiff line numberDiff line change
@@ -23,34 +23,38 @@ type updater struct {
2323
mu sync.Mutex
2424
}
2525

26-
func (qu *updater) Set(terms ...interface{}) Updater {
27-
if len(terms) == 1 {
28-
ff, vv, _ := Map(terms[0], nil)
26+
func (qu *updater) Set(columns ...interface{}) Updater {
2927

30-
cvs := make([]exql.Fragment, 0, len(ff))
31-
args := make([]interface{}, 0, len(vv))
28+
if len(columns) == 1 {
29+
ff, vv, err := Map(columns[0], nil)
30+
if err == nil {
3231

33-
for i := range ff {
34-
cv := &exql.ColumnValue{
35-
Column: exql.ColumnWithName(ff[i]),
36-
Operator: qu.builder.t.AssignmentOperator,
37-
}
32+
cvs := make([]exql.Fragment, 0, len(ff))
33+
args := make([]interface{}, 0, len(vv))
3834

39-
var localArgs []interface{}
40-
cv.Value, localArgs = qu.builder.t.PlaceholderValue(vv[i])
35+
for i := range ff {
36+
cv := &exql.ColumnValue{
37+
Column: exql.ColumnWithName(ff[i]),
38+
Operator: qu.builder.t.AssignmentOperator,
39+
}
4140

42-
args = append(args, localArgs...)
43-
cvs = append(cvs, cv)
44-
}
41+
var localArgs []interface{}
42+
cv.Value, localArgs = qu.builder.t.PlaceholderValue(vv[i])
43+
44+
args = append(args, localArgs...)
45+
cvs = append(cvs, cv)
46+
}
4547

46-
qu.columnValues.Insert(cvs...)
47-
qu.columnValuesArgs = append(qu.columnValuesArgs, args...)
48-
} else if len(terms) > 1 {
49-
cv, arguments := qu.builder.t.ToColumnValues(terms)
50-
qu.columnValues.Insert(cv.ColumnValues...)
51-
qu.columnValuesArgs = append(qu.columnValuesArgs, arguments...)
48+
qu.columnValues.Insert(cvs...)
49+
qu.columnValuesArgs = append(qu.columnValuesArgs, args...)
50+
return qu
51+
}
5252
}
5353

54+
cv, arguments := qu.builder.t.ToColumnValues(columns)
55+
qu.columnValues.Insert(cv.ColumnValues...)
56+
qu.columnValuesArgs = append(qu.columnValuesArgs, arguments...)
57+
5458
return qu
5559
}
5660

0 commit comments

Comments
 (0)