aboutsummaryrefslogtreecommitdiff
path: root/sqlite3.go
diff options
context:
space:
mode:
authorBen Johnson <benbjohnson@yahoo.com>2022-01-28 08:37:05 -0700
committermattn <mattn.jp@gmail.com>2022-01-29 01:58:27 +0900
commitae2a61f847e10e6dd771ecd4e1c55e0421cdc7f9 (patch)
tree7afef61544d9d1b6a4e08e13a847fee8201cbe1f /sqlite3.go
parentAdd example using driverName (diff)
downloadgolite-ae2a61f847e10e6dd771ecd4e1c55e0421cdc7f9.tar.gz
golite-ae2a61f847e10e6dd771ecd4e1c55e0421cdc7f9.tar.xz
Add sqlite3_file_control() support
This commit adds the SQLiteConn.FileControlInt() method which calls the underlying sqlite3_file_control() function with an int argument. This can be used for low-level operations on SQLite databases such as persisting the WAL file after database close.
Diffstat (limited to 'sqlite3.go')
-rw-r--r--sqlite3.go70
1 files changed, 70 insertions, 0 deletions
diff --git a/sqlite3.go b/sqlite3.go
index 31b2735..e037857 100644
--- a/sqlite3.go
+++ b/sqlite3.go
@@ -297,6 +297,51 @@ const (
/*SQLITE_RECURSIVE = C.SQLITE_RECURSIVE*/
)
+// Standard File Control Opcodes
+// See: https://www.sqlite.org/c3ref/c_fcntl_begin_atomic_write.html
+const (
+ SQLITE_FCNTL_LOCKSTATE = int(1)
+ SQLITE_FCNTL_GET_LOCKPROXYFILE = int(2)
+ SQLITE_FCNTL_SET_LOCKPROXYFILE = int(3)
+ SQLITE_FCNTL_LAST_ERRNO = int(4)
+ SQLITE_FCNTL_SIZE_HINT = int(5)
+ SQLITE_FCNTL_CHUNK_SIZE = int(6)
+ SQLITE_FCNTL_FILE_POINTER = int(7)
+ SQLITE_FCNTL_SYNC_OMITTED = int(8)
+ SQLITE_FCNTL_WIN32_AV_RETRY = int(9)
+ SQLITE_FCNTL_PERSIST_WAL = int(10)
+ SQLITE_FCNTL_OVERWRITE = int(11)
+ SQLITE_FCNTL_VFSNAME = int(12)
+ SQLITE_FCNTL_POWERSAFE_OVERWRITE = int(13)
+ SQLITE_FCNTL_PRAGMA = int(14)
+ SQLITE_FCNTL_BUSYHANDLER = int(15)
+ SQLITE_FCNTL_TEMPFILENAME = int(16)
+ SQLITE_FCNTL_MMAP_SIZE = int(18)
+ SQLITE_FCNTL_TRACE = int(19)
+ SQLITE_FCNTL_HAS_MOVED = int(20)
+ SQLITE_FCNTL_SYNC = int(21)
+ SQLITE_FCNTL_COMMIT_PHASETWO = int(22)
+ SQLITE_FCNTL_WIN32_SET_HANDLE = int(23)
+ SQLITE_FCNTL_WAL_BLOCK = int(24)
+ SQLITE_FCNTL_ZIPVFS = int(25)
+ SQLITE_FCNTL_RBU = int(26)
+ SQLITE_FCNTL_VFS_POINTER = int(27)
+ SQLITE_FCNTL_JOURNAL_POINTER = int(28)
+ SQLITE_FCNTL_WIN32_GET_HANDLE = int(29)
+ SQLITE_FCNTL_PDB = int(30)
+ SQLITE_FCNTL_BEGIN_ATOMIC_WRITE = int(31)
+ SQLITE_FCNTL_COMMIT_ATOMIC_WRITE = int(32)
+ SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE = int(33)
+ SQLITE_FCNTL_LOCK_TIMEOUT = int(34)
+ SQLITE_FCNTL_DATA_VERSION = int(35)
+ SQLITE_FCNTL_SIZE_LIMIT = int(36)
+ SQLITE_FCNTL_CKPT_DONE = int(37)
+ SQLITE_FCNTL_RESERVE_BYTES = int(38)
+ SQLITE_FCNTL_CKPT_START = int(39)
+ SQLITE_FCNTL_EXTERNAL_READER = int(40)
+ SQLITE_FCNTL_CKSM_FILE = int(41)
+)
+
// SQLiteDriver implements driver.Driver.
type SQLiteDriver struct {
Extensions []string
@@ -1813,6 +1858,31 @@ func (c *SQLiteConn) SetLimit(id int, newVal int) int {
return int(C._sqlite3_limit(c.db, C.int(id), C.int(newVal)))
}
+// SetFileControlInt invokes the xFileControl method on a given database. The
+// dbName is the name of the database. It will default to "main" if left blank.
+// The op is one of the opcodes prefixed by "SQLITE_FCNTL_". The arg argument
+// and return code are both opcode-specific. Please see the SQLite documentation.
+//
+// This method is not thread-safe as the returned error code can be changed by
+// another call if invoked concurrently.
+//
+// See: sqlite3_file_control, https://www.sqlite.org/c3ref/file_control.html
+func (c *SQLiteConn) SetFileControlInt(dbName string, op int, arg int) error {
+ if dbName == "" {
+ dbName = "main"
+ }
+
+ cDBName := C.CString(dbName)
+ defer C.free(unsafe.Pointer(cDBName))
+
+ cArg := C.int(arg)
+ rv := C.sqlite3_file_control(c.db, cDBName, C.int(op), unsafe.Pointer(&cArg))
+ if rv != C.SQLITE_OK {
+ return c.lastError()
+ }
+ return nil
+}
+
// Close the statement.
func (s *SQLiteStmt) Close() error {
s.mu.Lock()