diff --git a/sqlite3.go b/sqlite3.go index ed2a9e2..0748e2d 100644 --- a/sqlite3.go +++ b/sqlite3.go @@ -959,6 +959,44 @@ func (c *SQLiteConn) query(ctx context.Context, query string, args []driver.Name } } +type SqliteDBStatusOption int + +const ( + SQLITE_DBSTATUS_LOOKASIDE_USED SqliteDBStatusOption = iota + SQLITE_DBSTATUS_CACHE_USED + SQLITE_DBSTATUS_SCHEMA_USED + SQLITE_DBSTATUS_STMT_USED + SQLITE_DBSTATUS_LOOKASIDE_HIT + SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE + SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL + SQLITE_DBSTATUS_CACHE_HIT + SQLITE_DBSTATUS_CACHE_MISS + SQLITE_DBSTATUS_CACHE_WRITE + SQLITE_DBSTATUS_DEFERRED_FKS + SQLITE_DBSTATUS_CACHE_USED_SHARED + SQLITE_DBSTATUS_CACHE_SPILL + SQLITE_DBSTATUS_MAX = iota - 1 /* Largest defined SqliteDBStatusOption */ +) + +// GetDBStatus retrieve runtime status information about a single database connection. +// See: sqlite3_db_status https://www.sqlite.org/c3ref/db_status.html +func (c *SQLiteConn) GetDBStatus(option SqliteDBStatusOption, resetFlag bool) (int, int, error) { + var curr C.int + var hiwtr C.int + + reset := C.int(0) + if resetFlag { + reset = C.int(1) + } + + ret := C.sqlite3_db_status(c.db, C.int(option), &curr, &hiwtr, reset) + if ret != C.SQLITE_OK { + return 0, 0, lastError(c.db) + } + + return int(curr), int(hiwtr), nil +} + // Begin transaction. func (c *SQLiteConn) Begin() (driver.Tx, error) { return c.begin(context.Background()) diff --git a/sqlite3_test.go b/sqlite3_test.go index 63c939d..a0ee320 100644 --- a/sqlite3_test.go +++ b/sqlite3_test.go @@ -1090,6 +1090,25 @@ func TestExecer(t *testing.T) { } } +func TestDBStatus(t *testing.T) { + tempFilename := TempFilename(t) + defer os.Remove(tempFilename) + + d := SQLiteDriver{} + conn, err := d.Open(tempFilename) + if err != nil { + t.Fatal("Failed to open database:", err) + } + defer conn.Close() + + for i := 0; i <= SQLITE_DBSTATUS_MAX; i++ { + _, _, err := conn.(*SQLiteConn).GetDBStatus(SqliteDBStatusOption(i), false) + if err != nil { + t.Fatal("Failed to get db status:", err) + } + } +} + func TestQueryer(t *testing.T) { tempFilename := TempFilename(t) defer os.Remove(tempFilename)