63 lines
1.3 KiB
Go
63 lines
1.3 KiB
Go
package migrate
|
|
|
|
import (
|
|
"database/sql"
|
|
"embed"
|
|
"fmt"
|
|
"log"
|
|
"log/slog"
|
|
|
|
_ "github.com/jackc/pgx/v5/stdlib"
|
|
)
|
|
|
|
//go:embed migrations/*.sql
|
|
var migrations embed.FS
|
|
|
|
type Migration struct {
|
|
Version int
|
|
Name string
|
|
}
|
|
|
|
func Migrate(logger *slog.Logger, db *sql.DB) {
|
|
logger.Info("Running migrations...")
|
|
migrationTableSql := `
|
|
CREATE TABLE IF NOT EXISTS migrations(
|
|
version SERIAL PRIMARY KEY,
|
|
name VARCHAR(50)
|
|
);`
|
|
|
|
_, err := db.Exec(migrationTableSql)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
files, err := migrations.ReadDir("migrations")
|
|
if err != nil {
|
|
log.Fatal("Failed to read migrations directory")
|
|
}
|
|
|
|
for _, file := range files {
|
|
var migration Migration
|
|
row := db.QueryRow("SELECT * FROM migrations WHERE name = $1;", file.Name())
|
|
err = row.Scan(&migration.Version, &migration.Name)
|
|
if err == sql.ErrNoRows {
|
|
logger.Info(fmt.Sprintf("Running migration: %s", file.Name()))
|
|
migrationSql, err := migrations.ReadFile(fmt.Sprintf("migrations/%s", file.Name()))
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
_, err = db.Exec(string(migrationSql))
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
_, err = db.Exec("INSERT INTO migrations(name) VALUES($1);", file.Name())
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
}
|
|
logger.Info("Migrations completed")
|
|
}
|