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  }