mirror of
https://github.com/ncruces/go-sqlite3.git
synced 2026-01-11 21:49:13 +00:00
Prepare statements.
This commit is contained in:
@@ -34,7 +34,8 @@ zig cc --target=wasm32-wasi -flto -g0 -O2 \
|
|||||||
-DSQLITE_OMIT_UTF16 \
|
-DSQLITE_OMIT_UTF16 \
|
||||||
-Wl,--export=sqlite3_open_v2 \
|
-Wl,--export=sqlite3_open_v2 \
|
||||||
-Wl,--export=sqlite3_close \
|
-Wl,--export=sqlite3_close \
|
||||||
-Wl,--export=sqlite3_prepare_v2 \
|
-Wl,--export=sqlite3_prepare_v3 \
|
||||||
|
-Wl,--export=sqlite3_finalize \
|
||||||
-Wl,--export=sqlite3_exec \
|
-Wl,--export=sqlite3_exec \
|
||||||
-Wl,--export=sqlite3_step \
|
-Wl,--export=sqlite3_step \
|
||||||
-Wl,--export=sqlite3_column_text \
|
-Wl,--export=sqlite3_column_text \
|
||||||
|
|||||||
10
cmd/main.go
10
cmd/main.go
@@ -23,6 +23,16 @@ func main() {
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stmt, _, err := db.Prepare(`SELECT id, name FROM users`, 0)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = stmt.Close()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
err = db.Close()
|
err = db.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
|||||||
44
conn.go
44
conn.go
@@ -56,7 +56,8 @@ func Open(name string, flags uint64, vfs string) (conn *Conn, err error) {
|
|||||||
errext: module.ExportedFunction("sqlite3_extended_errcode"),
|
errext: module.ExportedFunction("sqlite3_extended_errcode"),
|
||||||
open: module.ExportedFunction("sqlite3_open_v2"),
|
open: module.ExportedFunction("sqlite3_open_v2"),
|
||||||
close: module.ExportedFunction("sqlite3_close"),
|
close: module.ExportedFunction("sqlite3_close"),
|
||||||
prepare: module.ExportedFunction("sqlite3_prepare_v2"),
|
prepare: module.ExportedFunction("sqlite3_prepare_v3"),
|
||||||
|
finalize: module.ExportedFunction("sqlite3_finalize"),
|
||||||
exec: module.ExportedFunction("sqlite3_exec"),
|
exec: module.ExportedFunction("sqlite3_exec"),
|
||||||
step: module.ExportedFunction("sqlite3_step"),
|
step: module.ExportedFunction("sqlite3_step"),
|
||||||
columnText: module.ExportedFunction("sqlite3_column_text"),
|
columnText: module.ExportedFunction("sqlite3_column_text"),
|
||||||
@@ -72,7 +73,7 @@ func Open(name string, flags uint64, vfs string) (conn *Conn, err error) {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
namePtr := c.newString(name)
|
namePtr := c.newString(name)
|
||||||
handlePtr := c.newBytes(4)
|
connPtr := c.newBytes(ptrSize)
|
||||||
|
|
||||||
if flags == 0 {
|
if flags == 0 {
|
||||||
flags = OPEN_READWRITE | OPEN_CREATE
|
flags = OPEN_READWRITE | OPEN_CREATE
|
||||||
@@ -83,13 +84,13 @@ func Open(name string, flags uint64, vfs string) (conn *Conn, err error) {
|
|||||||
vfsPtr = c.newString(vfs)
|
vfsPtr = c.newString(vfs)
|
||||||
}
|
}
|
||||||
|
|
||||||
r, err := c.api.open.Call(ctx, uint64(namePtr), uint64(handlePtr), flags, uint64(vfsPtr))
|
r, err := c.api.open.Call(ctx, uint64(namePtr), uint64(connPtr), flags, uint64(vfsPtr))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
c.handle, _ = c.memory.ReadUint32Le(handlePtr)
|
c.handle, _ = c.memory.ReadUint32Le(connPtr)
|
||||||
c.free(handlePtr)
|
c.free(connPtr)
|
||||||
c.free(namePtr)
|
c.free(namePtr)
|
||||||
c.free(vfsPtr)
|
c.free(vfsPtr)
|
||||||
|
|
||||||
@@ -127,6 +128,36 @@ func (c *Conn) Exec(sql string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Conn) Prepare(sql string, flags uint64, args ...any) (stmt *Stmt, tail string, err error) {
|
||||||
|
sqlPtr := c.newString(sql)
|
||||||
|
stmtPtr := c.newBytes(ptrSize)
|
||||||
|
tailPtr := c.newBytes(ptrSize)
|
||||||
|
|
||||||
|
r, err := c.api.prepare.Call(context.TODO(), uint64(c.handle),
|
||||||
|
uint64(sqlPtr), uint64(len(sql)+1), flags,
|
||||||
|
uint64(stmtPtr), uint64(tailPtr))
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
stmt = &Stmt{c: c}
|
||||||
|
stmt.handle, _ = c.memory.ReadUint32Le(stmtPtr)
|
||||||
|
i, _ := c.memory.ReadUint32Le(tailPtr)
|
||||||
|
tail = sql[i-sqlPtr:]
|
||||||
|
|
||||||
|
c.free(tailPtr)
|
||||||
|
c.free(stmtPtr)
|
||||||
|
c.free(sqlPtr)
|
||||||
|
|
||||||
|
if r[0] != OK {
|
||||||
|
return nil, "", c.error(r[0])
|
||||||
|
}
|
||||||
|
if stmt.handle == 0 {
|
||||||
|
return nil, "", nil
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Conn) error(rc uint64) *Error {
|
func (c *Conn) error(rc uint64) *Error {
|
||||||
serr := Error{Code: int(rc)}
|
serr := Error{Code: int(rc)}
|
||||||
|
|
||||||
@@ -209,6 +240,8 @@ func (c *Conn) getString(ptr, maxlen uint32) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ptrSize = 4
|
||||||
|
|
||||||
type sqliteAPI struct {
|
type sqliteAPI struct {
|
||||||
malloc api.Function
|
malloc api.Function
|
||||||
free api.Function
|
free api.Function
|
||||||
@@ -219,6 +252,7 @@ type sqliteAPI struct {
|
|||||||
open api.Function
|
open api.Function
|
||||||
close api.Function
|
close api.Function
|
||||||
prepare api.Function
|
prepare api.Function
|
||||||
|
finalize api.Function
|
||||||
exec api.Function
|
exec api.Function
|
||||||
step api.Function
|
step api.Function
|
||||||
columnInt api.Function
|
columnInt api.Function
|
||||||
|
|||||||
2
go.mod
2
go.mod
@@ -2,4 +2,4 @@ module github.com/ncruces/go-sqlite3
|
|||||||
|
|
||||||
go 1.19
|
go 1.19
|
||||||
|
|
||||||
require github.com/tetratelabs/wazero v1.0.0-pre.7
|
require github.com/tetratelabs/wazero v1.0.0-pre.7.0.20230114234926-2ce8988ab763
|
||||||
|
|||||||
4
go.sum
4
go.sum
@@ -1,2 +1,2 @@
|
|||||||
github.com/tetratelabs/wazero v1.0.0-pre.7 h1:WI5N14XxoXw+ZWhcjSazJ6rEowhJbH/x8hglxC5gN7k=
|
github.com/tetratelabs/wazero v1.0.0-pre.7.0.20230114234926-2ce8988ab763 h1:cuXa6OWMd3L3+nNrX9SfT6GxS6ykUAvx8/eegN6KeNo=
|
||||||
github.com/tetratelabs/wazero v1.0.0-pre.7/go.mod h1:u8wrFmpdrykiFK0DFPiFm5a4+0RzsdmXYVtijBKqUVo=
|
github.com/tetratelabs/wazero v1.0.0-pre.7.0.20230114234926-2ce8988ab763/go.mod h1:u8wrFmpdrykiFK0DFPiFm5a4+0RzsdmXYVtijBKqUVo=
|
||||||
|
|||||||
21
stmt.go
Normal file
21
stmt.go
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package sqlite3
|
||||||
|
|
||||||
|
import "context"
|
||||||
|
|
||||||
|
type Stmt struct {
|
||||||
|
c *Conn
|
||||||
|
handle uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Stmt) Close() error {
|
||||||
|
r, err := s.c.api.finalize.Call(context.TODO(), uint64(s.handle))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
s.handle = 0
|
||||||
|
if r[0] != OK {
|
||||||
|
return s.c.error(r[0])
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user