summaryrefslogtreecommitdiff
path: root/vendor/github.com/ncruces/go-sqlite3/config.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/ncruces/go-sqlite3/config.go')
-rw-r--r--vendor/github.com/ncruces/go-sqlite3/config.go144
1 files changed, 138 insertions, 6 deletions
diff --git a/vendor/github.com/ncruces/go-sqlite3/config.go b/vendor/github.com/ncruces/go-sqlite3/config.go
index 0342be7fb..3f60b8fe9 100644
--- a/vendor/github.com/ncruces/go-sqlite3/config.go
+++ b/vendor/github.com/ncruces/go-sqlite3/config.go
@@ -4,6 +4,7 @@ import (
"context"
"github.com/ncruces/go-sqlite3/internal/util"
+ "github.com/ncruces/go-sqlite3/vfs"
"github.com/tetratelabs/wazero/api"
)
@@ -56,6 +57,99 @@ func logCallback(ctx context.Context, mod api.Module, _, iCode, zMsg uint32) {
}
}
+// FileControl allows low-level control of database files.
+// Only a subset of opcodes are supported.
+//
+// https://sqlite.org/c3ref/file_control.html
+func (c *Conn) FileControl(schema string, op FcntlOpcode, arg ...any) (any, error) {
+ defer c.arena.mark()()
+
+ var schemaPtr uint32
+ if schema != "" {
+ schemaPtr = c.arena.string(schema)
+ }
+
+ switch op {
+ case FCNTL_RESET_CACHE:
+ r := c.call("sqlite3_file_control",
+ uint64(c.handle), uint64(schemaPtr),
+ uint64(op), 0)
+ return nil, c.error(r)
+
+ case FCNTL_PERSIST_WAL, FCNTL_POWERSAFE_OVERWRITE:
+ var flag int
+ switch {
+ case len(arg) == 0:
+ flag = -1
+ case arg[0]:
+ flag = 1
+ }
+ ptr := c.arena.new(4)
+ util.WriteUint32(c.mod, ptr, uint32(flag))
+ r := c.call("sqlite3_file_control",
+ uint64(c.handle), uint64(schemaPtr),
+ uint64(op), uint64(ptr))
+ return util.ReadUint32(c.mod, ptr) != 0, c.error(r)
+
+ case FCNTL_CHUNK_SIZE:
+ ptr := c.arena.new(4)
+ util.WriteUint32(c.mod, ptr, uint32(arg[0].(int)))
+ r := c.call("sqlite3_file_control",
+ uint64(c.handle), uint64(schemaPtr),
+ uint64(op), uint64(ptr))
+ return nil, c.error(r)
+
+ case FCNTL_RESERVE_BYTES:
+ bytes := -1
+ if len(arg) > 0 {
+ bytes = arg[0].(int)
+ }
+ ptr := c.arena.new(4)
+ util.WriteUint32(c.mod, ptr, uint32(bytes))
+ r := c.call("sqlite3_file_control",
+ uint64(c.handle), uint64(schemaPtr),
+ uint64(op), uint64(ptr))
+ return int(util.ReadUint32(c.mod, ptr)), c.error(r)
+
+ case FCNTL_DATA_VERSION:
+ ptr := c.arena.new(4)
+ r := c.call("sqlite3_file_control",
+ uint64(c.handle), uint64(schemaPtr),
+ uint64(op), uint64(ptr))
+ return util.ReadUint32(c.mod, ptr), c.error(r)
+
+ case FCNTL_LOCKSTATE:
+ ptr := c.arena.new(4)
+ r := c.call("sqlite3_file_control",
+ uint64(c.handle), uint64(schemaPtr),
+ uint64(op), uint64(ptr))
+ return vfs.LockLevel(util.ReadUint32(c.mod, ptr)), c.error(r)
+
+ case FCNTL_VFS_POINTER:
+ ptr := c.arena.new(4)
+ r := c.call("sqlite3_file_control",
+ uint64(c.handle), uint64(schemaPtr),
+ uint64(op), uint64(ptr))
+ const zNameOffset = 16
+ ptr = util.ReadUint32(c.mod, ptr)
+ ptr = util.ReadUint32(c.mod, ptr+zNameOffset)
+ name := util.ReadString(c.mod, ptr, _MAX_NAME)
+ return vfs.Find(name), c.error(r)
+
+ case FCNTL_FILE_POINTER, FCNTL_JOURNAL_POINTER:
+ ptr := c.arena.new(4)
+ r := c.call("sqlite3_file_control",
+ uint64(c.handle), uint64(schemaPtr),
+ uint64(op), uint64(ptr))
+ const fileHandleOffset = 4
+ ptr = util.ReadUint32(c.mod, ptr)
+ ptr = util.ReadUint32(c.mod, ptr+fileHandleOffset)
+ return util.GetHandle(c.ctx, ptr), c.error(r)
+ }
+
+ return nil, MISUSE
+}
+
// Limit allows the size of various constructs to be
// limited on a connection by connection basis.
//
@@ -68,7 +162,7 @@ func (c *Conn) Limit(id LimitCategory, value int) int {
// SetAuthorizer registers an authorizer callback with the database connection.
//
// https://sqlite.org/c3ref/set_authorizer.html
-func (c *Conn) SetAuthorizer(cb func(action AuthorizerActionCode, name3rd, name4th, schema, nameInner string) AuthorizerReturnCode) error {
+func (c *Conn) SetAuthorizer(cb func(action AuthorizerActionCode, name3rd, name4th, schema, inner string) AuthorizerReturnCode) error {
var enable uint64
if cb != nil {
enable = 1
@@ -82,9 +176,9 @@ func (c *Conn) SetAuthorizer(cb func(action AuthorizerActionCode, name3rd, name4
}
-func authorizerCallback(ctx context.Context, mod api.Module, pDB uint32, action AuthorizerActionCode, zName3rd, zName4th, zSchema, zNameInner uint32) (rc AuthorizerReturnCode) {
+func authorizerCallback(ctx context.Context, mod api.Module, pDB uint32, action AuthorizerActionCode, zName3rd, zName4th, zSchema, zInner uint32) (rc AuthorizerReturnCode) {
if c, ok := ctx.Value(connKey{}).(*Conn); ok && c.handle == pDB && c.authorizer != nil {
- var name3rd, name4th, schema, nameInner string
+ var name3rd, name4th, schema, inner string
if zName3rd != 0 {
name3rd = util.ReadString(mod, zName3rd, _MAX_NAME)
}
@@ -94,10 +188,48 @@ func authorizerCallback(ctx context.Context, mod api.Module, pDB uint32, action
if zSchema != 0 {
schema = util.ReadString(mod, zSchema, _MAX_NAME)
}
- if zNameInner != 0 {
- nameInner = util.ReadString(mod, zNameInner, _MAX_NAME)
+ if zInner != 0 {
+ inner = util.ReadString(mod, zInner, _MAX_NAME)
+ }
+ rc = c.authorizer(action, name3rd, name4th, schema, inner)
+ }
+ return rc
+}
+
+// Trace registers a trace callback function against the database connection.
+//
+// https://sqlite.org/c3ref/trace_v2.html
+func (c *Conn) Trace(mask TraceEvent, cb func(evt TraceEvent, arg1 any, arg2 any) error) error {
+ r := c.call("sqlite3_trace_go", uint64(c.handle), uint64(mask))
+ if err := c.error(r); err != nil {
+ return err
+ }
+ c.trace = cb
+ return nil
+}
+
+func traceCallback(ctx context.Context, mod api.Module, evt TraceEvent, pDB, pArg1, pArg2 uint32) (rc uint32) {
+ if c, ok := ctx.Value(connKey{}).(*Conn); ok && c.handle == pDB && c.trace != nil {
+ var arg1, arg2 any
+ if evt == TRACE_CLOSE {
+ arg1 = c
+ } else {
+ for _, s := range c.stmts {
+ if pArg1 == s.handle {
+ arg1 = s
+ switch evt {
+ case TRACE_STMT:
+ arg2 = s.SQL()
+ case TRACE_PROFILE:
+ arg2 = int64(util.ReadUint64(mod, pArg2))
+ }
+ break
+ }
+ }
+ }
+ if arg1 != nil {
+ _, rc = errorCode(c.trace(evt, arg1, arg2), ERROR)
}
- rc = c.authorizer(action, name3rd, name4th, schema, nameInner)
}
return rc
}