This commit is contained in:
Nuno Cruces
2023-05-23 14:44:25 +01:00
parent e6969432e3
commit cfb69e4ce7
5 changed files with 75 additions and 78 deletions

View File

@@ -1,8 +1,6 @@
// Package sqlite3vfs wraps the C SQLite VFS API.
package sqlite3vfs
import "sync"
// A VFS defines the interface between the SQLite core and the underlying operating system.
//
// Use sqlite3.ErrorCode or sqlite3.ExtendedErrorCode to return specific error codes to SQLite.
@@ -71,39 +69,3 @@ type FilePowersafeOverwrite interface {
PowersafeOverwrite() bool
SetPowersafeOverwrite(bool)
}
var (
vfsRegistry map[string]VFS
vfsRegistryMtx sync.Mutex
)
// Find returns a VFS given its name.
// If there is no match, nil is returned.
//
// https://www.sqlite.org/c3ref/vfs_find.html
func Find(name string) VFS {
vfsRegistryMtx.Lock()
defer vfsRegistryMtx.Unlock()
return vfsRegistry[name]
}
// Register registers a VFS.
//
// https://www.sqlite.org/c3ref/vfs_find.html
func Register(name string, vfs VFS) {
vfsRegistryMtx.Lock()
defer vfsRegistryMtx.Unlock()
if vfsRegistry == nil {
vfsRegistry = map[string]VFS{}
}
vfsRegistry[name] = vfs
}
// Unregister unregisters a VFS.
//
// https://www.sqlite.org/c3ref/vfs_find.html
func Unregister(name string) {
vfsRegistryMtx.Lock()
defer vfsRegistryMtx.Unlock()
delete(vfsRegistry, name)
}

View File

@@ -1,7 +1,6 @@
package sqlite3vfs
import (
"context"
"errors"
"io"
"io/fs"
@@ -10,9 +9,6 @@ import (
"runtime"
"syscall"
"time"
"github.com/ncruces/go-sqlite3/internal/util"
"github.com/tetratelabs/wazero/api"
)
type vfsOS struct{}
@@ -132,42 +128,6 @@ var (
_ FilePowersafeOverwrite = &vfsFile{}
)
func vfsFileNew(vfs *vfsState, file File) uint32 {
// Find an empty slot.
for id, f := range vfs.files {
if f == nil {
vfs.files[id] = file
return uint32(id)
}
}
// Add a new slot.
vfs.files = append(vfs.files, file)
return uint32(len(vfs.files) - 1)
}
func vfsFileRegister(ctx context.Context, mod api.Module, pFile uint32, file File) {
const fileHandleOffset = 4
id := vfsFileNew(ctx.Value(vfsKey{}).(*vfsState), file)
util.WriteUint32(mod, pFile+fileHandleOffset, id)
}
func vfsFileGet(ctx context.Context, mod api.Module, pFile uint32) File {
const fileHandleOffset = 4
vfs := ctx.Value(vfsKey{}).(*vfsState)
id := util.ReadUint32(mod, pFile+fileHandleOffset)
return vfs.files[id]
}
func vfsFileClose(ctx context.Context, mod api.Module, pFile uint32) error {
const fileHandleOffset = 4
vfs := ctx.Value(vfsKey{}).(*vfsState)
id := util.ReadUint32(mod, pFile+fileHandleOffset)
file := vfs.files[id]
vfs.files[id] = nil
return file.Close()
}
func (f *vfsFile) Sync(flags SyncFlag) error {
dataonly := (flags & SYNC_DATAONLY) != 0
fullsync := (flags & 0x0f) == SYNC_FULL

39
sqlite3vfs/registry.go Normal file
View File

@@ -0,0 +1,39 @@
package sqlite3vfs
import "sync"
var (
vfsRegistry map[string]VFS
vfsRegistryMtx sync.Mutex
)
// Find returns a VFS given its name.
// If there is no match, nil is returned.
//
// https://www.sqlite.org/c3ref/vfs_find.html
func Find(name string) VFS {
vfsRegistryMtx.Lock()
defer vfsRegistryMtx.Unlock()
return vfsRegistry[name]
}
// Register registers a VFS.
//
// https://www.sqlite.org/c3ref/vfs_find.html
func Register(name string, vfs VFS) {
vfsRegistryMtx.Lock()
defer vfsRegistryMtx.Unlock()
if vfsRegistry == nil {
vfsRegistry = map[string]VFS{}
}
vfsRegistry[name] = vfs
}
// Unregister unregisters a VFS.
//
// https://www.sqlite.org/c3ref/vfs_find.html
func Unregister(name string) {
vfsRegistryMtx.Lock()
defer vfsRegistryMtx.Unlock()
delete(vfsRegistry, name)
}

View File

@@ -354,6 +354,42 @@ func vfsGet(mod api.Module, pVfs uint32) VFS {
panic(util.NoVFSErr + util.ErrorString(name))
}
func vfsFileNew(vfs *vfsState, file File) uint32 {
// Find an empty slot.
for id, f := range vfs.files {
if f == nil {
vfs.files[id] = file
return uint32(id)
}
}
// Add a new slot.
vfs.files = append(vfs.files, file)
return uint32(len(vfs.files) - 1)
}
func vfsFileRegister(ctx context.Context, mod api.Module, pFile uint32, file File) {
const fileHandleOffset = 4
id := vfsFileNew(ctx.Value(vfsKey{}).(*vfsState), file)
util.WriteUint32(mod, pFile+fileHandleOffset, id)
}
func vfsFileGet(ctx context.Context, mod api.Module, pFile uint32) File {
const fileHandleOffset = 4
vfs := ctx.Value(vfsKey{}).(*vfsState)
id := util.ReadUint32(mod, pFile+fileHandleOffset)
return vfs.files[id]
}
func vfsFileClose(ctx context.Context, mod api.Module, pFile uint32) error {
const fileHandleOffset = 4
vfs := ctx.Value(vfsKey{}).(*vfsState)
id := util.ReadUint32(mod, pFile+fileHandleOffset)
file := vfs.files[id]
vfs.files[id] = nil
return file.Close()
}
func vfsErrorCode(err error, def _ErrorCode) _ErrorCode {
if err == nil {
return _OK