Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 0eec847

Browse files
authored
Merge pull request mattn#623 from graf0/feature/mattn#619
implementation of set_authorizer interface
2 parents 3198c77 + df0c034 commit 0eec847

File tree

3 files changed

+102
-0
lines changed

3 files changed

+102
-0
lines changed

‎callback.go‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,12 @@ func updateHookTrampoline(handle uintptr, op int, db *C.char, table *C.char, row
7777
callback(op, C.GoString(db), C.GoString(table), rowid)
7878
}
7979

80+
//export authorizerTrampoline
81+
func authorizerTrampoline(handle uintptr, op int, arg1 *C.char, arg2 *C.char, arg3 *C.char) int {
82+
callback := lookupHandle(handle).(func(int, string, string, string) int)
83+
return callback(op, C.GoString(arg1), C.GoString(arg2), C.GoString(arg3))
84+
}
85+
8086
// Use handles to avoid passing Go pointers to C.
8187

8288
type handleVal struct {

‎sqlite3.go‎

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ int commitHookTrampoline(void*);
119119
void rollbackHookTrampoline(void*);
120120
void updateHookTrampoline(void*, int, char*, char*, sqlite3_int64);
121121
122+
int authorizerTrampoline(void*, int, char*, char*, char*, char*);
123+
122124
#ifdef SQLITE_LIMIT_WORKER_THREADS
123125
# define _SQLITE_HAS_LIMIT
124126
# define SQLITE_LIMIT_LENGTH 0
@@ -200,9 +202,48 @@ func Version() (libVersion string, libVersionNumber int, sourceID string) {
200202
}
201203

202204
const (
205+
// used by authorizer and pre_update_hook
203206
SQLITE_DELETE = C.SQLITE_DELETE
204207
SQLITE_INSERT = C.SQLITE_INSERT
205208
SQLITE_UPDATE = C.SQLITE_UPDATE
209+
210+
// used by authorzier - as return value
211+
SQLITE_OK = C.SQLITE_OK
212+
SQLITE_IGNORE = C.SQLITE_IGNORE
213+
SQLITE_DENY = C.SQLITE_DENY
214+
215+
// different actions query tries to do - passed as argument to authorizer
216+
SQLITE_CREATE_INDEX = C.SQLITE_CREATE_INDEX
217+
SQLITE_CREATE_TABLE = C.SQLITE_CREATE_TABLE
218+
SQLITE_CREATE_TEMP_INDEX = C.SQLITE_CREATE_TEMP_INDEX
219+
SQLITE_CREATE_TEMP_TABLE = C.SQLITE_CREATE_TEMP_TABLE
220+
SQLITE_CREATE_TEMP_TRIGGER = C.SQLITE_CREATE_TEMP_TRIGGER
221+
SQLITE_CREATE_TEMP_VIEW = C.SQLITE_CREATE_TEMP_VIEW
222+
SQLITE_CREATE_TRIGGER = C.SQLITE_CREATE_TRIGGER
223+
SQLITE_CREATE_VIEW = C.SQLITE_CREATE_VIEW
224+
SQLITE_CREATE_VTABLE = C.SQLITE_CREATE_VTABLE
225+
SQLITE_DROP_INDEX = C.SQLITE_DROP_INDEX
226+
SQLITE_DROP_TABLE = C.SQLITE_DROP_TABLE
227+
SQLITE_DROP_TEMP_INDEX = C.SQLITE_DROP_TEMP_INDEX
228+
SQLITE_DROP_TEMP_TABLE = C.SQLITE_DROP_TEMP_TABLE
229+
SQLITE_DROP_TEMP_TRIGGER = C.SQLITE_DROP_TEMP_TRIGGER
230+
SQLITE_DROP_TEMP_VIEW = C.SQLITE_DROP_TEMP_VIEW
231+
SQLITE_DROP_TRIGGER = C.SQLITE_DROP_TRIGGER
232+
SQLITE_DROP_VIEW = C.SQLITE_DROP_VIEW
233+
SQLITE_DROP_VTABLE = C.SQLITE_DROP_VTABLE
234+
SQLITE_PRAGMA = C.SQLITE_PRAGMA
235+
SQLITE_READ = C.SQLITE_READ
236+
SQLITE_SELECT = C.SQLITE_SELECT
237+
SQLITE_TRANSACTION = C.SQLITE_TRANSACTION
238+
SQLITE_ATTACH = C.SQLITE_ATTACH
239+
SQLITE_DETACH = C.SQLITE_DETACH
240+
SQLITE_ALTER_TABLE = C.SQLITE_ALTER_TABLE
241+
SQLITE_REINDEX = C.SQLITE_REINDEX
242+
SQLITE_ANALYZE = C.SQLITE_ANALYZE
243+
SQLITE_FUNCTION = C.SQLITE_FUNCTION
244+
SQLITE_SAVEPOINT = C.SQLITE_SAVEPOINT
245+
SQLITE_COPY = C.SQLITE_COPY
246+
SQLITE_RECURSIVE = C.SQLITE_RECURSIVE
206247
)
207248

208249
// SQLiteDriver implements driver.Driver.
@@ -440,6 +481,20 @@ func (c *SQLiteConn) RegisterUpdateHook(callback func(int, string, string, int64
440481
}
441482
}
442483

484+
// RegisterAuthorizer sets the authorizer for connection.
485+
//
486+
// The parameters to the callback are the operation (one of the constants
487+
// SQLITE_INSERT, SQLITE_DELETE, or SQLITE_UPDATE), and 1 to 3 arguments,
488+
// depending on operation. More details see:
489+
// https://www.sqlite.org/c3ref/c_alter_table.html
490+
func (c *SQLiteConn) RegisterAuthorizer(callback func(int, string, string, string) int) {
491+
if callback == nil {
492+
C.sqlite3_set_authorizer(c.db, nil, nil)
493+
} else {
494+
C.sqlite3_set_authorizer(c.db, (*[0]byte)(C.authorizerTrampoline), unsafe.Pointer(newHandle(c, callback)))
495+
}
496+
}
497+
443498
// RegisterFunc makes a Go function available as a SQLite function.
444499
//
445500
// The Go function can have arguments of the following types: any

‎sqlite3_test.go‎

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1574,6 +1574,47 @@ func TestUpdateAndTransactionHooks(t *testing.T) {
15741574
}
15751575
}
15761576

