diff options
Diffstat (limited to 'vendor/github.com/ncruces/go-sqlite3/vfs')
8 files changed, 92 insertions, 27 deletions
diff --git a/vendor/github.com/ncruces/go-sqlite3/vfs/api.go b/vendor/github.com/ncruces/go-sqlite3/vfs/api.go index 330e8a2b1..f2531f223 100644 --- a/vendor/github.com/ncruces/go-sqlite3/vfs/api.go +++ b/vendor/github.com/ncruces/go-sqlite3/vfs/api.go @@ -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) +} diff --git a/vendor/github.com/ncruces/go-sqlite3/vfs/const.go b/vendor/github.com/ncruces/go-sqlite3/vfs/const.go index 896cdaca4..1c9b77a7a 100644 --- a/vendor/github.com/ncruces/go-sqlite3/vfs/const.go +++ b/vendor/github.com/ncruces/go-sqlite3/vfs/const.go @@ -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 diff --git a/vendor/github.com/ncruces/go-sqlite3/vfs/file.go b/vendor/github.com/ncruces/go-sqlite3/vfs/file.go index b5d285375..e028a2a55 100644 --- a/vendor/github.com/ncruces/go-sqlite3/vfs/file.go +++ b/vendor/github.com/ncruces/go-sqlite3/vfs/file.go @@ -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 } 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 686f8e9a7..4adb2dde2 100644 --- a/vendor/github.com/ncruces/go-sqlite3/vfs/memdb/memdb.go +++ b/vendor/github.com/ncruces/go-sqlite3/vfs/memdb/memdb.go @@ -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) { diff --git a/vendor/github.com/ncruces/go-sqlite3/vfs/os_std.go b/vendor/github.com/ncruces/go-sqlite3/vfs/os_std.go index a17893d2e..0d0ca24c9 100644 --- a/vendor/github.com/ncruces/go-sqlite3/vfs/os_std.go +++ b/vendor/github.com/ncruces/go-sqlite3/vfs/os_std.go @@ -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) diff --git a/vendor/github.com/ncruces/go-sqlite3/vfs/os_unix.go b/vendor/github.com/ncruces/go-sqlite3/vfs/os_unix.go index 6637c2922..c4f9ba870 100644 --- a/vendor/github.com/ncruces/go-sqlite3/vfs/os_unix.go +++ b/vendor/github.com/ncruces/go-sqlite3/vfs/os_unix.go @@ -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 diff --git a/vendor/github.com/ncruces/go-sqlite3/vfs/shm_bsd.go b/vendor/github.com/ncruces/go-sqlite3/vfs/shm_bsd.go index 5f4f5d108..76e6888e1 100644 --- a/vendor/github.com/ncruces/go-sqlite3/vfs/shm_bsd.go +++ b/vendor/github.com/ncruces/go-sqlite3/vfs/shm_bsd.go @@ -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)) } diff --git a/vendor/github.com/ncruces/go-sqlite3/vfs/vfs.go b/vendor/github.com/ncruces/go-sqlite3/vfs/vfs.go index 83c95d08d..d8816e409 100644 --- a/vendor/github.com/ncruces/go-sqlite3/vfs/vfs.go +++ b/vendor/github.com/ncruces/go-sqlite3/vfs/vfs.go @@ -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 } |