aboutsummaryrefslogtreecommitdiff
path: root/sqlite3_test.go
diff options
context:
space:
mode:
authorDavid Anderson <dave@natulte.net>2015-08-21 13:38:22 -0700
committerDavid Anderson <dave@natulte.net>2015-08-21 16:37:45 -0700
commit122ddb16de825ed3d989d25d4d7b2d2e278abdf6 (patch)
tree43d4cad7936f67a709c32b80439fef32805ddebf /sqlite3_test.go
parentImplement support for passing Go functions as custom functions to SQLite. (diff)
downloadgolite-122ddb16de825ed3d989d25d4d7b2d2e278abdf6.tar.gz
golite-122ddb16de825ed3d989d25d4d7b2d2e278abdf6.tar.xz
Move argument converters to callback.go, and optimize return value handling.
A call now doesn't have to do any reflection, it just blindly invokes a bunch of argument and return value handlers to execute the translation, and the safety of the translation is determined at registration time.
Diffstat (limited to 'sqlite3_test.go')
-rw-r--r--sqlite3_test.go102
1 files changed, 53 insertions, 49 deletions
diff --git a/sqlite3_test.go b/sqlite3_test.go
index a58e373..e8dfe5c 100644
--- a/sqlite3_test.go
+++ b/sqlite3_test.go
@@ -15,6 +15,7 @@ import (
"net/url"
"os"
"path/filepath"
+ "reflect"
"regexp"
"strings"
"sync"
@@ -1060,25 +1061,41 @@ func TestDateTimeNow(t *testing.T) {
}
func TestFunctionRegistration(t *testing.T) {
- custom_add := func(a, b int64) (int64, error) {
- return a + b, nil
- }
- custom_regex := func(s, re string) bool {
- matched, err := regexp.MatchString(re, s)
- if err != nil {
- // We should really return the error here, but this
- // function is also testing single return value functions.
- panic("Bad regexp")
- }
- return matched
+ addi_8_16_32 := func(a int8, b int16) int32 { return int32(a) + int32(b) }
+ addi_64 := func(a, b int64) int64 { return a + b }
+ addu_8_16_32 := func(a uint8, b uint16) uint32 { return uint32(a) + uint32(b) }
+ addu_64 := func(a, b uint64) uint64 { return a + b }
+ addiu := func(a int, b uint) int64 { return int64(a) + int64(b) }
+ addf_32_64 := func(a float32, b float64) float64 { return float64(a) + b }
+ not := func(a bool) bool { return !a }
+ regex := func(re, s string) (bool, error) {
+ return regexp.MatchString(re, s)
}
sql.Register("sqlite3_FunctionRegistration", &SQLiteDriver{
ConnectHook: func(conn *SQLiteConn) error {
- if err := conn.RegisterFunc("custom_add", custom_add, true); err != nil {
+ if err := conn.RegisterFunc("addi_8_16_32", addi_8_16_32, true); err != nil {
+ return err
+ }
+ if err := conn.RegisterFunc("addi_64", addi_64, true); err != nil {
+ return err
+ }
+ if err := conn.RegisterFunc("addu_8_16_32", addu_8_16_32, true); err != nil {
return err
}
- if err := conn.RegisterFunc("regexp", custom_regex, true); err != nil {
+ if err := conn.RegisterFunc("addu_64", addu_64, true); err != nil {
+ return err
+ }
+ if err := conn.RegisterFunc("addiu", addiu, true); err != nil {
+ return err
+ }
+ if err := conn.RegisterFunc("addf_32_64", addf_32_64, true); err != nil {
+ return err
+ }
+ if err := conn.RegisterFunc("not", not, true); err != nil {
+ return err
+ }
+ if err := conn.RegisterFunc("regex", regex, true); err != nil {
return err
}
return nil
@@ -1090,42 +1107,29 @@ func TestFunctionRegistration(t *testing.T) {
}
defer db.Close()
- additions := []struct {
- a, b, c int64
+ ops := []struct {
+ query string
+ expected interface{}
}{
- {1, 1, 2},
- {1, 3, 4},
- {1, -1, 0},
- }
-
- for _, add := range additions {
- var i int64
- err = db.QueryRow("SELECT custom_add($1, $2)", add.a, add.b).Scan(&i)
+ {"SELECT addi_8_16_32(1,2)", int32(3)},
+ {"SELECT addi_64(1,2)", int64(3)},
+ {"SELECT addu_8_16_32(1,2)", uint32(3)},
+ {"SELECT addu_64(1,2)", uint64(3)},
+ {"SELECT addiu(1,2)", int64(3)},
+ {"SELECT addf_32_64(1.5,1.5)", float64(3)},
+ {"SELECT not(1)", false},
+ {"SELECT not(0)", true},
+ {`SELECT regex("^foo.*", "foobar")`, true},
+ {`SELECT regex("^foo.*", "barfoobar")`, false},
+ }
+
+ for _, op := range ops {
+ ret := reflect.New(reflect.TypeOf(op.expected))
+ err = db.QueryRow(op.query).Scan(ret.Interface())
if err != nil {
- t.Fatal("Failed to call custom_add:", err)
- }
- if i != add.c {
- t.Fatalf("custom_add returned the wrong value, got %d, want %d", i, add.c)
- }
- }
-
- regexes := []struct {
- re, in string
- out bool
- }{
- {".*", "foo", true},
- {"^foo.*", "foobar", true},
- {"^foo.*", "barfoo", false},
- }
-
- for _, re := range regexes {
- var b bool
- err = db.QueryRow("SELECT regexp($1, $2)", re.in, re.re).Scan(&b)
- if err != nil {
- t.Fatal("Failed to call regexp:", err)
- }
- if b != re.out {
- t.Fatalf("regexp returned the wrong value, got %v, want %v", b, re.out)
+ t.Errorf("Query %q failed: %s", op.query, err)
+ } else if !reflect.DeepEqual(ret.Elem().Interface(), op.expected) {
+ t.Errorf("Query %q returned wrong value: got %v (%T), want %v (%T)", op.query, ret.Elem().Interface(), ret.Elem().Interface(), op.expected, op.expected)
}
}
}
@@ -1134,8 +1138,8 @@ var customFunctionOnce sync.Once
func BenchmarkCustomFunctions(b *testing.B) {
customFunctionOnce.Do(func() {
- custom_add := func(a, b int64) (int64, error) {
- return a + b, nil
+ custom_add := func(a, b int64) int64 {
+ return a + b
}
sql.Register("sqlite3_BenchmarkCustomFunctions", &SQLiteDriver{