Skip to content

Commit 32ab0d8

Browse files
committed
refactoring
1 parent d5ce942 commit 32ab0d8

File tree

4 files changed

+202
-197
lines changed

4 files changed

+202
-197
lines changed

sqlite3.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ func (c *SQLiteConn) exec(ctx context.Context, query string, args []namedValue)
431431
na := s.NumInput()
432432
if len(args) < na {
433433
s.Close()
434-
return nil, fmt.Errorf("Not enough args to execute query. Expected %d, got %d.", na, len(args))
434+
return nil, fmt.Errorf("not enough args to execute query: want %d got %d", na, len(args))
435435
}
436436
for i := 0; i < na; i++ {
437437
args[i].Ordinal -= start
@@ -481,7 +481,7 @@ func (c *SQLiteConn) query(ctx context.Context, query string, args []namedValue)
481481
s.(*SQLiteStmt).cls = true
482482
na := s.NumInput()
483483
if len(args) < na {
484-
return nil, fmt.Errorf("Not enough args to execute query. Expected %d, got %d.", na, len(args))
484+
return nil, fmt.Errorf("not enough args to execute query: want %d got %d", na, len(args))
485485
}
486486
for i := 0; i < na; i++ {
487487
args[i].Ordinal -= start

vtable.go renamed to sqlite3_vtable.go

Lines changed: 199 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,198 @@ package sqlite3
2020
#endif
2121
#include <stdlib.h>
2222
#include <stdint.h>
23+
#include <memory.h>
2324
24-
int goSqlite3CreateModule(sqlite3 *db, const char *zName, uintptr_t pClientData);
25+
static inline char *_sqlite3_mprintf(char *zFormat, char *arg) {
26+
return sqlite3_mprintf(zFormat, arg);
27+
}
28+
29+
typedef struct goVTab goVTab;
30+
31+
struct goVTab {
32+
sqlite3_vtab base;
33+
void *vTab;
34+
};
35+
36+
uintptr_t goMInit(void *db, void *pAux, int argc, char **argv, char **pzErr, int isCreate);
37+
38+
static int cXInit(sqlite3 *db, void *pAux, int argc, const char *const*argv, sqlite3_vtab **ppVTab, char **pzErr, int isCreate) {
39+
void *vTab = (void *)goMInit(db, pAux, argc, (char**)argv, pzErr, isCreate);
40+
if (!vTab || *pzErr) {
41+
return SQLITE_ERROR;
42+
}
43+
goVTab *pvTab = (goVTab *)sqlite3_malloc(sizeof(goVTab));
44+
if (!pvTab) {
45+
*pzErr = sqlite3_mprintf("%s", "Out of memory");
46+
return SQLITE_NOMEM;
47+
}
48+
memset(pvTab, 0, sizeof(goVTab));
49+
pvTab->vTab = vTab;
50+
51+
*ppVTab = (sqlite3_vtab *)pvTab;
52+
*pzErr = 0;
53+
return SQLITE_OK;
54+
}
55+
56+
static inline int cXCreate(sqlite3 *db, void *pAux, int argc, const char *const*argv, sqlite3_vtab **ppVTab, char **pzErr) {
57+
return cXInit(db, pAux, argc, argv, ppVTab, pzErr, 1);
58+
}
59+
static inline int cXConnect(sqlite3 *db, void *pAux, int argc, const char *const*argv, sqlite3_vtab **ppVTab, char **pzErr) {
60+
return cXInit(db, pAux, argc, argv, ppVTab, pzErr, 0);
61+
}
62+
63+
char* goVBestIndex(void *pVTab, void *icp);
64+
65+
static inline int cXBestIndex(sqlite3_vtab *pVTab, sqlite3_index_info *info) {
66+
char *pzErr = goVBestIndex(((goVTab*)pVTab)->vTab, info);
67+
if (pzErr) {
68+
if (pVTab->zErrMsg)
69+
sqlite3_free(pVTab->zErrMsg);
70+
pVTab->zErrMsg = pzErr;
71+
return SQLITE_ERROR;
72+
}
73+
return SQLITE_OK;
74+
}
75+
76+
char* goVRelease(void *pVTab, int isDestroy);
77+
78+
static int cXRelease(sqlite3_vtab *pVTab, int isDestroy) {
79+
char *pzErr = goVRelease(((goVTab*)pVTab)->vTab, isDestroy);
80+
if (pzErr) {
81+
if (pVTab->zErrMsg)
82+
sqlite3_free(pVTab->zErrMsg);
83+
pVTab->zErrMsg = pzErr;
84+
return SQLITE_ERROR;
85+
}
86+
if (pVTab->zErrMsg)
87+
sqlite3_free(pVTab->zErrMsg);
88+
sqlite3_free(pVTab);
89+
return SQLITE_OK;
90+
}
91+
92+
static inline int cXDisconnect(sqlite3_vtab *pVTab) {
93+
return cXRelease(pVTab, 0);
94+
}
95+
static inline int cXDestroy(sqlite3_vtab *pVTab) {
96+
return cXRelease(pVTab, 1);
97+
}
98+
99+
typedef struct goVTabCursor goVTabCursor;
100+
101+
struct goVTabCursor {
102+
sqlite3_vtab_cursor base;
103+
void *vTabCursor;
104+
};
105+
106+
uintptr_t goVOpen(void *pVTab, char **pzErr);
107+
108+
static int cXOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor) {
109+
void *vTabCursor = (void *)goVOpen(((goVTab*)pVTab)->vTab, &(pVTab->zErrMsg));
110+
goVTabCursor *pCursor = (goVTabCursor *)sqlite3_malloc(sizeof(goVTabCursor));
111+
if (!pCursor) {
112+
return SQLITE_NOMEM;
113+
}
114+
memset(pCursor, 0, sizeof(goVTabCursor));
115+
pCursor->vTabCursor = vTabCursor;
116+
*ppCursor = (sqlite3_vtab_cursor *)pCursor;
117+
return SQLITE_OK;
118+
}
119+
120+
static int setErrMsg(sqlite3_vtab_cursor *pCursor, char *pzErr) {
121+
if (pCursor->pVtab->zErrMsg)
122+
sqlite3_free(pCursor->pVtab->zErrMsg);
123+
pCursor->pVtab->zErrMsg = pzErr;
124+
return SQLITE_ERROR;
125+
}
126+
127+
char* goVClose(void *pCursor);
128+
129+
static int cXClose(sqlite3_vtab_cursor *pCursor) {
130+
char *pzErr = goVClose(((goVTabCursor*)pCursor)->vTabCursor);
131+
if (pzErr) {
132+
return setErrMsg(pCursor, pzErr);
133+
}
134+
sqlite3_free(pCursor);
135+
return SQLITE_OK;
136+
}
137+
138+
char* goVFilter(void *pCursor, int idxNum, char* idxName, int argc, sqlite3_value **argv);
139+
140+
static int cXFilter(sqlite3_vtab_cursor *pCursor, int idxNum, const char *idxStr, int argc, sqlite3_value **argv) {
141+
char *pzErr = goVFilter(((goVTabCursor*)pCursor)->vTabCursor, idxNum, (char*)idxStr, argc, argv);
142+
if (pzErr) {
143+
return setErrMsg(pCursor, pzErr);
144+
}
145+
return SQLITE_OK;
146+
}
147+
148+
char* goVNext(void *pCursor);
149+
150+
static int cXNext(sqlite3_vtab_cursor *pCursor) {
151+
char *pzErr = goVNext(((goVTabCursor*)pCursor)->vTabCursor);
152+
if (pzErr) {
153+
return setErrMsg(pCursor, pzErr);
154+
}
155+
return SQLITE_OK;
156+
}
157+
158+
int goVEof(void *pCursor);
159+
160+
static inline int cXEof(sqlite3_vtab_cursor *pCursor) {
161+
return goVEof(((goVTabCursor*)pCursor)->vTabCursor);
162+
}
163+
164+
char* goVColumn(void *pCursor, void *cp, int col);
165+
166+
static int cXColumn(sqlite3_vtab_cursor *pCursor, sqlite3_context *ctx, int i) {
167+
char *pzErr = goVColumn(((goVTabCursor*)pCursor)->vTabCursor, ctx, i);
168+
if (pzErr) {
169+
return setErrMsg(pCursor, pzErr);
170+
}
171+
return SQLITE_OK;
172+
}
173+
174+
char* goVRowid(void *pCursor, sqlite3_int64 *pRowid);
175+
176+
static int cXRowid(sqlite3_vtab_cursor *pCursor, sqlite3_int64 *pRowid) {
177+
char *pzErr = goVRowid(((goVTabCursor*)pCursor)->vTabCursor, pRowid);
178+
if (pzErr) {
179+
return setErrMsg(pCursor, pzErr);
180+
}
181+
return SQLITE_OK;
182+
}
25183
26-
static inline char *my_mprintf(char *zFormat, char *arg) {
27-
return sqlite3_mprintf(zFormat, arg);
184+
static sqlite3_module goModule = {
185+
0, // iVersion
186+
cXCreate, // xCreate - create a table
187+
cXConnect, // xConnect - connect to an existing table
188+
cXBestIndex, // xBestIndex - Determine search strategy
189+
cXDisconnect, // xDisconnect - Disconnect from a table
190+
cXDestroy, // xDestroy - Drop a table
191+
cXOpen, // xOpen - open a cursor
192+
cXClose, // xClose - close a cursor
193+
cXFilter, // xFilter - configure scan constraints
194+
cXNext, // xNext - advance a cursor
195+
cXEof, // xEof
196+
cXColumn, // xColumn - read data
197+
cXRowid, // xRowid - read data
198+
// Not implemented
199+
0, // xUpdate - write data
200+
0, // xBegin - begin transaction
201+
0, // xSync - sync transaction
202+
0, // xCommit - commit transaction
203+
0, // xRollback - rollback transaction
204+
0, // xFindFunction - function overloading
205+
0, // xRename - rename the table
206+
0, // xSavepoint
207+
0, // xRelease
208+
0 // xRollbackTo
209+
};
210+
211+
void goMDestroy(void*);
212+
213+
static int _sqlite3_create_module(sqlite3 *db, const char *zName, uintptr_t pClientData) {
214+
return sqlite3_create_module_v2(db, zName, &goModule, (void*) pClientData, goMDestroy);
28215
}
29216
*/
30217
import "C"
@@ -136,19 +323,19 @@ func mPrintf(format, arg string) *C.char {
136323
defer C.free(unsafe.Pointer(cf))
137324
ca := C.CString(arg)
138325
defer C.free(unsafe.Pointer(ca))
139-
return C.my_mprintf(cf, ca)
326+
return C._sqlite3_mprintf(cf, ca)
140327
}
141328

142329
//export goMInit
143-
func goMInit(db, pClientData unsafe.Pointer, argc int, argv **C.char, pzErr **C.char, isCreate int) C.uintptr_t {
330+
func goMInit(db, pClientData unsafe.Pointer, argc C.int, argv **C.char, pzErr **C.char, isCreate C.int) C.uintptr_t {
144331
m := lookupHandle(uintptr(pClientData)).(*sqliteModule)
145332
if m.c.db != (*C.sqlite3)(db) {
146333
*pzErr = mPrintf("%s", "Inconsistent db handles")
147334
return 0
148335
}
149336
args := make([]string, argc)
150337
var A []*C.char
151-
slice := reflect.SliceHeader{Data: uintptr(unsafe.Pointer(argv)), Len: argc, Cap: argc}
338+
slice := reflect.SliceHeader{Data: uintptr(unsafe.Pointer(argv)), Len: int(argc), Cap: int(argc)}
152339
a := reflect.NewAt(reflect.TypeOf(A), unsafe.Pointer(&slice)).Elem().Interface()
153340
for i, s := range a.([]*C.char) {
154341
args[i] = C.GoString(s)
@@ -171,7 +358,7 @@ func goMInit(db, pClientData unsafe.Pointer, argc int, argv **C.char, pzErr **C.
171358
}
172359

173360
//export goVRelease
174-
func goVRelease(pVTab unsafe.Pointer, isDestroy int) *C.char {
361+
func goVRelease(pVTab unsafe.Pointer, isDestroy C.int) *C.char {
175362
vt := lookupHandle(uintptr(pVTab)).(*sqliteVTab)
176363
var err error
177364
if isDestroy == 1 {
@@ -254,7 +441,7 @@ func goMDestroy(pClientData unsafe.Pointer) {
254441
}
255442

256443
//export goVFilter
257-
func goVFilter(pCursor unsafe.Pointer, idxNum int, idxName *C.char, argc int, argv **C.sqlite3_value) *C.char {
444+
func goVFilter(pCursor unsafe.Pointer, idxNum C.int, idxName *C.char, argc C.int, argv **C.sqlite3_value) *C.char {
258445
vtc := lookupHandle(uintptr(pCursor)).(*sqliteVTabCursor)
259446
args := (*[(math.MaxInt32 - 1) / unsafe.Sizeof((*C.sqlite3_value)(nil))]*C.sqlite3_value)(unsafe.Pointer(argv))[:argc:argc]
260447
vals := make([]interface{}, 0, argc)
@@ -265,7 +452,7 @@ func goVFilter(pCursor unsafe.Pointer, idxNum int, idxName *C.char, argc int, ar
265452
}
266453
vals = append(vals, conv.Interface())
267454
}
268-
err := vtc.vTabCursor.Filter(idxNum, C.GoString(idxName), vals)
455+
err := vtc.vTabCursor.Filter(int(idxNum), C.GoString(idxName), vals)
269456
if err != nil {
270457
return mPrintf("%s", err.Error())
271458
}
@@ -293,10 +480,10 @@ func goVEof(pCursor unsafe.Pointer) C.int {
293480
}
294481

295482
//export goVColumn
296-
func goVColumn(pCursor, cp unsafe.Pointer, col int) *C.char {
483+
func goVColumn(pCursor, cp unsafe.Pointer, col C.int) *C.char {
297484
vtc := lookupHandle(uintptr(pCursor)).(*sqliteVTabCursor)
298485
c := (*SQLiteContext)(cp)
299-
err := vtc.vTabCursor.Column(c, col)
486+
err := vtc.vTabCursor.Column(c, int(col))
300487
if err != nil {
301488
return mPrintf("%s", err.Error())
302489
}
@@ -373,7 +560,7 @@ func (c *SQLiteConn) CreateModule(moduleName string, module Module) error {
373560
mname := C.CString(moduleName)
374561
defer C.free(unsafe.Pointer(mname))
375562
udm := sqliteModule{c, moduleName, module}
376-
rv := C.goSqlite3CreateModule(c.db, mname, C.uintptr_t(newHandle(c, &udm)))
563+
rv := C._sqlite3_create_module(c.db, mname, C.uintptr_t(newHandle(c, &udm)))
377564
if rv != C.SQLITE_OK {
378565
return c.lastError()
379566
}

vtable_test.go renamed to sqlite3_vtable_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ func TestCreateModule(t *testing.T) {
133133
}
134134
_, err = db.Exec("CREATE VIRTUAL TABLE vtab USING test('1', 2, three)")
135135
if err != nil {
136-
t.Fatal("could not create vtable: %v", err)
136+
t.Fatalf("could not create vtable: %v", err)
137137
}
138138

139139
var i, value int

0 commit comments

Comments
 (0)