Skip to content

Commit cc12253

Browse files
committed
Add ability to set an int64 file control
1 parent 82bc911 commit cc12253

File tree

2 files changed

+57
-0
lines changed

2 files changed

+57
-0
lines changed

sqlite3.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1893,6 +1893,34 @@ func (c *SQLiteConn) SetFileControlInt(dbName string, op int, arg int) error {
18931893
return nil
18941894
}
18951895

1896+
// SetFileControlInt invokes the xFileControl method on a given database. The
1897+
// dbName is the name of the database. It will default to "main" if left blank.
1898+
// The op is one of the opcodes prefixed by "SQLITE_FCNTL_". The arg argument
1899+
// and return code are both opcode-specific. Please see the SQLite documentation.
1900+
//
1901+
// This method is not thread-safe as the returned error code can be changed by
1902+
// another call if invoked concurrently.
1903+
//
1904+
// Prefer this method over SetFileControlInt when the argument to the underlying
1905+
// SQLite function is an int64.
1906+
//
1907+
// See: sqlite3_file_control, https://www.sqlite.org/c3ref/file_control.html
1908+
func (c *SQLiteConn) SetFileControlInt64(dbName string, op int, arg int64) error {
1909+
if dbName == "" {
1910+
dbName = "main"
1911+
}
1912+
1913+
cDBName := C.CString(dbName)
1914+
defer C.free(unsafe.Pointer(cDBName))
1915+
1916+
cArg := C.sqlite3_int64(arg)
1917+
rv := C.sqlite3_file_control(c.db, cDBName, C.int(op), unsafe.Pointer(&cArg))
1918+
if rv != C.SQLITE_OK {
1919+
return c.lastError()
1920+
}
1921+
return nil
1922+
}
1923+
18961924
// Close the statement.
18971925
func (s *SQLiteStmt) Close() error {
18981926
s.mu.Lock()

sqlite3_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1864,6 +1864,35 @@ func TestSetFileControlInt(t *testing.T) {
18641864
})
18651865
}
18661866

1867+
func TestSetFileControlInt64(t *testing.T) {
1868+
const GiB = 1024 * 1024 * 1024
1869+
1870+
t.Run("", func(t *testing.T) {
1871+
1872+
sql.Register("sqlite3_FCNTL_SIZE_LIMIT", &SQLiteDriver{
1873+
ConnectHook: func(conn *SQLiteConn) error {
1874+
if err := conn.SetFileControlInt64("", SQLITE_FCNTL_SIZE_LIMIT, 4*GiB); err != nil {
1875+
return fmt.Errorf("Unexpected error from SetFileControlInt64(): %w", err)
1876+
}
1877+
return nil
1878+
},
1879+
})
1880+
1881+
db, err := sql.Open("sqlite3", "file:/dbname?vfs=memdb")
1882+
if err != nil {
1883+
t.Fatal("Failed to open database:", err)
1884+
}
1885+
if err != nil {
1886+
t.Fatal("Failed to open", err)
1887+
}
1888+
err = db.Ping()
1889+
if err != nil {
1890+
t.Fatal("Failed to ping", err)
1891+
}
1892+
db.Close()
1893+
})
1894+
}
1895+
18671896
func TestNonColumnString(t *testing.T) {
18681897
db, err := sql.Open("sqlite3", ":memory:")
18691898
if err != nil {

0 commit comments

Comments
 (0)