Skip to content

Commit bed0fd3

Browse files
Add sql output format (#235)
1 parent 127e28f commit bed0fd3

File tree

3 files changed

+65
-0
lines changed

3 files changed

+65
-0
lines changed

cmd/pg-schema-diff/main_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ type runCmdWithAssertionsParams struct {
3434
// saving schemas to a randomly generated temporary directory.
3535
dynamicArgs []dArgGenerator
3636

37+
// outputEquals is the exact string that stdout should equal.
38+
outputEquals string
3739
// outputContains is a list of substrings that are expected to be contained in the stdout output of the command.
3840
outputContains []string
3941
// expectErrContains is a list of substrings that are expected to be contained in the error returned by
@@ -72,6 +74,9 @@ func (suite *cmdTestSuite) runCmdWithAssertions(tc runCmdWithAssertionsParams) {
7274
suite.Contains(stdOutStr, o)
7375
}
7476
}
77+
if len(tc.outputEquals) > 0 {
78+
suite.Equal(tc.outputEquals, stdOutStr)
79+
}
7580
}
7681

7782
// dArgGenerator generates argument at the run-time of the test case...

cmd/pg-schema-diff/plan_cmd.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,15 @@ var (
172172
convertToOutputString: planToJsonS,
173173
}
174174

175+
outputFormatSql = outputFormat{
176+
identifier: "sql",
177+
convertToOutputString: planToSql,
178+
}
179+
175180
outputFormats = []outputFormat{
176181
outputFormatPretty,
177182
outputFormatJson,
183+
outputFormatSql,
178184
}
179185

180186
outputFormatStrings = func() []string {
@@ -584,10 +590,30 @@ func hazardToPrettyS(hazard diff.MigrationHazard) string {
584590
}
585591
}
586592

593+
// planToJsonS converts the plan to JSON.
587594
func planToJsonS(plan diff.Plan) string {
588595
jsonData, err := json.MarshalIndent(plan, "", " ")
589596
if err != nil {
590597
panic(err)
591598
}
592599
return string(jsonData)
593600
}
601+
602+
// planToSql converts the plan to one large runnable SQL script.
603+
func planToSql(plan diff.Plan) string {
604+
sb := strings.Builder{}
605+
for i, stmt := range plan.Statements {
606+
if len(stmt.Hazards) > 0 {
607+
for _, hazard := range stmt.Hazards {
608+
sb.WriteString(fmt.Sprintf("-- Hazard %s\n", hazardToPrettyS(hazard)))
609+
}
610+
}
611+
sb.WriteString(fmt.Sprintf("SET SESSION statement_timeout = %d;\n", stmt.Timeout.Milliseconds()))
612+
sb.WriteString(fmt.Sprintf("SET SESSION lock_timeout = %d;\n", stmt.LockTimeout.Milliseconds()))
613+
sb.WriteString(fmt.Sprintf("%s;", stmt.DDL))
614+
if i < len(plan.Statements)-1 {
615+
sb.WriteString("\n\n")
616+
}
617+
}
618+
return sb.String()
619+
}

cmd/pg-schema-diff/plan_cmd_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ func (suite *cmdTestSuite) TestPlanCmd() {
1212
args []string
1313
dynamicArgs []dArgGenerator
1414

15+
// outputEquals is the exact string that stdout should equal.
16+
outputEquals string
1517
// outputContains is a list of substrings that are expected to be contained in the stdout output of the command.
1618
outputContains []string
1719
// expectErrContains is a list of substrings that are expected to be contained in the error returned by
@@ -91,11 +93,43 @@ func (suite *cmdTestSuite) TestPlanCmd() {
9193
args: []string{"--from-dir", "some-dir", "--to-dir", "some-other-dir"},
9294
expectErrContains: []string{"at least one Postgres server"},
9395
},
96+
{
97+
name: "sql output format",
98+
args: []string{"--output-format", "sql"},
99+
dynamicArgs: []dArgGenerator{
100+
tempDsnDArg(suite.pgEngine, "temp-db-dsn", []string{""}),
101+
tempSchemaDirDArg("from-dir", []string{`
102+
CREATE TABLE foobar(
103+
bar TEXT,
104+
fizzbuzz TEXT
105+
);
106+
`}),
107+
tempSchemaDirDArg("to-dir", []string{`
108+
CREATE TABLE foobar(
109+
bar TEXT,
110+
fizzbuzz TEXT
111+
);
112+
CREATE INDEX bar_idx ON foobar(bar);
113+
CREATE INDEX fizzbuzz_idx ON foobar(fizzbuzz);
114+
`}),
115+
},
116+
outputEquals: "-- Hazard INDEX_BUILD: This might affect database performance. Concurrent index builds require a non-trivial amount of CPU, potentially affecting database performance. They also can take a while but do not lock out writes.\nSET SESSION statement_timeout = 1200000;\nSET SESSION lock_timeout = 3000;\nCREATE INDEX CONCURRENTLY bar_idx ON public.foobar USING btree (bar);\n\n-- Hazard INDEX_BUILD: This might affect database performance. Concurrent index builds require a non-trivial amount of CPU, potentially affecting database performance. They also can take a while but do not lock out writes.\nSET SESSION statement_timeout = 1200000;\nSET SESSION lock_timeout = 3000;\nCREATE INDEX CONCURRENTLY fizzbuzz_idx ON public.foobar USING btree (fizzbuzz);\n",
117+
},
118+
{
119+
name: "invalid output format",
120+
args: []string{"--output-format", "invalid"},
121+
dynamicArgs: []dArgGenerator{
122+
tempDsnDArg(suite.pgEngine, "from-dsn", nil),
123+
tempDsnDArg(suite.pgEngine, "to-dsn", []string{"CREATE TABLE foobar()"}),
124+
},
125+
expectErrContains: []string{"invalid output format"},
126+
},
94127
} {
95128
suite.Run(tc.name, func() {
96129
suite.runCmdWithAssertions(runCmdWithAssertionsParams{
97130
args: append([]string{"plan"}, tc.args...),
98131
dynamicArgs: tc.dynamicArgs,
132+
outputEquals: tc.outputEquals,
99133
outputContains: tc.outputContains,
100134
expectErrContains: tc.expectErrContains,
101135
})

0 commit comments

Comments
 (0)