diff --git a/internal/sqlite3test/raw.go b/internal/sqlite3test/raw.go new file mode 100644 index 0000000..aed2e69 --- /dev/null +++ b/internal/sqlite3test/raw.go @@ -0,0 +1,35 @@ +package sqlite3test + +/* +#cgo CFLAGS: -DUSE_LIBSQLITE3 +#cgo linux LDFLAGS: -lsqlite3 +#cgo darwin LDFLAGS: -L/usr/local/opt/sqlite/lib -lsqlite3 +#cgo darwin CFLAGS: -I/usr/local/opt/sqlite/include +#cgo openbsd LDFLAGS: -lsqlite3 +#cgo solaris LDFLAGS: -lsqlite3 +#include +#include + +static void one(sqlite3_context* ctx, int n, sqlite3_value** vals) { + sqlite3_result_int(ctx, 1); +} + +static inline int _create_function(sqlite3* c) { + return sqlite3_create_function(c, "one", 0, SQLITE_UTF8|SQLITE_DETERMINISTIC, NULL, one, NULL, NULL); +} +*/ +import "C" +import ( + sqlite3 "github.com/mattn/go-sqlite3" + "unsafe" +) + +func RegisterFunction(conn *sqlite3.SQLiteConn) error { + return conn.Raw(func(raw unsafe.Pointer) error { + rawConn := (*C.sqlite3)(raw) + if ret := C._create_function(rawConn); ret != C.SQLITE_OK { + return sqlite3.ErrNo(ret) + } + return nil + }) +} diff --git a/raw_test.go b/raw_test.go new file mode 100644 index 0000000..9ac4cbf --- /dev/null +++ b/raw_test.go @@ -0,0 +1,37 @@ +package sqlite3_test + +import ( + "database/sql" + "testing" + + sqlite3 "github.com/mattn/go-sqlite3" + "github.com/mattn/go-sqlite3/internal/sqlite3test" +) + +func TestRaw(t *testing.T) { + sql.Register("sqlite3_rawtest", &sqlite3.SQLiteDriver{ + ConnectHook: func(c *sqlite3.SQLiteConn) error { + return sqlite3test.RegisterFunction(c) + }, + }) + + db, err := sql.Open("sqlite3_rawtest", "...") + if err != nil { + t.Fatal(err) + } + + defer db.Close() + + if err := db.Ping(); err != nil { + t.Fatal(err) + } + + var result int + if err := db.QueryRow(`SELECT one()`).Scan(&result); err != nil { + t.Fatal(err) + } + + if result != 1 { + t.Errorf("expected custom one() function to return 1, but got %d", result) + } +}