- pluggable per-domain Repository interfaces; PostgreSQL and SQLite impls - SQLite on modernc.org/sqlite (WAL, busy_timeout, foreign_keys, immediate tx) - separate migrations/sqlite and db.MigrateSQLite; store.NewPostgres/NewSQLite - cmd/reconcile compares object storage with the journal (report, then --delete) - storage.Backend.List and photos.Repository.AllStorageKeys - DB_BACKEND/SQLITE_PATH and STORAGE_BACKEND/FS_ROOT selectable; local defaults (sqlite ./galo.db, fs ./data) - Makefile reconcile/reconcile-delete; docs and .env.example updated
73 lines
1.9 KiB
Go
73 lines
1.9 KiB
Go
package db
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"io/fs"
|
|
|
|
"database/sql"
|
|
"github.com/golang-migrate/migrate/v4"
|
|
"github.com/golang-migrate/migrate/v4/database/pgx/v5"
|
|
sqlitemig "github.com/golang-migrate/migrate/v4/database/sqlite"
|
|
"github.com/golang-migrate/migrate/v4/source/iofs"
|
|
_ "github.com/jackc/pgx/v5/stdlib"
|
|
_ "modernc.org/sqlite"
|
|
)
|
|
|
|
// Migrate applies all up migrations from the given fs (root contains *.sql files).
|
|
func Migrate(dsn string, migrations fs.FS) error {
|
|
source, err := iofs.New(migrations, ".")
|
|
if err != nil {
|
|
return fmt.Errorf("migrations source: %w", err)
|
|
}
|
|
|
|
sqlDB, err := sql.Open("pgx", dsn)
|
|
if err != nil {
|
|
return fmt.Errorf("open sql db: %w", err)
|
|
}
|
|
defer sqlDB.Close()
|
|
|
|
driver, err := pgx.WithInstance(sqlDB, &pgx.Config{})
|
|
if err != nil {
|
|
return fmt.Errorf("migrate driver: %w", err)
|
|
}
|
|
|
|
m, err := migrate.NewWithInstance("iofs", source, "pgx", driver)
|
|
if err != nil {
|
|
return fmt.Errorf("migrate instance: %w", err)
|
|
}
|
|
if err := m.Up(); err != nil && !errors.Is(err, migrate.ErrNoChange) {
|
|
return fmt.Errorf("migrate up: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// MigrateSQLite applies all up migrations from the given fs to a SQLite database
|
|
// at path (creating it if needed).
|
|
func MigrateSQLite(path string, migrations fs.FS) error {
|
|
source, err := iofs.New(migrations, ".")
|
|
if err != nil {
|
|
return fmt.Errorf("migrations source: %w", err)
|
|
}
|
|
|
|
sqlDB, err := sql.Open("sqlite", path)
|
|
if err != nil {
|
|
return fmt.Errorf("open sql db: %w", err)
|
|
}
|
|
defer sqlDB.Close()
|
|
|
|
driver, err := sqlitemig.WithInstance(sqlDB, &sqlitemig.Config{})
|
|
if err != nil {
|
|
return fmt.Errorf("migrate driver: %w", err)
|
|
}
|
|
|
|
m, err := migrate.NewWithInstance("iofs", source, "sqlite", driver)
|
|
if err != nil {
|
|
return fmt.Errorf("migrate instance: %w", err)
|
|
}
|
|
if err := m.Up(); err != nil && !errors.Is(err, migrate.ErrNoChange) {
|
|
return fmt.Errorf("migrate up: %w", err)
|
|
}
|
|
return nil
|
|
}
|