/
migrate_actions.go
171 lines (149 loc) · 3.02 KB
/
migrate_actions.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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
package commands
import (
"fmt"
"os"
"github.com/cryptopay-dev/yaga/config"
"github.com/cryptopay-dev/yaga/logger"
"github.com/cryptopay-dev/yaga/migrate"
"github.com/urfave/cli"
)
var stepFlag = cli.IntFlag{
Name: "steps",
Value: 0,
Usage: "steps count to up/down",
}
var dbFlag = cli.StringFlag{
Name: "db",
Usage: "set database",
}
var dsnFlag = cli.StringFlag{
Name: "dsn",
Value: "",
Usage: "dsn (database source name)",
}
var mpathFlag = cli.StringFlag{
Name: "path",
Usage: "migration path",
Value: defaultMigratePath(),
}
func migrateFlags() []cli.Flag {
return []cli.Flag{
dbFlag,
dsnFlag,
stepFlag,
mpathFlag,
}
}
type migrateAct func(steps int) error
type migrateType uint
const (
migrateUp = iota
migrateDown
migrateVersion
migrateCleanup
migrateList
migratePlan
)
func (m migrateType) String() string {
switch m {
case migrateUp:
return "Up"
case migrateDown:
return "Down"
case migrateVersion:
return "Version"
case migrateCleanup:
return "Cleanup"
case migrateList:
return "List"
case migratePlan:
return "Plan"
default:
return fmt.Sprintf("Unknown(%d)", m)
}
}
func (m migrateType) needMigrations() bool {
return m == migrateUp ||
m == migrateDown ||
m == migratePlan
}
func migrateAction(mtype migrateType, db *config.Database, log logger.Logger) func(ctx *cli.Context) error {
return func(ctx *cli.Context) (err error) {
if db, err = FetchDB(ctx, db); err != nil {
log.Fatalf("can't find config file or dsn: %v", err)
}
if database := ctx.String("db"); len(database) != 0 {
db.Database = database
}
var steps = ctx.Int("steps")
mpath := ctx.String("path")
if mtype.needMigrations() {
if _, err = os.Stat(mpath); err != nil {
log.Fatalf("migration path not found: %v", err)
}
}
pg, err := db.Connect()
if err != nil {
log.Fatalf("postgres connection error: %v", err)
}
m, err := migrate.New(migrate.Options{
DB: pg,
Path: mpath,
Logger: log,
})
if err != nil {
log.Fatalf("migrate error: %v", err)
}
var action migrateAct
switch mtype {
case migrateUp:
action = m.Up
case migrateDown:
action = m.Down
if steps == 0 {
steps = 1
}
case migrateVersion:
action = func(int) error {
version, errV := m.Version()
if errV != nil {
return err
}
log.Infof("database version: %d", version)
return nil
}
case migrateList:
action = func(int) error {
items, errL := m.List()
if errL != nil {
return err
}
for _, item := range items {
log.Infof(
"%s -> %s",
item.RealName(),
item.CreatedAt,
)
}
return nil
}
case migratePlan:
action = func(int) error {
items, errL := m.Plan()
if errL != nil {
return err
}
for _, item := range items {
log.Infof("%s -> not applied", item.RealName())
}
return nil
}
default:
log.Fatalf("migrate unknown action: %s", mtype)
}
if err = action(steps); err != nil {
log.Fatalf("migrate action error: %v", err)
}
return
}
}