diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 50ae6ea6d..951637def 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -222,6 +222,8 @@ jobs: - unit tags="kvdb_etcd" - unit tags="kvdb_postgres" - unit tags="kvdb_sqlite" + - unit tags="test_db_sqlite" + - unit tags="test_db_postgres" - unit-race - unit-module diff --git a/graph/db/sql_store.go b/graph/db/sql_store.go new file mode 100644 index 000000000..fa7a49206 --- /dev/null +++ b/graph/db/sql_store.go @@ -0,0 +1,45 @@ +package graphdb + +import ( + "github.com/lightningnetwork/lnd/sqldb" +) + +// SQLQueries is a subset of the sqlc.Querier interface that can be used to +// execute queries against the SQL graph tables. +type SQLQueries interface { +} + +// BatchedSQLQueries is a version of SQLQueries that's capable of batched +// database operations. +type BatchedSQLQueries interface { + SQLQueries + sqldb.BatchedTx[SQLQueries] +} + +// SQLStore is an implementation of the V1Store interface that uses a SQL +// database as the backend. +// +// NOTE: currently, this temporarily embeds the KVStore struct so that we can +// implement the V1Store interface incrementally. For any method not +// implemented, things will fall back to the KVStore. This is ONLY the case +// for the time being while this struct is purely used in unit tests only. +type SQLStore struct { + db BatchedSQLQueries + + // Temporary fall-back to the KVStore so that we can implement the + // interface incrementally. + *KVStore +} + +// A compile-time assertion to ensure that SQLStore implements the V1Store +// interface. +var _ V1Store = (*SQLStore)(nil) + +// NewSQLStore creates a new SQLStore instance given an open BatchedSQLQueries +// storage backend. +func NewSQLStore(db BatchedSQLQueries, kvStore *KVStore) *SQLStore { + return &SQLStore{ + db: db, + KVStore: kvStore, + } +} diff --git a/graph/db/test_kvdb.go b/graph/db/test_kvdb.go index 375712972..0dd3bd2ff 100644 --- a/graph/db/test_kvdb.go +++ b/graph/db/test_kvdb.go @@ -1,3 +1,5 @@ +//go:build !test_db_sqlite && !test_db_postgres + package graphdb import ( diff --git a/graph/db/test_postgres.go b/graph/db/test_postgres.go new file mode 100644 index 000000000..0c2163083 --- /dev/null +++ b/graph/db/test_postgres.go @@ -0,0 +1,42 @@ +//go:build test_db_postgres && !test_db_sqlite + +package graphdb + +import ( + "database/sql" + "testing" + + "github.com/lightningnetwork/lnd/kvdb" + "github.com/lightningnetwork/lnd/sqldb" + "github.com/stretchr/testify/require" +) + +// NewTestDB is a helper function that creates a SQLStore backed by a postgres +// database for testing. At the moment, it embeds a KVStore but once the +// SQLStore fully implements the V1Store interface, the KVStore will be removed. +func NewTestDB(t testing.TB) *SQLStore { + backend, backendCleanup, err := kvdb.GetTestBackend(t.TempDir(), "cgr") + require.NoError(t, err) + + t.Cleanup(backendCleanup) + + graphStore, err := NewKVStore(backend) + require.NoError(t, err) + + pgFixture := sqldb.NewTestPgFixture( + t, sqldb.DefaultPostgresFixtureLifetime, + ) + t.Cleanup(func() { + pgFixture.TearDown(t) + }) + + db := sqldb.NewTestPostgresDB(t, pgFixture).BaseDB + + executor := sqldb.NewTransactionExecutor( + db, func(tx *sql.Tx) SQLQueries { + return db.WithTx(tx) + }, + ) + + return NewSQLStore(executor, graphStore) +} diff --git a/graph/db/test_sqlite.go b/graph/db/test_sqlite.go new file mode 100644 index 000000000..5cfe16812 --- /dev/null +++ b/graph/db/test_sqlite.go @@ -0,0 +1,35 @@ +//go:build !test_db_posgres && test_db_sqlite + +package graphdb + +import ( + "database/sql" + "testing" + + "github.com/lightningnetwork/lnd/kvdb" + "github.com/lightningnetwork/lnd/sqldb" + "github.com/stretchr/testify/require" +) + +// NewTestDB is a helper function that creates a SQLStore backed by a sqlite +// database for testing. At the moment, it embeds a KVStore but once the +// SQLStore fully implements the V1Store interface, the KVStore will be removed. +func NewTestDB(t testing.TB) *SQLStore { + backend, backendCleanup, err := kvdb.GetTestBackend(t.TempDir(), "cgr") + require.NoError(t, err) + + t.Cleanup(backendCleanup) + + graphStore, err := NewKVStore(backend) + require.NoError(t, err) + + db := sqldb.NewTestSqliteDB(t).BaseDB + + executor := sqldb.NewTransactionExecutor( + db, func(tx *sql.Tx) SQLQueries { + return db.WithTx(tx) + }, + ) + + return NewSQLStore(executor, graphStore) +}