diff options
| author | 2025-09-04 15:29:27 +0200 | |
|---|---|---|
| committer | 2025-09-04 15:29:27 +0200 | |
| commit | 78defcd9166a202eb3140dc27afd288e1f9bfec4 (patch) | |
| tree | dfe061abc810096f0141b7f585d38401c099c488 /vendor/github.com/ncruces | |
| parent | [performance] faster request id generation (#4405) (diff) | |
| download | gotosocial-78defcd9166a202eb3140dc27afd288e1f9bfec4.tar.xz | |
[chore] bump dependencies (#4406)
- codeberg.org/gruf/go-ffmpreg: v0.6.9 -> v0.6.10
- github.com/ncruces/go-sqlite3: v0.27.1 -> v0.28.0
- github.com/stretchr/testify: v1.10.0 -> v1.11.1
- github.com/tdewolff/minify/v2 v2.23.11 -> v2.24.2
- go.opentelemetry.io/otel{,/*}: v1.37.0 -> v1.38.0
- go.opentelemetry.io/contrib/*: v0.62.0 -> v0.63.0
Reviewed-on: https://codeberg.org/superseriousbusiness/gotosocial/pulls/4406
Co-authored-by: kim <grufwub@gmail.com>
Co-committed-by: kim <grufwub@gmail.com>
Diffstat (limited to 'vendor/github.com/ncruces')
16 files changed, 415 insertions, 165 deletions
diff --git a/vendor/github.com/ncruces/go-sqlite3/driver/driver.go b/vendor/github.com/ncruces/go-sqlite3/driver/driver.go index 280611f71..27496f6cb 100644 --- a/vendor/github.com/ncruces/go-sqlite3/driver/driver.go +++ b/vendor/github.com/ncruces/go-sqlite3/driver/driver.go @@ -604,15 +604,6 @@ func (r resultRowsAffected) RowsAffected() (int64, error) { return int64(r), nil } -type rows struct { - ctx context.Context - *stmt - names []string - types []string - nulls []bool - scans []scantype -} - type scantype byte const ( @@ -648,10 +639,20 @@ func scanFromDecl(decl string) scantype { return _ANY } +type rows struct { + ctx context.Context + *stmt + names []string + types []string + nulls []bool + scans []scantype +} + var ( // Ensure these interfaces are implemented: _ driver.RowsColumnTypeDatabaseTypeName = &rows{} _ driver.RowsColumnTypeNullable = &rows{} + // _ driver.RowsColumnScanner = &rows{} ) func (r *rows) Close() error { @@ -740,7 +741,7 @@ func (r *rows) ColumnTypeScanType(index int) (typ reflect.Type) { switch { case scan == _TIME && val != _BLOB && val != _NULL: t := r.Stmt.ColumnTime(index, r.tmRead) - useValType = t == time.Time{} + useValType = t.IsZero() case scan == _BOOL && val == _INT: i := r.Stmt.ColumnInt64(index) useValType = i != 0 && i != 1 @@ -830,3 +831,23 @@ func (r *rows) Next(dest []driver.Value) error { } return nil } + +func (r *rows) ScanColumn(dest any, index int) error { + // notest // Go 1.26 + var ptr *time.Time + switch d := dest.(type) { + case *time.Time: + ptr = d + case *sql.NullTime: + ptr = &d.Time + case *sql.Null[time.Time]: + ptr = &d.V + default: + return driver.ErrSkip + } + if t := r.Stmt.ColumnTime(index, r.tmRead); !t.IsZero() { + *ptr = t + return nil + } + return driver.ErrSkip +} diff --git a/vendor/github.com/ncruces/go-sqlite3/embed/README.md b/vendor/github.com/ncruces/go-sqlite3/embed/README.md index 346a4e308..67af2977b 100644 --- a/vendor/github.com/ncruces/go-sqlite3/embed/README.md +++ b/vendor/github.com/ncruces/go-sqlite3/embed/README.md @@ -1,6 +1,6 @@ # Embeddable Wasm build of SQLite -This folder includes an embeddable Wasm build of SQLite 3.50.3 for use with +This folder includes an embeddable Wasm build of SQLite 3.50.4 for use with [`github.com/ncruces/go-sqlite3`](https://pkg.go.dev/github.com/ncruces/go-sqlite3). The following optional features are compiled in: diff --git a/vendor/github.com/ncruces/go-sqlite3/embed/build.sh b/vendor/github.com/ncruces/go-sqlite3/embed/build.sh index c96a18653..e078c1065 100644 --- a/vendor/github.com/ncruces/go-sqlite3/embed/build.sh +++ b/vendor/github.com/ncruces/go-sqlite3/embed/build.sh @@ -17,7 +17,8 @@ trap 'rm -f sqlite3.tmp' EXIT -mmutable-globals -mnontrapping-fptoint \ -msimd128 -mbulk-memory -msign-ext \ -mreference-types -mmultivalue \ - -fno-stack-protector -fno-stack-clash-protection \ + -mno-extended-const \ + -fno-stack-protector \ -Wl,--stack-first \ -Wl,--import-undefined \ -Wl,--initial-memory=327680 \ diff --git a/vendor/github.com/ncruces/go-sqlite3/embed/sqlite3.wasm b/vendor/github.com/ncruces/go-sqlite3/embed/sqlite3.wasm Binary files differindex dac29da3d..f8c8f5f86 100644 --- a/vendor/github.com/ncruces/go-sqlite3/embed/sqlite3.wasm +++ b/vendor/github.com/ncruces/go-sqlite3/embed/sqlite3.wasm diff --git a/vendor/github.com/ncruces/go-sqlite3/func.go b/vendor/github.com/ncruces/go-sqlite3/func.go index 16b43056d..556d89ebc 100644 --- a/vendor/github.com/ncruces/go-sqlite3/func.go +++ b/vendor/github.com/ncruces/go-sqlite3/func.go @@ -59,7 +59,7 @@ func (c *Conn) CreateCollation(name string, fn CollatingFunction) error { return c.error(rc) } -// Collating function is the type of a collation callback. +// CollatingFunction is the type of a collation callback. // Implementations must not retain a or b. type CollatingFunction func(a, b []byte) int @@ -132,7 +132,7 @@ func (c *Conn) CreateWindowFunction(name string, nArg int, flag FunctionFlag, fn if win, ok := agg.(WindowFunction); ok { return win } - return windowFunc{agg, name} + return agg })) } rc := res_t(c.call("sqlite3_create_window_function_go", @@ -307,13 +307,3 @@ func (a *aggregateFunc) Close() error { a.stop() return nil } - -type windowFunc struct { - AggregateFunction - name string -} - -func (w windowFunc) Inverse(ctx Context, arg ...Value) { - // Implementing inverse allows certain queries that don't really need it to succeed. - ctx.ResultError(util.ErrorString(w.name + ": may not be used as a window function")) -} diff --git a/vendor/github.com/ncruces/go-sqlite3/internal/util/func.go b/vendor/github.com/ncruces/go-sqlite3/internal/util/func.go index e705f3181..8e89b118a 100644 --- a/vendor/github.com/ncruces/go-sqlite3/internal/util/func.go +++ b/vendor/github.com/ncruces/go-sqlite3/internal/util/func.go @@ -20,20 +20,6 @@ func ExportFuncVI[T0 i32](mod wazero.HostModuleBuilder, name string, fn func(con Export(name) } -type funcVII[T0, T1 i32] func(context.Context, api.Module, T0, T1) - -func (fn funcVII[T0, T1]) Call(ctx context.Context, mod api.Module, stack []uint64) { - _ = stack[1] // prevent bounds check on every slice access - fn(ctx, mod, T0(stack[0]), T1(stack[1])) -} - -func ExportFuncVII[T0, T1 i32](mod wazero.HostModuleBuilder, name string, fn func(context.Context, api.Module, T0, T1)) { - mod.NewFunctionBuilder(). - WithGoModuleFunction(funcVII[T0, T1](fn), - []api.ValueType{api.ValueTypeI32, api.ValueTypeI32}, nil). - Export(name) -} - type funcVIII[T0, T1, T2 i32] func(context.Context, api.Module, T0, T1, T2) func (fn funcVIII[T0, T1, T2]) Call(ctx context.Context, mod api.Module, stack []uint64) { diff --git a/vendor/github.com/ncruces/go-sqlite3/util/sql3util/wasm/sql3parse_table.wasm b/vendor/github.com/ncruces/go-sqlite3/util/sql3util/wasm/sql3parse_table.wasm Binary files differindex f7dc0cdf4..996541e76 100644 --- a/vendor/github.com/ncruces/go-sqlite3/util/sql3util/wasm/sql3parse_table.wasm +++ b/vendor/github.com/ncruces/go-sqlite3/util/sql3util/wasm/sql3parse_table.wasm diff --git a/vendor/github.com/ncruces/go-sqlite3/util/vfsutil/slice.go b/vendor/github.com/ncruces/go-sqlite3/util/vfsutil/slice.go new file mode 100644 index 000000000..b0fbe993c --- /dev/null +++ b/vendor/github.com/ncruces/go-sqlite3/util/vfsutil/slice.go @@ -0,0 +1,102 @@ +package vfsutil + +import ( + "io" + + "github.com/ncruces/go-sqlite3" + "github.com/ncruces/go-sqlite3/vfs" +) + +// SliceFile implements [vfs.File] with a byte slice. +// It is suitable for temporary files (such as [vfs.OPEN_TEMP_JOURNAL]), +// but not concurrency safe. +type SliceFile []byte + +var ( + // Ensure these interfaces are implemented: + _ vfs.FileSizeHint = &SliceFile{} +) + +// ReadAt implements [io.ReaderAt]. +func (f *SliceFile) ReadAt(b []byte, off int64) (n int, err error) { + if d := *f; off < int64(len(d)) { + n = copy(b, d[off:]) + } + if n < len(b) { + err = io.EOF + } + return +} + +// WriteAt implements [io.WriterAt]. +func (f *SliceFile) WriteAt(b []byte, off int64) (n int, err error) { + d := *f + if off > int64(len(d)) { + d = append(d, make([]byte, off-int64(len(d)))...) + } + d = append(d[:off], b...) + if len(d) > len(*f) { + *f = d + } + return len(b), nil +} + +// Size implements [vfs.File]. +func (f *SliceFile) Size() (int64, error) { + return int64(len(*f)), nil +} + +// Truncate implements [vfs.File]. +func (f *SliceFile) Truncate(size int64) error { + if d := *f; size < int64(len(d)) { + *f = d[:size] + } + return nil +} + +// SizeHint implements [vfs.FileSizeHint]. +func (f *SliceFile) SizeHint(size int64) error { + if d := *f; size > int64(len(d)) { + *f = append(d, make([]byte, size-int64(len(d)))...) + } + return nil +} + +// Close implements [io.Closer]. +func (*SliceFile) Close() error { return nil } + +// Sync implements [vfs.File]. +func (*SliceFile) Sync(flags vfs.SyncFlag) error { return nil } + +// Lock implements [vfs.File]. +func (*SliceFile) Lock(lock vfs.LockLevel) error { + // notest // not concurrency safe + return sqlite3.IOERR_LOCK +} + +// Unlock implements [vfs.File]. +func (*SliceFile) Unlock(lock vfs.LockLevel) error { + // notest // not concurrency safe + return sqlite3.IOERR_UNLOCK +} + +// CheckReservedLock implements [vfs.File]. +func (*SliceFile) CheckReservedLock() (bool, error) { + // notest // not concurrency safe + return false, sqlite3.IOERR_CHECKRESERVEDLOCK +} + +// SectorSize implements [vfs.File]. +func (*SliceFile) SectorSize() int { + // notest // safe default + return 0 +} + +// DeviceCharacteristics implements [vfs.File]. +func (*SliceFile) DeviceCharacteristics() vfs.DeviceCharacteristic { + return vfs.IOCAP_ATOMIC | + vfs.IOCAP_SEQUENTIAL | + vfs.IOCAP_SAFE_APPEND | + vfs.IOCAP_POWERSAFE_OVERWRITE | + vfs.IOCAP_SUBPAGE_READ +} diff --git a/vendor/github.com/ncruces/go-sqlite3/util/vfsutil/wrap.go b/vendor/github.com/ncruces/go-sqlite3/util/vfsutil/wrap.go new file mode 100644 index 000000000..ad96547fa --- /dev/null +++ b/vendor/github.com/ncruces/go-sqlite3/util/vfsutil/wrap.go @@ -0,0 +1,185 @@ +// Package vfsutil implements virtual filesystem utilities. +package vfsutil + +import ( + "github.com/ncruces/go-sqlite3" + "github.com/ncruces/go-sqlite3/vfs" +) + +// UnwrapFile unwraps a [vfs.File], +// possibly implementing [vfs.FileUnwrap], +// to a concrete type. +func UnwrapFile[T vfs.File](f vfs.File) (_ T, _ bool) { + for { + switch t := f.(type) { + default: + return + case T: + return t, true + case vfs.FileUnwrap: + f = t.Unwrap() + } + } +} + +// WrapOpen helps wrap [vfs.VFS]. +func WrapOpen(f vfs.VFS, name string, flags vfs.OpenFlag) (file vfs.File, _ vfs.OpenFlag, err error) { + if f, ok := f.(vfs.VFSFilename); name == "" && ok { + return f.OpenFilename(nil, flags) + } + return f.Open(name, flags) +} + +// WrapOpenFilename helps wrap [vfs.VFSFilename]. +func WrapOpenFilename(f vfs.VFS, name *vfs.Filename, flags vfs.OpenFlag) (file vfs.File, _ vfs.OpenFlag, err error) { + if f, ok := f.(vfs.VFSFilename); ok { + return f.OpenFilename(name, flags) + } + return f.Open(name.String(), flags) +} + +// WrapLockState helps wrap [vfs.FileLockState]. +func WrapLockState(f vfs.File) vfs.LockLevel { + if f, ok := f.(vfs.FileLockState); ok { + return f.LockState() + } + return vfs.LOCK_EXCLUSIVE + 1 // UNKNOWN_LOCK +} + +// WrapPersistWAL helps wrap [vfs.FilePersistWAL]. +func WrapPersistWAL(f vfs.File) bool { + if f, ok := f.(vfs.FilePersistWAL); ok { + return f.PersistWAL() + } + return false +} + +// WrapSetPersistWAL helps wrap [vfs.FilePersistWAL]. +func WrapSetPersistWAL(f vfs.File, keepWAL bool) { + if f, ok := f.(vfs.FilePersistWAL); ok { + f.SetPersistWAL(keepWAL) + } +} + +// WrapPowersafeOverwrite helps wrap [vfs.FilePowersafeOverwrite]. +func WrapPowersafeOverwrite(f vfs.File) bool { + if f, ok := f.(vfs.FilePowersafeOverwrite); ok { + return f.PowersafeOverwrite() + } + return false +} + +// WrapSetPowersafeOverwrite helps wrap [vfs.FilePowersafeOverwrite]. +func WrapSetPowersafeOverwrite(f vfs.File, psow bool) { + if f, ok := f.(vfs.FilePowersafeOverwrite); ok { + f.SetPowersafeOverwrite(psow) + } +} + +// WrapChunkSize helps wrap [vfs.FileChunkSize]. +func WrapChunkSize(f vfs.File, size int) { + if f, ok := f.(vfs.FileChunkSize); ok { + f.ChunkSize(size) + } +} + +// WrapSizeHint helps wrap [vfs.FileSizeHint]. +func WrapSizeHint(f vfs.File, size int64) error { + if f, ok := f.(vfs.FileSizeHint); ok { + return f.SizeHint(size) + } + return sqlite3.NOTFOUND +} + +// WrapHasMoved helps wrap [vfs.FileHasMoved]. +func WrapHasMoved(f vfs.File) (bool, error) { + if f, ok := f.(vfs.FileHasMoved); ok { + return f.HasMoved() + } + return false, sqlite3.NOTFOUND +} + +// WrapOverwrite helps wrap [vfs.FileOverwrite]. +func WrapOverwrite(f vfs.File) error { + if f, ok := f.(vfs.FileOverwrite); ok { + return f.Overwrite() + } + return sqlite3.NOTFOUND +} + +// WrapSyncSuper helps wrap [vfs.FileSync]. +func WrapSyncSuper(f vfs.File, super string) error { + if f, ok := f.(vfs.FileSync); ok { + return f.SyncSuper(super) + } + return sqlite3.NOTFOUND +} + +// WrapCommitPhaseTwo helps wrap [vfs.FileCommitPhaseTwo]. +func WrapCommitPhaseTwo(f vfs.File) error { + if f, ok := f.(vfs.FileCommitPhaseTwo); ok { + return f.CommitPhaseTwo() + } + return sqlite3.NOTFOUND +} + +// WrapBeginAtomicWrite helps wrap [vfs.FileBatchAtomicWrite]. +func WrapBeginAtomicWrite(f vfs.File) error { + if f, ok := f.(vfs.FileBatchAtomicWrite); ok { + return f.BeginAtomicWrite() + } + return sqlite3.NOTFOUND +} + +// WrapCommitAtomicWrite helps wrap [vfs.FileBatchAtomicWrite]. +func WrapCommitAtomicWrite(f vfs.File) error { + if f, ok := f.(vfs.FileBatchAtomicWrite); ok { + return f.CommitAtomicWrite() + } + return sqlite3.NOTFOUND +} + +// WrapRollbackAtomicWrite helps wrap [vfs.FileBatchAtomicWrite]. +func WrapRollbackAtomicWrite(f vfs.File) error { + if f, ok := f.(vfs.FileBatchAtomicWrite); ok { + return f.RollbackAtomicWrite() + } + return sqlite3.NOTFOUND +} + +// WrapCheckpointStart helps wrap [vfs.FileCheckpoint]. +func WrapCheckpointStart(f vfs.File) { + if f, ok := f.(vfs.FileCheckpoint); ok { + f.CheckpointStart() + } +} + +// WrapCheckpointDone helps wrap [vfs.FileCheckpoint]. +func WrapCheckpointDone(f vfs.File) { + if f, ok := f.(vfs.FileCheckpoint); ok { + f.CheckpointDone() + } +} + +// WrapPragma helps wrap [vfs.FilePragma]. +func WrapPragma(f vfs.File, name, value string) (string, error) { + if f, ok := f.(vfs.FilePragma); ok { + return f.Pragma(name, value) + } + return "", sqlite3.NOTFOUND +} + +// WrapBusyHandler helps wrap [vfs.FilePragma]. +func WrapBusyHandler(f vfs.File, handler func() bool) { + if f, ok := f.(vfs.FileBusyHandler); ok { + f.BusyHandler(handler) + } +} + +// WrapSharedMemory helps wrap [vfs.FileSharedMemory]. +func WrapSharedMemory(f vfs.File) vfs.SharedMemory { + if f, ok := f.(vfs.FileSharedMemory); ok { + return f.SharedMemory() + } + return nil +} diff --git a/vendor/github.com/ncruces/go-sqlite3/value.go b/vendor/github.com/ncruces/go-sqlite3/value.go index 54d8f21eb..6806e9a79 100644 --- a/vendor/github.com/ncruces/go-sqlite3/value.go +++ b/vendor/github.com/ncruces/go-sqlite3/value.go @@ -31,9 +31,9 @@ func (v Value) Dup() *Value { // Close frees an SQL value previously obtained by [Value.Dup]. // // https://sqlite.org/c3ref/value_dup.html -func (dup *Value) Close() error { - dup.c.call("sqlite3_value_free", stk_t(dup.handle)) - dup.handle = 0 +func (v *Value) Close() error { + v.c.call("sqlite3_value_free", stk_t(v.handle)) + v.handle = 0 return nil } diff --git a/vendor/github.com/ncruces/go-sqlite3/vfs/api.go b/vendor/github.com/ncruces/go-sqlite3/vfs/api.go index d5bb3a7ae..a0d36b214 100644 --- a/vendor/github.com/ncruces/go-sqlite3/vfs/api.go +++ b/vendor/github.com/ncruces/go-sqlite3/vfs/api.go @@ -36,9 +36,9 @@ type VFSFilename interface { // // https://sqlite.org/c3ref/io_methods.html type File interface { - Close() error - ReadAt(p []byte, off int64) (n int, err error) - WriteAt(p []byte, off int64) (n int, err error) + io.Closer + io.ReaderAt + io.WriterAt Truncate(size int64) error Sync(flags SyncFlag) error Size() (int64, error) diff --git a/vendor/github.com/ncruces/go-sqlite3/vfs/cksm.go b/vendor/github.com/ncruces/go-sqlite3/vfs/cksm.go index 0ff7b6f18..0123cc634 100644 --- a/vendor/github.com/ncruces/go-sqlite3/vfs/cksm.go +++ b/vendor/github.com/ncruces/go-sqlite3/vfs/cksm.go @@ -5,7 +5,6 @@ import ( "context" _ "embed" "encoding/binary" - "strconv" "github.com/tetratelabs/wazero/api" @@ -13,48 +12,30 @@ import ( "github.com/ncruces/go-sqlite3/util/sql3util" ) -func cksmWrapFile(name *Filename, flags OpenFlag, file File) File { - // Checksum only main databases and WALs. - if flags&(OPEN_MAIN_DB|OPEN_WAL) == 0 { +func cksmWrapFile(file File, flags OpenFlag) File { + // Checksum only main databases. + if flags&OPEN_MAIN_DB == 0 { return file } - - cksm := cksmFile{File: file} - - if flags&OPEN_WAL != 0 { - main, _ := name.DatabaseFile().(cksmFile) - cksm.cksmFlags = main.cksmFlags - } else { - cksm.cksmFlags = new(cksmFlags) - cksm.isDB = true - } - - return cksm + return &cksmFile{File: file} } type cksmFile struct { File - *cksmFlags - isDB bool -} - -type cksmFlags struct { - computeCksm bool verifyCksm bool - inCkpt bool - pageSize int + computeCksm bool } -func (c cksmFile) ReadAt(p []byte, off int64) (n int, err error) { +func (c *cksmFile) ReadAt(p []byte, off int64) (n int, err error) { n, err = c.File.ReadAt(p, off) p = p[:n] - if isHeader(c.isDB, p, off) { + if isHeader(p, off) { c.init((*[100]byte)(p)) } // Verify checksums. - if c.verifyCksm && !c.inCkpt && len(p) == c.pageSize { + if c.verifyCksm && sql3util.ValidPageSize(len(p)) { cksm1 := cksmCompute(p[:len(p)-8]) cksm2 := *(*[8]byte)(p[len(p)-8:]) if cksm1 != cksm2 { @@ -64,20 +45,20 @@ func (c cksmFile) ReadAt(p []byte, off int64) (n int, err error) { return n, err } -func (c cksmFile) WriteAt(p []byte, off int64) (n int, err error) { - if isHeader(c.isDB, p, off) { +func (c *cksmFile) WriteAt(p []byte, off int64) (n int, err error) { + if isHeader(p, off) { c.init((*[100]byte)(p)) } // Compute checksums. - if c.computeCksm && !c.inCkpt && len(p) == c.pageSize { + if c.computeCksm && sql3util.ValidPageSize(len(p)) { *(*[8]byte)(p[len(p)-8:]) = cksmCompute(p[:len(p)-8]) } return c.File.WriteAt(p, off) } -func (c cksmFile) Pragma(name string, value string) (string, error) { +func (c *cksmFile) Pragma(name string, value string) (string, error) { switch name { case "checksum_verification": b, ok := sql3util.ParseBool(value) @@ -90,15 +71,15 @@ func (c cksmFile) Pragma(name string, value string) (string, error) { return "1", nil case "page_size": - if c.computeCksm { + if c.computeCksm && value != "" { // Do not allow page size changes on a checksum database. - return strconv.Itoa(c.pageSize), nil + return "", nil } } return "", _NOTFOUND } -func (c cksmFile) DeviceCharacteristics() DeviceCharacteristic { +func (c *cksmFile) DeviceCharacteristics() DeviceCharacteristic { ret := c.File.DeviceCharacteristics() if c.verifyCksm { ret &^= IOCAP_SUBPAGE_READ @@ -106,13 +87,8 @@ func (c cksmFile) DeviceCharacteristics() DeviceCharacteristic { return ret } -func (c cksmFile) fileControl(ctx context.Context, mod api.Module, op _FcntlOpcode, pArg ptr_t) _ErrorCode { - switch op { - case _FCNTL_CKPT_START: - c.inCkpt = true - case _FCNTL_CKPT_DONE: - c.inCkpt = false - case _FCNTL_PRAGMA: +func (c *cksmFile) fileControl(ctx context.Context, mod api.Module, op _FcntlOpcode, pArg ptr_t) _ErrorCode { + if op == _FCNTL_PRAGMA { rc := vfsFileControlImpl(ctx, mod, c, op, pArg) if rc != _NOTFOUND { return rc @@ -121,24 +97,26 @@ 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 *[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 (c *cksmFile) init(header *[100]byte) { + if r := header[20] == 8; r != c.computeCksm { + c.computeCksm = r + c.verifyCksm = r } } -func isHeader(isDB bool, p []byte, off int64) bool { - check := sql3util.ValidPageSize(len(p)) - if isDB { - check = off == 0 && len(p) >= 100 +func (c *cksmFile) SharedMemory() SharedMemory { + if f, ok := c.File.(FileSharedMemory); ok { + return f.SharedMemory() } - return check && bytes.HasPrefix(p, []byte("SQLite format 3\000")) + return nil +} + +func (c *cksmFile) Unwrap() File { + return c.File +} + +func isHeader(p []byte, off int64) bool { + return off == 0 && len(p) >= 100 && bytes.HasPrefix(p, []byte("SQLite format 3\000")) } func cksmCompute(a []byte) (cksm [8]byte) { @@ -155,14 +133,3 @@ func cksmCompute(a []byte) (cksm [8]byte) { binary.LittleEndian.PutUint32(cksm[4:8], s2) return } - -func (c cksmFile) SharedMemory() SharedMemory { - if f, ok := c.File.(FileSharedMemory); ok { - return f.SharedMemory() - } - return nil -} - -func (c cksmFile) Unwrap() File { - return c.File -} diff --git a/vendor/github.com/ncruces/go-sqlite3/vfs/file.go b/vendor/github.com/ncruces/go-sqlite3/vfs/file.go index 8e65ca660..06906c961 100644 --- a/vendor/github.com/ncruces/go-sqlite3/vfs/file.go +++ b/vendor/github.com/ncruces/go-sqlite3/vfs/file.go @@ -75,6 +75,9 @@ func (vfsOS) Access(name string, flags AccessFlag) (bool, error) { func (vfsOS) Open(name string, flags OpenFlag) (File, OpenFlag, error) { // notest // OpenFilename is called instead + if name == "" { + return vfsOS{}.OpenFilename(nil, flags) + } return nil, 0, _CANTOPEN } diff --git a/vendor/github.com/ncruces/go-sqlite3/vfs/filename.go b/vendor/github.com/ncruces/go-sqlite3/vfs/filename.go index 965c3b1a6..be16b3dde 100644 --- a/vendor/github.com/ncruces/go-sqlite3/vfs/filename.go +++ b/vendor/github.com/ncruces/go-sqlite3/vfs/filename.go @@ -56,7 +56,7 @@ func (n *Filename) Journal() string { return n.path("sqlite3_filename_journal") } -// Journal returns the name of the corresponding WAL file. +// WAL returns the name of the corresponding WAL file. // // https://sqlite.org/c3ref/filename_database.html func (n *Filename) WAL() string { diff --git a/vendor/github.com/ncruces/go-sqlite3/vfs/memdb/memdb.go b/vendor/github.com/ncruces/go-sqlite3/vfs/memdb/memdb.go index b99070496..e304f6d58 100644 --- a/vendor/github.com/ncruces/go-sqlite3/vfs/memdb/memdb.go +++ b/vendor/github.com/ncruces/go-sqlite3/vfs/memdb/memdb.go @@ -2,40 +2,39 @@ package memdb import ( "io" + "strings" "sync" "time" "github.com/ncruces/go-sqlite3" + "github.com/ncruces/go-sqlite3/util/vfsutil" "github.com/ncruces/go-sqlite3/vfs" ) const sectorSize = 65536 -// Ensure sectorSize is a multiple of 64K (the largest page size). -var _ [0]struct{} = [sectorSize & 65535]struct{}{} - type memVFS struct{} func (memVFS) Open(name string, flags vfs.OpenFlag) (vfs.File, vfs.OpenFlag, error) { // For simplicity, we do not support reading or writing data // across "sector" boundaries. - // - // This is not a problem for most SQLite file types: - // - databases, which only do page aligned reads/writes; - // - temp journals, as used by the sorter, which does the same: - // https://github.com/sqlite/sqlite/blob/b74eb0/src/vdbesort.c#L409-L412 - // - // We refuse to open all other file types, - // but returning OPEN_MEMORY means SQLite won't ask us to. - const types = vfs.OPEN_MAIN_DB | vfs.OPEN_TEMP_DB | - vfs.OPEN_TRANSIENT_DB | vfs.OPEN_TEMP_JOURNAL - if flags&types == 0 { + // This is not a problem for SQLite database files. + const databases = vfs.OPEN_MAIN_DB | vfs.OPEN_TEMP_DB | vfs.OPEN_TRANSIENT_DB + + // Temp journals, as used by the sorter, use SliceFile. + if flags&vfs.OPEN_TEMP_JOURNAL != 0 { + return &vfsutil.SliceFile{}, flags | vfs.OPEN_MEMORY, nil + } + + // Refuse to open all other file types. + // Returning OPEN_MEMORY means SQLite won't ask us to. + if flags&databases == 0 { // notest // OPEN_MEMORY return nil, flags, sqlite3.CANTOPEN } // A shared database has a name that begins with "/". - shared := len(name) > 1 && name[0] == '/' + shared := strings.HasPrefix(name, "/") var db *memDB if shared { @@ -76,18 +75,16 @@ func (memVFS) FullPathname(name string) (string, error) { type memDB struct { name string + // +checklocks:lockMtx + waiter *sync.Cond // +checklocks:dataMtx data []*[sectorSize]byte - // +checklocks:dataMtx - size int64 - - // +checklocks:memoryMtx - refs int32 - shared int32 // +checklocks:lockMtx - pending bool // +checklocks:lockMtx - reserved bool // +checklocks:lockMtx - waiter *sync.Cond // +checklocks:lockMtx + size int64 // +checklocks:dataMtx + refs int32 // +checklocks:memoryMtx + shared int32 // +checklocks:lockMtx + pending bool // +checklocks:lockMtx + reserved bool // +checklocks:lockMtx lockMtx sync.Mutex dataMtx sync.RWMutex @@ -129,7 +126,7 @@ func (m *memFile) ReadAt(b []byte, off int64) (n int, err error) { base := off / sectorSize rest := off % sectorSize have := int64(sectorSize) - if base == int64(len(m.data))-1 { + if m.size < off+int64(len(b)) { have = modRoundUp(m.size, sectorSize) } n = copy(b, (*m.data[base])[rest:have]) @@ -150,22 +147,37 @@ func (m *memFile) WriteAt(b []byte, off int64) (n int, err error) { m.data = append(m.data, new([sectorSize]byte)) } n = copy((*m.data[base])[rest:], b) + if size := off + int64(n); size > m.size { + m.size = size + } if n < len(b) { // notest // assume writes are page aligned return n, io.ErrShortWrite } - if size := off + int64(len(b)); size > m.size { - m.size = size - } return n, nil } +func (m *memFile) Size() (int64, error) { + m.dataMtx.RLock() + defer m.dataMtx.RUnlock() + return m.size, nil +} + func (m *memFile) Truncate(size int64) error { m.dataMtx.Lock() defer m.dataMtx.Unlock() return m.truncate(size) } +func (m *memFile) SizeHint(size int64) error { + m.dataMtx.Lock() + defer m.dataMtx.Unlock() + if size > m.size { + return m.truncate(size) + } + return nil +} + // +checklocks:m.dataMtx func (m *memFile) truncate(size int64) error { if size < m.size { @@ -185,16 +197,6 @@ func (m *memFile) truncate(size int64) error { return nil } -func (m *memFile) Sync(flag vfs.SyncFlag) error { - return nil -} - -func (m *memFile) Size() (int64, error) { - m.dataMtx.RLock() - defer m.dataMtx.RUnlock() - return m.size, nil -} - func (m *memFile) Lock(lock vfs.LockLevel) error { if m.lock >= lock { return nil @@ -278,31 +280,24 @@ func (m *memFile) CheckReservedLock() (bool, error) { return m.reserved, nil } -func (m *memFile) SectorSize() int { +func (m *memFile) LockState() vfs.LockLevel { + return m.lock +} + +func (*memFile) Sync(flag vfs.SyncFlag) error { return nil } + +func (*memFile) SectorSize() int { // notest // IOCAP_POWERSAFE_OVERWRITE return sectorSize } -func (m *memFile) DeviceCharacteristics() vfs.DeviceCharacteristic { +func (*memFile) DeviceCharacteristics() vfs.DeviceCharacteristic { return vfs.IOCAP_ATOMIC | vfs.IOCAP_SEQUENTIAL | vfs.IOCAP_SAFE_APPEND | vfs.IOCAP_POWERSAFE_OVERWRITE } -func (m *memFile) SizeHint(size int64) error { - m.dataMtx.Lock() - defer m.dataMtx.Unlock() - if size > m.size { - return m.truncate(size) - } - return nil -} - -func (m *memFile) LockState() vfs.LockLevel { - return m.lock -} - func divRoundUp(a, b int64) int64 { return (a + b - 1) / b } diff --git a/vendor/github.com/ncruces/go-sqlite3/vfs/vfs.go b/vendor/github.com/ncruces/go-sqlite3/vfs/vfs.go index 2656ddb49..aef81c3f2 100644 --- a/vendor/github.com/ncruces/go-sqlite3/vfs/vfs.go +++ b/vendor/github.com/ncruces/go-sqlite3/vfs/vfs.go @@ -148,7 +148,7 @@ func vfsOpen(ctx context.Context, mod api.Module, pVfs, zPath, pFile ptr_t, flag if pOutFlags != 0 { util.Write32(mod, pOutFlags, flags) } - file = cksmWrapFile(name, flags, file) + file = cksmWrapFile(file, flags) vfsFileRegister(ctx, mod, pFile, file) return _OK } |
