update ncruces/go-sqlite3 v0.21.3 -> v0.22.0, gruf/go-ffmpreg v0.6.4 -> v0.6.5 (#3646)

This commit is contained in:
kim
2025-01-14 18:30:55 +00:00
committed by GitHub
parent b8ef9fc4bc
commit 81b66ad7e3
28 changed files with 165 additions and 57 deletions

View File

@ -76,7 +76,7 @@ It also benefits greatly from [SQLite's](https://sqlite.org/testing.html) and
Every commit is [tested](https://github.com/ncruces/go-sqlite3/wiki/Support-matrix) on
Linux (amd64/arm64/386/riscv64/ppc64le/s390x), macOS (amd64/arm64),
Windows (amd64), FreeBSD (amd64), OpenBSD (amd64), NetBSD (amd64),
Windows (amd64), FreeBSD (amd64/arm64), OpenBSD (amd64), NetBSD (amd64/arm64),
DragonFly BSD (amd64), illumos (amd64), and Solaris (amd64).
The Go VFS is tested by running SQLite's

View File

@ -6,6 +6,7 @@ import (
"math"
"math/rand"
"net/url"
"runtime"
"strings"
"time"
@ -67,7 +68,7 @@ func OpenFlags(filename string, flags OpenFlag) (*Conn, error) {
return newConn(context.Background(), filename, flags)
}
type connKey struct{}
type connKey = util.ConnKey
func newConn(ctx context.Context, filename string, flags OpenFlag) (res *Conn, _ error) {
err := ctx.Err()
@ -375,8 +376,13 @@ func (c *Conn) checkInterrupt(handle uint32) {
}
func progressCallback(ctx context.Context, mod api.Module, _ uint32) (interrupt uint32) {
if c, ok := ctx.Value(connKey{}).(*Conn); ok && c.interrupt.Err() != nil {
interrupt = 1
if c, ok := ctx.Value(connKey{}).(*Conn); ok {
if c.interrupt.Done() != nil {
runtime.Gosched()
}
if c.interrupt.Err() != nil {
interrupt = 1
}
}
return interrupt
}

View File

@ -166,6 +166,7 @@ const (
PREPARE_PERSISTENT PrepareFlag = 0x01
PREPARE_NORMALIZE PrepareFlag = 0x02
PREPARE_NO_VTAB PrepareFlag = 0x04
PREPARE_DONT_LOG PrepareFlag = 0x10
)
// FunctionFlag is a flag that can be passed to
@ -219,6 +220,7 @@ const (
DBSTATUS_DEFERRED_FKS DBStatus = 10
DBSTATUS_CACHE_USED_SHARED DBStatus = 11
DBSTATUS_CACHE_SPILL DBStatus = 12
// DBSTATUS_MAX DBStatus = 12
)
// DBConfig are the available database connection configuration options.

View File

@ -1,6 +1,6 @@
# Embeddable Wasm build of SQLite
This folder includes an embeddable Wasm build of SQLite 3.47.2 for use with
This folder includes an embeddable Wasm build of SQLite 3.48.0 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

@ -14,7 +14,7 @@ trap 'rm -f sqlite3.tmp' EXIT
-o sqlite3.wasm "$ROOT/sqlite3/main.c" \
-I"$ROOT/sqlite3" \
-mexec-model=reactor \
-matomics -msimd128 -mmutable-globals -mmultivalue \
-msimd128 -mmutable-globals -mmultivalue \
-mbulk-memory -mreference-types \
-mnontrapping-fptoint -msign-ext \
-fno-stack-protector -fno-stack-clash-protection \

View File

@ -77,6 +77,7 @@ sqlite3_get_autocommit
sqlite3_get_auxdata
sqlite3_hard_heap_limit64
sqlite3_interrupt
sqlite3_invoke_busy_handler_go
sqlite3_last_insert_rowid
sqlite3_limit
sqlite3_malloc64

View File

@ -8,13 +8,14 @@ package embed
import (
_ "embed"
"unsafe"
"github.com/ncruces/go-sqlite3"
)
//go:embed sqlite3.wasm
var binary []byte
var binary string
func init() {
sqlite3.Binary = binary
sqlite3.Binary = unsafe.Slice(unsafe.StringData(binary), len(binary))
}

Binary file not shown.

View File

@ -12,5 +12,6 @@ golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8=
golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M=
golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E=
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=

View File

@ -0,0 +1,27 @@
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

@ -8,6 +8,8 @@ import (
"github.com/ncruces/go-sqlite3/internal/alloc"
)
type ConnKey struct{}
type moduleKey struct{}
type moduleState struct {
mmapState

View File

@ -11,7 +11,6 @@ import (
"github.com/tetratelabs/wazero"
"github.com/tetratelabs/wazero/api"
"github.com/tetratelabs/wazero/experimental"
"github.com/ncruces/go-sqlite3/internal/util"
"github.com/ncruces/go-sqlite3/vfs"
@ -49,14 +48,18 @@ func compileSQLite() {
ctx := context.Background()
cfg := RuntimeConfig
if cfg == nil {
cfg = wazero.NewRuntimeConfig()
if bits.UintSize >= 64 {
cfg = cfg.WithMemoryLimitPages(4096) // 256MB
if util.CompilerSupported() {
cfg = wazero.NewRuntimeConfigCompiler()
} else {
cfg = wazero.NewRuntimeConfigInterpreter()
}
if bits.UintSize < 64 {
cfg = cfg.WithMemoryLimitPages(512) // 32MB
} else {
cfg = cfg.WithMemoryLimitPages(4096) // 256MB
}
}
cfg = cfg.WithCoreFeatures(api.CoreFeaturesV2 | experimental.CoreFeaturesThreads)
cfg = cfg.WithCoreFeatures(api.CoreFeaturesV2)
instance.runtime = wazero.NewRuntimeWithConfig(ctx, cfg)

View File

@ -17,7 +17,7 @@ const (
)
var (
//go:embed parse/sql3parse_table.wasm
//go:embed wasm/sql3parse_table.wasm
binary []byte
once sync.Once
runtime wazero.Runtime

View File

@ -65,14 +65,14 @@ type FileLockState interface {
LockState() LockLevel
}
// FilePersistentWAL extends File to implement the
// FilePersistWAL extends File to implement the
// SQLITE_FCNTL_PERSIST_WAL file control opcode.
//
// https://sqlite.org/c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlpersistwal
type FilePersistentWAL interface {
type FilePersistWAL interface {
File
PersistentWAL() bool
SetPersistentWAL(bool)
PersistWAL() bool
SetPersistWAL(bool)
}
// FilePowersafeOverwrite extends File to implement the
@ -121,6 +121,15 @@ type FileOverwrite interface {
Overwrite() error
}
// FileSync extends File to implement the
// SQLITE_FCNTL_SYNC file control opcode.
//
// https://sqlite.org/c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlsync
type FileSync interface {
File
SyncSuper(super string) error
}
// FileCommitPhaseTwo extends File to implement the
// SQLITE_FCNTL_COMMIT_PHASETWO file control opcode.
//
@ -162,6 +171,15 @@ type FilePragma interface {
Pragma(name, value string) (string, error)
}
// FileBusyHandler extends File to implement the
// SQLITE_FCNTL_BUSYHANDLER file control opcode.
//
// https://sqlite.org/c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlbusyhandler
type FileBusyHandler interface {
File
BusyHandler(func() bool)
}
// FileSharedMemory extends File to possibly implement
// shared-memory for the WAL-index.
// The same shared-memory instance must be returned
@ -191,3 +209,8 @@ type fileControl interface {
File
fileControl(ctx context.Context, mod api.Module, op _FcntlOpcode, pArg uint32) _ErrorCode
}
type filePDB interface {
File
SetDB(any)
}

View File

@ -225,6 +225,7 @@ const (
_FCNTL_EXTERNAL_READER _FcntlOpcode = 40
_FCNTL_CKSM_FILE _FcntlOpcode = 41
_FCNTL_RESET_CACHE _FcntlOpcode = 42
_FCNTL_NULL_IO _FcntlOpcode = 43
)
// https://sqlite.org/c3ref/c_shm_exclusive.html

View File

@ -6,7 +6,6 @@ import (
"io/fs"
"os"
"path/filepath"
"runtime"
"syscall"
"github.com/ncruces/go-sqlite3/util/osutil"
@ -41,7 +40,7 @@ func (vfsOS) Delete(path string, syncDir bool) error {
if err != nil {
return err
}
if runtime.GOOS != "windows" && syncDir {
if canSyncDirs && syncDir {
f, err := os.Open(filepath.Dir(path))
if err != nil {
return _OK
@ -120,9 +119,9 @@ func (vfsOS) OpenFilename(name *Filename, flags OpenFlag) (File, OpenFlag, error
File: f,
psow: true,
readOnly: flags&OPEN_READONLY != 0,
syncDir: runtime.GOOS != "windows" &&
flags&(OPEN_CREATE) != 0 &&
flags&(OPEN_MAIN_JOURNAL|OPEN_SUPER_JOURNAL|OPEN_WAL) != 0,
syncDir: canSyncDirs &&
flags&(OPEN_MAIN_JOURNAL|OPEN_SUPER_JOURNAL|OPEN_WAL) != 0 &&
flags&(OPEN_CREATE) != 0,
shm: NewSharedMemory(name.String()+"-shm", flags),
}
return &file, flags, nil
@ -143,7 +142,7 @@ var (
_ FileLockState = &vfsFile{}
_ FileHasMoved = &vfsFile{}
_ FileSizeHint = &vfsFile{}
_ FilePersistentWAL = &vfsFile{}
_ FilePersistWAL = &vfsFile{}
_ FilePowersafeOverwrite = &vfsFile{}
)
@ -163,7 +162,7 @@ func (f *vfsFile) Sync(flags SyncFlag) error {
if err != nil {
return err
}
if runtime.GOOS != "windows" && f.syncDir {
if canSyncDirs && f.syncDir {
f.syncDir = false
d, err := os.Open(filepath.Dir(f.File.Name()))
if err != nil {
@ -218,6 +217,6 @@ func (f *vfsFile) HasMoved() (bool, error) {
func (f *vfsFile) LockState() LockLevel { return f.lock }
func (f *vfsFile) PowersafeOverwrite() bool { return f.psow }
func (f *vfsFile) PersistentWAL() bool { return f.keepWAL }
func (f *vfsFile) PersistWAL() bool { return f.keepWAL }
func (f *vfsFile) SetPowersafeOverwrite(psow bool) { f.psow = psow }
func (f *vfsFile) SetPersistentWAL(keepWAL bool) { f.keepWAL = keepWAL }
func (f *vfsFile) SetPersistWAL(keepWAL bool) { f.keepWAL = keepWAL }

View File

@ -62,11 +62,11 @@ func (memVFS) Open(name string, flags vfs.OpenFlag) (vfs.File, vfs.OpenFlag, err
}
func (memVFS) Delete(name string, dirSync bool) error {
return sqlite3.IOERR_DELETE
return sqlite3.IOERR_DELETE_NOENT // used to delete journals
}
func (memVFS) Access(name string, flag vfs.AccessFlag) (bool, error) {
return false, nil
return false, nil // used to check for journals
}
func (memVFS) FullPathname(name string) (string, error) {

View File

@ -7,7 +7,10 @@ import (
"os"
)
const _O_NOFOLLOW = 0
const (
_O_NOFOLLOW = 0
canSyncDirs = false
)
func osAccess(path string, flags AccessFlag) error {
fi, err := os.Stat(path)

View File

@ -9,7 +9,10 @@ import (
"golang.org/x/sys/unix"
)
const _O_NOFOLLOW = unix.O_NOFOLLOW
const (
_O_NOFOLLOW = unix.O_NOFOLLOW
canSyncDirs = true
)
func osAccess(path string, flags AccessFlag) error {
var access uint32 // unix.F_OK

View File

@ -178,7 +178,7 @@ func (s *vfsShm) shmLock(offset, n int32, flags _ShmFlag) _ErrorCode {
s.Lock()
defer s.Unlock()
// Check if we could obtain/release the lock locally.
// Check if we can obtain/release locks locally.
rc := s.shmMemLock(offset, n, flags)
if rc != _OK {
return rc
@ -187,6 +187,8 @@ func (s *vfsShm) shmLock(offset, n int32, flags _ShmFlag) _ErrorCode {
// Obtain/release the appropriate file locks.
switch {
case flags&_SHM_UNLOCK != 0:
// Relasing a shared lock decrements the counter,
// but may leave parts of the range still locked.
begin, end := offset, offset+n
for i := begin; i < end; i++ {
if s.vfsShmParent.lock[i] != 0 {
@ -201,14 +203,22 @@ func (s *vfsShm) shmLock(offset, n int32, flags _ShmFlag) _ErrorCode {
}
return rc
case flags&_SHM_SHARED != 0:
rc = osReadLock(s.File, _SHM_BASE+int64(offset), int64(n))
// Acquiring a new shared lock on the file is only necessary
// if there was a new shared lock in the range.
for i := offset; i < offset+n; i++ {
if s.vfsShmParent.lock[i] == 1 {
rc = osReadLock(s.File, _SHM_BASE+int64(offset), int64(n))
break
}
}
case flags&_SHM_EXCLUSIVE != 0:
// Acquiring an exclusive lock on the file is always necessary.
rc = osWriteLock(s.File, _SHM_BASE+int64(offset), int64(n))
default:
panic(util.AssertErr())
}
// Release the local lock we had acquired.
// Release the local locks we had acquired.
if rc != _OK {
s.shmMemLock(offset, n, flags^(_SHM_UNLOCK|_SHM_LOCK))
}

View File

@ -255,10 +255,10 @@ func vfsFileControlImpl(ctx context.Context, mod api.Module, file File, op _Fcnt
}
case _FCNTL_PERSIST_WAL:
if file, ok := file.(FilePersistentWAL); ok {
if file, ok := file.(FilePersistWAL); ok {
if i := util.ReadUint32(mod, pArg); int32(i) >= 0 {
file.SetPersistentWAL(i != 0)
} else if file.PersistentWAL() {
file.SetPersistWAL(i != 0)
} else if file.PersistWAL() {
util.WriteUint32(mod, pArg, 1)
} else {
util.WriteUint32(mod, pArg, 0)
@ -309,6 +309,16 @@ func vfsFileControlImpl(ctx context.Context, mod api.Module, file File, op _Fcnt
return vfsErrorCode(err, _IOERR)
}
case _FCNTL_SYNC:
if file, ok := file.(FileSync); ok {
var name string
if pArg != 0 {
name = util.ReadString(mod, pArg, _MAX_PATHNAME)
}
err := file.SyncSuper(name)
return vfsErrorCode(err, _IOERR)
}
case _FCNTL_COMMIT_PHASETWO:
if file, ok := file.(FileCommitPhaseTwo); ok {
err := file.CommitPhaseTwo()
@ -369,6 +379,20 @@ func vfsFileControlImpl(ctx context.Context, mod api.Module, file File, op _Fcnt
return ret
}
case _FCNTL_BUSYHANDLER:
if file, ok := file.(FileBusyHandler); ok {
arg := util.ReadUint64(mod, pArg)
fn := mod.ExportedFunction("sqlite3_invoke_busy_handler_go")
file.BusyHandler(func() bool {
stack := [...]uint64{arg}
if err := fn.CallWithStack(ctx, stack[:]); err != nil {
panic(err)
}
return uint32(stack[0]) != 0
})
return _OK
}
case _FCNTL_LOCK_TIMEOUT:
if file, ok := file.(FileSharedMemory); ok {
if shm, ok := file.SharedMemory().(blockingSharedMemory); ok {
@ -376,12 +400,14 @@ func vfsFileControlImpl(ctx context.Context, mod api.Module, file File, op _Fcnt
return _OK
}
}
case _FCNTL_PDB:
if file, ok := file.(filePDB); ok {
file.SetDB(ctx.Value(util.ConnKey{}))
return _OK
}
}
// Consider also implementing these opcodes (in use by SQLite):
// _FCNTL_BUSYHANDLER
// _FCNTL_LAST_ERRNO
// _FCNTL_SYNC
return _NOTFOUND
}

View File

@ -242,7 +242,7 @@ type VTabSavepointer interface {
// A VTabCursor may optionally implement
// [io.Closer] to free resources.
//
// http://sqlite.org/c3ref/vtab_cursor.html
// https://sqlite.org/c3ref/vtab_cursor.html
type VTabCursor interface {
// https://sqlite.org/vtab.html#xfilter
Filter(idxNum int, idxStr string, arg ...Value) error