good morning!!!!

Skip to content
Snippets Groups Projects
Commit 59bb9878 authored by Carlos Nieto's avatar Carlos Nieto
Browse files

Adding db.Func{} support.

parent 07bcbc06
No related branches found
No related tags found
No related merge requests found
...@@ -27,6 +27,7 @@ import ( ...@@ -27,6 +27,7 @@ import (
"fmt" "fmt"
_ "github.com/go-sql-driver/mysql" _ "github.com/go-sql-driver/mysql"
"menteslibres.net/gosexy/to" "menteslibres.net/gosexy/to"
"reflect"
"strings" "strings"
"time" "time"
"upper.io/db" "upper.io/db"
...@@ -112,27 +113,46 @@ func (self *Table) compileConditions(term interface{}) (string, []interface{}) { ...@@ -112,27 +113,46 @@ func (self *Table) compileConditions(term interface{}) (string, []interface{}) {
return "", args return "", args
} }
func (self *Table) compileStatement(where db.Cond) (string, []interface{}) { func (self *Table) compileStatement(cond db.Cond) (string, []interface{}) {
str := make([]string, len(where)) total := len(cond)
arg := make([]interface{}, len(where))
i := 0 str := make([]string, 0, total)
arg := make([]interface{}, 0, total)
for key, _ := range where { // Walking over conditions
key = strings.Trim(key, ` `) for field, value := range cond {
chunks := strings.SplitN(key, ` `, 2) // Removing leading or trailing spaces.
field = strings.TrimSpace(field)
chunks := strings.SplitN(field, ` `, 2)
// Default operator.
op := `=` op := `=`
if len(chunks) > 1 { if len(chunks) > 1 {
// User has defined a different operator.
op = chunks[1] op = chunks[1]
} }
str[i] = fmt.Sprintf(`%s %s ?`, chunks[0], op) switch value := value.(type) {
arg[i] = toInternal(where[key]) case db.Func:
value_i := interfaceArgs(value.Args)
i++ if value_i == nil {
str = append(str, fmt.Sprintf(`%s %s ()`, chunks[0], value.Name))
} else {
str = append(str, fmt.Sprintf(`%s %s (?%s)`, chunks[0], value.Name, strings.Repeat(`,?`, len(value_i)-1)))
arg = append(arg, value_i...)
}
default:
value_i := interfaceArgs(value)
if value_i == nil {
str = append(str, fmt.Sprintf(`%s %s ()`, chunks[0], op))
} else {
str = append(str, fmt.Sprintf(`%s %s (?%s)`, chunks[0], op, strings.Repeat(`,?`, len(value_i)-1)))
arg = append(arg, value_i...)
}
}
} }
switch len(str) { switch len(str) {
...@@ -235,3 +255,34 @@ func toInternal(val interface{}) interface{} { ...@@ -235,3 +255,34 @@ func toInternal(val interface{}) interface{} {
func toNative(val interface{}) interface{} { func toNative(val interface{}) interface{} {
return val return val
} }
func interfaceArgs(value interface{}) (args []interface{}) {
if value == nil {
return nil
}
value_v := reflect.ValueOf(value)
switch value_v.Type().Kind() {
case reflect.Slice:
var i, total int
total = value_v.Len()
if total > 0 {
args = make([]interface{}, total)
for i = 0; i < total; i++ {
args[i] = toInternal(value_v.Index(i).Interface())
}
return args
} else {
return nil
}
default:
args = []interface{}{toInternal(value)}
}
return args
}
...@@ -513,6 +513,48 @@ func TestUpdate(t *testing.T) { ...@@ -513,6 +513,48 @@ func TestUpdate(t *testing.T) {
} }
// Test database functions
func TestFunction(t *testing.T) {
var err error
var res db.Result
// Opening database.
sess, err := db.Open(wrapperName, settings)
if err != nil {
t.Fatalf(err.Error())
}
// We should close the database when it's no longer in use.
defer sess.Close()
// Getting a pointer to the "artist" collection.
artist, err := sess.Collection("artist")
if err != nil {
t.Fatalf(err.Error())
}
row_s := struct {
Id uint64
Name string
}{}
res = artist.Find(db.Cond{"id NOT IN": []int{0, -1}})
if err = res.One(&row_s); err != nil {
t.Fatalf("One: %q", err)
}
res = artist.Find(db.Cond{"id": db.Func{"NOT IN", []int{0, -1}}})
if err = res.One(&row_s); err != nil {
t.Fatalf("One: %q", err)
}
res.Close()
}
// This test tries to remove some previously added rows. // This test tries to remove some previously added rows.
func TestRemove(t *testing.T) { func TestRemove(t *testing.T) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment