-
Notifications
You must be signed in to change notification settings - Fork 3
/
main.go
99 lines (87 loc) · 2.68 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
// Example:
//
// 1. Make changes to schema files (internal/storage/persistence/ent/schema),
// 2. Re-generate (make gen-ent),
// 3. Run:
// $ go run ./cmd/migrate/ \
// --config="./enduro.toml" \
// --dsn="mysql://enduro:enduro123@tcp(localhost:3306)/enduro_storage" \
// --name="init" \
// --path="./internal/storage/persistence/migrations"
package main
import (
"context"
"fmt"
"log"
"os"
"path/filepath"
"strings"
"ariga.io/atlas/sql/sqltool"
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql/schema"
"github.com/go-sql-driver/mysql"
"github.com/spf13/pflag"
"github.com/artefactual-sdps/enduro/internal/config"
"github.com/artefactual-sdps/enduro/internal/storage/persistence/ent/db/migrate"
)
func main() {
p := pflag.NewFlagSet("migrate", pflag.ExitOnError)
p.String("config", "", "Configuration file")
p.String("dsn", "", "MySQL DSN")
p.String("path", "", "Migration directory")
p.String("name", "changes", "Migration name")
_ = p.Parse(os.Args[1:])
path, _ := p.GetString("path")
if path == "" {
wd, err := os.Getwd()
if err != nil {
os.Exit(1)
}
// Guessing that running it from the root folder.
path = filepath.Join(wd, "internal/storage/persistence/migrations")
}
var cfg config.Configuration
configFile, _ := p.GetString("config")
_, _, err := config.Read(&cfg, configFile)
if err != nil {
fmt.Printf("Failed to read configuration: %v\n", err)
os.Exit(1)
}
DSN := cfg.Storage.Database.DSN
flagDSN, _ := p.GetString("dsn")
if flagDSN != "" {
DSN = flagDSN
}
// MySQL's DSN format is not accepted by Ent, convert as needed (remove Net).
DSN = strings.TrimPrefix(DSN, "mysql://")
DSNConfig, err := mysql.ParseDSN(DSN)
if err != nil {
fmt.Printf("Failed to parse MySQL DSN: %v\n", err)
os.Exit(1)
}
entDSN := fmt.Sprintf("%s://%s:%s@%s/%s",
"mysql",
DSNConfig.User,
DSNConfig.Passwd,
DSNConfig.Addr,
DSNConfig.DBName,
)
ctx := context.Background()
// Create a local migration directory able to understand golang-migrate migration files for replay.
dir, err := sqltool.NewGolangMigrateDir(path)
if err != nil {
log.Fatalf("failed creating atlas migration directory: %v", err)
}
// Write migration diff.
opts := []schema.MigrateOption{
schema.WithDir(dir), // provide migration directory
schema.WithMigrationMode(schema.ModeReplay), // provide migration mode
schema.WithDialect(dialect.MySQL), // Ent dialect to use
}
// Generate migrations using Atlas support for TiDB (note the Ent dialect option passed above).
name, _ := p.GetString("name")
err = migrate.NamedDiff(ctx, entDSN, name, opts...)
if err != nil {
log.Fatalf("failed generating migration file: %v", err)
}
}