diff options
author | 2024-08-15 00:30:58 +0000 | |
---|---|---|
committer | 2024-08-15 00:30:58 +0000 | |
commit | 586639ccf0e2fefbd1da2c59d5abcb8d64d37434 (patch) | |
tree | 52a9d7412e98ef406c39f09a6fad6e3fa7a7ad49 /vendor/github.com/ncruces/go-sqlite3/config.go | |
parent | update go-ffmpreg to v0.2.5 (pulls in latest tetratelabs/wazero) (#3203) (diff) | |
download | gotosocial-586639ccf0e2fefbd1da2c59d5abcb8d64d37434.tar.xz |
update go-sqlite3 to v0.18.0 (#3204)
Diffstat (limited to 'vendor/github.com/ncruces/go-sqlite3/config.go')
-rw-r--r-- | vendor/github.com/ncruces/go-sqlite3/config.go | 144 |
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 } |