Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gosqlite
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
gosqlite
Commits
ecae65ef
Commit
ecae65ef
authored
Oct 27, 2011
by
gwenn
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add CommitHook and RollbackHook methods.
parent
8f71d095
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
152 additions
and
74 deletions
+152
-74
hook.go
hook.go
+74
-11
sqlite.go
sqlite.go
+2
-0
trace.go
trace.go
+56
-56
trace_test.go
trace_test.go
+20
-7
No files found.
hook.go
View file @
ecae65ef
...
...
@@ -10,10 +10,22 @@ package sqlite
#include <sqlite3.h>
#include <stdlib.h>
extern
void goXUpdateHook(void *pArg, int action, char const *db, char const *table, sqlite3_int64 rowId
);
extern
int goXCommitHook(void *udp
);
static void goSqlite3UpdateHook(sqlite3 *db, void *pArg) {
sqlite3_update_hook(db, goXUpdateHook, pArg);
static void* goSqlite3CommitHook(sqlite3 *db, void *udp) {
return sqlite3_commit_hook(db, goXCommitHook, udp);
}
extern void goXRollbackHook(void *udp);
static void* goSqlite3RollbackHook(sqlite3 *db, void *udp) {
return sqlite3_rollback_hook(db, goXRollbackHook, udp);
}
extern void goXUpdateHook(void *udp, int action, char const *dbName, char const *tableName, sqlite3_int64 rowId);
static void* goSqlite3UpdateHook(sqlite3 *db, void *udp) {
return sqlite3_update_hook(db, goXUpdateHook, udp);
}
*/
import
"C"
...
...
@@ -22,26 +34,77 @@ import (
"unsafe"
)
type
UpdateHook
func
(
d
interface
{},
a
Action
,
db
,
table
string
,
rowId
int64
)
type
CommitHook
func
(
udp
interface
{})
int
type
sqliteCommitHook
struct
{
f
CommitHook
udp
interface
{}
}
//export goXCommitHook
func
goXCommitHook
(
udp
unsafe
.
Pointer
)
C
.
int
{
arg
:=
(
*
sqliteCommitHook
)(
udp
)
return
C
.
int
(
arg
.
f
(
arg
.
udp
))
}
// Calls http://sqlite.org/c3ref/commit_hook.html
func
(
c
*
Conn
)
CommitHook
(
f
CommitHook
,
udp
interface
{})
{
if
f
==
nil
{
c
.
commitHook
=
nil
C
.
sqlite3_commit_hook
(
c
.
db
,
nil
,
nil
)
return
}
// To make sure it is not gced, keep a reference in the connection.
c
.
commitHook
=
&
sqliteCommitHook
{
f
,
udp
}
C
.
goSqlite3CommitHook
(
c
.
db
,
unsafe
.
Pointer
(
c
.
commitHook
))
}
type
RollbackHook
func
(
udp
interface
{})
type
sqliteRollbackHook
struct
{
f
RollbackHook
udp
interface
{}
}
//export goXRollbackHook
func
goXRollbackHook
(
udp
unsafe
.
Pointer
)
{
arg
:=
(
*
sqliteRollbackHook
)(
udp
)
arg
.
f
(
arg
.
udp
)
}
// Calls http://sqlite.org/c3ref/commit_hook.html
func
(
c
*
Conn
)
RollbackHook
(
f
RollbackHook
,
udp
interface
{})
{
if
f
==
nil
{
c
.
rollbackHook
=
nil
C
.
sqlite3_rollback_hook
(
c
.
db
,
nil
,
nil
)
return
}
// To make sure it is not gced, keep a reference in the connection.
c
.
rollbackHook
=
&
sqliteRollbackHook
{
f
,
udp
}
C
.
goSqlite3RollbackHook
(
c
.
db
,
unsafe
.
Pointer
(
c
.
rollbackHook
))
}
type
UpdateHook
func
(
udp
interface
{},
a
Action
,
dbName
,
tableName
string
,
rowId
int64
)
type
sqliteUpdateHook
struct
{
f
UpdateHook
d
interface
{}
f
UpdateHook
udp
interface
{}
}
//export goXUpdateHook
func
goXUpdateHook
(
pArg
unsafe
.
Pointer
,
action
C
.
int
,
db
,
tabl
e
*
C
.
char
,
rowId
C
.
sqlite3_int64
)
{
arg
:=
(
*
sqliteUpdateHook
)(
pArg
)
arg
.
f
(
arg
.
d
,
Action
(
action
),
C
.
GoString
(
db
),
C
.
GoString
(
tabl
e
),
int64
(
rowId
))
func
goXUpdateHook
(
udp
unsafe
.
Pointer
,
action
C
.
int
,
dbName
,
tableNam
e
*
C
.
char
,
rowId
C
.
sqlite3_int64
)
{
arg
:=
(
*
sqliteUpdateHook
)(
udp
)
arg
.
f
(
arg
.
udp
,
Action
(
action
),
C
.
GoString
(
dbName
),
C
.
GoString
(
tableNam
e
),
int64
(
rowId
))
}
// Calls http://sqlite.org/c3ref/update_hook.html
func
(
c
*
Conn
)
UpdateHook
(
f
UpdateHook
,
arg
interface
{})
{
func
(
c
*
Conn
)
UpdateHook
(
f
UpdateHook
,
udp
interface
{})
{
if
f
==
nil
{
c
.
updateHook
=
nil
C
.
sqlite3_update_hook
(
c
.
db
,
nil
,
nil
)
return
}
// To make sure it is not gced, keep a reference in the connection.
c
.
updateHook
=
&
sqliteUpdateHook
{
f
,
arg
}
c
.
updateHook
=
&
sqliteUpdateHook
{
f
,
udp
}
C
.
goSqlite3UpdateHook
(
c
.
db
,
unsafe
.
Pointer
(
c
.
updateHook
))
}
sqlite.go
View file @
ecae65ef
...
...
@@ -140,6 +140,8 @@ type Conn struct {
profile
*
sqliteProfile
progressHandler
*
sqliteProgressHandler
trace
*
sqliteTrace
commitHook
*
sqliteCommitHook
rollbackHook
*
sqliteRollbackHook
updateHook
*
sqliteUpdateHook
}
...
...
trace.go
View file @
ecae65ef
...
...
@@ -10,33 +10,33 @@ package sqlite
#include <sqlite3.h>
#include <stdlib.h>
extern void goXTrace(void *
pArg, const char *t
);
extern void goXTrace(void *
udp, const char *sql
);
static void goSqlite3Trace(sqlite3 *db, void *
pArg
) {
sqlite3_trace(db, goXTrace,
pArg
);
static void goSqlite3Trace(sqlite3 *db, void *
udp
) {
sqlite3_trace(db, goXTrace,
udp
);
}
extern void goXProfile(void *
pArg
, const char *sql, sqlite3_uint64 nanoseconds);
extern void goXProfile(void *
udp
, const char *sql, sqlite3_uint64 nanoseconds);
static void goSqlite3Profile(sqlite3 *db, void *
pArg
) {
sqlite3_profile(db, goXProfile,
pArg
);
static void goSqlite3Profile(sqlite3 *db, void *
udp
) {
sqlite3_profile(db, goXProfile,
udp
);
}
extern int goXAuth(void *
pUserData, int action, const char *arg1, const char *arg2, const char *arg3, const char *arg4
);
extern int goXAuth(void *
udp, int action, const char *arg1, const char *arg2, const char *dbName, const char *triggerName
);
static int goSqlite3SetAuthorizer(sqlite3 *db, void *
pUserData
) {
return sqlite3_set_authorizer(db, goXAuth,
pUserData
);
static int goSqlite3SetAuthorizer(sqlite3 *db, void *
udp
) {
return sqlite3_set_authorizer(db, goXAuth,
udp
);
}
extern int goXBusy(void *
pArg, int n
);
extern int goXBusy(void *
udp, int count
);
static int goSqlite3BusyHandler(sqlite3 *db, void *
pArg
) {
return sqlite3_busy_handler(db, goXBusy,
pArg
);
static int goSqlite3BusyHandler(sqlite3 *db, void *
udp
) {
return sqlite3_busy_handler(db, goXBusy,
udp
);
}
extern int goXProgress(void *
pArg
);
extern int goXProgress(void *
udp
);
static void goSqlite3ProgressHandler(sqlite3 *db, int
freq, void *pArg
) {
sqlite3_progress_handler(db,
freq, goXProgress, pArg
);
static void goSqlite3ProgressHandler(sqlite3 *db, int
numOps, void *udp
) {
sqlite3_progress_handler(db,
numOps, goXProgress, udp
);
}
// cgo doesn't support varargs
...
...
@@ -51,53 +51,53 @@ import (
"unsafe"
)
type
Tracer
func
(
d
interface
{},
t
string
)
type
Tracer
func
(
udp
interface
{},
sql
string
)
type
sqliteTrace
struct
{
f
Tracer
d
interface
{}
f
Tracer
udp
interface
{}
}
//export goXTrace
func
goXTrace
(
pArg
unsafe
.
Pointer
,
t
*
C
.
char
)
{
arg
:=
(
*
sqliteTrace
)(
pArg
)
arg
.
f
(
arg
.
d
,
C
.
GoString
(
t
))
func
goXTrace
(
udp
unsafe
.
Pointer
,
sql
*
C
.
char
)
{
arg
:=
(
*
sqliteTrace
)(
udp
)
arg
.
f
(
arg
.
udp
,
C
.
GoString
(
sql
))
}
// Calls sqlite3_trace, http://sqlite.org/c3ref/profile.html
func
(
c
*
Conn
)
Trace
(
f
Tracer
,
arg
interface
{})
{
func
(
c
*
Conn
)
Trace
(
f
Tracer
,
udp
interface
{})
{
if
f
==
nil
{
c
.
trace
=
nil
C
.
sqlite3_trace
(
c
.
db
,
nil
,
nil
)
return
}
// To make sure it is not gced, keep a reference in the connection.
c
.
trace
=
&
sqliteTrace
{
f
,
arg
}
c
.
trace
=
&
sqliteTrace
{
f
,
udp
}
C
.
goSqlite3Trace
(
c
.
db
,
unsafe
.
Pointer
(
c
.
trace
))
}
type
Profiler
func
(
d
interface
{},
sql
string
,
nanoseconds
uint64
)
type
Profiler
func
(
udp
interface
{},
sql
string
,
nanoseconds
uint64
)
type
sqliteProfile
struct
{
f
Profiler
d
interface
{}
f
Profiler
udp
interface
{}
}
//export goXProfile
func
goXProfile
(
pArg
unsafe
.
Pointer
,
sql
*
C
.
char
,
nanoseconds
C
.
sqlite3_uint64
)
{
arg
:=
(
*
sqliteProfile
)(
pArg
)
arg
.
f
(
arg
.
d
,
C
.
GoString
(
sql
),
uint64
(
nanoseconds
))
func
goXProfile
(
udp
unsafe
.
Pointer
,
sql
*
C
.
char
,
nanoseconds
C
.
sqlite3_uint64
)
{
arg
:=
(
*
sqliteProfile
)(
udp
)
arg
.
f
(
arg
.
udp
,
C
.
GoString
(
sql
),
uint64
(
nanoseconds
))
}
// Calls sqlite3_profile, http://sqlite.org/c3ref/profile.html
func
(
c
*
Conn
)
Profile
(
f
Profiler
,
arg
interface
{})
{
func
(
c
*
Conn
)
Profile
(
f
Profiler
,
udp
interface
{})
{
if
f
==
nil
{
c
.
profile
=
nil
C
.
sqlite3_profile
(
c
.
db
,
nil
,
nil
)
return
}
// To make sure it is not gced, keep a reference in the connection.
c
.
profile
=
&
sqliteProfile
{
f
,
arg
}
c
.
profile
=
&
sqliteProfile
{
f
,
udp
}
C
.
goSqlite3Profile
(
c
.
db
,
unsafe
.
Pointer
(
c
.
profile
))
}
...
...
@@ -147,82 +147,82 @@ const (
COPY
Action
=
C
.
SQLITE_COPY
)
type
Authorizer
func
(
d
interface
{},
action
Action
,
arg1
,
arg2
,
arg3
,
arg4
string
)
Auth
type
Authorizer
func
(
udp
interface
{},
action
Action
,
arg1
,
arg2
,
dbName
,
triggerName
string
)
Auth
type
sqliteAuthorizer
struct
{
f
Authorizer
d
interface
{}
f
Authorizer
udp
interface
{}
}
//export goXAuth
func
goXAuth
(
pUserData
unsafe
.
Pointer
,
action
C
.
int
,
arg1
,
arg2
,
arg3
,
arg4
*
C
.
char
)
C
.
int
{
arg
:=
(
*
sqliteAuthorizer
)(
pUserData
)
result
:=
arg
.
f
(
arg
.
d
,
Action
(
action
),
C
.
GoString
(
arg1
),
C
.
GoString
(
arg2
),
C
.
GoString
(
arg3
),
C
.
GoString
(
arg4
))
func
goXAuth
(
udp
unsafe
.
Pointer
,
action
C
.
int
,
arg1
,
arg2
,
dbName
,
triggerName
*
C
.
char
)
C
.
int
{
arg
:=
(
*
sqliteAuthorizer
)(
udp
)
result
:=
arg
.
f
(
arg
.
udp
,
Action
(
action
),
C
.
GoString
(
arg1
),
C
.
GoString
(
arg2
),
C
.
GoString
(
dbName
),
C
.
GoString
(
triggerName
))
return
C
.
int
(
result
)
}
// Calls http://sqlite.org/c3ref/set_authorizer.html
func
(
c
*
Conn
)
SetAuthorizer
(
f
Authorizer
,
arg
interface
{})
os
.
Error
{
func
(
c
*
Conn
)
SetAuthorizer
(
f
Authorizer
,
udp
interface
{})
os
.
Error
{
if
f
==
nil
{
c
.
authorizer
=
nil
return
c
.
error
(
C
.
sqlite3_set_authorizer
(
c
.
db
,
nil
,
nil
))
}
// To make sure it is not gced, keep a reference in the connection.
c
.
authorizer
=
&
sqliteAuthorizer
{
f
,
arg
}
c
.
authorizer
=
&
sqliteAuthorizer
{
f
,
udp
}
return
c
.
error
(
C
.
goSqlite3SetAuthorizer
(
c
.
db
,
unsafe
.
Pointer
(
c
.
authorizer
)))
}
type
BusyHandler
func
(
d
interface
{},
n
int
)
int
type
BusyHandler
func
(
udp
interface
{},
count
int
)
int
type
sqliteBusyHandler
struct
{
f
BusyHandler
d
interface
{}
f
BusyHandler
udp
interface
{}
}
//export goXBusy
func
goXBusy
(
pArg
unsafe
.
Pointer
,
n
C
.
int
)
C
.
int
{
arg
:=
(
*
sqliteBusyHandler
)(
pArg
)
result
:=
arg
.
f
(
arg
.
d
,
int
(
n
))
func
goXBusy
(
udp
unsafe
.
Pointer
,
count
C
.
int
)
C
.
int
{
arg
:=
(
*
sqliteBusyHandler
)(
udp
)
result
:=
arg
.
f
(
arg
.
udp
,
int
(
count
))
return
C
.
int
(
result
)
}
// TODO NOT TESTED
// Calls http://sqlite.org/c3ref/busy_handler.html
func
(
c
*
Conn
)
BusyHandler
(
f
BusyHandler
,
arg
interface
{})
os
.
Error
{
func
(
c
*
Conn
)
BusyHandler
(
f
BusyHandler
,
udp
interface
{})
os
.
Error
{
if
f
==
nil
{
c
.
busyHandler
=
nil
return
c
.
error
(
C
.
sqlite3_busy_handler
(
c
.
db
,
nil
,
nil
))
}
// To make sure it is not gced, keep a reference in the connection.
c
.
busyHandler
=
&
sqliteBusyHandler
{
f
,
arg
}
c
.
busyHandler
=
&
sqliteBusyHandler
{
f
,
udp
}
return
c
.
error
(
C
.
goSqlite3BusyHandler
(
c
.
db
,
unsafe
.
Pointer
(
c
.
busyHandler
)))
}
// Returns non-zero to interrupt.
type
ProgressHandler
func
(
d
interface
{})
int
type
ProgressHandler
func
(
udp
interface
{})
int
type
sqliteProgressHandler
struct
{
f
ProgressHandler
d
interface
{}
f
ProgressHandler
udp
interface
{}
}
//export goXProgress
func
goXProgress
(
pArg
unsafe
.
Pointer
)
C
.
int
{
arg
:=
(
*
sqliteProgressHandler
)(
pArg
)
result
:=
arg
.
f
(
arg
.
d
)
func
goXProgress
(
udp
unsafe
.
Pointer
)
C
.
int
{
arg
:=
(
*
sqliteProgressHandler
)(
udp
)
result
:=
arg
.
f
(
arg
.
udp
)
return
C
.
int
(
result
)
}
// Calls http://sqlite.org/c3ref/progress_handler.html
func
(
c
*
Conn
)
ProgressHandler
(
f
ProgressHandler
,
freq
int
,
arg
interface
{})
{
func
(
c
*
Conn
)
ProgressHandler
(
f
ProgressHandler
,
numOps
int
,
udp
interface
{})
{
if
f
==
nil
{
c
.
progressHandler
=
nil
C
.
sqlite3_progress_handler
(
c
.
db
,
0
,
nil
,
nil
)
return
}
// To make sure it is not gced, keep a reference in the connection.
c
.
progressHandler
=
&
sqliteProgressHandler
{
f
,
arg
}
C
.
goSqlite3ProgressHandler
(
c
.
db
,
C
.
int
(
freq
),
unsafe
.
Pointer
(
c
.
progressHandler
))
c
.
progressHandler
=
&
sqliteProgressHandler
{
f
,
udp
}
C
.
goSqlite3ProgressHandler
(
c
.
db
,
C
.
int
(
numOps
),
unsafe
.
Pointer
(
c
.
progressHandler
))
}
type
StmtStatus
int
...
...
trace_test.go
View file @
ecae65ef
...
...
@@ -6,12 +6,12 @@ import (
"testing"
)
func
trace
(
d
interface
{},
t
string
)
{
//fmt.Printf("%s: %s\n", d,
t
)
func
trace
(
d
interface
{},
sql
string
)
{
//fmt.Printf("%s: %s\n", d,
sql
)
}
func
authorizer
(
d
interface
{},
action
Action
,
arg1
,
arg2
,
arg3
,
arg4
string
)
Auth
{
//fmt.Printf("%s: %d, %s, %s, %s, %s\n", d, action, arg1, arg2,
arg3, arg4
)
func
authorizer
(
d
interface
{},
action
Action
,
arg1
,
arg2
,
dbName
,
triggerName
string
)
Auth
{
//fmt.Printf("%s: %d, %s, %s, %s, %s\n", d, action, arg1, arg2,
dbName, triggerName
)
return
AUTH_OK
}
...
...
@@ -24,8 +24,17 @@ func progressHandler(d interface{}) int {
return
0
}
func
update_hook
(
d
interface
{},
a
Action
,
db
,
table
string
,
rowId
int64
)
{
fmt
.
Printf
(
"%s: %d, %s.%s.%d
\n
"
,
d
,
a
,
db
,
table
,
rowId
)
func
commitHook
(
d
interface
{})
int
{
fmt
.
Printf
(
"%s
\n
"
,
d
)
return
0
}
func
rollbackHook
(
d
interface
{})
{
fmt
.
Printf
(
"%s
\n
"
,
d
)
}
func
updateHook
(
d
interface
{},
a
Action
,
dbName
,
tableName
string
,
rowId
int64
)
{
fmt
.
Printf
(
"%s: %d, %s.%s.%d
\n
"
,
d
,
a
,
dbName
,
tableName
,
rowId
)
}
func
TestNoTrace
(
t
*
testing
.
T
)
{
...
...
@@ -38,6 +47,8 @@ func TestNoTrace(t *testing.T) {
db
.
Profile
(
nil
,
nil
)
db
.
ProgressHandler
(
nil
,
0
,
nil
)
db
.
BusyHandler
(
nil
,
nil
)
db
.
CommitHook
(
nil
,
nil
)
db
.
RollbackHook
(
nil
,
nil
)
db
.
UpdateHook
(
nil
,
nil
)
db
.
Close
()
}
...
...
@@ -51,6 +62,8 @@ func TestTrace(t *testing.T) {
}
db
.
Profile
(
profile
,
"PROFILE"
)
db
.
ProgressHandler
(
progressHandler
,
1
,
/*20*/
nil
)
db
.
UpdateHook
(
update_hook
,
"TEST"
)
db
.
CommitHook
(
commitHook
,
"CMT"
)
db
.
RollbackHook
(
rollbackHook
,
"RBK"
)
db
.
UpdateHook
(
updateHook
,
"UPD"
)
db
.
Exists
(
"SELECT 1 WHERE 1 = ?"
,
1
)
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment