feat(backend): establish gin sqlite service skeleton
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestOpenConfiguresSQLiteAndClosesCleanly(t *testing.T) {
|
||||
path := filepath.Join(t.TempDir(), "nested", "test.db")
|
||||
db, err := Open(context.Background(), path)
|
||||
if err != nil {
|
||||
t.Fatalf("Open() error = %v; cause = %v", err, errors.Unwrap(err))
|
||||
}
|
||||
|
||||
assertPragmaInt(t, db, "foreign_keys", 1)
|
||||
assertPragmaInt(t, db, "busy_timeout", busyTimeoutMilliseconds)
|
||||
assertPragmaString(t, db, "journal_mode", "wal")
|
||||
|
||||
if db.Stats().MaxOpenConnections != 1 {
|
||||
t.Fatalf("MaxOpenConnections = %d", db.Stats().MaxOpenConnections)
|
||||
}
|
||||
if err := db.Close(); err != nil {
|
||||
t.Fatalf("Close() error = %v", err)
|
||||
}
|
||||
if err := db.PingContext(context.Background()); err == nil {
|
||||
t.Fatal("PingContext() after Close() error = nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestOpenEnforcesForeignKeys(t *testing.T) {
|
||||
db, err := Open(
|
||||
context.Background(),
|
||||
filepath.Join(t.TempDir(), "foreign-keys.db"),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("Open() error = %v; cause = %v", err, errors.Unwrap(err))
|
||||
}
|
||||
t.Cleanup(func() { _ = db.Close() })
|
||||
|
||||
if _, err := db.Exec(`
|
||||
CREATE TABLE parent (id INTEGER PRIMARY KEY);
|
||||
CREATE TABLE child (
|
||||
id INTEGER PRIMARY KEY,
|
||||
parent_id INTEGER NOT NULL REFERENCES parent(id)
|
||||
);
|
||||
`); err != nil {
|
||||
t.Fatalf("create tables: %v", err)
|
||||
}
|
||||
if _, err := db.Exec(
|
||||
"INSERT INTO child (id, parent_id) VALUES (1, 999)",
|
||||
); err == nil {
|
||||
t.Fatal("foreign key violation error = nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDataSourceNameIncludesRequiredOptions(t *testing.T) {
|
||||
dsn := dataSourceName(filepath.Join(t.TempDir(), "test.db"))
|
||||
if !isSafeDataSourceName(dsn) {
|
||||
t.Fatalf("unsafe DSN options")
|
||||
}
|
||||
}
|
||||
|
||||
func assertPragmaInt(t *testing.T, db *sql.DB, name string, want int) {
|
||||
t.Helper()
|
||||
var got int
|
||||
if err := db.QueryRow("PRAGMA " + name).Scan(&got); err != nil {
|
||||
t.Fatalf("PRAGMA %s: %v", name, err)
|
||||
}
|
||||
if got != want {
|
||||
t.Fatalf("PRAGMA %s = %d, want %d", name, got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func assertPragmaString(t *testing.T, db *sql.DB, name, want string) {
|
||||
t.Helper()
|
||||
var got string
|
||||
if err := db.QueryRow("PRAGMA " + name).Scan(&got); err != nil {
|
||||
t.Fatalf("PRAGMA %s: %v", name, err)
|
||||
}
|
||||
if got != want {
|
||||
t.Fatalf("PRAGMA %s = %q, want %q", name, got, want)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user