feat: initial sqlite store
This commit is contained in:
parent
52814db43d
commit
9918c9918f
10 changed files with 560 additions and 6 deletions
71
store/sqlite/store_test.go
Normal file
71
store/sqlite/store_test.go
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
package sqlite_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"testing"
|
||||
|
||||
"git.juancwu.dev/juancwu/pase/store/sqlite"
|
||||
"git.juancwu.dev/juancwu/pase/store/storetest"
|
||||
|
||||
// modernc.org/sqlite registers the "sqlite" driver. Pure Go, no CGO.
|
||||
// Imported only by tests; the sqlite package itself stays driver-agnostic.
|
||||
_ "modernc.org/sqlite"
|
||||
)
|
||||
|
||||
// newSQLiteStore opens a fresh in-memory SQLite, applies migrations, and
|
||||
// returns a Store ready to be exercised by the storetest suite. Each call
|
||||
// produces an isolated database — no cross-test pollution.
|
||||
//
|
||||
// DSN notes:
|
||||
// - file::memory: form is required so the driver parses query params.
|
||||
// Plain ":memory:?..." would silently ignore them.
|
||||
// - _pragma=foreign_keys(1) enables ON DELETE CASCADE on this connection.
|
||||
// - _time_format=sqlite makes the driver write time.Time as
|
||||
// "2006-01-02 15:04:05.999999999-07:00", which Go's stdlib can read back
|
||||
// via sql.NullTime.Scan.
|
||||
func newSQLiteStore(t *testing.T) storetest.SuiteStore {
|
||||
t.Helper()
|
||||
|
||||
db, err := sql.Open("sqlite", "file::memory:?_pragma=foreign_keys(1)&_time_format=sqlite")
|
||||
if err != nil {
|
||||
t.Fatalf("open sqlite: %v", err)
|
||||
}
|
||||
t.Cleanup(func() { _ = db.Close() })
|
||||
|
||||
// In-memory databases are per-connection by default. Pin the pool to a
|
||||
// single connection so subsequent calls hit the same database.
|
||||
db.SetMaxOpenConns(1)
|
||||
|
||||
if err := sqlite.Migrate(context.Background(), db); err != nil {
|
||||
t.Fatalf("migrate: %v", err)
|
||||
}
|
||||
|
||||
return sqlite.NewStore(db)
|
||||
}
|
||||
|
||||
// TestSQLiteStore runs the full Store contract suite against the SQLite
|
||||
// implementation. Add new dialect-specific tests below; they should be
|
||||
// rare — anything testable as a contract belongs in storetest.
|
||||
func TestSQLiteStore(t *testing.T) {
|
||||
storetest.RunSuite(t, newSQLiteStore)
|
||||
}
|
||||
|
||||
// TestMigrate_idempotent stays here because migrations are dialect-specific
|
||||
// (per-package embed.FS) and not part of the Store interface contract.
|
||||
func TestMigrate_idempotent(t *testing.T) {
|
||||
db, err := sql.Open("sqlite", "file::memory:?_pragma=foreign_keys(1)&_time_format=sqlite")
|
||||
if err != nil {
|
||||
t.Fatalf("open sqlite: %v", err)
|
||||
}
|
||||
t.Cleanup(func() { _ = db.Close() })
|
||||
db.SetMaxOpenConns(1)
|
||||
|
||||
ctx := context.Background()
|
||||
if err := sqlite.Migrate(ctx, db); err != nil {
|
||||
t.Fatalf("first Migrate: %v", err)
|
||||
}
|
||||
if err := sqlite.Migrate(ctx, db); err != nil {
|
||||
t.Fatalf("second Migrate should succeed, got: %v", err)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue