diff options
-rw-r--r-- | callback.go | 50 | ||||
-rw-r--r-- | sqlite3.go | 20 | ||||
-rw-r--r-- | sqlite3_opt_vtable.go | 30 |
3 files changed, 47 insertions, 53 deletions
diff --git a/callback.go b/callback.go index 6450575..c3ce752 100644 --- a/callback.go +++ b/callback.go @@ -35,56 +35,55 @@ import ( //export callbackTrampoline func callbackTrampoline(ctx *C.sqlite3_context, argc int, argv **C.sqlite3_value) { args := (*[(math.MaxInt32 - 1) / unsafe.Sizeof((*C.sqlite3_value)(nil))]*C.sqlite3_value)(unsafe.Pointer(argv))[:argc:argc] - fi := lookupHandle(uintptr(C.sqlite3_user_data(ctx))).(*functionInfo) + fi := lookupHandle(C.sqlite3_user_data(ctx)).(*functionInfo) fi.Call(ctx, args) } //export stepTrampoline func stepTrampoline(ctx *C.sqlite3_context, argc C.int, argv **C.sqlite3_value) { args := (*[(math.MaxInt32 - 1) / unsafe.Sizeof((*C.sqlite3_value)(nil))]*C.sqlite3_value)(unsafe.Pointer(argv))[:int(argc):int(argc)] - ai := lookupHandle(uintptr(C.sqlite3_user_data(ctx))).(*aggInfo) + ai := lookupHandle(C.sqlite3_user_data(ctx)).(*aggInfo) ai.Step(ctx, args) } //export doneTrampoline func doneTrampoline(ctx *C.sqlite3_context) { - handle := uintptr(C.sqlite3_user_data(ctx)) - ai := lookupHandle(handle).(*aggInfo) + ai := lookupHandle(C.sqlite3_user_data(ctx)).(*aggInfo) ai.Done(ctx) } //export compareTrampoline -func compareTrampoline(handlePtr uintptr, la C.int, a *C.char, lb C.int, b *C.char) C.int { +func compareTrampoline(handlePtr unsafe.Pointer, la C.int, a *C.char, lb C.int, b *C.char) C.int { cmp := lookupHandle(handlePtr).(func(string, string) int) return C.int(cmp(C.GoStringN(a, la), C.GoStringN(b, lb))) } //export commitHookTrampoline -func commitHookTrampoline(handle uintptr) int { +func commitHookTrampoline(handle unsafe.Pointer) int { callback := lookupHandle(handle).(func() int) return callback() } //export rollbackHookTrampoline -func rollbackHookTrampoline(handle uintptr) { +func rollbackHookTrampoline(handle unsafe.Pointer) { callback := lookupHandle(handle).(func()) callback() } //export updateHookTrampoline -func updateHookTrampoline(handle uintptr, op int, db *C.char, table *C.char, rowid int64) { +func updateHookTrampoline(handle unsafe.Pointer, op int, db *C.char, table *C.char, rowid int64) { callback := lookupHandle(handle).(func(int, string, string, int64)) callback(op, C.GoString(db), C.GoString(table), rowid) } //export authorizerTrampoline -func authorizerTrampoline(handle uintptr, op int, arg1 *C.char, arg2 *C.char, arg3 *C.char) int { +func authorizerTrampoline(handle unsafe.Pointer, op int, arg1 *C.char, arg2 *C.char, arg3 *C.char) int { callback := lookupHandle(handle).(func(int, string, string, string) int) return callback(op, C.GoString(arg1), C.GoString(arg2), C.GoString(arg3)) } //export preUpdateHookTrampoline -func preUpdateHookTrampoline(handle uintptr, dbHandle uintptr, op int, db *C.char, table *C.char, oldrowid int64, newrowid int64) { +func preUpdateHookTrampoline(handle unsafe.Pointer, dbHandle uintptr, op int, db *C.char, table *C.char, oldrowid int64, newrowid int64) { hval := lookupHandleVal(handle) data := SQLitePreUpdateData{ Conn: hval.db, @@ -105,33 +104,27 @@ type handleVal struct { } var handleLock sync.Mutex -var handleVals = make(map[uintptr]handleVal) -var handleIndex uintptr = 100 +var handleVals = make(map[unsafe.Pointer]handleVal) -func newHandle(db *SQLiteConn, v interface{}) uintptr { +func newHandle(db *SQLiteConn, v interface{}) unsafe.Pointer { handleLock.Lock() defer handleLock.Unlock() - i := handleIndex - handleIndex++ - handleVals[i] = handleVal{db, v} - return i + val := handleVal{db: db, val: v} + var p unsafe.Pointer = C.malloc(C.size_t(1)) + if p == nil { + panic("can't allocate 'cgo-pointer hack index pointer': ptr == nil") + } + handleVals[p] = val + return p } -func lookupHandleVal(handle uintptr) handleVal { +func lookupHandleVal(handle unsafe.Pointer) handleVal { handleLock.Lock() defer handleLock.Unlock() - r, ok := handleVals[handle] - if !ok { - if handle >= 100 && handle < handleIndex { - panic("deleted handle") - } else { - panic("invalid handle") - } - } - return r + return handleVals[handle] } -func lookupHandle(handle uintptr) interface{} { +func lookupHandle(handle unsafe.Pointer) interface{} { return lookupHandleVal(handle).val } @@ -141,6 +134,7 @@ func deleteHandles(db *SQLiteConn) { for handle, val := range handleVals { if val.db == db { delete(handleVals, handle) + C.free(handle) } } } @@ -473,7 +473,7 @@ func (c *SQLiteConn) RegisterCollation(name string, cmp func(string, string) int handle := newHandle(c, cmp) cname := C.CString(name) defer C.free(unsafe.Pointer(cname)) - rv := C.sqlite3_create_collation(c.db, cname, C.SQLITE_UTF8, unsafe.Pointer(handle), (*[0]byte)(unsafe.Pointer(C.compareTrampoline))) + rv := C.sqlite3_create_collation(c.db, cname, C.SQLITE_UTF8, handle, (*[0]byte)(unsafe.Pointer(C.compareTrampoline))) if rv != C.SQLITE_OK { return c.lastError() } @@ -491,7 +491,7 @@ func (c *SQLiteConn) RegisterCommitHook(callback func() int) { if callback == nil { C.sqlite3_commit_hook(c.db, nil, nil) } else { - C.sqlite3_commit_hook(c.db, (*[0]byte)(C.commitHookTrampoline), unsafe.Pointer(newHandle(c, callback))) + C.sqlite3_commit_hook(c.db, (*[0]byte)(C.commitHookTrampoline), newHandle(c, callback)) } } @@ -504,7 +504,7 @@ func (c *SQLiteConn) RegisterRollbackHook(callback func()) { if callback == nil { C.sqlite3_rollback_hook(c.db, nil, nil) } else { - C.sqlite3_rollback_hook(c.db, (*[0]byte)(C.rollbackHookTrampoline), unsafe.Pointer(newHandle(c, callback))) + C.sqlite3_rollback_hook(c.db, (*[0]byte)(C.rollbackHookTrampoline), newHandle(c, callback)) } } @@ -521,7 +521,7 @@ func (c *SQLiteConn) RegisterUpdateHook(callback func(int, string, string, int64 if callback == nil { C.sqlite3_update_hook(c.db, nil, nil) } else { - C.sqlite3_update_hook(c.db, (*[0]byte)(C.updateHookTrampoline), unsafe.Pointer(newHandle(c, callback))) + C.sqlite3_update_hook(c.db, (*[0]byte)(C.updateHookTrampoline), newHandle(c, callback)) } } @@ -535,7 +535,7 @@ func (c *SQLiteConn) RegisterAuthorizer(callback func(int, string, string, strin if callback == nil { C.sqlite3_set_authorizer(c.db, nil, nil) } else { - C.sqlite3_set_authorizer(c.db, (*[0]byte)(C.authorizerTrampoline), unsafe.Pointer(newHandle(c, callback))) + C.sqlite3_set_authorizer(c.db, (*[0]byte)(C.authorizerTrampoline), newHandle(c, callback)) } } @@ -616,8 +616,8 @@ func (c *SQLiteConn) RegisterFunc(name string, impl interface{}, pure bool) erro return nil } -func sqlite3CreateFunction(db *C.sqlite3, zFunctionName *C.char, nArg C.int, eTextRep C.int, pApp uintptr, xFunc unsafe.Pointer, xStep unsafe.Pointer, xFinal unsafe.Pointer) C.int { - return C._sqlite3_create_function(db, zFunctionName, nArg, eTextRep, C.uintptr_t(pApp), (*[0]byte)(xFunc), (*[0]byte)(xStep), (*[0]byte)(xFinal)) +func sqlite3CreateFunction(db *C.sqlite3, zFunctionName *C.char, nArg C.int, eTextRep C.int, pApp unsafe.Pointer, xFunc unsafe.Pointer, xStep unsafe.Pointer, xFinal unsafe.Pointer) C.int { + return C._sqlite3_create_function(db, zFunctionName, nArg, eTextRep, C.uintptr_t(uintptr(pApp)), (*[0]byte)(xFunc), (*[0]byte)(xStep), (*[0]byte)(xFinal)) } // RegisterAggregator makes a Go type available as a SQLite aggregation function. @@ -804,7 +804,7 @@ func (c *SQLiteConn) exec(ctx context.Context, query string, args []namedValue) if s.(*SQLiteStmt).s != nil { stmtArgs := make([]namedValue, 0, len(args)) na := s.NumInput() - if len(args) - start < na { + if len(args)-start < na { s.Close() return nil, fmt.Errorf("not enough args to execute query: want %d got %d", na, len(args)) } @@ -864,8 +864,8 @@ func (c *SQLiteConn) query(ctx context.Context, query string, args []namedValue) } s.(*SQLiteStmt).cls = true na := s.NumInput() - if len(args) - start < na { - return nil, fmt.Errorf("not enough args to execute query: want %d got %d", na, len(args) - start) + if len(args)-start < na { + return nil, fmt.Errorf("not enough args to execute query: want %d got %d", na, len(args)-start) } // consume the number of arguments used in the current // statement and append all named arguments not contained diff --git a/sqlite3_opt_vtable.go b/sqlite3_opt_vtable.go index 1af1c60..c0a6214 100644 --- a/sqlite3_opt_vtable.go +++ b/sqlite3_opt_vtable.go @@ -353,7 +353,7 @@ func mPrintf(format, arg string) *C.char { //export goMInit func goMInit(db, pClientData unsafe.Pointer, argc C.int, argv **C.char, pzErr **C.char, isCreate C.int) C.uintptr_t { - m := lookupHandle(uintptr(pClientData)).(*sqliteModule) + m := lookupHandle(pClientData).(*sqliteModule) if m.c.db != (*C.sqlite3)(db) { *pzErr = mPrintf("%s", "Inconsistent db handles") return 0 @@ -379,12 +379,12 @@ func goMInit(db, pClientData unsafe.Pointer, argc C.int, argv **C.char, pzErr ** } vt := sqliteVTab{m, vTab} *pzErr = nil - return C.uintptr_t(newHandle(m.c, &vt)) + return C.uintptr_t(uintptr(newHandle(m.c, &vt))) } //export goVRelease func goVRelease(pVTab unsafe.Pointer, isDestroy C.int) *C.char { - vt := lookupHandle(uintptr(pVTab)).(*sqliteVTab) + vt := lookupHandle(pVTab).(*sqliteVTab) var err error if isDestroy == 1 { err = vt.vTab.Destroy() @@ -399,7 +399,7 @@ func goVRelease(pVTab unsafe.Pointer, isDestroy C.int) *C.char { //export goVOpen func goVOpen(pVTab unsafe.Pointer, pzErr **C.char) C.uintptr_t { - vt := lookupHandle(uintptr(pVTab)).(*sqliteVTab) + vt := lookupHandle(pVTab).(*sqliteVTab) vTabCursor, err := vt.vTab.Open() if err != nil { *pzErr = mPrintf("%s", err.Error()) @@ -407,12 +407,12 @@ func goVOpen(pVTab unsafe.Pointer, pzErr **C.char) C.uintptr_t { } vtc := sqliteVTabCursor{vt, vTabCursor} *pzErr = nil - return C.uintptr_t(newHandle(vt.module.c, &vtc)) + return C.uintptr_t(uintptr(newHandle(vt.module.c, &vtc))) } //export goVBestIndex func goVBestIndex(pVTab unsafe.Pointer, icp unsafe.Pointer) *C.char { - vt := lookupHandle(uintptr(pVTab)).(*sqliteVTab) + vt := lookupHandle(pVTab).(*sqliteVTab) info := (*C.sqlite3_index_info)(icp) csts := constraints(info) res, err := vt.vTab.BestIndex(csts, orderBys(info)) @@ -455,7 +455,7 @@ func goVBestIndex(pVTab unsafe.Pointer, icp unsafe.Pointer) *C.char { //export goVClose func goVClose(pCursor unsafe.Pointer) *C.char { - vtc := lookupHandle(uintptr(pCursor)).(*sqliteVTabCursor) + vtc := lookupHandle(pCursor).(*sqliteVTabCursor) err := vtc.vTabCursor.Close() if err != nil { return mPrintf("%s", err.Error()) @@ -465,13 +465,13 @@ func goVClose(pCursor unsafe.Pointer) *C.char { //export goMDestroy func goMDestroy(pClientData unsafe.Pointer) { - m := lookupHandle(uintptr(pClientData)).(*sqliteModule) + m := lookupHandle(pClientData).(*sqliteModule) m.module.DestroyModule() } //export goVFilter func goVFilter(pCursor unsafe.Pointer, idxNum C.int, idxName *C.char, argc C.int, argv **C.sqlite3_value) *C.char { - vtc := lookupHandle(uintptr(pCursor)).(*sqliteVTabCursor) + vtc := lookupHandle(pCursor).(*sqliteVTabCursor) args := (*[(math.MaxInt32 - 1) / unsafe.Sizeof((*C.sqlite3_value)(nil))]*C.sqlite3_value)(unsafe.Pointer(argv))[:argc:argc] vals := make([]interface{}, 0, argc) for _, v := range args { @@ -490,7 +490,7 @@ func goVFilter(pCursor unsafe.Pointer, idxNum C.int, idxName *C.char, argc C.int //export goVNext func goVNext(pCursor unsafe.Pointer) *C.char { - vtc := lookupHandle(uintptr(pCursor)).(*sqliteVTabCursor) + vtc := lookupHandle(pCursor).(*sqliteVTabCursor) err := vtc.vTabCursor.Next() if err != nil { return mPrintf("%s", err.Error()) @@ -500,7 +500,7 @@ func goVNext(pCursor unsafe.Pointer) *C.char { //export goVEof func goVEof(pCursor unsafe.Pointer) C.int { - vtc := lookupHandle(uintptr(pCursor)).(*sqliteVTabCursor) + vtc := lookupHandle(pCursor).(*sqliteVTabCursor) err := vtc.vTabCursor.EOF() if err { return 1 @@ -510,7 +510,7 @@ func goVEof(pCursor unsafe.Pointer) C.int { //export goVColumn func goVColumn(pCursor, cp unsafe.Pointer, col C.int) *C.char { - vtc := lookupHandle(uintptr(pCursor)).(*sqliteVTabCursor) + vtc := lookupHandle(pCursor).(*sqliteVTabCursor) c := (*SQLiteContext)(cp) err := vtc.vTabCursor.Column(c, int(col)) if err != nil { @@ -521,7 +521,7 @@ func goVColumn(pCursor, cp unsafe.Pointer, col C.int) *C.char { //export goVRowid func goVRowid(pCursor unsafe.Pointer, pRowid *C.sqlite3_int64) *C.char { - vtc := lookupHandle(uintptr(pCursor)).(*sqliteVTabCursor) + vtc := lookupHandle(pCursor).(*sqliteVTabCursor) rowid, err := vtc.vTabCursor.Rowid() if err != nil { return mPrintf("%s", err.Error()) @@ -532,7 +532,7 @@ func goVRowid(pCursor unsafe.Pointer, pRowid *C.sqlite3_int64) *C.char { //export goVUpdate func goVUpdate(pVTab unsafe.Pointer, argc C.int, argv **C.sqlite3_value, pRowid *C.sqlite3_int64) *C.char { - vt := lookupHandle(uintptr(pVTab)).(*sqliteVTab) + vt := lookupHandle(pVTab).(*sqliteVTab) var tname string if n, ok := vt.vTab.(interface { @@ -652,7 +652,7 @@ func (c *SQLiteConn) CreateModule(moduleName string, module Module) error { mname := C.CString(moduleName) defer C.free(unsafe.Pointer(mname)) udm := sqliteModule{c, moduleName, module} - rv := C._sqlite3_create_module(c.db, mname, C.uintptr_t(newHandle(c, &udm))) + rv := C._sqlite3_create_module(c.db, mname, C.uintptr_t(uintptr(newHandle(c, &udm)))) if rv != C.SQLITE_OK { return c.lastError() } |