diff --git a/README.md b/README.md index c4ba326..e71da49 100644 --- a/README.md +++ b/README.md @@ -100,16 +100,21 @@ On BSD Unixes, this module uses [BSD locks](https://man.freebsd.org/cgi/man.cgi?query=flock&sektion=2). On BSD Unixes, BSD locks are fully compatible with POSIX advisory locks. -On Windows, this module uses `LockFile`, `LockFileEx`, and `UnlockFile`, +On Windows, this module uses `LockFileEx` and `UnlockFileEx`, like SQLite. On all other platforms, file locking is not supported, and you must use [`nolock=1`](https://sqlite.org/uri.html#urinolock) +(or [`immutable=1`](https://sqlite.org/uri.html#uriimmutable)) to open database files. + To use the [`database/sql`](https://pkg.go.dev/database/sql) driver with `nolock=1` you must disable connection pooling by calling [`db.SetMaxOpenConns(1)`](https://pkg.go.dev/database/sql#DB.SetMaxOpenConns). +You can use [`vfs.SupportsFileLocking`](https://pkg.go.dev/github.com/ncruces/go-sqlite3/vfs#SupportsFileLocking) +to check if your platform supports file locking. + ### Testing This project aims for [high test coverage](https://github.com/ncruces/go-sqlite3/wiki/Test-coverage-report). diff --git a/vfs/os_nolock.go b/vfs/os_nolock.go index d2beefb..82379ec 100644 --- a/vfs/os_nolock.go +++ b/vfs/os_nolock.go @@ -4,6 +4,14 @@ 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(file *os.File) _ErrorCode { return _IOERR_RDLOCK } diff --git a/vfs/os_unix2.go b/vfs/os_unix_lock.go similarity index 86% rename from vfs/os_unix2.go rename to vfs/os_unix_lock.go index b57a032..9cbe152 100644 --- a/vfs/os_unix2.go +++ b/vfs/os_unix_lock.go @@ -9,6 +9,14 @@ 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 b0d3c4d..7ea9775 100644 --- a/vfs/os_windows.go +++ b/vfs/os_windows.go @@ -9,6 +9,14 @@ 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) @@ -49,7 +57,7 @@ func osGetExclusiveLock(file *os.File) _ErrorCode { func osDowngradeLock(file *os.File, state LockLevel) _ErrorCode { if state >= LOCK_EXCLUSIVE { - // Release the SHARED lock. + // Release the EXCLUSIVE lock. osUnlock(file, _SHARED_FIRST, _SHARED_SIZE) // Reacquire the SHARED lock.