package sqlite import ( "fmt" "log" "os" "path" "time" "git.phc.dm.unipi.it/phc/website/database" "github.com/jmoiron/sqlx" ) type sqliteDBMigrate struct{ *sqlx.DB } var _ database.DBMigrate = sqliteDBMigrate{} func (db sqliteDBMigrate) Migrate(migrationFolder string) error { log.Printf(`Creating migrations table`) if _, err := db.Exec(`CREATE TABLE IF NOT EXISTS migrations(timestamp TEXT, filename TEXT)`); err != nil { return err } log.Printf(`Loading applied migrations`) appliedMigrations := []migration{} if err := db.Select(&appliedMigrations, `SELECT * FROM migrations`); err != nil { return err } entries, err := os.ReadDir(migrationFolder) if err != nil { return err } for i, entry := range entries { if entry.IsDir() { return fmt.Errorf("no dirs in migrations folder") } if i < len(appliedMigrations) { if appliedMigrations[i].Filename != entry.Name() { return fmt.Errorf("misapplied migration %q with %q", appliedMigrations[i].Filename, entry.Name()) } log.Printf("Found applied migration %q", entry.Name()) continue } log.Printf("Applying new migration %q", entry.Name()) migrationPath := path.Join(migrationFolder, entry.Name()) sqlStmts, err := os.ReadFile(migrationPath) if err != nil { return err } tx, err := db.Beginx() if err != nil { return err } if _, err := tx.Exec(string(sqlStmts)); err != nil { return err } if _, err := tx.Exec(`INSERT INTO migrations VALUES (?, ?)`, time.Now().Format(time.RFC3339), entry.Name(), ); err != nil { return err } if err := tx.Commit(); err != nil { return err } } log.Printf("All migrations applied successfully, database up to date") return nil }