mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-11-11 14:48:14 +01:00
sqldb: add support for custom in-code migrations
This commit introduces support for custom, in-code migrations, allowing a specific Go function to be executed at a designated database version during sqlc migrations. If the current database version surpasses the specified version, the migration will be skipped.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package sqldb
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"net/url"
|
||||
@@ -32,6 +33,9 @@ var (
|
||||
"BIGINT PRIMARY KEY": "BIGSERIAL PRIMARY KEY",
|
||||
"TIMESTAMP": "TIMESTAMP WITHOUT TIME ZONE",
|
||||
}
|
||||
|
||||
// Make sure PostgresStore implements the MigrationExecutor interface.
|
||||
_ MigrationExecutor = (*PostgresStore)(nil)
|
||||
)
|
||||
|
||||
// replacePasswordInDSN takes a DSN string and returns it with the password
|
||||
@@ -85,43 +89,62 @@ type PostgresStore struct {
|
||||
|
||||
// NewPostgresStore creates a new store that is backed by a Postgres database
|
||||
// backend.
|
||||
func NewPostgresStore(cfg *PostgresConfig) (*PostgresStore, error) {
|
||||
func NewPostgresStore(cfg *PostgresConfig, migrations []MigrationConfig) (
|
||||
*PostgresStore, error) {
|
||||
|
||||
sanitizedDSN, err := replacePasswordInDSN(cfg.Dsn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
log.Infof("Using SQL database '%s'", sanitizedDSN)
|
||||
|
||||
rawDB, err := sql.Open("pgx", cfg.Dsn)
|
||||
db, err := sql.Open("pgx", cfg.Dsn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Ensure the migration tracker table exists before running migrations.
|
||||
// This table tracks migration progress and ensures compatibility with
|
||||
// SQLC query generation. If the table is already created by an SQLC
|
||||
// migration, this operation becomes a no-op.
|
||||
migrationTrackerSQL := `
|
||||
CREATE TABLE IF NOT EXISTS migration_tracker (
|
||||
version INTEGER UNIQUE NOT NULL,
|
||||
migration_time TIMESTAMP NOT NULL
|
||||
);`
|
||||
|
||||
_, err = db.Exec(migrationTrackerSQL)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating migration tracker: %w",
|
||||
err)
|
||||
}
|
||||
|
||||
maxConns := defaultMaxConns
|
||||
if cfg.MaxConnections > 0 {
|
||||
maxConns = cfg.MaxConnections
|
||||
}
|
||||
|
||||
rawDB.SetMaxOpenConns(maxConns)
|
||||
rawDB.SetMaxIdleConns(maxConns)
|
||||
rawDB.SetConnMaxLifetime(connIdleLifetime)
|
||||
db.SetMaxOpenConns(maxConns)
|
||||
db.SetMaxIdleConns(maxConns)
|
||||
db.SetConnMaxLifetime(connIdleLifetime)
|
||||
|
||||
queries := sqlc.New(rawDB)
|
||||
queries := sqlc.New(db)
|
||||
|
||||
s := &PostgresStore{
|
||||
cfg: cfg,
|
||||
BaseDB: &BaseDB{
|
||||
DB: rawDB,
|
||||
DB: db,
|
||||
Queries: queries,
|
||||
},
|
||||
}
|
||||
|
||||
// Execute migrations unless configured to skip them.
|
||||
if !cfg.SkipMigrations {
|
||||
err := s.ExecuteMigrations(TargetLatest)
|
||||
err := ApplyMigrations(
|
||||
context.Background(), s.BaseDB, s, migrations,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error executing migrations: %w",
|
||||
err)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user