More APIs. (#125)

sqlite3_db_cacheflush
sqlite3_db_status
sqlite3_expanded_sql
sqlite3_next_stmt
sqlite3_sql
sqlite3_table_column_metadata
sqlite3_trace_v2
sqlite3_value_frombind
This commit is contained in:
Nuno Cruces
2024-07-31 12:15:08 +01:00
committed by GitHub
parent 22132620b8
commit 3bb1898335
28 changed files with 453 additions and 34 deletions

View File

@@ -543,6 +543,78 @@ func TestConn_SetAuthorizer(t *testing.T) {
}
}
func TestConn_Trace(t *testing.T) {
t.Parallel()
db, err := sqlite3.Open(":memory:")
if err != nil {
t.Fatal(err)
}
defer db.Close()
rows := 0
closed := false
err = db.Trace(math.MaxUint32, func(evt sqlite3.TraceEvent, a1 any, a2 any) error {
switch evt {
case sqlite3.TRACE_CLOSE:
closed = true
_ = a1.(*sqlite3.Conn)
return db.Exec(`PRAGMA optimize`)
case sqlite3.TRACE_STMT:
stmt := a1.(*sqlite3.Stmt)
if sql := a2.(string); sql != stmt.SQL() {
t.Errorf("got %q, want %q", sql, stmt.SQL())
}
if sql := stmt.ExpandedSQL(); sql != `SELECT 1` {
t.Errorf("got %q", sql)
}
case sqlite3.TRACE_PROFILE:
_ = a1.(*sqlite3.Stmt)
if ns := a2.(int64); ns < 0 {
t.Errorf("got %d", ns)
}
case sqlite3.TRACE_ROW:
_ = a1.(*sqlite3.Stmt)
if a2 != nil {
t.Errorf("got %v", a2)
}
rows++
}
return nil
})
if err != nil {
t.Fatal(err)
}
stmt, _, err := db.Prepare(`SELECT ?`)
if err != nil {
t.Fatal(err)
}
err = stmt.BindInt(1, 1)
if err != nil {
t.Fatal(err)
}
err = stmt.Exec()
if err != nil {
t.Fatal(err)
}
err = stmt.Close()
if err != nil {
t.Fatal(err)
}
if rows != 1 {
t.Error("want 1")
}
err = db.Close()
if err != nil {
t.Fatal(err)
}
if !closed {
t.Error("want closed")
}
}
func TestConn_ReleaseMemory(t *testing.T) {
t.Parallel()
@@ -684,3 +756,96 @@ func TestConn_AutoVacuumPages(t *testing.T) {
t.Fatal(err)
}
}
func TestConn_Status(t *testing.T) {
t.Parallel()
db, err := sqlite3.Open(":memory:")
if err != nil {
t.Fatal(err)
}
defer db.Close()
err = db.Exec(`CREATE TABLE test (col)`)
if err != nil {
t.Fatal(err)
}
cr, hi, err := db.Status(sqlite3.DBSTATUS_SCHEMA_USED, true)
if err != nil {
t.Error("want nil")
}
if cr == 0 {
t.Error("want something")
}
if hi != 0 {
t.Error("want zero")
}
cr, hi, err = db.Status(sqlite3.DBSTATUS_LOOKASIDE_HIT, true)
if err != nil {
t.Error("want nil")
}
if cr != 0 {
t.Error("want zero")
}
if hi == 0 {
t.Error("want something")
}
cr, hi, err = db.Status(sqlite3.DBSTATUS_LOOKASIDE_HIT, true)
if err != nil {
t.Error("want nil")
}
if cr != 0 {
t.Error("want zero")
}
if hi != 0 {
t.Error("want zero")
}
}
func TestConn_TableColumnMetadata(t *testing.T) {
t.Parallel()
db, err := sqlite3.Open(":memory:")
if err != nil {
t.Fatal(err)
}
defer db.Close()
err = db.Exec(`CREATE TABLE test (col)`)
if err != nil {
t.Fatal(err)
}
_, _, _, _, _, err = db.TableColumnMetadata("", "table", "")
if err == nil {
t.Error("want error")
}
_, _, _, _, _, err = db.TableColumnMetadata("", "test", "")
if err != nil {
t.Error("want nil")
}
typ, ord, nn, pk, ai, err := db.TableColumnMetadata("", "test", "rowid")
if err != nil {
t.Error("want nil")
}
if typ != "INTEGER" {
t.Error("want INTEGER")
}
if ord != "BINARY" {
t.Error("want BINARY")
}
if nn != false {
t.Error("want false")
}
if pk != true {
t.Error("want true")
}
if ai != false {
t.Error("want false")
}
}

View File

@@ -4,6 +4,7 @@ import (
"context"
"testing"
"github.com/ncruces/go-sqlite3"
"github.com/ncruces/go-sqlite3/driver"
_ "github.com/ncruces/go-sqlite3/embed"
_ "github.com/ncruces/go-sqlite3/internal/testcfg"
@@ -15,7 +16,9 @@ func TestDriver(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
db, err := driver.Open(":memory:", nil)
db, err := driver.Open(":memory:", nil, func(c *sqlite3.Conn) error {
return c.Exec(`PRAGMA optimize`)
})
if err != nil {
t.Fatal(err)
}

View File

@@ -48,7 +48,9 @@ func TestCreateFunction(t *testing.T) {
case 10:
ctx.ResultNull()
case 11:
arg.NoChange()
if arg.NoChange() || arg.FromBind() {
t.Error()
}
ctx.ResultError(sqlite3.FULL)
}
})

View File

@@ -20,7 +20,7 @@ func TestJSON(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
db, err := driver.Open(":memory:", nil)
db, err := driver.Open(":memory:")
if err != nil {
t.Fatal(err)
}

View File

@@ -503,6 +503,13 @@ func TestStmt(t *testing.T) {
}
}
db.Stmts()(func(s *sqlite3.Stmt) bool {
if s != stmt {
t.Error()
}
return false
})
if err := stmt.Close(); err != nil {
t.Fatal(err)
}

View File

@@ -136,7 +136,7 @@ func TestTimeFormat_Scanner(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
db, err := driver.Open(":memory:", nil)
db, err := driver.Open(":memory:")
if err != nil {
t.Fatal(err)
}

View File

@@ -184,6 +184,10 @@ func TestConn_Transaction_interrupt(t *testing.T) {
if err != nil {
t.Fatal(err)
}
err = db.CacheFlush()
if err != nil {
t.Fatal(err)
}
cancel()
_, err = db.BeginImmediate()

View File

@@ -54,13 +54,13 @@ func TestWAL_readonly(t *testing.T) {
tmp := filepath.ToSlash(filepath.Join(t.TempDir(), "test.db"))
db1, err := driver.Open("file:"+tmp+"?_pragma=journal_mode(wal)&_txlock=immediate", nil)
db1, err := driver.Open("file:" + tmp + "?_pragma=journal_mode(wal)&_txlock=immediate")
if err != nil {
t.Fatal(err)
}
defer db1.Close()
db2, err := driver.Open("file:"+tmp+"?_pragma=journal_mode(wal)&mode=ro", nil)
db2, err := driver.Open("file:" + tmp + "?_pragma=journal_mode(wal)&mode=ro")
if err != nil {
t.Fatal(err)
}