Skip to content

Commit 538b38b

Browse files
authored
Merge pull request #9 from ReifyAB/jl/add-statement-joiner
Add StatementAppender
2 parents 4f3502a + 6756222 commit 538b38b

19 files changed

+111
-124
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
## [Unreleased]
22

3+
- Introduce StatementAppender for better spacing between statements
4+
35
## [0.2.1] - 2025-02-15
46

57
- Add transform to remove SET commands with default values

README.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,8 +191,6 @@ INSERT INTO "schema_migrations" (version) VALUES
191191
into this normalize (and much more compatch & readable) version:
192192

193193
```sql
194-
195-
196194
CREATE EXTENSION IF NOT EXISTS pgcrypto SCHEMA public;
197195

198196

lib/activerecord-pg-format-db-structure.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
require_relative "activerecord-pg-format-db-structure/version"
44

55
require_relative "activerecord-pg-format-db-structure/deparser"
6+
require_relative "activerecord-pg-format-db-structure/statement_appender"
67
require_relative "activerecord-pg-format-db-structure/transforms/remove_comments_on_extensions"
78
require_relative "activerecord-pg-format-db-structure/transforms/inline_serials"
89
require_relative "activerecord-pg-format-db-structure/transforms/inline_primary_keys"
@@ -29,6 +30,7 @@ module ActiveRecordPgFormatDbStructure
2930
].freeze
3031

3132
DEFAULT_DEPARSER = Deparser
33+
DEFAULT_STATEMENT_APPENDER = StatementAppender
3234
end
3335

3436
# :nocov:

lib/activerecord-pg-format-db-structure/deparser.rb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,42 +32,42 @@ def deparse_raw_statement(raw_statement)
3232
private
3333

3434
def deparse_stmt_generic(stmt)
35-
generic_str = +"\n\n"
35+
generic_str = +""
3636
generic_str << deparse_stmt_and_indent(stmt)
3737
generic_str << ";"
3838
generic_str
3939
end
4040

4141
def deparse_stmt_compact(stmt)
42-
compact_str = +"\n"
42+
compact_str = +""
4343
compact_str << deparse_stmt(stmt)
4444
compact_str << ";"
4545
compact_str
4646
end
4747

4848
def deparse_insert_stmt(stmt)
49-
insert_str = +"\n\n\n"
49+
insert_str = +""
5050
insert_str << deparse_stmt_and_indent(stmt)
5151
insert_str << "\n;"
5252
insert_str
5353
end
5454

5555
def deparse_create_stmt(stmt)
56-
table_str = "\n\n\n-- Name: #{stmt.relation.relname}; Type: TABLE;\n\n"
56+
table_str = "-- Name: #{stmt.relation.relname}; Type: TABLE;\n\n"
5757
table_str << deparse_stmt_and_indent(stmt)
5858
table_str << ";"
5959
table_str
6060
end
6161

6262
def deparse_view_stmt(stmt)
63-
table_str = "\n\n\n-- Name: #{stmt.view.relname}; Type: VIEW;\n\n"
63+
table_str = "-- Name: #{stmt.view.relname}; Type: VIEW;\n\n"
6464
table_str << deparse_stmt_and_indent(stmt)
6565
table_str << ";"
6666
table_str
6767
end
6868

6969
def deparse_create_table_as_stmt(stmt)
70-
table_str = "\n\n\n-- Name: #{stmt.into.rel.relname}; Type: MATERIALIZED VIEW;\n\n"
70+
table_str = "-- Name: #{stmt.into.rel.relname}; Type: MATERIALIZED VIEW;\n\n"
7171
table_str << deparse_stmt_and_indent(stmt)
7272

7373
# couldn't find a better solution for this, but probably an OK workaround?

lib/activerecord-pg-format-db-structure/formatter.rb

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,16 @@
66
module ActiveRecordPgFormatDbStructure
77
# Formats & normalizes in place the given SQL string
88
class Formatter
9-
attr_reader :transforms, :deparser
9+
attr_reader :transforms, :deparser, :statement_appender
1010

1111
def initialize(
1212
transforms: DEFAULT_TRANSFORMS,
13-
deparser: DEFAULT_DEPARSER
13+
deparser: DEFAULT_DEPARSER,
14+
statement_appender: DEFAULT_STATEMENT_APPENDER
1415
)
1516
@transforms = transforms
1617
@deparser = deparser
18+
@statement_appender = statement_appender
1719
end
1820

1921
def format(source)
@@ -23,9 +25,17 @@ def format(source)
2325
transform.new(raw_statements).transform!
2426
end
2527

26-
raw_statements.map do |raw_statement|
27-
deparser.new(source).deparse_raw_statement(raw_statement)
28-
end.compact.join
28+
appender = statement_appender.new
29+
raw_statements.each do |raw_statement|
30+
statement = deparser.new(source).deparse_raw_statement(raw_statement)
31+
appender.append_statement!(
32+
statement,
33+
statement_kind: PgQuery::Node.inner_class_to_name(
34+
raw_statement.stmt.inner.class
35+
)
36+
)
37+
end
38+
appender.output
2939
end
3040
end
3141
end

lib/activerecord-pg-format-db-structure/railtie.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ class Railtie < Rails::Railtie
66
config.activerecord_pg_format_db_structure = ActiveSupport::OrderedOptions.new
77
config.activerecord_pg_format_db_structure.transforms = DEFAULT_TRANSFORMS.dup
88
config.activerecord_pg_format_db_structure.deparser = DEFAULT_DEPARSER
9+
config.activerecord_pg_format_db_structure.statement_appender = DEFAULT_STATEMENT_APPENDER
910

1011
rake_tasks do
1112
load "activerecord-pg-format-db-structure/tasks/clean_db_structure.rake"
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# frozen_string_literal: true
2+
3+
require "pg_query"
4+
require_relative "indenter"
5+
6+
module ActiveRecordPgFormatDbStructure
7+
# Appends statements with reasonable spacing in-between
8+
class StatementAppender
9+
attr_reader :output
10+
11+
def initialize(output = +"")
12+
@output = output
13+
@previous_statement_kind = nil
14+
end
15+
16+
def append_statement!(statement, statement_kind:)
17+
output.chomp!
18+
output << newlines_separator(
19+
previous_kind: @previous_statement_kind,
20+
current_kind: statement_kind
21+
)
22+
@previous_statement_kind = statement_kind
23+
output << statement
24+
output << "\n"
25+
end
26+
27+
private
28+
29+
def newlines_separator(previous_kind:, current_kind:)
30+
case [
31+
previous_kind,
32+
current_kind
33+
]
34+
in [
35+
nil,
36+
_
37+
]
38+
""
39+
in [
40+
_,
41+
:insert_stmt | :create_stmt | :view_stmt | :create_table_as_stmt
42+
]
43+
"\n\n\n"
44+
in [
45+
:create_stmt | :view_stmt | :create_table_as_stmt | :index_stmt,
46+
:index_stmt
47+
] | [
48+
:variable_set_stmt,
49+
:variable_set_stmt
50+
]
51+
"\n"
52+
else
53+
"\n\n"
54+
end
55+
end
56+
end
57+
end

spec/activerecord-pg-format-db-structure/deparser_spec.rb

Lines changed: 12 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@
1515
SELECT * FROM my_table WHERE 1 = 1;
1616
SQL
1717

18-
expect(formatter.format(source)).to eq(<<~SQL.chomp)
19-
20-
18+
expect(formatter.format(source)).to eq(<<~SQL)
2119
SELECT *
2220
FROM my_table
2321
WHERE 1 = 1;
@@ -29,9 +27,7 @@
2927
SELECT '1'::integer;
3028
SQL
3129

32-
expect(formatter.format(source)).to eq(<<~SQL.chomp)
33-
34-
30+
expect(formatter.format(source)).to eq(<<~SQL)
3531
SELECT '1'::int;
3632
SQL
3733
end
@@ -48,9 +44,7 @@
4844
WHERE bar > 10 OR bar < 5 OR (bar < 2 AND baz);
4945
SQL
5046

51-
expect(formatter.format(source)).to eq(<<~SQL.chomp)
52-
53-
47+
expect(formatter.format(source)).to eq(<<~SQL)
5448
SELECT sum(foo) AS column_a,
5549
CASE
5650
WHEN foo = 'a' THEN 1
@@ -71,10 +65,7 @@
7165
INSERT INTO schema_migrations (version) VALUES ('20250124155339'), ('20250134155339') , ('20250144155339');
7266
SQL
7367

74-
expect(formatter.format(source)).to eq(<<~SQL.chomp)
75-
76-
77-
68+
expect(formatter.format(source)).to eq(<<~SQL)
7869
INSERT INTO schema_migrations (version) VALUES
7970
('20250124155339')
8071
, ('20250134155339')
@@ -89,10 +80,7 @@
8980
9081
SQL
9182

92-
expect(formatter.format(source)).to eq(<<~SQL.chomp)
93-
94-
95-
83+
expect(formatter.format(source)).to eq(<<~SQL)
9684
INSERT INTO schema_migrations (version)
9785
SELECT foo
9886
FROM bar
@@ -107,8 +95,7 @@
10795
CREATE UNIQUE INDEX only_one_pending_per_comment_id ON public.my_table USING btree (comment_id) WHERE pending;
10896
SQL
10997

110-
expect(formatter.format(source)).to eq(<<~SQL.chomp)
111-
98+
expect(formatter.format(source)).to eq(<<~SQL)
11299
CREATE UNIQUE INDEX only_one_pending_per_comment_id ON public.my_table USING btree (comment_id) WHERE pending;
113100
SQL
114101
end
@@ -122,10 +109,7 @@
122109
);
123110
SQL
124111

125-
expect(formatter.format(source)).to eq(<<~SQL.chomp)
126-
127-
128-
112+
expect(formatter.format(source)).to eq(<<~SQL)
129113
-- Name: post_stats; Type: VIEW;
130114
131115
CREATE VIEW public.post_stats AS
@@ -141,10 +125,7 @@
141125
);
142126
SQL
143127

144-
expect(formatter.format(source)).to eq(<<~SQL.chomp)
145-
146-
147-
128+
expect(formatter.format(source)).to eq(<<~SQL)
148129
-- Name: post_stats; Type: VIEW;
149130
150131
CREATE VIEW public.post_stats AS
@@ -160,9 +141,7 @@
160141
SELECT * from my_cte;
161142
SQL
162143

163-
expect(formatter.format(source)).to eq(<<~SQL.chomp)
164-
165-
144+
expect(formatter.format(source)).to eq(<<~SQL)
166145
WITH my_cte AS (
167146
SELECT foo,
168147
baz
@@ -182,10 +161,7 @@
182161
);
183162
SQL
184163

185-
expect(formatter.format(source)).to eq(<<~SQL.chomp)
186-
187-
188-
164+
expect(formatter.format(source)).to eq(<<~SQL)
189165
-- Name: post_stats; Type: MATERIALIZED VIEW;
190166
191167
CREATE MATERIALIZED VIEW public.post_stats AS
@@ -201,10 +177,7 @@
201177
) WITH NO DATA;
202178
SQL
203179

204-
expect(formatter.format(source)).to eq(<<~SQL.chomp)
205-
206-
207-
180+
expect(formatter.format(source)).to eq(<<~SQL)
208181
-- Name: post_stats; Type: MATERIALIZED VIEW;
209182
210183
CREATE MATERIALIZED VIEW public.post_stats AS
@@ -250,10 +223,7 @@
250223
) main_status;
251224
SQL
252225

253-
expect(formatter.format(source)).to eq(<<~SQL.chomp)
254-
255-
256-
226+
expect(formatter.format(source)).to eq(<<~SQL)
257227
-- Name: my_bigg_aggregated_view; Type: VIEW;
258228
259229
CREATE VIEW public.my_bigg_aggregated_view AS

spec/activerecord-pg-format-db-structure/formatter_spec.rb

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -178,17 +178,13 @@
178178
('20250124155339');
179179
SQL
180180

181-
expect(formatter.format(source)).to eq(<<~SQL.chomp)
182-
183-
181+
expect(formatter.format(source)).to eq(<<~SQL)
184182
SET client_encoding TO "UTF8";
185183
186184
SELECT pg_catalog.set_config('search_path', '', false);
187185
188186
SET check_function_bodies TO TRUE;
189-
190187
SET client_min_messages TO warning;
191-
192188
SET row_security TO OFF;
193189
194190
CREATE EXTENSION IF NOT EXISTS pgcrypto SCHEMA public;

spec/activerecord-pg-format-db-structure/transforms/group_alter_table_statements_spec.rb

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,7 @@
5656
('20250124155339');
5757
SQL
5858

59-
expect(formatter.format(source)).to eq(<<~SQL.chomp)
60-
61-
62-
59+
expect(formatter.format(source)).to eq(<<~SQL)
6360
-- Name: comments; Type: TABLE;
6461
6562
CREATE TABLE public.comments (
@@ -143,10 +140,7 @@
143140
('20250124155339');
144141
SQL
145142

146-
expect(formatter.format(source)).to eq(<<~SQL.chomp)
147-
148-
149-
143+
expect(formatter.format(source)).to eq(<<~SQL)
150144
-- Name: comments; Type: TABLE;
151145
152146
CREATE TABLE public.comments (

0 commit comments

Comments
 (0)