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 \
|
||||
-Wl,--export=sqlite3_open_v2 \
|
||||
-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_step \
|
||||
-Wl,--export=sqlite3_column_text \
|
||||
|
||||
10
cmd/main.go
10
cmd/main.go
@@ -23,6 +23,16 @@ func main() {
|
||||
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()
|
||||
if err != nil {
|
||||
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"),
|
||||
open: module.ExportedFunction("sqlite3_open_v2"),
|
||||
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"),
|
||||
step: module.ExportedFunction("sqlite3_step"),
|
||||
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)
|
||||
handlePtr := c.newBytes(4)
|
||||
connPtr := c.newBytes(ptrSize)
|
||||
|
||||
if flags == 0 {
|
||||
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)
|
||||
}
|
||||
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c.handle, _ = c.memory.ReadUint32Le(handlePtr)
|
||||
c.free(handlePtr)
|
||||
c.handle, _ = c.memory.ReadUint32Le(connPtr)
|
||||
c.free(connPtr)
|
||||
c.free(namePtr)
|
||||
c.free(vfsPtr)
|
||||
|
||||
@@ -127,6 +128,36 @@ func (c *Conn) Exec(sql string) error {
|
||||
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 {
|
||||
serr := Error{Code: int(rc)}
|
||||
|
||||
@@ -209,6 +240,8 @@ func (c *Conn) getString(ptr, maxlen uint32) string {
|
||||
}
|
||||
}
|
||||
|
||||
const ptrSize = 4
|
||||
|
||||
type sqliteAPI struct {
|
||||
malloc api.Function
|
||||
free api.Function
|
||||
@@ -219,6 +252,7 @@ type sqliteAPI struct {
|
||||
open api.Function
|
||||
close api.Function
|
||||
prepare api.Function
|
||||
finalize api.Function
|
||||
exec api.Function
|
||||
step api.Function
|
||||
columnInt api.Function
|
||||
|
||||
2
go.mod
2
go.mod
@@ -2,4 +2,4 @@ module github.com/ncruces/go-sqlite3
|
||||
|
||||
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/go.mod h1:u8wrFmpdrykiFK0DFPiFm5a4+0RzsdmXYVtijBKqUVo=
|
||||
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.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