graphicek/server/database/migrations.go

101 lines
1.6 KiB
Go
Raw Normal View History

2022-08-23 21:26:42 +02:00
package database
import (
"database/sql"
"embed"
"fmt"
"io/fs"
"sort"
"strings"
)
//go:embed migrations/*.sql
var migrationStorage embed.FS
func getAppliedMigrationsSet(db *sql.DB) (map[string]bool, error) {
set := make(map[string]bool)
rows, err := db.Query("SELECT id FROM migrations")
if err != nil {
return nil, err
}
defer rows.Close()
for rows.Next() {
var id string
err := rows.Scan(&id)
if err != nil {
return nil, err
}
set[id] = true
}
err = rows.Err()
if err != nil {
return nil, err
}
return set, nil
}
func getMigrations() ([]string, error) {
var items []string
entries, err := migrationStorage.ReadDir("migrations")
if err != nil {
return nil, err
}
for _, entry := range entries {
if !entry.IsDir() && strings.HasSuffix(entry.Name(), ".sql") {
items = append(items, strings.TrimSuffix(entry.Name(), ".sql"))
}
}
if err != nil {
return nil, err
}
sort.Strings(items)
return items, nil
}
func getMigrationContent(id string) (string, error) {
content, err := fs.ReadFile(migrationStorage, "migrations/"+id+".sql")
if err != nil {
return "", err
}
return string(content), nil
}
func getPendingMigrations(db *sql.DB) ([]string, error) {
var migrationsToRun []string
migrationSet, err := getAppliedMigrationsSet(db)
if err != nil {
return nil, err
}
storedMigrations, err := getMigrations()
if err != nil {
return nil, fmt.Errorf("failed to load stored migrations: %w", err)
}
for _, storedMigration := range storedMigrations {
if !migrationSet[storedMigration] {
migrationsToRun = append(migrationsToRun, storedMigration)
}
}
return migrationsToRun, nil
}