forked from stellar/go
/
main.go
117 lines (99 loc) · 3.49 KB
/
main.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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package schema
import (
"database/sql"
"errors"
stdLog "log"
migrate "github.com/rubenv/sql-migrate"
)
//go:generate go-bindata -nometadata -pkg schema -o bindata.go migrations/
// MigrateDir represents a direction in which to perform schema migrations.
type MigrateDir string
const (
// MigrateUp causes migrations to be run in the "up" direction.
MigrateUp MigrateDir = "up"
// MigrateDown causes migrations to be run in the "down" direction.
MigrateDown MigrateDir = "down"
// MigrateRedo causes migrations to be run down, then up
MigrateRedo MigrateDir = "redo"
)
// Migrations represents all of the schema migration for millennium
var Migrations migrate.MigrationSource = &migrate.AssetMigrationSource{
Asset: Asset,
AssetDir: AssetDir,
Dir: "migrations",
}
// Migrate performs schema migration. Migrations can occur in one of three
// ways:
//
// - up: migrations are performed from the currently installed version upwards.
// If count is 0, all unapplied migrations will be run.
//
// - down: migrations are performed from the current version downard. If count
// is 0, all applied migrations will be run in a downard direction.
//
// - redo: migrations are first ran downard `count` times, and then are rand
// upward back to the current version at the start of the process. If count is
// 0, a count of 1 will be assumed.
func Migrate(db *sql.DB, dir MigrateDir, count int) (int, error) {
switch dir {
case MigrateUp:
return migrate.ExecMax(db, "postgres", Migrations, migrate.Up, count)
case MigrateDown:
return migrate.ExecMax(db, "postgres", Migrations, migrate.Down, count)
case MigrateRedo:
if count == 0 {
count = 1
}
down, err := migrate.ExecMax(db, "postgres", Migrations, migrate.Down, count)
if err != nil {
return down, err
}
return migrate.ExecMax(db, "postgres", Migrations, migrate.Up, down)
default:
return 0, errors.New("Invalid migration direction")
}
}
// GetMigrationsUp returns a list of names of any migrations needed in the
// "up" direction (more recent schema versions).
func GetMigrationsUp(dbUrl string) (migrationIds []string) {
// Get a DB handle
db, dbErr := sql.Open("postgres", dbUrl)
if dbErr != nil {
stdLog.Fatal(dbErr)
}
defer db.Close()
// Get the possible migrations
possibleMigrations, _, migrateErr := migrate.PlanMigration(db, "postgres", Migrations, migrate.Up, 0)
if migrateErr != nil {
stdLog.Fatal(migrateErr)
}
// Extract a list of the possible migration names
for _, m := range possibleMigrations {
migrationIds = append(migrationIds, m.Id)
}
return migrationIds
}
// GetNumMigrationsDown returns the number of migrations to apply in the
// "down" direction to return to the older schema version expected by this
// version of Millennium. To keep the code simple, it does not provide a list of
// migration names.
func GetNumMigrationsDown(dbUrl string) (nMigrations int) {
// Get a DB handle
db, dbErr := sql.Open("postgres", dbUrl)
if dbErr != nil {
stdLog.Fatal(dbErr)
}
defer db.Close()
// Get the set of migrations recorded in the database
migrationRecords, recordErr := migrate.GetMigrationRecords(db, "postgres")
if recordErr != nil {
stdLog.Fatal(recordErr)
}
// Get the list of migrations needed by this version of Millennium
allNeededMigrations, _, migrateErr := migrate.PlanMigration(db, "postgres", Migrations, migrate.Down, 0)
if migrateErr != nil {
stdLog.Fatal(migrateErr)
}
// Return the size difference between the two sets of migrations
return len(migrationRecords) - len(allNeededMigrations)
}