42307f285f
encapi's schema was a cumulative IF NOT EXISTS blob re-executed inline on every start: it grows forever, records nothing, and cannot express a change that is not a fresh CREATE. golib owns that mechanism now, so encapi keeps the SQL and drops the runner. - Move the DDL verbatim into migrations/0001_init.sql, embedded via migrations.FS. It stays IF NOT EXISTS-guarded, so the first start against the live database re-runs it as a no-op and only lands the schema_migrations row. - Build the pool with pg.NewMigrated under the advisory lock named encapi-migrations, and delete the inline migrate(). database.New now takes a context and a logger; main.go hands it the signal context so a start blocked on the migration lock still dies on SIGTERM. - Render the DSN with pg.DSN. The env var contract is untouched — the fields are still resolved by internal/config, because encapi defaults DBUSER and DBNAME to "encapi" where pg.DSNFromEnv treats both as required. - Guard the set: embedded files must match migrations/, every CREATE must be idempotent, the derived lock key is pinned, and a container test proves the adoption path over a database that predates schema_migrations. - Plumb GOPRIVATE=git.unkin.net for the first cross-repo Go dependency: exported by the Makefile, set in the Dockerfile and the woodpecker Go steps, documented in the README.
34 lines
917 B
Go
34 lines
917 B
Go
package database
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
)
|
|
|
|
// encapi's schema predates schema_migrations, so the first start after this
|
|
// change re-applies 0001_init against a database that already has the tables.
|
|
// The file is IF NOT EXISTS-guarded for exactly that: the run must succeed and
|
|
// leave only the tracking row behind.
|
|
func TestMigrateAdoptsAnExistingSchema(t *testing.T) {
|
|
requireDB(t)
|
|
ctx := context.Background()
|
|
|
|
if _, err := testDB.Pool.Exec(ctx, `DROP TABLE schema_migrations`); err != nil {
|
|
t.Fatalf("drop schema_migrations: %v", err)
|
|
}
|
|
|
|
db, err := New(ctx, testDSN, nil)
|
|
if err != nil {
|
|
t.Fatalf("migrate over an existing schema: %v", err)
|
|
}
|
|
defer db.Close()
|
|
|
|
var n int
|
|
if err := db.Pool.QueryRow(ctx, `SELECT count(*) FROM schema_migrations`).Scan(&n); err != nil {
|
|
t.Fatalf("count schema_migrations: %v", err)
|
|
}
|
|
if n != 1 {
|
|
t.Fatalf("schema_migrations rows = %d, want 1", n)
|
|
}
|
|
}
|