[chore]: Bump github.com/ncruces/go-sqlite3 from 0.23.0 to 0.24.0 (#3862)

Bumps [github.com/ncruces/go-sqlite3](https://github.com/ncruces/go-sqlite3) from 0.23.0 to 0.24.0.
- [Release notes](https://github.com/ncruces/go-sqlite3/releases)
- [Commits](https://github.com/ncruces/go-sqlite3/compare/v0.23.0...v0.24.0)

---
updated-dependencies:
- dependency-name: github.com/ncruces/go-sqlite3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This commit is contained in:
dependabot[bot] 2025-03-03 09:51:42 +00:00 committed by GitHub
parent 8488ac9286
commit 0e2e8e54ab
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
26 changed files with 215 additions and 155 deletions

4
go.mod
View file

@ -53,7 +53,7 @@ require (
github.com/miekg/dns v1.1.63
github.com/minio/minio-go/v7 v7.0.85
github.com/mitchellh/mapstructure v1.5.0
github.com/ncruces/go-sqlite3 v0.23.0
github.com/ncruces/go-sqlite3 v0.24.0
github.com/oklog/ulid v1.3.1
github.com/prometheus/client_golang v1.20.5
github.com/rivo/uniseg v0.4.7
@ -81,7 +81,7 @@ require (
go.opentelemetry.io/otel/sdk/metric v1.34.0
go.opentelemetry.io/otel/trace v1.34.0
go.uber.org/automaxprocs v1.6.0
golang.org/x/crypto v0.34.0
golang.org/x/crypto v0.35.0
golang.org/x/image v0.24.0
golang.org/x/net v0.35.0
golang.org/x/oauth2 v0.27.0

8
go.sum generated
View file

@ -323,8 +323,8 @@ github.com/moul/http2curl v1.0.0 h1:dRMWoAtb+ePxMlLkrCbAqh4TlPHXvoGUSQ323/9Zahs=
github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/ncruces/go-sqlite3 v0.23.0 h1:90j/ar8Ywu2AtsfDl5WhO9sgP/rNk76BcKGIzAHO8AQ=
github.com/ncruces/go-sqlite3 v0.23.0/go.mod h1:gq2nriHSczOs11SqGW5+0X+SgLdkdj4K+j4F/AhQ+8g=
github.com/ncruces/go-sqlite3 v0.24.0 h1:Z4jfmzu2NCd4SmyFwLT2OmF3EnTZbqwATvdiuNHNhLA=
github.com/ncruces/go-sqlite3 v0.24.0/go.mod h1:/Vs8ACZHjJ1SA6E9RZUn3EyB1OP3nDQ4z/ar+0fplTQ=
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
github.com/ncruces/julianday v1.0.0 h1:fH0OKwa7NWvniGQtxdJRxAgkBMolni2BjDHaWTxqt7M=
@ -529,8 +529,8 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/crypto v0.34.0 h1:+/C6tk6rf/+t5DhUketUbD1aNGqiSX3j15Z6xuIDlBA=
golang.org/x/crypto v0.34.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ=
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc=
golang.org/x/image v0.24.0 h1:AN7zRgVsbvmTfNyqIbbOraYL8mSwcKncEj8ofjgzcMQ=

View file

@ -5,9 +5,6 @@
*.so
*.dylib
# Go workspace
go.work*
# Test binary, built with `go test -c`
*.test
@ -17,3 +14,10 @@ go.work*
# Dependency directories (remove the comment below to include it)
# vendor/
tools
# Go workspace file
go.work
go.work.sum
# env file
.env

View file

@ -98,7 +98,7 @@ Also, post there if you used this driver for something interesting
([_"Show and tell"_](https://github.com/ncruces/go-sqlite3/discussions/categories/show-and-tell)),
have an [idea](https://github.com/ncruces/go-sqlite3/discussions/categories/ideas)…
The [Issue](https://github.com/ncruces/go-sqlite3/issues) tracker is for bugs we want fixed,
The [Issue](https://github.com/ncruces/go-sqlite3/issues) tracker is for bugs,
and features we're working on, planning to work on, or asking for help with.
### Alternatives

View file

@ -45,7 +45,7 @@ func (c *Conn) Config(op DBConfig, arg ...bool) (bool, error) {
rc := res_t(c.call("sqlite3_db_config", stk_t(c.handle),
stk_t(op), stk_t(argsPtr)))
return util.Read32[uint32](c.mod, argsPtr) != 0, c.error(rc)
return util.ReadBool(c.mod, argsPtr), c.error(rc)
}
// ConfigLog sets up the error logging callback for the connection.
@ -116,7 +116,7 @@ func (c *Conn) FileControl(schema string, op FcntlOpcode, arg ...any) (any, erro
rc = res_t(c.call("sqlite3_file_control",
stk_t(c.handle), stk_t(schemaPtr),
stk_t(op), stk_t(ptr)))
ret = util.Read32[uint32](c.mod, ptr) != 0
ret = util.ReadBool(c.mod, ptr)
case FCNTL_CHUNK_SIZE:
util.Write32(c.mod, ptr, int32(arg[0].(int)))

View file

@ -3,6 +3,7 @@
import (
"context"
"fmt"
"iter"
"math"
"math/rand"
"net/url"
@ -492,9 +493,9 @@ func (c *Conn) TableColumnMetadata(schema, table, column string) (declType, coll
if ptr := util.Read32[ptr_t](c.mod, collSeqPtr); ptr != 0 {
collSeq = util.ReadString(c.mod, ptr, _MAX_NAME)
}
notNull = util.Read32[uint32](c.mod, notNullPtr) != 0
autoInc = util.Read32[uint32](c.mod, autoIncPtr) != 0
primaryKey = util.Read32[uint32](c.mod, primaryKeyPtr) != 0
notNull = util.ReadBool(c.mod, notNullPtr)
autoInc = util.ReadBool(c.mod, autoIncPtr)
primaryKey = util.ReadBool(c.mod, primaryKeyPtr)
}
return
}
@ -503,10 +504,16 @@ func (c *Conn) error(rc res_t, sql ...string) error {
return c.sqlite.error(rc, c.handle, sql...)
}
func (c *Conn) stmtsIter(yield func(*Stmt) bool) {
// Stmts returns an iterator for the prepared statements
// associated with the database connection.
//
// https://sqlite.org/c3ref/next_stmt.html
func (c *Conn) Stmts() iter.Seq[*Stmt] {
return func(yield func(*Stmt) bool) {
for _, s := range c.stmts {
if !yield(s) {
break
}
}
}
}

View file

@ -1,11 +0,0 @@
//go:build go1.23
package sqlite3
import "iter"
// Stmts returns an iterator for the prepared statements
// associated with the database connection.
//
// https://sqlite.org/c3ref/next_stmt.html
func (c *Conn) Stmts() iter.Seq[*Stmt] { return c.stmtsIter }

View file

@ -1,9 +0,0 @@
//go:build !go1.23
package sqlite3
// Stmts returns an iterator for the prepared statements
// associated with the database connection.
//
// https://sqlite.org/c3ref/next_stmt.html
func (c *Conn) Stmts() func(func(*Stmt) bool) { return c.stmtsIter }

View file

@ -259,7 +259,10 @@
DBCONFIG_TRUSTED_SCHEMA DBConfig = 1017
DBCONFIG_STMT_SCANSTATUS DBConfig = 1018
DBCONFIG_REVERSE_SCANORDER DBConfig = 1019
// DBCONFIG_MAX DBConfig = 1019
DBCONFIG_ENABLE_ATTACH_CREATE DBConfig = 1020
DBCONFIG_ENABLE_ATTACH_WRITE DBConfig = 1021
DBCONFIG_ENABLE_COMMENTS DBConfig = 1022
// DBCONFIG_MAX DBConfig = 1022
)
// FcntlOpcode are the available opcodes for [Conn.FileControl].

View file

@ -1,6 +1,6 @@
# Embeddable Wasm build of SQLite
This folder includes an embeddable Wasm build of SQLite 3.49.0 for use with
This folder includes an embeddable Wasm build of SQLite 3.49.1 for use with
[`github.com/ncruces/go-sqlite3`](https://pkg.go.dev/github.com/ncruces/go-sqlite3).
The following optional features are compiled in:

View file

@ -80,6 +80,7 @@ sqlite3_interrupt
sqlite3_invoke_busy_handler_go
sqlite3_last_insert_rowid
sqlite3_limit
sqlite3_log_go
sqlite3_malloc64
sqlite3_open_v2
sqlite3_overload_function

Binary file not shown.

View file

@ -2,6 +2,7 @@
import (
"context"
"io"
"sync"
"github.com/tetratelabs/wazero/api"
@ -85,13 +86,19 @@ func (c *Conn) CreateWindowFunction(name string, nArg int, flag FunctionFlag, fn
var funcPtr ptr_t
defer c.arena.mark()()
namePtr := c.arena.string(name)
if fn != nil {
funcPtr = util.AddHandle(c.ctx, fn)
}
call := "sqlite3_create_aggregate_function_go"
if _, ok := fn().(WindowFunction); ok {
if fn != nil {
agg := fn()
if c, ok := agg.(io.Closer); ok {
if err := c.Close(); err != nil {
return err
}
}
if _, ok := agg.(WindowFunction); ok {
call = "sqlite3_create_window_function_go"
}
funcPtr = util.AddHandle(c.ctx, fn)
}
rc := res_t(c.call(call,
stk_t(c.handle), stk_t(namePtr), stk_t(nArg),
stk_t(flag), stk_t(funcPtr)))
@ -168,20 +175,24 @@ func stepCallback(ctx context.Context, mod api.Module, pCtx, pAgg, pApp ptr_t, n
fn.Step(Context{db, pCtx}, args[:nArg]...)
}
func finalCallback(ctx context.Context, mod api.Module, pCtx, pAgg, pApp ptr_t) {
func valueCallback(ctx context.Context, mod api.Module, pCtx, pAgg, pApp ptr_t, final int32) {
db := ctx.Value(connKey{}).(*Conn)
fn, handle := callbackAggregate(db, pAgg, pApp)
fn.Value(Context{db, pCtx})
if err := util.DelHandle(ctx, handle); err != nil {
// Cleanup.
if final != 0 {
var err error
if handle != 0 {
err = util.DelHandle(ctx, handle)
} else if c, ok := fn.(io.Closer); ok {
err = c.Close()
}
if err != nil {
Context{db, pCtx}.ResultError(err)
return // notest
}
}
func valueCallback(ctx context.Context, mod api.Module, pCtx, pAgg ptr_t) {
db := ctx.Value(connKey{}).(*Conn)
fn := util.GetHandle(db.ctx, pAgg).(AggregateFunction)
fn.Value(Context{db, pCtx})
}
}
func inverseCallback(ctx context.Context, mod api.Module, pCtx, pAgg ptr_t, nArg int32, pArg ptr_t) {

View file

@ -1,27 +0,0 @@
package util
import (
"runtime"
"golang.org/x/sys/cpu"
)
func CompilerSupported() bool {
switch runtime.GOOS {
case "linux", "android",
"windows", "darwin",
"freebsd", "netbsd", "dragonfly",
"solaris", "illumos":
break
default:
return false
}
switch runtime.GOARCH {
case "amd64":
return cpu.X86.HasSSE41
case "arm64":
return true
default:
return false
}
}

View file

@ -26,9 +26,6 @@ func View(mod api.Module, ptr Ptr_t, size int64) []byte {
if ptr == 0 {
panic(NilErr)
}
if size == 0 {
return nil
}
if uint64(size) > math.MaxUint32 {
panic(RangeErr)
}
@ -110,6 +107,18 @@ func WriteFloat64(mod api.Module, ptr Ptr_t, v float64) {
Write64(mod, ptr, math.Float64bits(v))
}
func ReadBool(mod api.Module, ptr Ptr_t) bool {
return Read32[int32](mod, ptr) != 0
}
func WriteBool(mod api.Module, ptr Ptr_t, v bool) {
var i int32
if v {
i = 1
}
Write32(mod, ptr, i)
}
func ReadString(mod api.Module, ptr Ptr_t, maxlen int64) string {
if ptr == 0 {
panic(NilErr)

View file

@ -47,11 +47,7 @@ func compileSQLite() {
ctx := context.Background()
cfg := RuntimeConfig
if cfg == nil {
if util.CompilerSupported() {
cfg = wazero.NewRuntimeConfigCompiler()
} else {
cfg = wazero.NewRuntimeConfigInterpreter()
}
cfg = wazero.NewRuntimeConfig()
if bits.UintSize < 64 {
cfg = cfg.WithMemoryLimitPages(512) // 32MB
} else {
@ -321,8 +317,7 @@ func exportCallbacks(env wazero.HostModuleBuilder) wazero.HostModuleBuilder {
util.ExportFuncVI(env, "go_destroy", destroyCallback)
util.ExportFuncVIIII(env, "go_func", funcCallback)
util.ExportFuncVIIIII(env, "go_step", stepCallback)
util.ExportFuncVIII(env, "go_final", finalCallback)
util.ExportFuncVII(env, "go_value", valueCallback)
util.ExportFuncVIIII(env, "go_value", valueCallback)
util.ExportFuncVIIII(env, "go_inverse", inverseCallback)
util.ExportFuncVIIII(env, "go_collation_needed", collationCallback)
util.ExportFuncIIIIII(env, "go_compare", compareCallback)

View file

@ -47,11 +47,12 @@ type cksmFlags struct {
func (c cksmFile) ReadAt(p []byte, off int64) (n int, err error) {
n, err = c.File.ReadAt(p, off)
p = p[:n]
// SQLite is reading the header of a database file.
if c.isDB && off == 0 && len(p) >= 100 &&
bytes.HasPrefix(p, []byte("SQLite format 3\000")) {
c.init(p)
c.init((*[100]byte)(p))
}
// Verify checksums.
@ -69,7 +70,7 @@ func (c cksmFile) WriteAt(p []byte, off int64) (n int, err error) {
// SQLite is writing the first page of a database file.
if c.isDB && off == 0 && len(p) >= 100 &&
bytes.HasPrefix(p, []byte("SQLite format 3\000")) {
c.init(p)
c.init((*[100]byte)(p))
}
// Compute checksums.
@ -122,12 +123,16 @@ func (c cksmFile) fileControl(ctx context.Context, mod api.Module, op _FcntlOpco
return vfsFileControlImpl(ctx, mod, c.File, op, pArg)
}
func (f *cksmFlags) init(header []byte) {
func (f *cksmFlags) init(header *[100]byte) {
f.pageSize = 256 * int(binary.LittleEndian.Uint16(header[16:18]))
if r := header[20] == 8; r != f.computeCksm {
f.computeCksm = r
f.verifyCksm = r
}
if !sql3util.ValidPageSize(f.pageSize) {
f.computeCksm = false
f.verifyCksm = false
}
}
func cksmCompute(a []byte) (cksm [8]byte) {

View file

@ -31,6 +31,7 @@ func (e _ErrorCode) Error() string {
_READONLY _ErrorCode = util.READONLY
_IOERR _ErrorCode = util.IOERR
_NOTFOUND _ErrorCode = util.NOTFOUND
_FULL _ErrorCode = util.FULL
_CANTOPEN _ErrorCode = util.CANTOPEN
_IOERR_READ _ErrorCode = util.IOERR_READ
_IOERR_SHORT_READ _ErrorCode = util.IOERR_SHORT_READ
@ -57,10 +58,12 @@ func (e _ErrorCode) Error() string {
_IOERR_COMMIT_ATOMIC _ErrorCode = util.IOERR_COMMIT_ATOMIC
_IOERR_ROLLBACK_ATOMIC _ErrorCode = util.IOERR_ROLLBACK_ATOMIC
_IOERR_DATA _ErrorCode = util.IOERR_DATA
_IOERR_CORRUPTFS _ErrorCode = util.IOERR_CORRUPTFS
_BUSY_SNAPSHOT _ErrorCode = util.BUSY_SNAPSHOT
_CANTOPEN_FULLPATH _ErrorCode = util.CANTOPEN_FULLPATH
_CANTOPEN_ISDIR _ErrorCode = util.CANTOPEN_ISDIR
_READONLY_CANTINIT _ErrorCode = util.READONLY_CANTINIT
_READONLY_DIRECTORY _ErrorCode = util.READONLY_DIRECTORY
_OK_SYMLINK _ErrorCode = util.OK_SYMLINK
)

View file

@ -88,10 +88,13 @@ func (vfsOS) OpenFilename(name *Filename, flags OpenFlag) (File, OpenFlag, error
oflags |= os.O_RDWR
}
isCreate := flags&(OPEN_CREATE) != 0
isJournl := flags&(OPEN_MAIN_JOURNAL|OPEN_SUPER_JOURNAL|OPEN_WAL) != 0
var err error
var f *os.File
if name == nil {
f, err = os.CreateTemp("", "*.db")
f, err = os.CreateTemp(os.Getenv("SQLITE_TMPDIR"), "*.db")
} else {
f, err = osutil.OpenFile(name.String(), oflags, 0666)
}
@ -102,6 +105,10 @@ func (vfsOS) OpenFilename(name *Filename, flags OpenFlag) (File, OpenFlag, error
if errors.Is(err, syscall.EISDIR) {
return nil, flags, _CANTOPEN_ISDIR
}
if isCreate && isJournl && errors.Is(err, fs.ErrPermission) &&
osAccess(name.String(), ACCESS_EXISTS) != nil {
return nil, flags, _READONLY_DIRECTORY
}
return nil, flags, err
}
@ -119,9 +126,7 @@ func (vfsOS) OpenFilename(name *Filename, flags OpenFlag) (File, OpenFlag, error
File: f,
psow: true,
readOnly: flags&OPEN_READONLY != 0,
syncDir: canSyncDirs &&
flags&(OPEN_MAIN_JOURNAL|OPEN_SUPER_JOURNAL|OPEN_WAL) != 0 &&
flags&(OPEN_CREATE) != 0,
syncDir: canSyncDirs && isCreate && isJournl,
shm: NewSharedMemory(name.String()+"-shm", flags),
}
return &file, flags, nil
@ -154,6 +159,14 @@ func (f *vfsFile) Close() error {
return f.File.Close()
}
func (f *vfsFile) ReadAt(p []byte, off int64) (n int, err error) {
return osReadAt(f.File, p, off)
}
func (f *vfsFile) WriteAt(p []byte, off int64) (n int, err error) {
return osWriteAt(f.File, p, off)
}
func (f *vfsFile) Sync(flags SyncFlag) error {
dataonly := (flags & SYNC_DATAONLY) != 0
fullsync := (flags & 0x0f) == SYNC_FULL

13
vendor/github.com/ncruces/go-sqlite3/vfs/os_std_rw.go generated vendored Normal file
View file

@ -0,0 +1,13 @@
//go:build !unix && (!windows || sqlite3_dotlk)
package vfs
import "os"
func osReadAt(file *os.File, p []byte, off int64) (int, error) {
return file.ReadAt(p, off)
}
func osWriteAt(file *os.File, p []byte, off int64) (int, error) {
return file.WriteAt(p, off)
}

View file

@ -25,6 +25,28 @@ func osAccess(path string, flags AccessFlag) error {
return unix.Access(path, access)
}
func osReadAt(file *os.File, p []byte, off int64) (int, error) {
n, err := file.ReadAt(p, off)
if errno, ok := err.(unix.Errno); ok {
switch errno {
case
unix.ERANGE,
unix.EIO,
unix.ENXIO:
return n, _IOERR_CORRUPTFS
}
}
return n, err
}
func osWriteAt(file *os.File, p []byte, off int64) (int, error) {
n, err := file.WriteAt(p, off)
if errno, ok := err.(unix.Errno); ok && errno == unix.ENOSPC {
return n, _FULL
}
return n, err
}
func osSetMode(file *os.File, modeof string) error {
fi, err := os.Stat(modeof)
if err != nil {

View file

@ -9,6 +9,23 @@
"golang.org/x/sys/windows"
)
func osReadAt(file *os.File, p []byte, off int64) (int, error) {
return file.ReadAt(p, off)
}
func osWriteAt(file *os.File, p []byte, off int64) (int, error) {
n, err := file.WriteAt(p, off)
if errno, ok := err.(windows.Errno); ok {
switch errno {
case
windows.ERROR_HANDLE_DISK_FULL,
windows.ERROR_DISK_FULL:
return n, _FULL
}
}
return n, err
}
func osGetSharedLock(file *os.File) _ErrorCode {
// Acquire the PENDING lock temporarily before acquiring a new SHARED lock.
rc := osReadLock(file, _PENDING_BYTE, 1, 0)

View file

@ -58,13 +58,8 @@ func vfsFind(ctx context.Context, mod api.Module, zVfsName ptr_t) uint32 {
}
func vfsLocaltime(ctx context.Context, mod api.Module, pTm ptr_t, t int64) _ErrorCode {
tm := time.Unix(t, 0)
var isdst int32
if tm.IsDST() {
isdst = 1
}
const size = 32 / 8
tm := time.Unix(t, 0)
// https://pubs.opengroup.org/onlinepubs/7908799/xsh/time.h.html
util.Write32(mod, pTm+0*size, int32(tm.Second()))
util.Write32(mod, pTm+1*size, int32(tm.Minute()))
@ -74,7 +69,7 @@ func vfsLocaltime(ctx context.Context, mod api.Module, pTm ptr_t, t int64) _Erro
util.Write32(mod, pTm+5*size, int32(tm.Year()-1900))
util.Write32(mod, pTm+6*size, int32(tm.Weekday()-time.Sunday))
util.Write32(mod, pTm+7*size, int32(tm.YearDay()-1))
util.Write32(mod, pTm+8*size, isdst)
util.WriteBool(mod, pTm+8*size, tm.IsDST())
return _OK
}
@ -123,11 +118,7 @@ func vfsAccess(ctx context.Context, mod api.Module, pVfs, zPath ptr_t, flags Acc
path := util.ReadString(mod, zPath, _MAX_PATHNAME)
ok, err := vfs.Access(path, flags)
var res int32
if ok {
res = 1
}
util.Write32(mod, pResOut, res)
util.WriteBool(mod, pResOut, ok)
return vfsErrorCode(err, _IOERR_ACCESS)
}
@ -151,9 +142,8 @@ func vfsOpen(ctx context.Context, mod api.Module, pVfs, zPath, pFile ptr_t, flag
file.SetPowersafeOverwrite(b)
}
}
if file, ok := file.(FileSharedMemory); ok &&
pOutVFS != 0 && file.SharedMemory() != nil {
util.Write32(mod, pOutVFS, int32(1))
if file, ok := file.(FileSharedMemory); ok && pOutVFS != 0 {
util.WriteBool(mod, pOutVFS, file.SharedMemory() != nil)
}
if pOutFlags != 0 {
util.Write32(mod, pOutFlags, flags)
@ -225,12 +215,7 @@ func vfsUnlock(ctx context.Context, mod api.Module, pFile ptr_t, eLock LockLevel
func vfsCheckReservedLock(ctx context.Context, mod api.Module, pFile, pResOut ptr_t) _ErrorCode {
file := vfsFileGet(ctx, mod, pFile).(File)
locked, err := file.CheckReservedLock()
var res int32
if locked {
res = 1
}
util.Write32(mod, pResOut, res)
util.WriteBool(mod, pResOut, locked)
return vfsErrorCode(err, _IOERR_CHECKRESERVEDLOCK)
}
@ -254,24 +239,20 @@ func vfsFileControlImpl(ctx context.Context, mod api.Module, file File, op _Fcnt
case _FCNTL_PERSIST_WAL:
if file, ok := file.(FilePersistWAL); ok {
if i := util.Read32[int32](mod, pArg); i >= 0 {
file.SetPersistWAL(i != 0)
} else if file.PersistWAL() {
util.Write32(mod, pArg, int32(1))
if i := util.Read32[int32](mod, pArg); i < 0 {
util.WriteBool(mod, pArg, file.PersistWAL())
} else {
util.Write32(mod, pArg, int32(0))
file.SetPersistWAL(i != 0)
}
return _OK
}
case _FCNTL_POWERSAFE_OVERWRITE:
if file, ok := file.(FilePowersafeOverwrite); ok {
if i := util.Read32[int32](mod, pArg); i >= 0 {
file.SetPowersafeOverwrite(i != 0)
} else if file.PowersafeOverwrite() {
util.Write32(mod, pArg, int32(1))
if i := util.Read32[int32](mod, pArg); i < 0 {
util.WriteBool(mod, pArg, file.PowersafeOverwrite())
} else {
util.Write32(mod, pArg, int32(0))
file.SetPowersafeOverwrite(i != 0)
}
return _OK
}
@ -293,11 +274,7 @@ func vfsFileControlImpl(ctx context.Context, mod api.Module, file File, op _Fcnt
case _FCNTL_HAS_MOVED:
if file, ok := file.(FileHasMoved); ok {
moved, err := file.HasMoved()
var val uint32
if moved {
val = 1
}
util.Write32(mod, pArg, val)
util.WriteBool(mod, pArg, moved)
return vfsErrorCode(err, _IOERR_FSTAT)
}
@ -394,7 +371,7 @@ func vfsFileControlImpl(ctx context.Context, mod api.Module, file File, op _Fcnt
case _FCNTL_LOCK_TIMEOUT:
if file, ok := file.(FileSharedMemory); ok {
if shm, ok := file.SharedMemory().(blockingSharedMemory); ok {
shm.shmEnableBlocking(util.Read32[uint32](mod, pArg) != 0)
shm.shmEnableBlocking(util.ReadBool(mod, pArg))
return _OK
}
}

View file

@ -399,10 +399,10 @@ func (idx *IndexInfo) save() {
util.Write32(mod, ptr+20, int32(idx.IdxNum))
if idx.IdxStr != "" {
util.Write32(mod, ptr+24, idx.c.newString(idx.IdxStr))
util.Write32(mod, ptr+28, int32(1)) // needToFreeIdxStr
util.WriteBool(mod, ptr+28, true) // needToFreeIdxStr
}
if idx.OrderByConsumed {
util.Write32(mod, ptr+32, int32(1))
util.WriteBool(mod, ptr+32, true)
}
util.WriteFloat64(mod, ptr+40, idx.EstimatedCost)
util.Write64(mod, ptr+48, idx.EstimatedRows)

View file

@ -25,6 +25,11 @@
// quickly.
const chanSize = 16
// maxPendingPackets sets the maximum number of packets to queue while waiting
// for KEX to complete. This limits the total pending data to maxPendingPackets
// * maxPacket bytes, which is ~16.8MB.
const maxPendingPackets = 64
// keyingTransport is a packet based transport that supports key
// changes. It need not be thread-safe. It should pass through
// msgNewKeys in both directions.
@ -74,10 +79,18 @@ type handshakeTransport struct {
readError error
mu sync.Mutex
// Condition for the above mutex. It is used to notify a completed key
// exchange or a write failure. Writes can wait for this condition while a
// key exchange is in progress.
writeCond *sync.Cond
writeError error
sentInitPacket []byte
sentInitMsg *kexInitMsg
pendingPackets [][]byte // Used when a key exchange is in progress.
// Used to queue writes when a key exchange is in progress. The length is
// limited by pendingPacketsSize. Once full, writes will block until the key
// exchange is completed or an error occurs. If not empty, it is emptied
// all at once when the key exchange is completed in kexLoop.
pendingPackets [][]byte
writePacketsLeft uint32
writeBytesLeft int64
userAuthComplete bool // whether the user authentication phase is complete
@ -134,6 +147,7 @@ func newHandshakeTransport(conn keyingTransport, config *Config, clientVersion,
config: config,
}
t.writeCond = sync.NewCond(&t.mu)
t.resetReadThresholds()
t.resetWriteThresholds()
@ -260,6 +274,7 @@ func (t *handshakeTransport) recordWriteError(err error) {
defer t.mu.Unlock()
if t.writeError == nil && err != nil {
t.writeError = err
t.writeCond.Broadcast()
}
}
@ -363,6 +378,8 @@ func (t *handshakeTransport) kexLoop() {
}
}
t.pendingPackets = t.pendingPackets[:0]
// Unblock writePacket if waiting for KEX.
t.writeCond.Broadcast()
t.mu.Unlock()
}
@ -577,12 +594,21 @@ func (t *handshakeTransport) writePacket(p []byte) error {
}
if t.sentInitMsg != nil {
if len(t.pendingPackets) < maxPendingPackets {
// Copy the packet so the writer can reuse the buffer.
cp := make([]byte, len(p))
copy(cp, p)
t.pendingPackets = append(t.pendingPackets, cp)
return nil
}
for t.sentInitMsg != nil {
// Block and wait for KEX to complete or an error.
t.writeCond.Wait()
if t.writeError != nil {
return t.writeError
}
}
}
if t.writeBytesLeft > 0 {
t.writeBytesLeft -= int64(len(p))
@ -598,6 +624,7 @@ func (t *handshakeTransport) writePacket(p []byte) error {
if err := t.pushPacket(p); err != nil {
t.writeError = err
t.writeCond.Broadcast()
}
return nil

6
vendor/modules.txt vendored
View file

@ -698,8 +698,8 @@ github.com/modern-go/reflect2
# github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822
## explicit
github.com/munnerz/goautoneg
# github.com/ncruces/go-sqlite3 v0.23.0
## explicit; go 1.22
# github.com/ncruces/go-sqlite3 v0.24.0
## explicit; go 1.23.0
github.com/ncruces/go-sqlite3
github.com/ncruces/go-sqlite3/driver
github.com/ncruces/go-sqlite3/embed
@ -1057,7 +1057,7 @@ go.uber.org/multierr
# golang.org/x/arch v0.13.0
## explicit; go 1.18
golang.org/x/arch/x86/x86asm
# golang.org/x/crypto v0.34.0
# golang.org/x/crypto v0.35.0
## explicit; go 1.23.0
golang.org/x/crypto/acme
golang.org/x/crypto/acme/autocert