cleanup: remove redundant and old architectural files
This commit is contained in:
@@ -1,118 +0,0 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// RunMigrations applies all *.sql files in migrationsDir in sorted order,
|
||||
// skipping any already recorded in migration_version.
|
||||
func RunMigrations(db *sql.DB, migrationsDir string) error {
|
||||
if migrationsDir == "" {
|
||||
return fmt.Errorf("migrations directory is required")
|
||||
}
|
||||
|
||||
// Create migration tracking table
|
||||
_, err := db.Exec(`
|
||||
CREATE TABLE IF NOT EXISTS migration_version (
|
||||
name TEXT PRIMARY KEY,
|
||||
applied_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
migrations, err := filepath.Glob(filepath.Join(migrationsDir, "*.sql"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(migrations) == 0 {
|
||||
return fmt.Errorf("no migration files found in %s", migrationsDir)
|
||||
}
|
||||
|
||||
sort.Strings(migrations)
|
||||
|
||||
appliedNames, err := loadAppliedMigrationNames(db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, migrationFile := range migrations {
|
||||
migrationName := filepath.Base(migrationFile)
|
||||
if migrationApplied(appliedNames, migrationName) {
|
||||
continue // already applied
|
||||
}
|
||||
|
||||
migrationSQL, err := os.ReadFile(migrationFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := db.Exec(string(migrationSQL)); err != nil {
|
||||
return err // stop on first failure
|
||||
}
|
||||
|
||||
// record applied migration
|
||||
_, err = db.Exec("INSERT INTO migration_version (name) VALUES (?)", migrationName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
appliedNames[migrationName] = struct{}{}
|
||||
|
||||
log.Printf("migration %s applied successfully", migrationName)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func loadAppliedMigrationNames(db *sql.DB) (map[string]struct{}, error) {
|
||||
rows, err := db.Query("SELECT name FROM migration_version")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() { _ = rows.Close() }()
|
||||
|
||||
applied := make(map[string]struct{})
|
||||
for rows.Next() {
|
||||
var name string
|
||||
if err := rows.Scan(&name); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
applied[name] = struct{}{}
|
||||
}
|
||||
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return applied, nil
|
||||
}
|
||||
|
||||
// migrationApplied checks the applied names map for a match,
|
||||
// including legacy paths and case-insensitive basename matches.
|
||||
func migrationApplied(appliedNames map[string]struct{}, migrationName string) bool {
|
||||
if _, exists := appliedNames[migrationName]; exists {
|
||||
return true
|
||||
}
|
||||
|
||||
legacyName := filepath.ToSlash(filepath.Join("migrations", migrationName))
|
||||
if _, exists := appliedNames[legacyName]; exists {
|
||||
return true
|
||||
}
|
||||
|
||||
for appliedName := range appliedNames {
|
||||
if strings.EqualFold(filepath.Base(appliedName), migrationName) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
Reference in New Issue
Block a user