1577+
func TestAuthorizer(t *testing.T) {
1578+
var authorizerReturn = 0
1579+
1580+
sql.Register("sqlite3_Authorizer", &SQLiteDriver{
1581+
ConnectHook: func(conn *SQLiteConn) error {
1582+
conn.RegisterAuthorizer(func(op int, arg1, arg2, arg3 string) int {
1583+
return authorizerReturn
1584+
})
1585+
return nil
1586+
},
1587+
})
1588+
db, err := sql.Open("sqlite3_Authorizer", ":memory:")
1589+
if err != nil {
1590+
t.Fatal("Failed to open database:", err)
1591+
}
1592+
defer db.Close()
1593+
1594+
statements := []string{
1595+
"create table foo (id integer primary key, name varchar)",
1596+
"insert into foo values (9, 'test9')",
1597+
"update foo set name = 'test99' where id = 9",
1598+
"select * from foo",
1599+
}
1600+
1601+
authorizerReturn = SQLITE_OK
1602+
for _, statement := range statements {
1603+
_, err = db.Exec(statement)
1604+
if err != nil {
1605+
t.Fatalf("No error expected [%v]: %v", statement, err)
1606+
}
1607+
}
1608+
1609+
authorizerReturn = SQLITE_DENY
1610+
for _, statement := range statements {
1611+
_, err = db.Exec(statement)
1612+
if err == nil {
1613+
t.Fatalf("Authorizer didn't worked - nil received, but error expected: [%v]", statement)
1614+
}
1615+
}
1616+
}
1617+
15771618
func TestNilAndEmptyBytes(t *testing.T) {
15781619
db, err := sql.Open("sqlite3", ":memory:")
15791620
if err != nil {

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /