From a5310ff8adc93b63abcf8c08b5c09f4dd90ed224 Mon Sep 17 00:00:00 2001 From: Nuno Cruces Date: Wed, 3 Apr 2024 12:11:03 +0100 Subject: [PATCH] More. --- go.mod | 2 +- go.sum | 4 ++-- go.work.sum | 4 ++-- sqlite.go | 2 +- tests/db_test.go | 6 +++++ tests/parallel/parallel_test.go | 15 ++++++++++++ vfs/lock.go | 10 ++++++++ vfs/lock_other.go | 23 ++++++++++++++++++ vfs/os_nolock.go | 41 --------------------------------- vfs/os_unix_lock.go | 8 ------- vfs/os_windows.go | 8 ------- vfs/shm.go | 12 +++++++++- vfs/shm_other.go | 12 +++++++++- vfs/tests/mptest/mptest_test.go | 22 ++++++++++++++++-- 14 files changed, 102 insertions(+), 67 deletions(-) create mode 100644 vfs/lock_other.go delete mode 100644 vfs/os_nolock.go diff --git a/go.mod b/go.mod index 3e00bc0a..c9c37fc7 100644 --- a/go.mod +++ b/go.mod @@ -14,4 +14,4 @@ require ( retract v0.4.0 // tagged from the wrong branch -replace github.com/tetratelabs/wazero => github.com/ncruces/wazero v0.0.0-20240327075005-1e61961e4b45 +replace github.com/tetratelabs/wazero => github.com/ncruces/wazero v0.0.0-20240401071028-c9d05f062413 diff --git a/go.sum b/go.sum index bfce8c5c..acb53467 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,7 @@ github.com/ncruces/julianday v1.0.0 h1:fH0OKwa7NWvniGQtxdJRxAgkBMolni2BjDHaWTxqt7M= github.com/ncruces/julianday v1.0.0/go.mod h1:Dusn2KvZrrovOMJuOt0TNXL6tB7U2E8kvza5fFc9G7g= -github.com/ncruces/wazero v0.0.0-20240327075005-1e61961e4b45 h1:S7fG4oq29CgXycris/pkmon/gbKFufnU8PTaRv5ewFs= -github.com/ncruces/wazero v0.0.0-20240327075005-1e61961e4b45/go.mod h1:ytl6Zuh20R/eROuyDaGPkp82O9C/DJfXAwJfQ3X6/7Y= +github.com/ncruces/wazero v0.0.0-20240401071028-c9d05f062413 h1:wUE8Bx0aoqNFkRu+GbC3/51kyq0hmE4txY8Z2EqEHhM= +github.com/ncruces/wazero v0.0.0-20240401071028-c9d05f062413/go.mod h1:ytl6Zuh20R/eROuyDaGPkp82O9C/DJfXAwJfQ3X6/7Y= github.com/psanford/httpreadat v0.1.0 h1:VleW1HS2zO7/4c7c7zNl33fO6oYACSagjJIyMIwZLUE= github.com/psanford/httpreadat v0.1.0/go.mod h1:Zg7P+TlBm3bYbyHTKv/EdtSJZn3qwbPwpfZ/I9GKCRE= golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= diff --git a/go.work.sum b/go.work.sum index bb2e49ef..2a550fa3 100644 --- a/go.work.sum +++ b/go.work.sum @@ -1,5 +1,5 @@ -github.com/ncruces/wazero v0.0.0-20240327075005-1e61961e4b45 h1:S7fG4oq29CgXycris/pkmon/gbKFufnU8PTaRv5ewFs= -github.com/ncruces/wazero v0.0.0-20240327075005-1e61961e4b45/go.mod h1:ytl6Zuh20R/eROuyDaGPkp82O9C/DJfXAwJfQ3X6/7Y= +github.com/ncruces/wazero v0.0.0-20240401071028-c9d05f062413 h1:wUE8Bx0aoqNFkRu+GbC3/51kyq0hmE4txY8Z2EqEHhM= +github.com/ncruces/wazero v0.0.0-20240401071028-c9d05f062413/go.mod h1:ytl6Zuh20R/eROuyDaGPkp82O9C/DJfXAwJfQ3X6/7Y= 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= diff --git a/sqlite.go b/sqlite.go index c69f3bb3..56ea68b8 100644 --- a/sqlite.go +++ b/sqlite.go @@ -37,7 +37,7 @@ var instance struct { func compileSQLite() { if RuntimeConfig == nil { - RuntimeConfig = wazero.NewRuntimeConfig().WithMemoryLimitPages(1024).WithMemoryCapacityFromMax(true) + RuntimeConfig = wazero.NewRuntimeConfig() } ctx := context.Background() diff --git a/tests/db_test.go b/tests/db_test.go index 168cae58..88d23a8d 100644 --- a/tests/db_test.go +++ b/tests/db_test.go @@ -9,6 +9,7 @@ import ( "github.com/ncruces/go-sqlite3" _ "github.com/ncruces/go-sqlite3/embed" + "github.com/ncruces/go-sqlite3/vfs" _ "github.com/ncruces/go-sqlite3/vfs/memdb" ) @@ -36,6 +37,11 @@ func TestDB_nolock(t *testing.T) { } func TestDB_wal(t *testing.T) { + // TODO: reconsider this. + if !vfs.SupportsSharedMemory { + t.Skip("skipping without shared memory") + } + t.Parallel() tmp := filepath.Join(t.TempDir(), "test.db") err := os.WriteFile(tmp, waldb, 0666) diff --git a/tests/parallel/parallel_test.go b/tests/parallel/parallel_test.go index 604261ba..e0740f00 100644 --- a/tests/parallel/parallel_test.go +++ b/tests/parallel/parallel_test.go @@ -12,9 +12,20 @@ import ( "github.com/ncruces/go-sqlite3" _ "github.com/ncruces/go-sqlite3/embed" + "github.com/ncruces/go-sqlite3/vfs" "github.com/ncruces/go-sqlite3/vfs/memdb" + "github.com/tetratelabs/wazero" ) +func TestMain(m *testing.M) { + if vfs.SupportsSharedMemory { + sqlite3.RuntimeConfig = wazero.NewRuntimeConfig(). + WithMemoryCapacityFromMax(true). + WithMemoryLimitPages(1024) + } + os.Exit(m.Run()) +} + func TestParallel(t *testing.T) { var iter int if testing.Short() { @@ -33,6 +44,10 @@ func TestParallel(t *testing.T) { } func TestWAL(t *testing.T) { + if !vfs.SupportsSharedMemory { + t.Skip("skipping without shared memory") + } + name := "file:" + filepath.Join(t.TempDir(), "test.db") + "?_pragma=busy_timeout(10000)" + diff --git a/vfs/lock.go b/vfs/lock.go index 1b705499..9332c9f5 100644 --- a/vfs/lock.go +++ b/vfs/lock.go @@ -1,7 +1,17 @@ +//go:build (linux || darwin || windows || freebsd || openbsd || netbsd || dragonfly || illumos) && !sqlite3_nosys + package vfs import "github.com/ncruces/go-sqlite3/internal/util" +// SupportsFileLocking is false on platforms that do not support file locking. +// To open a database file on those platforms, +// you need to use the [nolock] or [immutable] URI parameters. +// +// [nolock]: https://sqlite.org/uri.html#urinolock +// [immutable]: https://sqlite.org/uri.html#uriimmutable +const SupportsFileLocking = true + const ( _PENDING_BYTE = 0x40000000 _RESERVED_BYTE = (_PENDING_BYTE + 1) diff --git a/vfs/lock_other.go b/vfs/lock_other.go new file mode 100644 index 00000000..a4563af4 --- /dev/null +++ b/vfs/lock_other.go @@ -0,0 +1,23 @@ +//go:build !(linux || darwin || windows || freebsd || openbsd || netbsd || dragonfly || illumos) || sqlite3_nosys + +package vfs + +// SupportsFileLocking is false on platforms that do not support file locking. +// To open a database file on those platforms, +// you need to use the [nolock] or [immutable] URI parameters. +// +// [nolock]: https://sqlite.org/uri.html#urinolock +// [immutable]: https://sqlite.org/uri.html#uriimmutable +const SupportsFileLocking = false + +func (f *vfsFile) Lock(LockLevel) error { + return _IOERR_LOCK +} + +func (f *vfsFile) Unlock(LockLevel) error { + return _IOERR_UNLOCK +} + +func (f *vfsFile) CheckReservedLock() (bool, error) { + return false, _IOERR_CHECKRESERVEDLOCK +} diff --git a/vfs/os_nolock.go b/vfs/os_nolock.go deleted file mode 100644 index 4bceefed..00000000 --- a/vfs/os_nolock.go +++ /dev/null @@ -1,41 +0,0 @@ -//go:build !(linux || darwin || windows || freebsd || openbsd || netbsd || dragonfly || illumos) || sqlite3_nosys - -package vfs - -import "os" - -// SupportsFileLocking is false on platforms that do not support file locking. -// To open a database file in one such platform, -// you need to use the [nolock] or [immutable] URI parameters. -// -// [nolock]: https://sqlite.org/uri.html#urinolock -// [immutable]: https://sqlite.org/uri.html#uriimmutable -const SupportsFileLocking = false - -func osGetSharedLock(_ *os.File) _ErrorCode { - return _IOERR_RDLOCK -} - -func osGetReservedLock(_ *os.File) _ErrorCode { - return _IOERR_LOCK -} - -func osGetPendingLock(_ *os.File, _ bool) _ErrorCode { - return _IOERR_LOCK -} - -func osGetExclusiveLock(_ *os.File, _ bool) _ErrorCode { - return _IOERR_LOCK -} - -func osDowngradeLock(_ *os.File, _ LockLevel) _ErrorCode { - return _IOERR_RDLOCK -} - -func osReleaseLock(_ *os.File, _ LockLevel) _ErrorCode { - return _IOERR_UNLOCK -} - -func osCheckReservedLock(_ *os.File) (bool, _ErrorCode) { - return false, _IOERR_CHECKRESERVEDLOCK -} diff --git a/vfs/os_unix_lock.go b/vfs/os_unix_lock.go index 15db23f0..8f90e67e 100644 --- a/vfs/os_unix_lock.go +++ b/vfs/os_unix_lock.go @@ -9,14 +9,6 @@ import ( "golang.org/x/sys/unix" ) -// SupportsFileLocking is false on platforms that do not support file locking. -// To open a database file in one such platform, -// you need to use the [nolock] or [immutable] URI parameters. -// -// [nolock]: https://sqlite.org/uri.html#urinolock -// [immutable]: https://sqlite.org/uri.html#uriimmutable -const SupportsFileLocking = true - func osGetSharedLock(file *os.File) _ErrorCode { // Test the PENDING lock before acquiring a new SHARED lock. if pending, _ := osCheckLock(file, _PENDING_BYTE, 1); pending { diff --git a/vfs/os_windows.go b/vfs/os_windows.go index abc6c4b7..9e53e14b 100644 --- a/vfs/os_windows.go +++ b/vfs/os_windows.go @@ -9,14 +9,6 @@ import ( "golang.org/x/sys/windows" ) -// SupportsFileLocking is false on platforms that do not support file locking. -// To open a database file in one such platform, -// you need to use the [nolock] or [immutable] URI parameters. -// -// [nolock]: https://sqlite.org/uri.html#urinolock -// [immutable]: https://sqlite.org/uri.html#uriimmutable -const SupportsFileLocking = true - func osGetSharedLock(file *os.File) _ErrorCode { // Acquire the PENDING lock temporarily before acquiring a new SHARED lock. rc := osReadLock(file, _PENDING_BYTE, 1, 0) diff --git a/vfs/shm.go b/vfs/shm.go index ff417c3a..b852e3a0 100644 --- a/vfs/shm.go +++ b/vfs/shm.go @@ -1,4 +1,4 @@ -//go:build (linux || darwin) && (amd64 || arm64) && !sqlite3_nosys +//go:build (linux || darwin) && (amd64 || arm64) && !sqlite3_flock && !sqlite3_nosys package vfs @@ -13,6 +13,16 @@ import ( "golang.org/x/sys/unix" ) +// SupportsSharedMemory is true on platforms that support shared memory. +// To enable shared memory support on those platforms, +// you need to set the appropriate [wazero.RuntimeConfig]; +// otherwise, [EXCLUSIVE locking mode] is activated automatically +// to use [WAL without shared-memory]. +// +// [WAL without shared-memory]: https://sqlite.org/wal.html#noshm +// [EXCLUSIVE locking mode]: https://sqlite.org/pragma.html#pragma_locking_mode +const SupportsSharedMemory = true + type vfsShm struct { *os.File regions []shmRegion diff --git a/vfs/shm_other.go b/vfs/shm_other.go index 8b7117af..5ce3518f 100644 --- a/vfs/shm_other.go +++ b/vfs/shm_other.go @@ -1,4 +1,4 @@ -//go:build !(linux || darwin) || !(amd64 || arm64) || sqlite3_nosys +//go:build !(linux || darwin) || !(amd64 || arm64) || sqlite3_flock || sqlite3_nosys package vfs @@ -8,6 +8,16 @@ import ( "github.com/tetratelabs/wazero/api" ) +// SupportsSharedMemory is true on platforms that support shared memory. +// To enable shared memory support on those platforms, +// you need to set the appropriate [wazero.RuntimeConfig]; +// otherwise, [EXCLUSIVE locking mode] is activated automatically +// to use [WAL without shared-memory]. +// +// [WAL without shared-memory]: https://sqlite.org/wal.html#noshm +// [EXCLUSIVE locking mode]: https://sqlite.org/pragma.html#pragma_locking_mode +const SupportsSharedMemory = false + type vfsShm struct{} func (f *vfsFile) ShmMap(ctx context.Context, mod api.Module, id, size uint32, extend bool) (uint32, error) { diff --git a/vfs/tests/mptest/mptest_test.go b/vfs/tests/mptest/mptest_test.go index 127cec67..fc3c2ca3 100644 --- a/vfs/tests/mptest/mptest_test.go +++ b/vfs/tests/mptest/mptest_test.go @@ -39,8 +39,11 @@ var ( func TestMain(m *testing.M) { ctx := context.Background() - rt = wazero.NewRuntimeWithConfig(ctx, - wazero.NewRuntimeConfig().WithMemoryLimitPages(1024).WithMemoryCapacityFromMax(true)) + cfg := wazero.NewRuntimeConfig() + if vfs.SupportsSharedMemory { + cfg = cfg.WithMemoryLimitPages(1024).WithMemoryCapacityFromMax(true) + } + rt = wazero.NewRuntimeWithConfig(ctx, cfg) wasi_snapshot_preview1.MustInstantiate(ctx, rt) env := vfs.ExportHostFunctions(rt.NewHostModuleBuilder("env")) @@ -189,6 +192,11 @@ func Test_multiwrite01_memory(t *testing.T) { } func Test_config01_wal(t *testing.T) { + // TODO: reconsider this. + if !vfs.SupportsSharedMemory { + t.Skip("skipping without shared memory") + } + ctx := util.NewContext(newContext(t)) name := filepath.Join(t.TempDir(), "test.db") cfg := config(ctx).WithArgs("mptest", name, "config01.test", @@ -201,6 +209,11 @@ func Test_config01_wal(t *testing.T) { } func Test_crash01_wal(t *testing.T) { + // TODO: reconsider this. + if !vfs.SupportsSharedMemory { + t.Skip("skipping without shared memory") + } + if testing.Short() { t.Skip("skipping in short mode") } @@ -220,6 +233,11 @@ func Test_crash01_wal(t *testing.T) { } func Test_multiwrite01_wal(t *testing.T) { + // TODO: reconsider this. + if !vfs.SupportsSharedMemory { + t.Skip("skipping without shared memory") + } + if testing.Short() { t.Skip("skipping in short mode") }