aboutsummaryrefslogtreecommitdiff
path: root/callback.go
diff options
context:
space:
mode:
Diffstat (limited to 'callback.go')
-rw-r--r--callback.go47
1 files changed, 47 insertions, 0 deletions
diff --git a/callback.go b/callback.go
index b1704fe..61fc8d1 100644
--- a/callback.go
+++ b/callback.go
@@ -12,6 +12,7 @@ package sqlite3
/*
#include <sqlite3-binding.h>
+#include <stdlib.h>
void _sqlite3_result_text(sqlite3_context* ctx, const char* s);
void _sqlite3_result_blob(sqlite3_context* ctx, const void* b, int l);
@@ -32,6 +33,19 @@ func callbackTrampoline(ctx *C.sqlite3_context, argc int, argv **C.sqlite3_value
fi.Call(ctx, args)
}
+//export stepTrampoline
+func stepTrampoline(ctx *C.sqlite3_context, argc int, argv **C.sqlite3_value) {
+ args := (*[1 << 30]*C.sqlite3_value)(unsafe.Pointer(argv))[:argc:argc]
+ ai := (*aggInfo)(unsafe.Pointer(C.sqlite3_user_data(ctx)))
+ ai.Step(ctx, args)
+}
+
+//export doneTrampoline
+func doneTrampoline(ctx *C.sqlite3_context) {
+ ai := (*aggInfo)(unsafe.Pointer(C.sqlite3_user_data(ctx)))
+ ai.Done(ctx)
+}
+
// This is only here so that tests can refer to it.
type callbackArgRaw C.sqlite3_value
@@ -158,6 +172,33 @@ func callbackArg(typ reflect.Type) (callbackArgConverter, error) {
}
}
+func callbackConvertArgs(argv []*C.sqlite3_value, converters []callbackArgConverter, variadic callbackArgConverter) ([]reflect.Value, error) {
+ var args []reflect.Value
+
+ if len(argv) < len(converters) {
+ return nil, fmt.Errorf("function requires at least %d arguments", len(converters))
+ }
+
+ for i, arg := range argv[:len(converters)] {
+ v, err := converters[i](arg)
+ if err != nil {
+ return nil, err
+ }
+ args = append(args, v)
+ }
+
+ if variadic != nil {
+ for _, arg := range argv[len(converters):] {
+ v, err := variadic(arg)
+ if err != nil {
+ return nil, err
+ }
+ args = append(args, v)
+ }
+ }
+ return args, nil
+}
+
type callbackRetConverter func(*C.sqlite3_context, reflect.Value) error
func callbackRetInteger(ctx *C.sqlite3_context, v reflect.Value) error {
@@ -233,6 +274,12 @@ func callbackRet(typ reflect.Type) (callbackRetConverter, error) {
}
}
+func callbackError(ctx *C.sqlite3_context, err error) {
+ cstr := C.CString(err.Error())
+ defer C.free(unsafe.Pointer(cstr))
+ C.sqlite3_result_error(ctx, cstr, -1)
+}
+
// Test support code. Tests are not allowed to import "C", so we can't
// declare any functions that use C.sqlite3_value.
func callbackSyntheticForTests(v reflect.Value, err error) callbackArgConverter {