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
dee9b21f
Commit
dee9b21f
authored
Jan 01, 2012
by
gwenn
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Second draft of user's defined functions in Go.
parent
7b3d5a3e
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
69 additions
and
37 deletions
+69
-37
function.go
function.go
+64
-32
hook.go
hook.go
+1
-1
trace.go
trace.go
+4
-4
No files found.
function.go
View file @
dee9b21f
...
@@ -17,6 +17,35 @@ static void my_result_blob(sqlite3_context *ctx, void *p, int np) {
...
@@ -17,6 +17,35 @@ static void my_result_blob(sqlite3_context *ctx, void *p, int np) {
sqlite3_result_blob(ctx, p, np, SQLITE_TRANSIENT);
sqlite3_result_blob(ctx, p, np, SQLITE_TRANSIENT);
}
}
static void my_result_value(sqlite3_context* ctx, sqlite3_value** argv, int i) {
sqlite3_result_value(ctx, argv[i]);
}
static const void *my_value_blob(sqlite3_value** argv, int i) {
return sqlite3_value_blob(argv[i]);
}
static int my_value_bytes(sqlite3_value** argv, int i) {
return sqlite3_value_bytes(argv[i]);
}
static double my_value_double(sqlite3_value** argv, int i) {
return sqlite3_value_double(argv[i]);
}
static int my_value_int(sqlite3_value** argv, int i) {
return sqlite3_value_int(argv[i]);
}
static sqlite3_int64 my_value_int64(sqlite3_value** argv, int i) {
return sqlite3_value_int64(argv[i]);
}
static const unsigned char *my_value_text(sqlite3_value** argv, int i) {
return sqlite3_value_text(argv[i]);
}
static int my_value_type(sqlite3_value** argv, int i) {
return sqlite3_value_type(argv[i]);
}
static int my_value_numeric_type(sqlite3_value** argv, int i) {
return sqlite3_value_numeric_type(argv[i]);
}
extern void goXFunc(sqlite3_context* ctx, int argc, sqlite3_value** argv);
extern void goXFunc(sqlite3_context* ctx, int argc, sqlite3_value** argv);
extern void goXDestroy(void *pApp);
extern void goXDestroy(void *pApp);
...
@@ -39,7 +68,7 @@ sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
...
@@ -39,7 +68,7 @@ sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
type
Context
struct
{
type
Context
struct
{
context
*
C
.
sqlite3_context
context
*
C
.
sqlite3_context
pApp
interface
{}
argv
**
C
.
sqlite3_value
}
}
// Set the result of an SQL function
// Set the result of an SQL function
...
@@ -111,9 +140,10 @@ func (c *Context) ResultText(s string) {
...
@@ -111,9 +140,10 @@ func (c *Context) ResultText(s string) {
}
}
// Set the result of an SQL function
// Set the result of an SQL function
// The leftmost value is number 0.
// Calls sqlite3_result_value, http://sqlite.org/c3ref/result_blob.html
// Calls sqlite3_result_value, http://sqlite.org/c3ref/result_blob.html
func
(
c
*
Context
)
ResultValue
(
v
*
Value
)
{
func
(
c
*
Context
)
ResultValue
(
i
int
)
{
C
.
sqlite3_result_value
(
c
.
context
,
v
.
value
)
C
.
my_result_value
(
c
.
context
,
c
.
argv
,
C
.
int
(
i
)
)
}
}
// Set the result of an SQL function
// Set the result of an SQL function
...
@@ -125,7 +155,8 @@ func (c *Context) ResultZeroblob(n ZeroBlobLength) {
...
@@ -125,7 +155,8 @@ func (c *Context) ResultZeroblob(n ZeroBlobLength) {
// User data for functions
// User data for functions
// Calls http://sqlite.org/c3ref/user_data.html
// Calls http://sqlite.org/c3ref/user_data.html
func
(
c
*
Context
)
UserData
()
interface
{}
{
func
(
c
*
Context
)
UserData
()
interface
{}
{
return
c
.
pApp
udp
:=
(
*
sqliteScalarFunction
)(
C
.
sqlite3_user_data
(
c
.
context
))
return
udp
.
pApp
}
}
// Function auxiliary data
// Function auxiliary data
...
@@ -142,59 +173,61 @@ func (c *Context) SetAuxData(n int, ad interface{}, f AuxDataDestructor) {
...
@@ -142,59 +173,61 @@ func (c *Context) SetAuxData(n int, ad interface{}, f AuxDataDestructor) {
// FIXME C.sqlite3_set_auxdata(c.context, C.int(n), unsafe.Pointer(ad), nil /*void (*)(void*)*/ )
// FIXME C.sqlite3_set_auxdata(c.context, C.int(n), unsafe.Pointer(ad), nil /*void (*)(void*)*/ )
}
}
// SQL function parameter value
// The leftmost value is number 0.
type
Value
struct
{
value
*
C
.
sqlite3_value
}
// Calls sqlite3_value_blob and sqlite3_value_bytes, http://sqlite.org/c3ref/value_blob.html
// Calls sqlite3_value_blob and sqlite3_value_bytes, http://sqlite.org/c3ref/value_blob.html
func
(
v
*
Value
)
Blob
(
)
(
value
[]
byte
)
{
func
(
c
*
Context
)
Blob
(
i
int
)
(
value
[]
byte
)
{
p
:=
C
.
sqlite3_value_blob
(
v
.
value
)
p
:=
C
.
my_value_blob
(
c
.
argv
,
C
.
int
(
i
)
)
if
p
!=
nil
{
if
p
!=
nil
{
n
:=
C
.
sqlite3_value_bytes
(
v
.
value
)
n
:=
C
.
my_value_bytes
(
c
.
argv
,
C
.
int
(
i
)
)
value
=
(
*
[
1
<<
30
]
byte
)(
unsafe
.
Pointer
(
p
))[
0
:
n
]
value
=
(
*
[
1
<<
30
]
byte
)(
unsafe
.
Pointer
(
p
))[
0
:
n
]
}
}
return
return
}
}
// The leftmost value is number 0.
// Calls sqlite3_value_double, http://sqlite.org/c3ref/value_blob.html
// Calls sqlite3_value_double, http://sqlite.org/c3ref/value_blob.html
func
(
v
*
Value
)
Double
(
)
float64
{
func
(
c
*
Context
)
Double
(
i
int
)
float64
{
return
float64
(
C
.
sqlite3_value_double
(
v
.
value
))
return
float64
(
C
.
my_value_double
(
c
.
argv
,
C
.
int
(
i
)
))
}
}
// The leftmost value is number 0.
// Calls sqlite3_value_int, http://sqlite.org/c3ref/value_blob.html
// Calls sqlite3_value_int, http://sqlite.org/c3ref/value_blob.html
func
(
v
*
Value
)
Int
(
)
int
{
func
(
c
*
Context
)
Int
(
i
int
)
int
{
return
int
(
C
.
sqlite3_value_int
(
v
.
value
))
return
int
(
C
.
my_value_int
(
c
.
argv
,
C
.
int
(
i
)
))
}
}
// The leftmost value is number 0.
// Calls sqlite3_value_int64, http://sqlite.org/c3ref/value_blob.html
// Calls sqlite3_value_int64, http://sqlite.org/c3ref/value_blob.html
func
(
v
*
Value
)
Int64
(
)
int64
{
func
(
c
*
Context
)
Int64
(
i
int
)
int64
{
return
int64
(
C
.
sqlite3_value_int64
(
v
.
value
))
return
int64
(
C
.
my_value_int64
(
c
.
argv
,
C
.
int
(
i
)
))
}
}
// The leftmost value is number 0.
// Calls sqlite3_value_text, http://sqlite.org/c3ref/value_blob.html
// Calls sqlite3_value_text, http://sqlite.org/c3ref/value_blob.html
func
(
v
*
Value
)
Text
(
)
string
{
func
(
c
*
Context
)
Text
(
i
int
)
string
{
p
:=
C
.
sqlite3_value_text
(
v
.
value
)
p
:=
C
.
my_value_text
(
c
.
argv
,
C
.
int
(
i
)
)
if
p
==
nil
{
if
p
==
nil
{
return
""
return
""
}
}
n
:=
C
.
sqlite3_value_bytes
(
v
.
value
)
n
:=
C
.
my_value_bytes
(
c
.
argv
,
C
.
int
(
i
)
)
return
C
.
GoStringN
((
*
C
.
char
)(
unsafe
.
Pointer
(
p
)),
n
)
return
C
.
GoStringN
((
*
C
.
char
)(
unsafe
.
Pointer
(
p
)),
n
)
}
}
// The leftmost value is number 0.
// SQL function parameter value type
// SQL function parameter value type
// Calls sqlite3_value_type, http://sqlite.org/c3ref/value_blob.html
// Calls sqlite3_value_type, http://sqlite.org/c3ref/value_blob.html
func
(
v
*
Value
)
Type
(
)
Type
{
func
(
c
*
Context
)
Type
(
i
int
)
Type
{
return
Type
(
C
.
sqlite3_value_type
(
v
.
value
))
return
Type
(
C
.
my_value_type
(
c
.
argv
,
C
.
int
(
i
)
))
}
}
// The leftmost value is number 0.
// SQL function parameter value numeric type (with possible conversion)
// SQL function parameter value numeric type (with possible conversion)
// Calls sqlite3_value_numeric_type, http://sqlite.org/c3ref/value_blob.html
// Calls sqlite3_value_numeric_type, http://sqlite.org/c3ref/value_blob.html
func
(
v
*
Value
)
NumericType
(
)
Type
{
func
(
c
*
Context
)
NumericType
(
i
int
)
Type
{
return
Type
(
C
.
sqlite3_value_numeric_type
(
v
.
value
))
return
Type
(
C
.
my_value_numeric_type
(
c
.
argv
,
C
.
int
(
i
)
))
}
}
type
ScalarFunction
func
(
ctx
*
Context
,
values
[]
Value
)
type
ScalarFunction
func
(
ctx
*
Context
,
nArg
int
)
type
DestroyFunctionData
func
(
pApp
interface
{})
type
DestroyFunctionData
func
(
pApp
interface
{})
type
sqliteScalarFunction
struct
{
type
sqliteScalarFunction
struct
{
...
@@ -204,13 +237,12 @@ type sqliteScalarFunction struct {
...
@@ -204,13 +237,12 @@ type sqliteScalarFunction struct {
}
}
//export goXFunc
//export goXFunc
func
goXFunc
(
ctxp
unsafe
.
Pointer
,
argc
C
.
int
,
argvp
unsafe
.
Pointer
)
{
func
goXFunc
(
ctxp
unsafe
.
Pointer
,
argc
int
,
argv
unsafe
.
Pointer
)
{
ctx
:=
(
*
C
.
sqlite3_context
)(
ctxp
)
ctx
:=
(
*
C
.
sqlite3_context
)(
ctxp
)
argv
:=
(
**
C
.
sqlite3_value
)(
argvp
)
udp
:=
(
*
sqliteScalarFunction
)(
C
.
sqlite3_user_data
(
ctx
))
pApp
:=
(
*
sqliteScalarFunction
)(
C
.
sqlite3_user_data
(
ctx
))
// TODO How to avoid to create a Context at each call?
// TODO How to avoid to create a Context at each call?
// TODO How to avoid to create Values at each call?
context
:=
&
Context
{
ctx
,
(
**
C
.
sqlite3_value
)(
argv
)}
println
(
ctx
,
pApp
,
argc
,
argv
)
udp
.
f
(
context
,
argc
)
}
}
//export goXDestroy
//export goXDestroy
...
@@ -240,4 +272,4 @@ func (c *Conn) CreateScalarFunction(functionName string, nArg int, pApp interfac
...
@@ -240,4 +272,4 @@ func (c *Conn) CreateScalarFunction(functionName string, nArg int, pApp interfac
}
}
c
.
udfs
[
functionName
]
=
xFunc
// FIXME same function name with different args is not supported
c
.
udfs
[
functionName
]
=
xFunc
// FIXME same function name with different args is not supported
return
c
.
error
(
C
.
goSqlite3CreateFunctionV2
(
c
.
db
,
fname
,
C
.
int
(
nArg
),
C
.
SQLITE_UTF8
,
unsafe
.
Pointer
(
xFunc
)))
return
c
.
error
(
C
.
goSqlite3CreateFunctionV2
(
c
.
db
,
fname
,
C
.
int
(
nArg
),
C
.
SQLITE_UTF8
,
unsafe
.
Pointer
(
xFunc
)))
}
}
\ No newline at end of file
hook.go
View file @
dee9b21f
...
@@ -92,7 +92,7 @@ type sqliteUpdateHook struct {
...
@@ -92,7 +92,7 @@ type sqliteUpdateHook struct {
}
}
//export goXUpdateHook
//export goXUpdateHook
func
goXUpdateHook
(
udp
unsafe
.
Pointer
,
action
C
.
int
,
dbName
,
tableName
*
C
.
char
,
rowId
C
.
sqlite3_int64
)
{
func
goXUpdateHook
(
udp
unsafe
.
Pointer
,
action
int
,
dbName
,
tableName
*
C
.
char
,
rowId
C
.
sqlite3_int64
)
{
arg
:=
(
*
sqliteUpdateHook
)(
udp
)
arg
:=
(
*
sqliteUpdateHook
)(
udp
)
arg
.
f
(
arg
.
udp
,
Action
(
action
),
C
.
GoString
(
dbName
),
C
.
GoString
(
tableName
),
int64
(
rowId
))
arg
.
f
(
arg
.
udp
,
Action
(
action
),
C
.
GoString
(
dbName
),
C
.
GoString
(
tableName
),
int64
(
rowId
))
}
}
...
...
trace.go
View file @
dee9b21f
...
@@ -167,7 +167,7 @@ type sqliteAuthorizer struct {
...
@@ -167,7 +167,7 @@ type sqliteAuthorizer struct {
}
}
//export goXAuth
//export goXAuth
func
goXAuth
(
udp
unsafe
.
Pointer
,
action
C
.
int
,
arg1
,
arg2
,
dbName
,
triggerName
*
C
.
char
)
C
.
int
{
func
goXAuth
(
udp
unsafe
.
Pointer
,
action
int
,
arg1
,
arg2
,
dbName
,
triggerName
*
C
.
char
)
C
.
int
{
arg
:=
(
*
sqliteAuthorizer
)(
udp
)
arg
:=
(
*
sqliteAuthorizer
)(
udp
)
result
:=
arg
.
f
(
arg
.
udp
,
Action
(
action
),
C
.
GoString
(
arg1
),
C
.
GoString
(
arg2
),
C
.
GoString
(
dbName
),
C
.
GoString
(
triggerName
))
result
:=
arg
.
f
(
arg
.
udp
,
Action
(
action
),
C
.
GoString
(
arg1
),
C
.
GoString
(
arg2
),
C
.
GoString
(
dbName
),
C
.
GoString
(
triggerName
))
return
C
.
int
(
result
)
return
C
.
int
(
result
)
...
@@ -195,9 +195,9 @@ type sqliteBusyHandler struct {
...
@@ -195,9 +195,9 @@ type sqliteBusyHandler struct {
}
}
//export goXBusy
//export goXBusy
func
goXBusy
(
udp
unsafe
.
Pointer
,
count
C
.
int
)
C
.
int
{
func
goXBusy
(
udp
unsafe
.
Pointer
,
count
int
)
C
.
int
{
arg
:=
(
*
sqliteBusyHandler
)(
udp
)
arg
:=
(
*
sqliteBusyHandler
)(
udp
)
result
:=
arg
.
f
(
arg
.
udp
,
int
(
count
)
)
result
:=
arg
.
f
(
arg
.
udp
,
count
)
return
btocint
(
result
)
return
btocint
(
result
)
}
}
...
@@ -307,7 +307,7 @@ type sqliteLogger struct {
...
@@ -307,7 +307,7 @@ type sqliteLogger struct {
}
}
//export goXLog
//export goXLog
func
goXLog
(
udp
unsafe
.
Pointer
,
err
C
.
int
,
msg
*
C
.
char
)
{
func
goXLog
(
udp
unsafe
.
Pointer
,
err
int
,
msg
*
C
.
char
)
{
arg
:=
(
*
sqliteLogger
)(
udp
)
arg
:=
(
*
sqliteLogger
)(
udp
)
arg
.
f
(
arg
.
udp
,
Errno
(
err
),
C
.
GoString
(
msg
))
arg
.
f
(
arg
.
udp
,
Errno
(
err
),
C
.
GoString
(
msg
))
return
return
...
...
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