ref: master
db/migrations.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
package db import ( "embed" "fmt" "log" "sort" ) //go:embed migrations var migrationsDir embed.FS func Migrate() error { _, err := db.Exec("create table if not exists migrations(id text)") if err != nil { return fmt.Errorf("while creating migrations table: %w", err) } rows, err := db.Query("select id from migrations order by id") if err != nil { return fmt.Errorf("while checking if migrations exist: %w", err) } migrationEntries, err := migrationsDir.ReadDir("migrations") if err != nil { return fmt.Errorf("while reading migrations directory: %w", err) } sort.Slice(migrationEntries, func(i int, j int) bool { return (migrationEntries[i].Name() < migrationEntries[j].Name()) }) for i, migrationEntry := range migrationEntries { if rows.Next() { var nameInDB string err := rows.Scan(&nameInDB) if err != nil { return fmt.Errorf("while scanning migration %d: %w", i, err) } if migrationEntry.Name() != nameInDB { return fmt.Errorf("while checking migration %d, mismatch in names: ā%sā in db, ā%sā in file", i, nameInDB, migrationEntry.Name()) } } else { log.Printf("performing migration %s\n", migrationEntry.Name()) migration, err := migrationsDir.ReadFile("migrations/" + migrationEntry.Name()) if err != nil { return fmt.Errorf("while reading migration %s: %w", migrationEntry.Name(), err) } _, err = db.Exec(string(migration)) if err != nil { return fmt.Errorf("while performing migration %s: %w", migrationEntry.Name(), err) } _, err = db.Exec("insert into migrations values($1)", migrationEntry.Name()) if err != nil { return fmt.Errorf("while adding migration %s to db: %w", migrationEntry.Name(), err) } } } return nil } |