-
Notifications
You must be signed in to change notification settings - Fork 4
/
store.go
140 lines (121 loc) · 3.37 KB
/
store.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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package gloat
// Store is an interface representing a place where the applied migrations are
// recorded.
type Store interface {
Source
Insert(*Migration, SQLExecer) error
Remove(*Migration, SQLExecer) error
}
// DatabaseStore is a Store that keeps the applied migrations in a database
// table called schema_migrations. The table is automatically created if it
// does not exist.
type DatabaseStore struct {
db SQLTransactor
createTableStatement string
insertMigrationStatement string
removeMigrationStatement string
selectAllMigrationsStatement string
}
// Insert records a migration version into the schema_migrations table.
func (s *DatabaseStore) Insert(migration *Migration, execer SQLExecer) error {
if execer == nil {
execer = s.db
}
if err := s.ensureSchemaTableExists(); err != nil {
return err
}
_, err := execer.Exec(s.insertMigrationStatement, migration.Version)
return err
}
// Remove removes a migration version from the schema_migrations table.
func (s *DatabaseStore) Remove(migration *Migration, execer SQLExecer) error {
if execer == nil {
execer = s.db
}
if err := s.ensureSchemaTableExists(); err != nil {
return err
}
_, err := execer.Exec(s.removeMigrationStatement, migration.Version)
return err
}
// Collect builds a slice of migrations with the versions of the recorded
// applied migrations.
func (s *DatabaseStore) Collect() (migrations Migrations, err error) {
if err = s.ensureSchemaTableExists(); err != nil {
return
}
rows, err := s.db.Query(s.selectAllMigrationsStatement)
if err != nil {
return
}
defer rows.Close()
for rows.Next() {
migration := &Migration{}
if err = rows.Scan(&migration.Version); err != nil {
return
}
migrations = append(migrations, migration)
}
return
}
func (s *DatabaseStore) ensureSchemaTableExists() error {
_, err := s.db.Exec(s.createTableStatement)
return err
}
// NewPostgreSQLStore creates a Store for PostgreSQL.
func NewPostgreSQLStore(db SQLTransactor) Store {
return &DatabaseStore{
db: db,
createTableStatement: `
CREATE TABLE IF NOT EXISTS schema_migrations (
version BIGINT PRIMARY KEY NOT NULL
)`,
insertMigrationStatement: `
INSERT INTO schema_migrations (version)
VALUES ($1)`,
removeMigrationStatement: `
DELETE FROM schema_migrations
WHERE version=$1`,
selectAllMigrationsStatement: `
SELECT version
FROM schema_migrations`,
}
}
// NewMySQLStore creates a Store for MySQL.
func NewMySQLStore(db SQLTransactor) Store {
return &DatabaseStore{
db: db,
createTableStatement: `
CREATE TABLE IF NOT EXISTS schema_migrations (
version BIGINT PRIMARY KEY NOT NULL
)`,
insertMigrationStatement: `
INSERT INTO schema_migrations (version)
VALUES (?)`,
removeMigrationStatement: `
DELETE FROM schema_migrations
WHERE version=?`,
selectAllMigrationsStatement: `
SELECT version
FROM schema_migrations`,
}
}
// NewSQLite3Store creates a Store for SQLite3.
func NewSQLite3Store(db SQLTransactor) Store {
return &DatabaseStore{
db: db,
createTableStatement: `
CREATE TABLE IF NOT EXISTS schema_migrations (
version BIGINT PRIMARY KEY NOT NULL
)`,
insertMigrationStatement: `
INSERT INTO schema_migrations (version)
VALUES (?)`,
removeMigrationStatement: `
DELETE FROM schema_migrations
WHERE version=?`,
selectAllMigrationsStatement: `
SELECT version
FROM schema_migrations`,
}
}