activerecord-pg-format-db-structure 0.1.1 → 0.1.3
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 +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
|