-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathupdate.go
125 lines (115 loc) · 2.59 KB
/
update.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
package main
import (
"flag"
"github.com/aj0strow/pgschema/order"
"github.com/aj0strow/pgschema/source/hcl"
"github.com/aj0strow/pgschema/source/psql"
"github.com/jackc/pgx"
"github.com/mitchellh/cli"
"io/ioutil"
)
type Update struct {
cli.Ui
}
func (cmd *Update) Synopsis() string {
return "Update database schema to match source file."
}
func (cmd *Update) Help() string {
return `
=> Update database schema to match source file.
pgschema update [flags]
-source <path> Path to source file in HCL schema format.
-uri <uri> Postgres database connection uri, eg. 'postgres://'.
-dsn <dsn> Postgres database connection dsn, eg. 'dbname='.
-dryRun Print SQL update commands without executing.
`
}
func (cmd *Update) Run(args []string) int {
var (
source string
uri string
dsn string
dryRun bool
)
f := flag.NewFlagSet("update", flag.ContinueOnError)
f.StringVar(&source, "source", "", "")
f.StringVar(&uri, "uri", "", "")
f.StringVar(&dsn, "dsn", "", "")
f.BoolVar(&dryRun, "dryRun", false, "")
if err := f.Parse(args); err != nil {
cmd.Error(err.Error())
return BadInput
}
if source == "" {
cmd.Error("-source input file can't be empty")
return BadInput
}
data, err := ioutil.ReadFile(source)
if err != nil {
cmd.Error(err.Error())
return BadInput
}
a, err := hcl.ParseBytes(data)
if err != nil {
cmd.Error(err.Error())
return BadInput
}
var pgConfig *pgx.ConnConfig
if dsn != "" {
config, err := pgx.ParseDSN(dsn)
if err != nil {
cmd.Error(err.Error())
return BadInput
}
pgConfig = &config
}
if uri != "" {
config, err := pgx.ParseURI(uri)
if err != nil {
cmd.Error(err.Error())
return BadInput
}
pgConfig = &config
}
if pgConfig == nil {
cmd.Error("database connection required, provide -dsn or -uri")
return BadInput
}
conn, err := pgx.Connect(*pgConfig)
if err != nil {
cmd.Error(err.Error())
return DatabaseError
}
defer conn.Close()
b, err := psql.LoadDatabase(conn)
if err != nil {
cmd.Error(err.Error())
return DatabaseError
}
changes := order.Changes(a, b)
if dryRun {
for _, change := range changes {
cmd.Info(change.String())
}
return Success
}
tx, err := conn.Begin()
if err != nil {
cmd.Error(err.Error())
return DatabaseError
}
defer tx.Rollback()
for _, change := range changes {
cmd.Info(change.String())
_, err := tx.Exec(change.String())
if err != nil {
cmd.Error(err.Error())
return DatabaseError
}
}
if err := tx.Commit(); err != nil {
cmd.Error(err.Error())
return DatabaseError
}
return Success
}