github.com/ncruces/go-sqlite3@v0.15.1-0.20240520133447-53eef1510ff0/tests/db_test.go (about) 1 package tests 2 3 import ( 4 "os" 5 "path/filepath" 6 "testing" 7 8 _ "embed" 9 10 "github.com/ncruces/go-sqlite3" 11 _ "github.com/ncruces/go-sqlite3/embed" 12 _ "github.com/ncruces/go-sqlite3/tests/testcfg" 13 "github.com/ncruces/go-sqlite3/vfs" 14 _ "github.com/ncruces/go-sqlite3/vfs/adiantum" 15 _ "github.com/ncruces/go-sqlite3/vfs/memdb" 16 ) 17 18 //go:embed testdata/wal.db 19 var walDB []byte 20 21 //go:embed testdata/utf16be.db 22 var utf16DB []byte 23 24 func TestDB_memory(t *testing.T) { 25 t.Parallel() 26 testDB(t, ":memory:") 27 } 28 29 func TestDB_file(t *testing.T) { 30 if !vfs.SupportsFileLocking { 31 t.Skip("skipping without locks") 32 } 33 34 t.Parallel() 35 testDB(t, filepath.Join(t.TempDir(), "test.db")) 36 } 37 38 func TestDB_wal(t *testing.T) { 39 if !vfs.SupportsSharedMemory { 40 t.Skip("skipping without shared memory") 41 } 42 43 t.Parallel() 44 tmp := filepath.Join(t.TempDir(), "test.db") 45 err := os.WriteFile(tmp, walDB, 0666) 46 if err != nil { 47 t.Fatal(err) 48 } 49 testDB(t, tmp) 50 } 51 52 func TestDB_utf16(t *testing.T) { 53 if !vfs.SupportsFileLocking { 54 t.Skip("skipping without locks") 55 } 56 57 t.Parallel() 58 tmp := filepath.Join(t.TempDir(), "test.db") 59 err := os.WriteFile(tmp, utf16DB, 0666) 60 if err != nil { 61 t.Fatal(err) 62 } 63 testDB(t, tmp) 64 } 65 66 func TestDB_memdb(t *testing.T) { 67 t.Parallel() 68 testDB(t, "file:test.db?vfs=memdb") 69 } 70 71 func TestDB_adiantum(t *testing.T) { 72 t.Parallel() 73 tmp := filepath.Join(t.TempDir(), "test.db") 74 testDB(t, "file:"+filepath.ToSlash(tmp)+"?nolock=1"+ 75 "&vfs=adiantum&textkey=correct+horse+battery+staple") 76 } 77 78 func TestDB_nolock(t *testing.T) { 79 t.Parallel() 80 tmp := filepath.Join(t.TempDir(), "test.db") 81 testDB(t, "file:"+filepath.ToSlash(tmp)+"?nolock=1") 82 } 83 84 func testDB(t testing.TB, name string) { 85 db, err := sqlite3.Open(name) 86 if err != nil { 87 t.Fatal(err) 88 } 89 defer db.Close() 90 91 err = db.Exec(`CREATE TABLE IF NOT EXISTS users (id INT, name VARCHAR(10))`) 92 if err != nil { 93 t.Fatal(err) 94 } 95 96 err = db.Exec(`INSERT INTO users (id, name) VALUES (0, 'go'), (1, 'zig'), (2, 'whatever')`) 97 if err != nil { 98 t.Fatal(err) 99 } 100 changes := db.Changes() 101 if changes != 3 { 102 t.Errorf("got %d want 3", changes) 103 } 104 105 stmt, _, err := db.Prepare(`SELECT id, name FROM users`) 106 if err != nil { 107 t.Fatal(err) 108 } 109 defer stmt.Close() 110 111 row := 0 112 ids := []int{0, 1, 2} 113 names := []string{"go", "zig", "whatever"} 114 for ; stmt.Step(); row++ { 115 id := stmt.ColumnInt(0) 116 name := stmt.ColumnText(1) 117 118 if row >= 3 { 119 continue 120 } 121 if id != ids[row] { 122 t.Errorf("got %d, want %d", id, ids[row]) 123 } 124 if name != names[row] { 125 t.Errorf("got %q, want %q", name, names[row]) 126 } 127 } 128 if row != 3 { 129 t.Errorf("got %d, want %d", row, len(ids)) 130 } 131 132 if err := stmt.Err(); err != nil { 133 t.Fatal(err) 134 } 135 136 err = stmt.Close() 137 if err != nil { 138 t.Fatal(err) 139 } 140 141 err = db.Close() 142 if err != nil { 143 t.Fatal(err) 144 } 145 }