activerecord-pg-format-db-structure 0.1.1 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +2 -11
- data/CHANGELOG.md +8 -0
- data/README.md +2 -2
- data/lib/activerecord-pg-format-db-structure/deparser.rb +41 -140
- data/lib/activerecord-pg-format-db-structure/indenter.rb +278 -0
- data/lib/activerecord-pg-format-db-structure/version.rb +1 -1
- metadata +3 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9eadcc90f7e5d8ec76f9f9494e7049646bf68ed37df502df31a1dc9fae87d2b6
|
4
|
+
data.tar.gz: bee026074f768393231546155fc52e0d00098cbdec981729a63c5a8d1efeb1c4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: efe9804695f586ea988faa923d5db83483b0a0e1395bdaaaabd3dcdbd93358d96a7c5a0f7688b5bf1512d4e14d49bf68f46c65000c9700cb3ad8ef7d63094908
|
7
|
+
data.tar.gz: dbdfa7873bd2551f2c1284befbd039c194cc87aaafea7690df8daabc84724c78a06ff3f021940204aa80cdef569566b9c81bfe4cc0aa3aa6180cb7a660e0bb21
|
data/.rubocop.yml
CHANGED
@@ -15,19 +15,10 @@ Style/StringLiteralsInInterpolation:
|
|
15
15
|
Naming/FileName:
|
16
16
|
Enabled: false
|
17
17
|
|
18
|
-
|
18
|
+
Naming/VariableNumber:
|
19
19
|
Enabled: false
|
20
20
|
|
21
|
-
Metrics
|
22
|
-
Enabled: false
|
23
|
-
|
24
|
-
Metrics/AbcSize:
|
25
|
-
Enabled: false
|
26
|
-
|
27
|
-
Metrics/ClassLength:
|
28
|
-
Enabled: false
|
29
|
-
|
30
|
-
Metrics/CyclomaticComplexity:
|
21
|
+
Metrics:
|
31
22
|
Enabled: false
|
32
23
|
|
33
24
|
RSpec/SpecFilePathFormat:
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [0.1.3] - 2025-02-02
|
4
|
+
|
5
|
+
- Rework SQL formatting by only adding indentation to deparsed statements
|
6
|
+
|
7
|
+
## [0.1.2] - 2025-01-30
|
8
|
+
|
9
|
+
- Get rid of `anbt-sql-formatter` dependency since it breaks queries with type casting
|
10
|
+
|
3
11
|
## [0.1.1] - 2025-01-29
|
4
12
|
|
5
13
|
- Proper deparsing of all statements
|
data/README.md
CHANGED
@@ -221,7 +221,7 @@ ALTER TABLE ONLY public.comments
|
|
221
221
|
|
222
222
|
|
223
223
|
INSERT INTO schema_migrations (version) VALUES
|
224
|
-
|
224
|
+
('20250124155339')
|
225
225
|
;
|
226
226
|
```
|
227
227
|
|
@@ -338,7 +338,7 @@ Should be run after other operations that inline alter statements.
|
|
338
338
|
|
339
339
|
Returns an SQL string from raw PgQuery statements.
|
340
340
|
|
341
|
-
Relying mostly on `PgQuery.deparse`,
|
341
|
+
Relying mostly on `PgQuery.deparse`, and does a best effort to add some indentation where possible.
|
342
342
|
|
343
343
|
## Development
|
344
344
|
|
@@ -1,187 +1,88 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "pg_query"
|
4
|
-
|
4
|
+
require_relative "indenter"
|
5
5
|
|
6
6
|
module ActiveRecordPgFormatDbStructure
|
7
7
|
# Returns a list of SQL strings from a list of PgQuery::RawStmt.
|
8
8
|
class Deparser
|
9
9
|
attr_reader :source
|
10
10
|
|
11
|
-
PRETTY_INDENT_STRING = " "
|
12
|
-
|
13
11
|
def initialize(source)
|
14
12
|
@source = source
|
15
13
|
end
|
16
14
|
|
17
15
|
def deparse_raw_statement(raw_statement)
|
18
16
|
case raw_statement.to_h
|
17
|
+
in stmt: { insert_stmt: _ }
|
18
|
+
deparse_insert_stmt(raw_statement.stmt.insert_stmt)
|
19
19
|
in stmt: { create_stmt: _ }
|
20
20
|
deparse_create_stmt(raw_statement.stmt.create_stmt)
|
21
|
-
in stmt: { index_stmt: _ }
|
22
|
-
deparse_index_stmt(raw_statement.stmt.index_stmt)
|
23
|
-
in stmt: { alter_table_stmt: _ }
|
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
21
|
in stmt: { view_stmt: _ }
|
32
22
|
deparse_view_stmt(raw_statement.stmt.view_stmt)
|
23
|
+
in stmt: { create_table_as_stmt: _ }
|
24
|
+
deparse_create_table_as_stmt(raw_statement.stmt.create_table_as_stmt)
|
25
|
+
in stmt: { index_stmt: _ }
|
26
|
+
deparse_stmt_compact(raw_statement.stmt.index_stmt)
|
33
27
|
else
|
34
|
-
|
28
|
+
deparse_stmt_generic(raw_statement.stmt.inner)
|
35
29
|
end
|
36
30
|
end
|
37
31
|
|
38
32
|
private
|
39
33
|
|
40
|
-
def
|
41
|
-
"\n
|
34
|
+
def deparse_stmt_generic(stmt)
|
35
|
+
generic_str = +"\n\n"
|
36
|
+
generic_str << deparse_stmt_and_indent(stmt)
|
37
|
+
generic_str << ";"
|
38
|
+
generic_str
|
42
39
|
end
|
43
40
|
|
44
|
-
def
|
45
|
-
|
46
|
-
|
47
|
-
|
41
|
+
def deparse_stmt_compact(stmt)
|
42
|
+
compact_str = +"\n"
|
43
|
+
compact_str << deparse_stmt(stmt)
|
44
|
+
compact_str << ";"
|
45
|
+
compact_str
|
48
46
|
end
|
49
47
|
|
50
|
-
def
|
51
|
-
|
48
|
+
def deparse_insert_stmt(stmt)
|
49
|
+
insert_str = +"\n\n\n"
|
50
|
+
insert_str << deparse_stmt_and_indent(stmt)
|
51
|
+
insert_str << "\n;"
|
52
|
+
insert_str
|
52
53
|
end
|
53
54
|
|
54
|
-
def
|
55
|
-
|
56
|
-
|
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
|
70
|
-
end
|
71
|
-
|
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 /, "")
|
79
|
-
end
|
80
|
-
|
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
|
-
|
91
|
-
table_str = "\n\n\n-- Name: #{create_stmt.relation.relname}; Type: TABLE;\n\n"
|
92
|
-
table_str << PgQuery.deparse_stmt(
|
93
|
-
PgQuery::CreateStmt.new(
|
94
|
-
**create_stmt.to_h,
|
95
|
-
table_elts: [placeholder_column]
|
96
|
-
)
|
97
|
-
)
|
55
|
+
def deparse_create_stmt(stmt)
|
56
|
+
table_str = "\n\n\n-- Name: #{stmt.relation.relname}; Type: TABLE;\n\n"
|
57
|
+
table_str << deparse_stmt_and_indent(stmt)
|
98
58
|
table_str << ";"
|
99
|
-
|
100
|
-
table_columns = create_stmt.table_elts.map do |elt|
|
101
|
-
"\n #{deparse_table_elt(elt)}"
|
102
|
-
end.join(",")
|
103
|
-
table_columns << "\n"
|
104
|
-
|
105
|
-
table_str[deparse_table_elt(placeholder_column)] = table_columns
|
106
|
-
|
107
59
|
table_str
|
108
60
|
end
|
109
61
|
|
110
|
-
def deparse_table_elt(elt)
|
111
|
-
PgQuery.deparse_stmt(
|
112
|
-
PgQuery::CreateStmt.new(
|
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)
|
124
|
-
)
|
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
62
|
def deparse_view_stmt(stmt)
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
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
|
63
|
+
table_str = "\n\n\n-- Name: #{stmt.view.relname}; Type: VIEW;\n\n"
|
64
|
+
table_str << deparse_stmt_and_indent(stmt)
|
65
|
+
table_str << ";"
|
66
|
+
table_str
|
152
67
|
end
|
153
68
|
|
154
|
-
def
|
155
|
-
|
156
|
-
|
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;"
|
69
|
+
def deparse_create_table_as_stmt(stmt)
|
70
|
+
table_str = "\n\n\n-- Name: #{stmt.into.rel.relname}; Type: MATERIALIZED VIEW;\n\n"
|
71
|
+
table_str << deparse_stmt_and_indent(stmt)
|
163
72
|
|
164
|
-
|
165
|
-
|
73
|
+
# couldn't find a better solution for this, but probably an OK workaround?
|
74
|
+
table_str.gsub!(/ WITH NO DATA\z/, "\nWITH NO DATA")
|
166
75
|
|
167
|
-
|
168
|
-
|
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)
|
76
|
+
table_str << ";"
|
77
|
+
table_str
|
177
78
|
end
|
178
79
|
|
179
|
-
def
|
180
|
-
|
80
|
+
def deparse_stmt_and_indent(stmt)
|
81
|
+
Indenter.new(deparse_stmt(stmt)).indent
|
181
82
|
end
|
182
83
|
|
183
|
-
def
|
184
|
-
|
84
|
+
def deparse_stmt(stmt)
|
85
|
+
PgQuery.deparse_stmt(stmt)
|
185
86
|
end
|
186
87
|
end
|
187
88
|
end
|
@@ -0,0 +1,278 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pg_query"
|
4
|
+
|
5
|
+
module ActiveRecordPgFormatDbStructure
|
6
|
+
# Inserts newlines and whitespace on a deparsed SQL string
|
7
|
+
class Indenter
|
8
|
+
Token = Data.define(:type, :string)
|
9
|
+
|
10
|
+
# Reserved Keywords
|
11
|
+
ADD = :ADD_P
|
12
|
+
ALTER = :ALTER
|
13
|
+
AND = :AND
|
14
|
+
AS = :AS
|
15
|
+
CASE = :CASE
|
16
|
+
CREATE = :CREATE
|
17
|
+
CROSS = :CROSS
|
18
|
+
DROP = :DROP
|
19
|
+
ELSE = :ELSE
|
20
|
+
END_P = :END_P
|
21
|
+
EXCEPT = :EXCEPT
|
22
|
+
FETCH = :FETCH
|
23
|
+
FOR = :FOR
|
24
|
+
FROM = :FROM
|
25
|
+
GROUP = :GROUP_P
|
26
|
+
HAVING = :HAVING
|
27
|
+
INNER = :INNER
|
28
|
+
INSERT = :INSERT
|
29
|
+
INTERSECT = :INTERSECT
|
30
|
+
JOIN = :JOIN
|
31
|
+
LEFT = :LEFT
|
32
|
+
LIMIT = :LIMIT
|
33
|
+
OFFSET = :OFFSET
|
34
|
+
OR = :OR
|
35
|
+
ORDER = :ORDER
|
36
|
+
RIGHT = :RIGHT
|
37
|
+
SELECT = :SELECT
|
38
|
+
TABLE = :TABLE
|
39
|
+
THEN = :THEN
|
40
|
+
UNION = :UNION
|
41
|
+
VALUES = :VALUES
|
42
|
+
VIEW = :VIEW
|
43
|
+
WHEN = :WHEN
|
44
|
+
WHERE = :WHERE
|
45
|
+
WHITESPACE = :WHITESPACE
|
46
|
+
WINDOW = :WINDOW
|
47
|
+
WITH = :WITH
|
48
|
+
|
49
|
+
# ASCII tokens
|
50
|
+
COMMA = :ASCII_44
|
51
|
+
OPEN_PARENS = :ASCII_40
|
52
|
+
CLOSE_PARENS = :ASCII_41
|
53
|
+
|
54
|
+
# Helpers
|
55
|
+
PARENS = :PARENS
|
56
|
+
INDENT_STRING = " "
|
57
|
+
SELECT_PADDING = " "
|
58
|
+
TABLE_ELTS = :TABLE_ELTS
|
59
|
+
|
60
|
+
attr_reader :source
|
61
|
+
|
62
|
+
def initialize(source)
|
63
|
+
@source = PgQuery.deparse(PgQuery.parse(source).tree)
|
64
|
+
end
|
65
|
+
|
66
|
+
def indent
|
67
|
+
output = Output.new
|
68
|
+
prev_token = nil
|
69
|
+
tokens.each do |token|
|
70
|
+
output.current_token = token
|
71
|
+
case { current_token: token.type, prev_token: prev_token&.type, inside: output.current_scope_type }
|
72
|
+
in { current_token: CREATE, inside: nil }
|
73
|
+
output.append_scope(type: CREATE)
|
74
|
+
output.append_token
|
75
|
+
in { current_token: ALTER, inside: nil }
|
76
|
+
output.append_scope(type: ALTER, indent: 1)
|
77
|
+
output.append_token
|
78
|
+
in { current_token: INSERT, inside: nil }
|
79
|
+
output.append_scope(type: INSERT, indent: 0)
|
80
|
+
output.append_token
|
81
|
+
in { current_token: VIEW, inside: CREATE }
|
82
|
+
output.append_scope(type: VIEW, indent: 2)
|
83
|
+
output.append_token
|
84
|
+
in { current_token: WITH, inside: CREATE | VIEW | nil }
|
85
|
+
output.append_scope(type: WITH)
|
86
|
+
output.append_token
|
87
|
+
in { current_token: WHITESPACE, prev_token: AS, inside: VIEW }
|
88
|
+
output.append_token
|
89
|
+
output.newline
|
90
|
+
output.apply_indent
|
91
|
+
in { current_token: WHITESPACE, prev_token: COMMA, inside: WITH | SELECT | TABLE_ELTS }
|
92
|
+
output.append_token
|
93
|
+
output.newline
|
94
|
+
output.apply_indent
|
95
|
+
in { current_token: COMMA, inside: INSERT }
|
96
|
+
output.newline
|
97
|
+
output.apply_indent
|
98
|
+
output.append_token
|
99
|
+
in { current_token: SELECT, inside: WITH | INSERT }
|
100
|
+
output.pop_scope
|
101
|
+
output.newline
|
102
|
+
output.apply_indent
|
103
|
+
output.append_token
|
104
|
+
output.append_scope(type: SELECT, indent: 2, padding: SELECT_PADDING)
|
105
|
+
in { current_token: SELECT }
|
106
|
+
output.append_token
|
107
|
+
output.append_scope(type: SELECT, indent: 2, padding: SELECT_PADDING)
|
108
|
+
in { current_token: ALTER | ADD | DROP, inside: ALTER }
|
109
|
+
output.newline
|
110
|
+
output.apply_indent
|
111
|
+
output.append_token
|
112
|
+
in {
|
113
|
+
current_token: CROSS | INNER | LEFT | RIGHT | JOIN => type,
|
114
|
+
inside: SELECT | FROM | JOIN
|
115
|
+
}
|
116
|
+
output.pop_scope
|
117
|
+
output.newline
|
118
|
+
output.apply_indent
|
119
|
+
output.append_token
|
120
|
+
output.append_scope(type:, indent: 0)
|
121
|
+
in {
|
122
|
+
current_token: CROSS | INNER | LEFT | RIGHT | JOIN => type,
|
123
|
+
inside: CROSS | INNER | LEFT | RIGHT
|
124
|
+
}
|
125
|
+
output.append_token
|
126
|
+
output.pop_scope
|
127
|
+
output.append_scope(type:, indent: 0)
|
128
|
+
in {
|
129
|
+
current_token: FROM | WHERE | GROUP | ORDER | WINDOW | HAVING | LIMIT | OFFSET | FETCH | FOR | UNION |
|
130
|
+
INTERSECT | EXCEPT => token_type
|
131
|
+
}
|
132
|
+
output.pop_scope
|
133
|
+
output.newline
|
134
|
+
output.apply_indent
|
135
|
+
output.append_token
|
136
|
+
output.append_scope(type: token_type, indent: 1)
|
137
|
+
in { current_token: OR | AND, inside: WHERE }
|
138
|
+
output.newline
|
139
|
+
output.apply_indent
|
140
|
+
output.append_token(rjust: 3)
|
141
|
+
in { current_token: CASE }
|
142
|
+
output.append_token
|
143
|
+
output.append_scope(type: CASE, indent: 1, padding: output.current_padding)
|
144
|
+
in { current_token: WHEN | ELSE, inside: CASE }
|
145
|
+
output.newline
|
146
|
+
output.apply_indent
|
147
|
+
output.append_token
|
148
|
+
in { current_token: END_P }
|
149
|
+
output.pop_scope
|
150
|
+
output.newline
|
151
|
+
output.apply_indent
|
152
|
+
output.append_token
|
153
|
+
in { current_token: VALUES, inside: INSERT }
|
154
|
+
output.append_token
|
155
|
+
output.newline
|
156
|
+
output.append_whitespace
|
157
|
+
in { current_token: OPEN_PARENS, inside: CREATE }
|
158
|
+
output.append_token
|
159
|
+
output.newline
|
160
|
+
output.append_scope(type: TABLE_ELTS, indent: 2)
|
161
|
+
output.apply_indent
|
162
|
+
in { current_token: OPEN_PARENS, inside: WITH }
|
163
|
+
output.append_token
|
164
|
+
output.newline
|
165
|
+
output.append_scope(type: PARENS, indent: 2)
|
166
|
+
output.apply_indent
|
167
|
+
in { current_token: OPEN_PARENS, inside: JOIN }
|
168
|
+
output.append_token
|
169
|
+
output.newline
|
170
|
+
output.append_scope(type: PARENS, indent: 2)
|
171
|
+
output.apply_indent
|
172
|
+
in { current_token: OPEN_PARENS }
|
173
|
+
output.append_scope(type: PARENS)
|
174
|
+
output.append_token
|
175
|
+
in { current_token: CLOSE_PARENS, inside: TABLE_ELTS }
|
176
|
+
output.pop_scope
|
177
|
+
output.newline
|
178
|
+
output.apply_indent
|
179
|
+
output.append_token
|
180
|
+
in { current_token: CLOSE_PARENS, inside: PARENS }
|
181
|
+
output.pop_scope
|
182
|
+
output.append_token
|
183
|
+
in { current_token: CLOSE_PARENS }
|
184
|
+
loop do
|
185
|
+
break if output.pop_scope in PARENS | nil
|
186
|
+
end
|
187
|
+
output.newline
|
188
|
+
output.apply_indent
|
189
|
+
output.append_token
|
190
|
+
else
|
191
|
+
output.append_token
|
192
|
+
end
|
193
|
+
prev_token = token
|
194
|
+
end
|
195
|
+
output.to_s
|
196
|
+
end
|
197
|
+
|
198
|
+
private
|
199
|
+
|
200
|
+
def tokens
|
201
|
+
tmp_tokens = []
|
202
|
+
prev_token = Data.define(:end).new(0)
|
203
|
+
PgQuery.scan(source).first.tokens.each do |token|
|
204
|
+
if prev_token.end != token.start
|
205
|
+
tmp_tokens << Token.new(
|
206
|
+
type: WHITESPACE,
|
207
|
+
string: " "
|
208
|
+
)
|
209
|
+
end
|
210
|
+
prev_token = token
|
211
|
+
tmp_tokens << Token.new(
|
212
|
+
type: token.token,
|
213
|
+
string: source[token.start...token.end]
|
214
|
+
)
|
215
|
+
end
|
216
|
+
tmp_tokens
|
217
|
+
end
|
218
|
+
|
219
|
+
# Wrapper that ensures we only append whitespace, and always
|
220
|
+
# append the current token exactly once for each loop.
|
221
|
+
class Output
|
222
|
+
Scope = Data.define(:type, :indent, :padding)
|
223
|
+
|
224
|
+
def initialize
|
225
|
+
@string = +""
|
226
|
+
@scopes = [Scope.new(type: nil, indent: 0, padding: "")]
|
227
|
+
@current_token = nil
|
228
|
+
end
|
229
|
+
|
230
|
+
def to_s
|
231
|
+
# clean extra whitespace at end of string
|
232
|
+
@string.gsub(/\s+\n/, "\n").freeze
|
233
|
+
end
|
234
|
+
|
235
|
+
def current_scope_type
|
236
|
+
@scopes.last.type
|
237
|
+
end
|
238
|
+
|
239
|
+
def current_token=(token)
|
240
|
+
raise "Previous token was not appended!" unless @current_token.nil?
|
241
|
+
|
242
|
+
@current_token = token
|
243
|
+
end
|
244
|
+
|
245
|
+
def append_scope(type:, indent: 0, padding: "")
|
246
|
+
@scopes << Scope.new(type:, indent:, padding:)
|
247
|
+
end
|
248
|
+
|
249
|
+
def current_padding
|
250
|
+
@scopes.last.padding
|
251
|
+
end
|
252
|
+
|
253
|
+
def pop_scope
|
254
|
+
@scopes.pop.type
|
255
|
+
end
|
256
|
+
|
257
|
+
def newline
|
258
|
+
@string << "\n"
|
259
|
+
end
|
260
|
+
|
261
|
+
def append_whitespace
|
262
|
+
@string << " "
|
263
|
+
end
|
264
|
+
|
265
|
+
def apply_indent
|
266
|
+
@string << (INDENT_STRING * @scopes.sum(&:indent))
|
267
|
+
@string << @scopes.last.padding
|
268
|
+
end
|
269
|
+
|
270
|
+
def append_token(rjust: 0)
|
271
|
+
raise "Token was already appended!" if @current_token.nil?
|
272
|
+
|
273
|
+
@string << @current_token.string.rjust(rjust)
|
274
|
+
@current_token = nil
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|
metadata
CHANGED
@@ -1,28 +1,14 @@
|
|
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.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jell
|
8
8
|
bindir: exe
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-
|
10
|
+
date: 2025-02-02 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'
|
26
12
|
- !ruby/object:Gem::Dependency
|
27
13
|
name: pg_query
|
28
14
|
requirement: !ruby/object:Gem::Requirement
|
@@ -55,6 +41,7 @@ files:
|
|
55
41
|
- lib/activerecord-pg-format-db-structure.rb
|
56
42
|
- lib/activerecord-pg-format-db-structure/deparser.rb
|
57
43
|
- lib/activerecord-pg-format-db-structure/formatter.rb
|
44
|
+
- lib/activerecord-pg-format-db-structure/indenter.rb
|
58
45
|
- lib/activerecord-pg-format-db-structure/preprocessors/remove_whitespaces.rb
|
59
46
|
- lib/activerecord-pg-format-db-structure/railtie.rb
|
60
47
|
- lib/activerecord-pg-format-db-structure/tasks/clean_db_structure.rake
|