Commit fcb3fce3 authored by gwenn's avatar gwenn

Add test with the regexp implementation in Go.

parent bc59e46a
......@@ -46,6 +46,12 @@ static int my_value_numeric_type(sqlite3_value** argv, int i) {
return sqlite3_value_numeric_type(argv[i]);
}
extern void goXAuxDataDestroy(void *ad);
static void goSqlite3SetAuxdata(sqlite3_context* ctx, int N, void* ad) {
sqlite3_set_auxdata(ctx, N, ad, goXAuxDataDestroy);
}
extern void goXFunc(sqlite3_context* ctx, int argc, sqlite3_value** argv);
extern void goXDestroy(void *pApp);
......@@ -71,6 +77,14 @@ type Context struct {
argv **C.sqlite3_value
}
func (c *Context) ResultBool(b bool) {
if b {
c.ResultInt(1)
} else {
c.ResultInt(0)
}
}
// Set the result of an SQL function
// Calls sqlite3_result_blob, http://sqlite.org/c3ref/result_blob.html
func (c *Context) ResultBlob(b []byte) {
......@@ -162,15 +176,33 @@ func (c *Context) UserData() interface{} {
// Function auxiliary data
// Calls sqlite3_get_auxdata, http://sqlite.org/c3ref/get_auxdata.html
func (c *Context) GetAuxData(n int) interface{} {
return C.sqlite3_get_auxdata(c.context, C.int(n))
adp := (*sqliteAuxData)(C.sqlite3_get_auxdata(c.context, C.int(n)))
if adp == nil {
return nil
}
return adp.ad
}
type AuxDataDestructor func(ad interface{})
type sqliteAuxData struct {
ad interface{}
d AuxDataDestructor
}
//export goXAuxDataDestroy
func goXAuxDataDestroy(ad unsafe.Pointer) {
adp := (*sqliteAuxData)(ad)
if adp != nil && adp.d != nil {
adp.d(adp.ad)
}
}
// Function auxiliary data
// Calls sqlite3_set_auxdata, http://sqlite.org/c3ref/get_auxdata.html
func (c *Context) SetAuxData(n int, ad interface{}, f AuxDataDestructor) {
// FIXME C.sqlite3_set_auxdata(c.context, C.int(n), unsafe.Pointer(ad), nil /*void (*)(void*)*/ )
func (c *Context) SetAuxData(n int, ad interface{}, d AuxDataDestructor) {
// How to make sure it is not gced?
adp := &sqliteAuxData{ad, d}
C.goSqlite3SetAuxdata(c.context, C.int(n), unsafe.Pointer(adp))
}
// The leftmost value is number 0.
......
......@@ -2,11 +2,17 @@ package sqlite_test
import (
. "github.com/gwenn/gosqlite"
"regexp"
"testing"
)
func half(ctx *Context, nArg int) {
ctx.ResultDouble(ctx.Double(0) / 2)
nt := ctx.NumericType(0)
if nt == Integer || nt == Float {
ctx.ResultDouble(ctx.Double(0) / 2)
} else {
ctx.ResultNull()
}
}
func TestScalarFunction(t *testing.T) {
......@@ -45,4 +51,76 @@ func TestScalarFunction(t *testing.T) {
if err != nil {
t.Errorf("couldn't destroy function: %s", err)
}
}
\ No newline at end of file
}
func re(ctx *Context, nArg int) {
ad := ctx.GetAuxData(0)
var re *regexp.Regexp
if ad == nil {
//println("Compile")
var err error
re, err = regexp.Compile(ctx.Text(0))
if err != nil {
ctx.ResultError(err.Error())
return
}
ctx.SetAuxData(0, re, nil)
} else {
//println("Reuse")
var ok bool
if re, ok = ad.(*regexp.Regexp); !ok {
ctx.ResultError("AuxData not a regexp ")
return
}
}
m := re.MatchString(ctx.Text(1))
ctx.ResultBool(m)
}
func TestRegexpFunction(t *testing.T) {
db, err := Open("")
if err != nil {
t.Fatalf("couldn't open database file: %s", err)
}
defer db.Close()
err = db.CreateScalarFunction("regexp", 2, nil, re, nil)
if err != nil {
t.Fatalf("couldn't create function: %s", err)
}
s, err := db.Prepare("select regexp('l.s[aeiouy]', name) from (select 'lisa' as name union all select 'bart' as name)")
if err != nil {
t.Fatalf("couldn't prepare statement: %s", err)
}
b, err := s.Next()
if err != nil {
t.Fatalf("couldn't step statement: %s", err)
}
if !b {
t.Fatalf("No result")
}
i, _, err := s.ScanInt(0)
if err != nil {
t.Fatalf("couldn't scan result: %s", err)
}
if i != 1 {
t.Errorf("Expected %d but got %d", 1, i)
}
b, err = s.Next()
if err != nil {
t.Fatalf("couldn't step statement: %s", err)
}
if !b {
t.Fatalf("No result")
}
i, _, err = s.ScanInt(0)
if err != nil {
t.Fatalf("couldn't scan result: %s", err)
}
if i != 0 {
t.Errorf("Expected %d but got %d", 0, i)
}
err = s.Finalize()
if err != nil {
t.Fatalf("couldn't finalize statement: %s", err)
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment