good morning!!!!

Skip to content
Snippets Groups Projects
Commit aa8cafe9 authored by José Carlos's avatar José Carlos
Browse files

Merge pull request #185 from upper/issue-176-v2

Using Raw and Function in update statements.
parents d784fa74 96c3f214
No related branches found
No related tags found
No related merge requests found
...@@ -131,6 +131,28 @@ func (tu *templateWithUtils) ToWhereWithArguments(term interface{}) (where exql. ...@@ -131,6 +131,28 @@ func (tu *templateWithUtils) ToWhereWithArguments(term interface{}) (where exql.
panic(fmt.Sprintf("Unknown condition type %T", term)) panic(fmt.Sprintf("Unknown condition type %T", term))
} }
func (tu *templateWithUtils) PlaceholderValue(in interface{}) (exql.Fragment, []interface{}) {
switch t := in.(type) {
case db.RawValue:
return exql.RawValue(t.String()), nil
case db.Function:
fnName := t.Name()
fnArgs := []interface{}{}
args := tu.ToInterfaceArguments(t.Arguments())
fragments := []string{}
for i := range args {
frag, args := tu.PlaceholderValue(args[i])
fragments = append(fragments, frag.Compile(tu.Template))
fnArgs = append(fnArgs, args...)
}
return exql.RawValue(fnName + `(` + strings.Join(fragments, `, `) + `)`), fnArgs
default:
// Value must be escaped.
return sqlPlaceholder, []interface{}{in}
}
}
// ToInterfaceArguments converts the given value into an array of interfaces. // ToInterfaceArguments converts the given value into an array of interfaces.
func (tu *templateWithUtils) ToInterfaceArguments(value interface{}) (args []interface{}) { func (tu *templateWithUtils) ToInterfaceArguments(value interface{}) (args []interface{}) {
if value == nil { if value == nil {
......
...@@ -20,17 +20,26 @@ func (qu *updater) Set(terms ...interface{}) Updater { ...@@ -20,17 +20,26 @@ func (qu *updater) Set(terms ...interface{}) Updater {
if len(terms) == 1 { if len(terms) == 1 {
ff, vv, _ := Map(terms[0]) ff, vv, _ := Map(terms[0])
cvs := make([]exql.Fragment, len(ff)) cvs := make([]exql.Fragment, 0, len(ff))
args := make([]interface{}, 0, len(vv))
for i := range ff { for i := range ff {
cvs[i] = &exql.ColumnValue{ cv := &exql.ColumnValue{
Column: exql.ColumnWithName(ff[i]), Column: exql.ColumnWithName(ff[i]),
Operator: qu.builder.t.AssignmentOperator, Operator: qu.builder.t.AssignmentOperator,
Value: sqlPlaceholder,
} }
var localArgs []interface{}
cv.Value, localArgs = qu.builder.t.PlaceholderValue(vv[i])
args = append(args, localArgs...)
cvs = append(cvs, cv)
} }
args = append(args, qu.arguments...)
qu.columnValues.Insert(cvs...) qu.columnValues.Insert(cvs...)
qu.arguments = append(qu.arguments, vv...) qu.arguments = append(qu.arguments, args...)
} else if len(terms) > 1 { } else if len(terms) > 1 {
cv, arguments := qu.builder.t.ToColumnValues(terms) cv, arguments := qu.builder.t.ToColumnValues(terms)
qu.columnValues.Insert(cv.ColumnValues...) qu.columnValues.Insert(cv.ColumnValues...)
......
...@@ -79,6 +79,7 @@ const ( ...@@ -79,6 +79,7 @@ const (
// care. // care.
type RawValue interface { type RawValue interface {
fmt.Stringer fmt.Stringer
Raw() string
} }
// Function interface defines methods for representing database functions. // Function interface defines methods for representing database functions.
...@@ -153,10 +154,14 @@ type rawValue struct { ...@@ -153,10 +154,14 @@ type rawValue struct {
v string v string
} }
func (r rawValue) String() string { func (r rawValue) Raw() string {
return r.v return r.v
} }
func (r rawValue) String() string {
return r.Raw()
}
type compound struct { type compound struct {
conds []Compound conds []Compound
} }
......
...@@ -564,6 +564,49 @@ func TestUpdate(t *testing.T) { ...@@ -564,6 +564,49 @@ func TestUpdate(t *testing.T) {
// Verifying. // Verifying.
assert.Equal(t, value.Name, rowMap["name"]) assert.Equal(t, value.Name, rowMap["name"])
if Adapter != "ql" {
// Updating using raw
if err = res.Update(map[string]interface{}{"name": db.Raw("LOWER(name)")}); err != nil {
t.Fatal(err)
}
// Pulling it again.
err = res.One(&value)
assert.NoError(t, err)
// Verifying.
assert.Equal(t, value.Name, strings.ToLower(rowMap["name"].(string)))
// Updating using raw
if err = res.Update(struct {
Name db.RawValue `db:"name"`
}{db.Raw(`UPPER(name)`)}); err != nil {
t.Fatal(err)
}
// Pulling it again.
err = res.One(&value)
assert.NoError(t, err)
// Verifying.
assert.Equal(t, value.Name, strings.ToUpper(rowMap["name"].(string)))
// Updating using raw
if err = res.Update(struct {
Name db.Function `db:"name"`
}{db.Func("LOWER", db.Raw("name"))}); err != nil {
t.Fatal(err)
}
// Pulling it again.
err = res.One(&value)
assert.NoError(t, err)
// Verifying.
assert.Equal(t, value.Name, strings.ToLower(rowMap["name"].(string)))
}
// Updating set with a struct // Updating set with a struct
rowStruct := struct { rowStruct := struct {
Name string `db:"name"` Name string `db:"name"`
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment