activerecord-pg-format-db-structure 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +6 -0
- data/CHANGELOG.md +5 -0
- data/README.md +8 -10
- data/lib/activerecord-pg-format-db-structure/deparser.rb +130 -19
- data/lib/activerecord-pg-format-db-structure/transforms/base.rb +16 -0
- data/lib/activerecord-pg-format-db-structure/transforms/group_alter_table_statements.rb +2 -8
- data/lib/activerecord-pg-format-db-structure/transforms/inline_constraints.rb +11 -16
- data/lib/activerecord-pg-format-db-structure/transforms/inline_foreign_keys.rb +11 -16
- data/lib/activerecord-pg-format-db-structure/transforms/inline_primary_keys.rb +9 -16
- data/lib/activerecord-pg-format-db-structure/transforms/inline_serials.rb +18 -23
- data/lib/activerecord-pg-format-db-structure/transforms/move_indices_after_create_table.rb +2 -8
- data/lib/activerecord-pg-format-db-structure/transforms/remove_comments_on_extensions.rb +2 -8
- data/lib/activerecord-pg-format-db-structure/version.rb +1 -1
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0f52ec941c9e147d32ce581a4e5384263455ca48295539f0d3a2b518cc7e4e51
|
4
|
+
data.tar.gz: 1ab211061fe2fca72d364dc8b92636e01c294ad4efddbd684a1a2b1b072d02a8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 87322b447a211cce08c5beebf137ca7a5da4947f0a01f37192978ea6a873d6f990201450ae3764501cccaa04667089b595bce39829d544e417ee7a9426d8ca5d
|
7
|
+
data.tar.gz: 27ebd693ed145add5112b35805c94e06b4f6f32e03419ffc92c62187116e3ec93d02694b0c67abf153e5a8582643989c2831e74b00f002b5758ba3fc7f6f7c5f
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -182,9 +182,9 @@ INSERT INTO "schema_migrations" (version) VALUES
|
|
182
182
|
into this much more compact and normalized version:
|
183
183
|
|
184
184
|
```sql
|
185
|
-
-- Name: pgcrypto; Type: EXTENSION
|
186
185
|
|
187
|
-
|
186
|
+
|
187
|
+
CREATE EXTENSION IF NOT EXISTS pgcrypto SCHEMA public;
|
188
188
|
|
189
189
|
|
190
190
|
-- Name: comments; Type: TABLE;
|
@@ -219,8 +219,10 @@ ALTER TABLE ONLY public.comments
|
|
219
219
|
ADD CONSTRAINT fk_rails_0000000001 FOREIGN KEY (post_id) REFERENCES public.posts (id),
|
220
220
|
ADD CONSTRAINT fk_rails_0000000002 FOREIGN KEY (user_id) REFERENCES public.users (id);
|
221
221
|
|
222
|
-
|
223
|
-
(
|
222
|
+
|
223
|
+
INSERT INTO schema_migrations (version) VALUES
|
224
|
+
('20250124155339')
|
225
|
+
;
|
224
226
|
```
|
225
227
|
|
226
228
|
which is a lot more compact, easier to read, and reduces the risk of
|
@@ -334,13 +336,9 @@ Should be run after other operations that inline alter statements.
|
|
334
336
|
|
335
337
|
## Deparser
|
336
338
|
|
337
|
-
|
338
|
-
|
339
|
-
As of now, it will only deparse `CREATE TABLE`, `CREATE INDEX` and
|
340
|
-
`ALTER TABLE` statements. Other statements will be kept unchanged from
|
341
|
-
the input SQL.
|
339
|
+
Returns an SQL string from raw PgQuery statements.
|
342
340
|
|
343
|
-
|
341
|
+
Relying mostly on `PgQuery.deparse`, but applying some formatting using the [anbt-sql-formatter](https://github.com/sonota88/anbt-sql-formatter) gem on select & insert statements.
|
344
342
|
|
345
343
|
## Development
|
346
344
|
|
@@ -1,12 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "pg_query"
|
4
|
+
require "anbt-sql-formatter/formatter"
|
4
5
|
|
5
6
|
module ActiveRecordPgFormatDbStructure
|
6
7
|
# Returns a list of SQL strings from a list of PgQuery::RawStmt.
|
7
8
|
class Deparser
|
8
9
|
attr_reader :source
|
9
10
|
|
11
|
+
PRETTY_INDENT_STRING = " "
|
12
|
+
|
10
13
|
def initialize(source)
|
11
14
|
@source = source
|
12
15
|
end
|
@@ -19,17 +22,29 @@ module ActiveRecordPgFormatDbStructure
|
|
19
22
|
deparse_index_stmt(raw_statement.stmt.index_stmt)
|
20
23
|
in stmt: { alter_table_stmt: _ }
|
21
24
|
deparse_alter_table_stmt(raw_statement.stmt.alter_table_stmt)
|
25
|
+
in stmt: { select_stmt: _ }
|
26
|
+
deparse_query_statement(raw_statement.stmt.select_stmt)
|
27
|
+
in stmt: { insert_stmt: _ }
|
28
|
+
deparse_insert_statement(raw_statement.stmt.insert_stmt)
|
29
|
+
in stmt: { create_table_as_stmt: _ }
|
30
|
+
deparse_create_table_as_stmt(raw_statement.stmt.create_table_as_stmt)
|
31
|
+
in stmt: { view_stmt: _ }
|
32
|
+
deparse_view_stmt(raw_statement.stmt.view_stmt)
|
22
33
|
else
|
23
|
-
|
34
|
+
"\n#{deparse_stmt(raw_statement.stmt.inner)}"
|
24
35
|
end
|
25
36
|
end
|
26
37
|
|
27
38
|
private
|
28
39
|
|
29
|
-
def
|
30
|
-
|
31
|
-
|
32
|
-
|
40
|
+
def deparse_stmt(stmt)
|
41
|
+
"\n#{PgQuery.deparse_stmt(stmt)};"
|
42
|
+
end
|
43
|
+
|
44
|
+
def deparse_query_statement(stmt)
|
45
|
+
generic_query_str = +"\n\n"
|
46
|
+
generic_query_str << pretty_formt_sql_string(PgQuery.deparse_stmt(stmt))
|
47
|
+
generic_query_str << ";"
|
33
48
|
end
|
34
49
|
|
35
50
|
def deparse_index_stmt(index_stmt)
|
@@ -37,40 +52,136 @@ module ActiveRecordPgFormatDbStructure
|
|
37
52
|
end
|
38
53
|
|
39
54
|
def deparse_alter_table_stmt(alter_table_stmt)
|
40
|
-
"\n
|
41
|
-
|
42
|
-
|
43
|
-
.
|
44
|
-
|
55
|
+
alter_table_str = +"\n\n"
|
56
|
+
alter_table_str << PgQuery.deparse_stmt(
|
57
|
+
PgQuery::AlterTableStmt.new(
|
58
|
+
**alter_table_stmt.to_h,
|
59
|
+
cmds: []
|
60
|
+
)
|
61
|
+
).chomp(" ")
|
62
|
+
|
63
|
+
alter_table_cmds_str = alter_table_stmt.cmds.map do |cmd|
|
64
|
+
"\n #{deparse_alter_table_cmd(cmd)}"
|
65
|
+
end.join(",")
|
66
|
+
|
67
|
+
alter_table_str << alter_table_cmds_str
|
68
|
+
alter_table_str << ";"
|
69
|
+
alter_table_str
|
45
70
|
end
|
46
71
|
|
47
|
-
def
|
48
|
-
|
72
|
+
def deparse_alter_table_cmd(cmd)
|
73
|
+
PgQuery.deparse_stmt(
|
74
|
+
PgQuery::AlterTableStmt.new(
|
75
|
+
relation: { relname: "tmp" },
|
76
|
+
cmds: [cmd]
|
77
|
+
)
|
78
|
+
).gsub(/\AALTER ONLY tmp /, "")
|
49
79
|
end
|
50
80
|
|
51
81
|
def deparse_create_stmt(create_stmt)
|
82
|
+
placeholder_column = PgQuery::Node.from(
|
83
|
+
PgQuery::ColumnDef.new(
|
84
|
+
colname: "placeholder_column",
|
85
|
+
type_name: {
|
86
|
+
names: [PgQuery::Node.from_string("placeholder_type")]
|
87
|
+
}
|
88
|
+
)
|
89
|
+
)
|
90
|
+
|
52
91
|
table_str = "\n\n\n-- Name: #{create_stmt.relation.relname}; Type: TABLE;\n\n"
|
53
92
|
table_str << PgQuery.deparse_stmt(
|
54
93
|
PgQuery::CreateStmt.new(
|
55
94
|
**create_stmt.to_h,
|
56
|
-
table_elts: []
|
95
|
+
table_elts: [placeholder_column]
|
57
96
|
)
|
58
97
|
)
|
59
|
-
table_str
|
60
|
-
|
61
|
-
|
98
|
+
table_str << ";"
|
99
|
+
|
100
|
+
table_columns = create_stmt.table_elts.map do |elt|
|
62
101
|
"\n #{deparse_table_elt(elt)}"
|
63
102
|
end.join(",")
|
64
|
-
|
103
|
+
table_columns << "\n"
|
104
|
+
|
105
|
+
table_str[deparse_table_elt(placeholder_column)] = table_columns
|
106
|
+
|
65
107
|
table_str
|
66
108
|
end
|
67
109
|
|
68
110
|
def deparse_table_elt(elt)
|
69
111
|
PgQuery.deparse_stmt(
|
70
112
|
PgQuery::CreateStmt.new(
|
71
|
-
relation:
|
113
|
+
relation: { relname: "tmp" }, table_elts: [elt]
|
114
|
+
)
|
115
|
+
).gsub(/\ACREATE TABLE ONLY tmp \((.*)\)\z/, '\1')
|
116
|
+
end
|
117
|
+
|
118
|
+
def deparse_create_table_as_stmt(stmt)
|
119
|
+
create_table_as_stmt_str = +"\n\n"
|
120
|
+
create_table_as_stmt_str << PgQuery.deparse_stmt(
|
121
|
+
PgQuery::CreateTableAsStmt.new(
|
122
|
+
**stmt.to_h,
|
123
|
+
query: PgQuery::Node.from(placeholder_query_stmt)
|
72
124
|
)
|
73
|
-
)
|
125
|
+
)
|
126
|
+
create_table_as_stmt_str << ";"
|
127
|
+
|
128
|
+
query_str = +"(\n"
|
129
|
+
query_str << pretty_formt_sql_string(PgQuery.deparse_stmt(stmt.query.inner)).gsub(/^/, PRETTY_INDENT_STRING)
|
130
|
+
query_str << "\n)"
|
131
|
+
|
132
|
+
create_table_as_stmt_str[placeholder_query_string] = query_str
|
133
|
+
create_table_as_stmt_str
|
134
|
+
end
|
135
|
+
|
136
|
+
def deparse_view_stmt(stmt)
|
137
|
+
view_stmt_str = +"\n\n"
|
138
|
+
view_stmt_str << PgQuery.deparse_stmt(
|
139
|
+
PgQuery::ViewStmt.new(
|
140
|
+
**stmt.to_h,
|
141
|
+
query: PgQuery::Node.from(placeholder_query_stmt)
|
142
|
+
)
|
143
|
+
)
|
144
|
+
view_stmt_str << ";"
|
145
|
+
|
146
|
+
query_str = +"(\n"
|
147
|
+
query_str << pretty_formt_sql_string(PgQuery.deparse_stmt(stmt.query.inner)).gsub(/^/, PRETTY_INDENT_STRING)
|
148
|
+
query_str << "\n)"
|
149
|
+
|
150
|
+
view_stmt_str[placeholder_query_string] = query_str
|
151
|
+
view_stmt_str
|
152
|
+
end
|
153
|
+
|
154
|
+
def deparse_insert_statement(insert_stmt)
|
155
|
+
insert_stmt_str = +"\n\n\n"
|
156
|
+
insert_stmt_str << PgQuery.deparse_stmt(
|
157
|
+
PgQuery::InsertStmt.new(
|
158
|
+
**insert_stmt.to_h,
|
159
|
+
select_stmt: PgQuery::Node.from(placeholder_query_stmt)
|
160
|
+
)
|
161
|
+
)
|
162
|
+
insert_stmt_str << "\n;"
|
163
|
+
|
164
|
+
query_str = pretty_formt_sql_string(PgQuery.deparse_stmt(insert_stmt.select_stmt.inner))
|
165
|
+
query_str.gsub!(/\AVALUES /, "VALUES\n ")
|
166
|
+
|
167
|
+
insert_stmt_str[placeholder_query_string] = query_str
|
168
|
+
insert_stmt_str
|
169
|
+
end
|
170
|
+
|
171
|
+
def pretty_formt_sql_string(sql)
|
172
|
+
rule = AnbtSql::Rule.new
|
173
|
+
rule.keyword = AnbtSql::Rule::KEYWORD_UPPER_CASE
|
174
|
+
rule.indent_string = PRETTY_INDENT_STRING
|
175
|
+
formatter = AnbtSql::Formatter.new(rule)
|
176
|
+
formatter.format(sql)
|
177
|
+
end
|
178
|
+
|
179
|
+
def placeholder_query_string
|
180
|
+
@placeholder_query_string ||= PgQuery.deparse_stmt(placeholder_query_stmt)
|
181
|
+
end
|
182
|
+
|
183
|
+
def placeholder_query_stmt
|
184
|
+
@placeholder_query_stmt ||= PgQuery.parse("SELECT placeholder").tree.stmts.first.stmt.select_stmt
|
74
185
|
end
|
75
186
|
end
|
76
187
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pg_query"
|
4
|
+
|
5
|
+
module ActiveRecordPgFormatDbStructure
|
6
|
+
module Transforms
|
7
|
+
# :nodoc:
|
8
|
+
class Base
|
9
|
+
attr_reader :raw_statements
|
10
|
+
|
11
|
+
def initialize(raw_statements)
|
12
|
+
@raw_statements = raw_statements
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -1,18 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require_relative "base"
|
4
4
|
|
5
5
|
module ActiveRecordPgFormatDbStructure
|
6
6
|
module Transforms
|
7
7
|
# Group alter table statements into one operation per
|
8
8
|
# table. Should be run after other operations that inline alter statements.
|
9
|
-
class GroupAlterTableStatements
|
10
|
-
attr_reader :raw_statements
|
11
|
-
|
12
|
-
def initialize(raw_statements)
|
13
|
-
@raw_statements = raw_statements
|
14
|
-
end
|
15
|
-
|
9
|
+
class GroupAlterTableStatements < Base
|
16
10
|
def transform!
|
17
11
|
alter_groups = extract_alter_table_statements!
|
18
12
|
|
@@ -1,27 +1,20 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require_relative "base"
|
4
4
|
|
5
5
|
module ActiveRecordPgFormatDbStructure
|
6
6
|
module Transforms
|
7
7
|
# Inline non-foreign key constraints into table declaration
|
8
|
-
class InlineConstraints
|
9
|
-
attr_reader :raw_statements
|
10
|
-
|
11
|
-
def initialize(raw_statements)
|
12
|
-
@raw_statements = raw_statements
|
13
|
-
@tables_with_constraint = {}
|
14
|
-
end
|
15
|
-
|
8
|
+
class InlineConstraints < Base
|
16
9
|
def transform!
|
17
|
-
extract_constraints_to_inline!
|
10
|
+
tables_with_constraint = extract_constraints_to_inline!
|
18
11
|
raw_statements.each do |raw_statement|
|
19
12
|
next unless raw_statement.stmt.to_h in create_stmt: { relation: { schemaname:, relname: }}
|
20
13
|
|
21
14
|
relation = { schemaname:, relname: }
|
22
|
-
next unless
|
15
|
+
next unless tables_with_constraint.include?(relation)
|
23
16
|
|
24
|
-
|
17
|
+
tables_with_constraint[relation].each do |constraint|
|
25
18
|
add_constraint!(raw_statement, constraint)
|
26
19
|
end
|
27
20
|
end
|
@@ -30,14 +23,16 @@ module ActiveRecordPgFormatDbStructure
|
|
30
23
|
private
|
31
24
|
|
32
25
|
def extract_constraints_to_inline!
|
26
|
+
tables_with_constraint = {}
|
33
27
|
raw_statements.delete_if do |raw_statement|
|
34
28
|
next unless match_alter_column_statement(raw_statement) in { table:, constraint: }
|
35
29
|
|
36
|
-
|
37
|
-
|
30
|
+
tables_with_constraint[table] ||= []
|
31
|
+
tables_with_constraint[table] << constraint
|
38
32
|
|
39
33
|
true
|
40
34
|
end
|
35
|
+
tables_with_constraint
|
41
36
|
end
|
42
37
|
|
43
38
|
def match_alter_column_statement(raw_statement)
|
@@ -68,8 +63,8 @@ module ActiveRecordPgFormatDbStructure
|
|
68
63
|
end
|
69
64
|
|
70
65
|
def add_constraint!(raw_statement, constraint)
|
71
|
-
raw_statement.stmt.create_stmt.table_elts << PgQuery::Node.
|
72
|
-
|
66
|
+
raw_statement.stmt.create_stmt.table_elts << PgQuery::Node.from(
|
67
|
+
PgQuery::Constraint.new(constraint)
|
73
68
|
)
|
74
69
|
end
|
75
70
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require_relative "base"
|
4
4
|
|
5
5
|
module ActiveRecordPgFormatDbStructure
|
6
6
|
module Transforms
|
@@ -9,23 +9,16 @@ module ActiveRecordPgFormatDbStructure
|
|
9
9
|
# Note: using this transform makes the structure file no longer
|
10
10
|
# loadable, since tables should be created before a foreign key
|
11
11
|
# can target it.
|
12
|
-
class InlineForeignKeys
|
13
|
-
attr_reader :raw_statements
|
14
|
-
|
15
|
-
def initialize(raw_statements)
|
16
|
-
@raw_statements = raw_statements
|
17
|
-
@columns_with_foreign_key = {}
|
18
|
-
end
|
19
|
-
|
12
|
+
class InlineForeignKeys < Base
|
20
13
|
def transform!
|
21
|
-
extract_foreign_keys_to_inline!
|
14
|
+
columns_with_foreign_key = extract_foreign_keys_to_inline!
|
22
15
|
raw_statements.each do |raw_statement|
|
23
16
|
next unless raw_statement.stmt.to_h in create_stmt: { relation: { schemaname:, relname: }}
|
24
17
|
|
25
18
|
relation = { schemaname:, relname: }
|
26
|
-
next unless
|
19
|
+
next unless columns_with_foreign_key.include?(relation)
|
27
20
|
|
28
|
-
|
21
|
+
columns_with_foreign_key[relation].each do |column_name, constraint|
|
29
22
|
add_constraint!(raw_statement, column_name, constraint)
|
30
23
|
end
|
31
24
|
end
|
@@ -34,15 +27,17 @@ module ActiveRecordPgFormatDbStructure
|
|
34
27
|
private
|
35
28
|
|
36
29
|
def extract_foreign_keys_to_inline!
|
30
|
+
columns_with_foreign_key = {}
|
37
31
|
raw_statements.delete_if do |raw_statement|
|
38
32
|
next unless match_alter_column_statement(raw_statement) in { column:, constraint: }
|
39
33
|
|
40
34
|
table = column.except(:colname)
|
41
|
-
|
42
|
-
|
35
|
+
columns_with_foreign_key[table] ||= {}
|
36
|
+
columns_with_foreign_key[table][column[:colname]] = constraint
|
43
37
|
|
44
38
|
true
|
45
39
|
end
|
40
|
+
columns_with_foreign_key
|
46
41
|
end
|
47
42
|
|
48
43
|
def match_alter_column_statement(raw_statement)
|
@@ -99,8 +94,8 @@ module ActiveRecordPgFormatDbStructure
|
|
99
94
|
raw_statement.stmt.create_stmt.table_elts.each do |table_elt|
|
100
95
|
next unless table_elt.to_h in { column_def: { colname: ^colname } }
|
101
96
|
|
102
|
-
table_elt.column_def.constraints << PgQuery::Node.
|
103
|
-
|
97
|
+
table_elt.column_def.constraints << PgQuery::Node.from(
|
98
|
+
PgQuery::Constraint.new(constraint)
|
104
99
|
)
|
105
100
|
end
|
106
101
|
end
|
@@ -1,25 +1,18 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require_relative "base"
|
4
4
|
|
5
5
|
module ActiveRecordPgFormatDbStructure
|
6
6
|
module Transforms
|
7
7
|
# Inlines primary keys with the table declaration
|
8
|
-
class InlinePrimaryKeys
|
9
|
-
attr_reader :raw_statements
|
10
|
-
|
11
|
-
def initialize(raw_statements)
|
12
|
-
@raw_statements = raw_statements
|
13
|
-
@columns_with_primary_key = {}
|
14
|
-
end
|
15
|
-
|
8
|
+
class InlinePrimaryKeys < Base
|
16
9
|
def transform!
|
17
|
-
extract_primary_keys_to_inline!
|
10
|
+
columns_with_primary_key = extract_primary_keys_to_inline!
|
18
11
|
raw_statements.each do |raw_statement|
|
19
12
|
next unless raw_statement.stmt.to_h in create_stmt: { relation: { schemaname:, relname: }}
|
20
13
|
|
21
14
|
relation = { schemaname:, relname: }
|
22
|
-
primary_key =
|
15
|
+
primary_key = columns_with_primary_key[relation]
|
23
16
|
add_primary_key!(raw_statement, primary_key) if primary_key
|
24
17
|
end
|
25
18
|
end
|
@@ -27,15 +20,17 @@ module ActiveRecordPgFormatDbStructure
|
|
27
20
|
private
|
28
21
|
|
29
22
|
def extract_primary_keys_to_inline!
|
23
|
+
columns_with_primary_key = {}
|
30
24
|
raw_statements.delete_if do |raw_statement|
|
31
25
|
next unless match_alter_column_statement(raw_statement) in { schemaname:, relname:, colname: }
|
32
26
|
|
33
27
|
column = { schemaname:, relname:, colname: }
|
34
28
|
table = column.except(:colname)
|
35
|
-
|
29
|
+
columns_with_primary_key[table] = column[:colname]
|
36
30
|
|
37
31
|
true
|
38
32
|
end
|
33
|
+
columns_with_primary_key
|
39
34
|
end
|
40
35
|
|
41
36
|
def match_alter_column_statement(raw_statement)
|
@@ -73,10 +68,8 @@ module ActiveRecordPgFormatDbStructure
|
|
73
68
|
c.to_h in { constraint: { contype: :CONSTR_NOTNULL } }
|
74
69
|
end
|
75
70
|
|
76
|
-
table_elt.column_def.constraints << PgQuery::Node.
|
77
|
-
|
78
|
-
contype: :CONSTR_PRIMARY
|
79
|
-
)
|
71
|
+
table_elt.column_def.constraints << PgQuery::Node.from(
|
72
|
+
PgQuery::Constraint.new(contype: :CONSTR_PRIMARY)
|
80
73
|
)
|
81
74
|
end
|
82
75
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require_relative "base"
|
4
4
|
|
5
5
|
module ActiveRecordPgFormatDbStructure
|
6
6
|
module Transforms
|
@@ -13,25 +13,17 @@ module ActiveRecordPgFormatDbStructure
|
|
13
13
|
# It also assumes that the associated sequence has default settings. A
|
14
14
|
# later version could try to be more strict / validate that the
|
15
15
|
# sequence indeed has default settings.
|
16
|
-
class InlineSerials
|
17
|
-
attr_reader :raw_statements
|
18
|
-
|
19
|
-
def initialize(raw_statements)
|
20
|
-
@raw_statements = raw_statements
|
21
|
-
@columns_to_replace_with_serial = {}
|
22
|
-
@sequences_to_remove = Set.new
|
23
|
-
end
|
24
|
-
|
16
|
+
class InlineSerials < Base
|
25
17
|
def transform!
|
26
|
-
extract_serials_to_inline!
|
27
|
-
delete_redundant_statements!
|
18
|
+
extract_serials_to_inline! => columns_to_replace_with_serial:, sequences_to_remove:
|
19
|
+
delete_redundant_statements!(sequences_to_remove)
|
28
20
|
raw_statements.each do |raw_statement|
|
29
21
|
next unless raw_statement.stmt.to_h in create_stmt: { relation: { schemaname:, relname: }}
|
30
22
|
|
31
23
|
relation = { schemaname:, relname: }
|
32
|
-
next unless
|
24
|
+
next unless columns_to_replace_with_serial.include?(relation)
|
33
25
|
|
34
|
-
|
26
|
+
columns_to_replace_with_serial[relation].each do |colname|
|
35
27
|
replace_id_with_serial!(raw_statement, colname)
|
36
28
|
end
|
37
29
|
end
|
@@ -40,16 +32,19 @@ module ActiveRecordPgFormatDbStructure
|
|
40
32
|
private
|
41
33
|
|
42
34
|
def extract_serials_to_inline!
|
35
|
+
columns_to_replace_with_serial = {}
|
36
|
+
sequences_to_remove = Set.new
|
43
37
|
raw_statements.delete_if do |raw_statement|
|
44
38
|
next unless match_alter_column_statement(raw_statement) in { column:, sequence: }
|
45
39
|
|
46
40
|
table = column.except(:column_name)
|
47
|
-
|
48
|
-
|
49
|
-
|
41
|
+
columns_to_replace_with_serial[table] ||= []
|
42
|
+
columns_to_replace_with_serial[table] << column[:column_name]
|
43
|
+
sequences_to_remove << sequence
|
50
44
|
|
51
45
|
true
|
52
46
|
end
|
47
|
+
{ columns_to_replace_with_serial:, sequences_to_remove: }
|
53
48
|
end
|
54
49
|
|
55
50
|
def match_alter_column_statement(raw_statement)
|
@@ -107,21 +102,21 @@ module ActiveRecordPgFormatDbStructure
|
|
107
102
|
|
108
103
|
table_elt.column_def.type_name = PgQuery::TypeName.new(
|
109
104
|
names: [
|
110
|
-
PgQuery::Node.
|
111
|
-
|
112
|
-
)
|
105
|
+
PgQuery::Node.from_string(
|
106
|
+
COLUMN_TYPE_TO_SERIAL_TYPE.fetch(integer_type)
|
107
|
+
)
|
113
108
|
]
|
114
109
|
)
|
115
110
|
end
|
116
111
|
end
|
117
112
|
|
118
|
-
def delete_redundant_statements!
|
113
|
+
def delete_redundant_statements!(sequences_to_remove)
|
119
114
|
raw_statements.delete_if do |raw_statement|
|
120
115
|
case raw_statement.stmt.to_h
|
121
116
|
in create_seq_stmt: { sequence: { schemaname:, relname: }}
|
122
|
-
|
117
|
+
sequences_to_remove.include?({ schemaname:, relname: })
|
123
118
|
in alter_seq_stmt: {sequence: { schemaname:, relname: }}
|
124
|
-
|
119
|
+
sequences_to_remove.include?({ schemaname:, relname: })
|
125
120
|
else
|
126
121
|
false
|
127
122
|
end
|
@@ -1,17 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require_relative "base"
|
4
4
|
|
5
5
|
module ActiveRecordPgFormatDbStructure
|
6
6
|
module Transforms
|
7
7
|
# Move indice declaration just below the table they index
|
8
|
-
class MoveIndicesAfterCreateTable
|
9
|
-
attr_reader :raw_statements
|
10
|
-
|
11
|
-
def initialize(raw_statements)
|
12
|
-
@raw_statements = raw_statements
|
13
|
-
end
|
14
|
-
|
8
|
+
class MoveIndicesAfterCreateTable < Base
|
15
9
|
def transform!
|
16
10
|
extract_table_indices!.each do |table, indices|
|
17
11
|
insert_index = find_insert_index(**table)
|
@@ -1,17 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require_relative "base"
|
4
4
|
|
5
5
|
module ActiveRecordPgFormatDbStructure
|
6
6
|
module Transforms
|
7
7
|
# Remove COMMENT statement applied to extensions
|
8
|
-
class RemoveCommentsOnExtensions
|
9
|
-
attr_reader :raw_statements
|
10
|
-
|
11
|
-
def initialize(raw_statements)
|
12
|
-
@raw_statements = raw_statements
|
13
|
-
end
|
14
|
-
|
8
|
+
class RemoveCommentsOnExtensions < Base
|
15
9
|
def transform!
|
16
10
|
raw_statements.delete_if do |raw_statement|
|
17
11
|
raw_statement.stmt.to_h in {
|
metadata
CHANGED
@@ -1,14 +1,28 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord-pg-format-db-structure
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jell
|
8
8
|
bindir: exe
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-01-
|
10
|
+
date: 2025-01-29 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
|
+
- !ruby/object:Gem::Dependency
|
13
|
+
name: anbt-sql-formatter
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - "~>"
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: '0.1'
|
19
|
+
type: :runtime
|
20
|
+
prerelease: false
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - "~>"
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: '0.1'
|
12
26
|
- !ruby/object:Gem::Dependency
|
13
27
|
name: pg_query
|
14
28
|
requirement: !ruby/object:Gem::Requirement
|
@@ -44,6 +58,7 @@ files:
|
|
44
58
|
- lib/activerecord-pg-format-db-structure/preprocessors/remove_whitespaces.rb
|
45
59
|
- lib/activerecord-pg-format-db-structure/railtie.rb
|
46
60
|
- lib/activerecord-pg-format-db-structure/tasks/clean_db_structure.rake
|
61
|
+
- lib/activerecord-pg-format-db-structure/transforms/base.rb
|
47
62
|
- lib/activerecord-pg-format-db-structure/transforms/group_alter_table_statements.rb
|
48
63
|
- lib/activerecord-pg-format-db-structure/transforms/inline_constraints.rb
|
49
64
|
- lib/activerecord-pg-format-db-structure/transforms/inline_foreign_keys.rb
|