diff --git a/go.work.sum b/go.work.sum index e69de29..342066c 100644 --- a/go.work.sum +++ b/go.work.sum @@ -0,0 +1,4 @@ +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= diff --git a/vfs/api.go b/vfs/api.go index df4d790..f191495 100644 --- a/vfs/api.go +++ b/vfs/api.go @@ -80,6 +80,16 @@ type FileOverwrite interface { Overwrite() error } +// FilePersistentWAL 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 { + File + PersistentWAL() bool + SetPersistentWAL(bool) +} + // FilePowersafeOverwrite extends File to implement the // SQLITE_FCNTL_POWERSAFE_OVERWRITE file control opcode. // @@ -90,7 +100,7 @@ type FilePowersafeOverwrite interface { SetPowersafeOverwrite(bool) } -// FilePowersafeOverwrite extends File to implement the +// FileCommitPhaseTwo extends File to implement the // SQLITE_FCNTL_COMMIT_PHASETWO file control opcode. // // https://sqlite.org/c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlcommitphasetwo diff --git a/vfs/file.go b/vfs/file.go index 705a13a..8664487 100644 --- a/vfs/file.go +++ b/vfs/file.go @@ -126,9 +126,10 @@ func (vfsOS) OpenParams(name string, flags OpenFlag, params url.Values) (File, O type vfsFile struct { *os.File lock LockLevel - psow bool - syncDir bool readOnly bool + keepWAL bool + syncDir bool + psow bool } var ( @@ -136,6 +137,7 @@ var ( _ FileLockState = &vfsFile{} _ FileHasMoved = &vfsFile{} _ FileSizeHint = &vfsFile{} + _ FilePersistentWAL = &vfsFile{} _ FilePowersafeOverwrite = &vfsFile{} ) @@ -198,4 +200,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) SetPowersafeOverwrite(psow bool) { f.psow = psow } +func (f *vfsFile) SetPersistentWAL(keepWAL bool) { f.keepWAL = keepWAL } diff --git a/vfs/vfs.go b/vfs/vfs.go index 820f4dc..d5efeab 100644 --- a/vfs/vfs.go +++ b/vfs/vfs.go @@ -257,19 +257,26 @@ func vfsFileControl(ctx context.Context, mod api.Module, pFile uint32, op _Fcntl return _OK } + case _FCNTL_PERSIST_WAL: + if file, ok := file.(FilePersistentWAL); ok { + if i := util.ReadUint32(mod, pArg); int32(i) >= 0 { + file.SetPersistentWAL(i != 0) + } else if file.PersistentWAL() { + util.WriteUint32(mod, pArg, 1) + } else { + util.WriteUint32(mod, pArg, 0) + } + return _OK + } + case _FCNTL_POWERSAFE_OVERWRITE: if file, ok := file.(FilePowersafeOverwrite); ok { - switch util.ReadUint32(mod, pArg) { - case 0: - file.SetPowersafeOverwrite(false) - case 1: - file.SetPowersafeOverwrite(true) - default: - if file.PowersafeOverwrite() { - util.WriteUint32(mod, pArg, 1) - } else { - util.WriteUint32(mod, pArg, 0) - } + if i := util.ReadUint32(mod, pArg); int32(i) >= 0 { + file.SetPowersafeOverwrite(i != 0) + } else if file.PowersafeOverwrite() { + util.WriteUint32(mod, pArg, 1) + } else { + util.WriteUint32(mod, pArg, 0) } return _OK } @@ -284,12 +291,10 @@ func vfsFileControl(ctx context.Context, mod api.Module, pFile uint32, op _Fcntl case _FCNTL_HAS_MOVED: if file, ok := file.(FileHasMoved); ok { moved, err := file.HasMoved() - var res uint32 if moved { res = 1 } - util.WriteUint32(mod, pArg, res) return vfsErrorCode(err, _IOERR_FSTAT) } @@ -326,6 +331,8 @@ func vfsFileControl(ctx context.Context, mod api.Module, pFile uint32, op _Fcntl // Consider also implementing these opcodes (in use by SQLite): // _FCNTL_BUSYHANDLER // _FCNTL_CHUNK_SIZE + // _FCNTL_CKPT_DONE + // _FCNTL_CKPT_START // _FCNTL_PRAGMA // _FCNTL_SYNC return _NOTFOUND