File tree Expand file tree Collapse file tree 3 files changed +111
-1
lines changed Expand file tree Collapse file tree 3 files changed +111
-1
lines changed Original file line number Diff line number Diff line change 1+ package cgosqlite
2+
3+ // #include <sqlite3.h>
4+ //
5+ // void logCallbackGo(void* userData, int errCode, char* msgC);
6+ //
7+ // static void log_callback_into_go(void *userData, int errCode, const char *msg) {
8+ // logCallbackGo(userData, errCode, (char*)msg);
9+ // }
10+ //
11+ // static int ts_sqlite3_config_log(void) {
12+ // return sqlite3_config(SQLITE_CONFIG_LOG, log_callback_into_go, NULL);
13+ // }
14+ import "C"
15+ import (
16+ "sync"
17+ "unsafe"
18+
19+ "github.com/tailscale/sqlite/sqliteh"
20+ )
21+
22+ // LogCallback receives SQLite log messages.
23+ type LogCallback func (code sqliteh.Code , msg string )
24+
25+ var (
26+ logCallbackMu sync.Mutex
27+ logCallback LogCallback
28+ )
29+
30+ //export logCallbackGo
31+ func logCallbackGo (userData unsafe.Pointer , errCode C.int , msgC * C.char ) {
32+ logCallbackMu .Lock ()
33+ cb := logCallback
34+ logCallbackMu .Unlock ()
35+
36+ if cb == nil {
37+ return
38+ }
39+
40+ msg := C .GoString (msgC )
41+ cb (sqliteh .Code (errCode ), msg )
42+ }
43+
44+ // SetLogCallback sets the global SQLite log callback.
45+ // If callback is nil, logs are discarded.
46+ func SetLogCallback (callback LogCallback ) error {
47+ logCallbackMu .Lock ()
48+ logCallback = callback
49+ logCallbackMu .Unlock ()
50+
51+ res := C .ts_sqlite3_config_log ()
52+ return errCode (res )
53+ }
Original file line number Diff line number Diff line change 33
44package sqlite
55
6- import "github.com/tailscale/sqlite/cgosqlite"
6+ import (
7+ "github.com/tailscale/sqlite/cgosqlite"
8+ "github.com/tailscale/sqlite/sqliteh"
9+ )
710
811func init () {
912 Open = cgosqlite .Open
1013}
14+
15+ // LogCallback receives SQLite log messages.
16+ type LogCallback func (code sqliteh.Code , msg string )
17+
18+ // SetLogCallback sets the global SQLite log callback.
19+ // If callback is nil, logs are discarded.
20+ func SetLogCallback (callback LogCallback ) error {
21+ return cgosqlite .SetLogCallback (cgosqlite .LogCallback (callback ))
22+ }
Original file line number Diff line number Diff line change 1+ //go:build cgo
2+ // +build cgo
3+
4+ package sqlite
5+
6+ import (
7+ "sync"
8+ "testing"
9+
10+ "github.com/tailscale/sqlite/cgosqlite"
11+ "github.com/tailscale/sqlite/sqliteh"
12+ )
13+
14+ // ensure LogCallback is convertible to cgosqlite.LogCallback
15+ var _ cgosqlite.LogCallback = cgosqlite .LogCallback (LogCallback (func (code sqliteh.Code , msg string ) {}))
16+
17+ func TestSetLogCallback (t * testing.T ) {
18+ var mu sync.Mutex
19+ var logs []string
20+
21+ err := SetLogCallback (func (code sqliteh.Code , msg string ) {
22+ mu .Lock ()
23+ defer mu .Unlock ()
24+ logs = append (logs , msg )
25+ })
26+ if err != nil {
27+ t .Fatal (err )
28+ }
29+ defer SetLogCallback (nil )
30+
31+ db := openTestDB (t )
32+
33+ _ , err = db .Exec ("SELECT * FROM nonexistent_table" )
34+ if err == nil {
35+ t .Fatal ("expected error from invalid SQL" )
36+ }
37+
38+ mu .Lock ()
39+ gotLogs := len (logs ) > 0
40+ mu .Unlock ()
41+
42+ if ! gotLogs {
43+ t .Fatal ("expected to receive log messages" )
44+ }
45+ }
You can’t perform that action at this time.
0 commit comments