sql_beautifier 0.6.0 → 0.7.0
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/CHANGELOG.md +12 -0
- data/README.md +2 -2
- data/lib/sql_beautifier/base.rb +9 -0
- data/lib/sql_beautifier/clauses/base.rb +2 -2
- data/lib/sql_beautifier/clauses/condition_clause.rb +1 -1
- data/lib/sql_beautifier/clauses/from.rb +15 -69
- data/lib/sql_beautifier/clauses/order_by.rb +12 -1
- data/lib/sql_beautifier/clauses/select.rb +28 -15
- data/lib/sql_beautifier/comment.rb +23 -0
- data/lib/sql_beautifier/{comment_stripper.rb → comment_parser.rb} +67 -24
- data/lib/sql_beautifier/condition.rb +162 -0
- data/lib/sql_beautifier/configuration.rb +4 -15
- data/lib/sql_beautifier/create_table_as.rb +127 -0
- data/lib/sql_beautifier/cte_definition.rb +41 -0
- data/lib/sql_beautifier/cte_query.rb +129 -0
- data/lib/sql_beautifier/expression.rb +54 -0
- data/lib/sql_beautifier/formatter.rb +13 -80
- data/lib/sql_beautifier/join.rb +69 -0
- data/lib/sql_beautifier/normalizer.rb +33 -59
- data/lib/sql_beautifier/query.rb +185 -0
- data/lib/sql_beautifier/scanner.rb +420 -0
- data/lib/sql_beautifier/sort_expression.rb +39 -0
- data/lib/sql_beautifier/statement_assembler.rb +4 -4
- data/lib/sql_beautifier/statement_splitter.rb +35 -143
- data/lib/sql_beautifier/table_reference.rb +52 -0
- data/lib/sql_beautifier/table_registry.rb +50 -124
- data/lib/sql_beautifier/tokenizer.rb +47 -278
- data/lib/sql_beautifier/types.rb +9 -0
- data/lib/sql_beautifier/version.rb +1 -1
- data/lib/sql_beautifier.rb +14 -6
- metadata +43 -7
- data/lib/sql_beautifier/comment_restorer.rb +0 -62
- data/lib/sql_beautifier/condition_formatter.rb +0 -127
- data/lib/sql_beautifier/create_table_as_formatter.rb +0 -177
- data/lib/sql_beautifier/cte_formatter.rb +0 -192
- data/lib/sql_beautifier/subquery_formatter.rb +0 -113
|
@@ -2,14 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
module SqlBeautifier
|
|
4
4
|
module Tokenizer
|
|
5
|
-
IDENTIFIER_CHARACTER = %r{[[:alnum:]_$]}
|
|
6
|
-
SENTINEL_MAX_LOOKBACK = 20
|
|
7
|
-
|
|
8
5
|
module_function
|
|
9
6
|
|
|
10
7
|
def find_top_level_keyword(sql, keyword)
|
|
11
8
|
keyword_pattern = %r{#{Regexp.escape(keyword)}}i
|
|
12
9
|
search_position = 0
|
|
10
|
+
scanner = Scanner.new(sql)
|
|
13
11
|
|
|
14
12
|
while search_position < sql.length
|
|
15
13
|
match = sql.match(keyword_pattern, search_position)
|
|
@@ -17,15 +15,15 @@ module SqlBeautifier
|
|
|
17
15
|
|
|
18
16
|
match_position = match.begin(0)
|
|
19
17
|
|
|
20
|
-
if inside_sentinel?(
|
|
21
|
-
search_position = sentinel_end_position(
|
|
18
|
+
if scanner.inside_sentinel?(match_position)
|
|
19
|
+
search_position = scanner.sentinel_end_position(match_position) || (match_position + 1)
|
|
22
20
|
next
|
|
23
21
|
end
|
|
24
22
|
|
|
25
|
-
previous_character = character_before(
|
|
26
|
-
next_character = character_after(
|
|
23
|
+
previous_character = scanner.character_before(match_position)
|
|
24
|
+
next_character = scanner.character_after(match_position, keyword.length)
|
|
27
25
|
|
|
28
|
-
return match_position if word_boundary?(previous_character) && word_boundary?(next_character) && top_level?(sql, match_position)
|
|
26
|
+
return match_position if scanner.word_boundary?(previous_character) && scanner.word_boundary?(next_character) && top_level?(sql, match_position)
|
|
29
27
|
|
|
30
28
|
search_position = match_position + 1
|
|
31
29
|
end
|
|
@@ -72,70 +70,30 @@ module SqlBeautifier
|
|
|
72
70
|
end
|
|
73
71
|
|
|
74
72
|
def split_by_top_level_commas(text)
|
|
73
|
+
scanner = Scanner.new(text)
|
|
75
74
|
segments = []
|
|
76
75
|
current_segment = +""
|
|
77
|
-
parenthesis_depth = 0
|
|
78
|
-
inside_string_literal = false
|
|
79
|
-
inside_quoted_identifier = false
|
|
80
|
-
position = 0
|
|
81
|
-
|
|
82
|
-
while position < text.length
|
|
83
|
-
character = text[position]
|
|
84
|
-
|
|
85
|
-
if inside_string_literal
|
|
86
|
-
current_segment << character
|
|
87
76
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
inside_string_literal = false
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
position += 1
|
|
77
|
+
until scanner.finished?
|
|
78
|
+
consumed = scanner.scan_quoted_or_sentinel!
|
|
79
|
+
if consumed
|
|
80
|
+
current_segment << consumed
|
|
96
81
|
next
|
|
97
82
|
end
|
|
98
83
|
|
|
99
|
-
|
|
100
|
-
current_segment << character
|
|
101
|
-
|
|
102
|
-
if escaped_double_quote?(text, position)
|
|
103
|
-
position += 1
|
|
104
|
-
current_segment << text[position]
|
|
105
|
-
elsif character == Constants::DOUBLE_QUOTE
|
|
106
|
-
inside_quoted_identifier = false
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
position += 1
|
|
110
|
-
next
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
if sentinel_at?(text, position)
|
|
114
|
-
end_position = sentinel_end_position(text, position)
|
|
115
|
-
current_segment << text[position...end_position]
|
|
116
|
-
position = end_position
|
|
117
|
-
next
|
|
118
|
-
end
|
|
84
|
+
character = scanner.current_char
|
|
119
85
|
|
|
120
86
|
case character
|
|
121
|
-
when Constants::SINGLE_QUOTE
|
|
122
|
-
inside_string_literal = true
|
|
123
|
-
current_segment << character
|
|
124
|
-
|
|
125
|
-
when Constants::DOUBLE_QUOTE
|
|
126
|
-
inside_quoted_identifier = true
|
|
127
|
-
current_segment << character
|
|
128
|
-
|
|
129
87
|
when Constants::OPEN_PARENTHESIS
|
|
130
|
-
|
|
88
|
+
scanner.increment_depth!
|
|
131
89
|
current_segment << character
|
|
132
90
|
|
|
133
91
|
when Constants::CLOSE_PARENTHESIS
|
|
134
|
-
|
|
92
|
+
scanner.decrement_depth!
|
|
135
93
|
current_segment << character
|
|
136
94
|
|
|
137
95
|
when Constants::COMMA
|
|
138
|
-
if parenthesis_depth.zero?
|
|
96
|
+
if scanner.parenthesis_depth.zero?
|
|
139
97
|
segments << current_segment.strip
|
|
140
98
|
current_segment = +""
|
|
141
99
|
else
|
|
@@ -146,7 +104,7 @@ module SqlBeautifier
|
|
|
146
104
|
current_segment << character
|
|
147
105
|
end
|
|
148
106
|
|
|
149
|
-
|
|
107
|
+
scanner.advance!
|
|
150
108
|
end
|
|
151
109
|
|
|
152
110
|
segments << current_segment.strip unless current_segment.strip.empty?
|
|
@@ -181,238 +139,64 @@ module SqlBeautifier
|
|
|
181
139
|
condition_pairs
|
|
182
140
|
end
|
|
183
141
|
|
|
184
|
-
def find_matching_parenthesis(text, opening_position)
|
|
185
|
-
parenthesis_depth = 0
|
|
186
|
-
inside_string_literal = false
|
|
187
|
-
inside_quoted_identifier = false
|
|
188
|
-
position = opening_position
|
|
189
|
-
|
|
190
|
-
while position < text.length
|
|
191
|
-
character = text[position]
|
|
192
|
-
|
|
193
|
-
if inside_string_literal
|
|
194
|
-
if escaped_single_quote?(text, position)
|
|
195
|
-
position += 2
|
|
196
|
-
next
|
|
197
|
-
elsif character == Constants::SINGLE_QUOTE
|
|
198
|
-
inside_string_literal = false
|
|
199
|
-
end
|
|
200
|
-
|
|
201
|
-
position += 1
|
|
202
|
-
next
|
|
203
|
-
end
|
|
204
|
-
|
|
205
|
-
if inside_quoted_identifier
|
|
206
|
-
if escaped_double_quote?(text, position)
|
|
207
|
-
position += 2
|
|
208
|
-
next
|
|
209
|
-
elsif character == Constants::DOUBLE_QUOTE
|
|
210
|
-
inside_quoted_identifier = false
|
|
211
|
-
end
|
|
212
|
-
|
|
213
|
-
position += 1
|
|
214
|
-
next
|
|
215
|
-
end
|
|
216
|
-
|
|
217
|
-
if sentinel_at?(text, position)
|
|
218
|
-
position = sentinel_end_position(text, position)
|
|
219
|
-
next
|
|
220
|
-
end
|
|
221
|
-
|
|
222
|
-
case character
|
|
223
|
-
when Constants::SINGLE_QUOTE
|
|
224
|
-
inside_string_literal = true
|
|
225
|
-
when Constants::DOUBLE_QUOTE
|
|
226
|
-
inside_quoted_identifier = true
|
|
227
|
-
when Constants::OPEN_PARENTHESIS
|
|
228
|
-
parenthesis_depth += 1
|
|
229
|
-
when Constants::CLOSE_PARENTHESIS
|
|
230
|
-
parenthesis_depth -= 1
|
|
231
|
-
return position if parenthesis_depth.zero?
|
|
232
|
-
end
|
|
233
|
-
|
|
234
|
-
position += 1
|
|
235
|
-
end
|
|
236
|
-
|
|
237
|
-
nil
|
|
238
|
-
end
|
|
239
|
-
|
|
240
142
|
def outer_parentheses_wrap_all?(text)
|
|
241
143
|
trimmed_text = text.strip
|
|
242
144
|
return false unless trimmed_text.start_with?(Constants::OPEN_PARENTHESIS)
|
|
243
145
|
|
|
244
|
-
closing_parenthesis_position = find_matching_parenthesis(
|
|
146
|
+
closing_parenthesis_position = Scanner.new(trimmed_text).find_matching_parenthesis(0)
|
|
245
147
|
|
|
246
148
|
closing_parenthesis_position == trimmed_text.length - 1
|
|
247
149
|
end
|
|
248
150
|
|
|
249
|
-
def word_boundary?(character)
|
|
250
|
-
character.nil? || character !~ IDENTIFIER_CHARACTER
|
|
251
|
-
end
|
|
252
|
-
|
|
253
|
-
def character_before(text, position)
|
|
254
|
-
return nil if position.zero?
|
|
255
|
-
|
|
256
|
-
text[position - 1]
|
|
257
|
-
end
|
|
258
|
-
|
|
259
|
-
def character_after(text, position, offset)
|
|
260
|
-
return nil if position + offset >= text.length
|
|
261
|
-
|
|
262
|
-
text[position + offset]
|
|
263
|
-
end
|
|
264
|
-
|
|
265
|
-
def escaped_single_quote?(text, position)
|
|
266
|
-
text[position] == Constants::SINGLE_QUOTE && text[position + 1] == Constants::SINGLE_QUOTE
|
|
267
|
-
end
|
|
268
|
-
|
|
269
|
-
def escaped_double_quote?(text, position)
|
|
270
|
-
text[position] == Constants::DOUBLE_QUOTE && text[position + 1] == Constants::DOUBLE_QUOTE
|
|
271
|
-
end
|
|
272
|
-
|
|
273
|
-
def dollar_quote_delimiter_at(text, position)
|
|
274
|
-
return "$$" if text[position, 2] == "$$"
|
|
275
|
-
return unless text[position] == "$"
|
|
276
|
-
|
|
277
|
-
closing_dollar_position = text.index("$", position + 1)
|
|
278
|
-
return unless closing_dollar_position
|
|
279
|
-
|
|
280
|
-
delimiter = text[position..closing_dollar_position]
|
|
281
|
-
tag = delimiter[1..-2]
|
|
282
|
-
return unless tag.match?(%r{\A[[:alpha:]_][[:alnum:]_]*\z})
|
|
283
|
-
|
|
284
|
-
delimiter
|
|
285
|
-
end
|
|
286
|
-
|
|
287
|
-
def sentinel_at?(text, position)
|
|
288
|
-
text[position, CommentStripper::SENTINEL_PREFIX.length] == CommentStripper::SENTINEL_PREFIX
|
|
289
|
-
end
|
|
290
|
-
|
|
291
|
-
def sentinel_end_position(text, position)
|
|
292
|
-
closing = text.index(CommentStripper::SENTINEL_SUFFIX, position + CommentStripper::SENTINEL_PREFIX.length)
|
|
293
|
-
return position + 1 unless closing
|
|
294
|
-
|
|
295
|
-
closing + CommentStripper::SENTINEL_SUFFIX.length
|
|
296
|
-
end
|
|
297
|
-
|
|
298
|
-
def inside_sentinel?(text, position)
|
|
299
|
-
search_start = [position - SENTINEL_MAX_LOOKBACK, 0].max
|
|
300
|
-
prefix_position = text.rindex(CommentStripper::SENTINEL_PREFIX, position)
|
|
301
|
-
return false unless prefix_position && prefix_position >= search_start
|
|
302
|
-
|
|
303
|
-
end_position = sentinel_end_position(text, prefix_position)
|
|
304
|
-
position < end_position
|
|
305
|
-
end
|
|
306
|
-
|
|
307
151
|
def top_level?(sql, target_position)
|
|
308
|
-
|
|
309
|
-
inside_string_literal = false
|
|
310
|
-
inside_quoted_identifier = false
|
|
311
|
-
position = 0
|
|
312
|
-
|
|
313
|
-
while position < target_position
|
|
314
|
-
character = sql[position]
|
|
315
|
-
|
|
316
|
-
if inside_string_literal
|
|
317
|
-
if escaped_single_quote?(sql, position)
|
|
318
|
-
position += 2
|
|
319
|
-
next
|
|
320
|
-
elsif character == Constants::SINGLE_QUOTE
|
|
321
|
-
inside_string_literal = false
|
|
322
|
-
end
|
|
323
|
-
|
|
324
|
-
position += 1
|
|
325
|
-
next
|
|
326
|
-
end
|
|
152
|
+
scanner = Scanner.new(sql)
|
|
327
153
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
position += 2
|
|
331
|
-
next
|
|
332
|
-
elsif character == Constants::DOUBLE_QUOTE
|
|
333
|
-
inside_quoted_identifier = false
|
|
334
|
-
end
|
|
335
|
-
|
|
336
|
-
position += 1
|
|
337
|
-
next
|
|
338
|
-
end
|
|
339
|
-
|
|
340
|
-
if sentinel_at?(sql, position)
|
|
341
|
-
position = sentinel_end_position(sql, position)
|
|
342
|
-
next
|
|
343
|
-
end
|
|
154
|
+
while scanner.position < target_position
|
|
155
|
+
next if scanner.skip_quoted_or_sentinel!
|
|
344
156
|
|
|
345
|
-
case
|
|
157
|
+
case scanner.current_char
|
|
346
158
|
when Constants::SINGLE_QUOTE
|
|
347
|
-
|
|
159
|
+
scanner.enter_single_quote!
|
|
348
160
|
when Constants::DOUBLE_QUOTE
|
|
349
|
-
|
|
161
|
+
scanner.enter_double_quote!
|
|
350
162
|
when Constants::OPEN_PARENTHESIS
|
|
351
|
-
|
|
163
|
+
scanner.increment_depth!
|
|
164
|
+
scanner.advance!
|
|
352
165
|
when Constants::CLOSE_PARENTHESIS
|
|
353
|
-
|
|
166
|
+
scanner.decrement_depth!
|
|
167
|
+
scanner.advance!
|
|
168
|
+
else
|
|
169
|
+
scanner.advance!
|
|
354
170
|
end
|
|
355
|
-
|
|
356
|
-
position += 1
|
|
357
171
|
end
|
|
358
172
|
|
|
359
|
-
|
|
173
|
+
scanner.top_level?
|
|
360
174
|
end
|
|
361
175
|
|
|
362
176
|
def scan_top_level_conjunctions(text)
|
|
177
|
+
scanner = Scanner.new(text)
|
|
363
178
|
conjunction_boundaries = []
|
|
364
|
-
parenthesis_depth = 0
|
|
365
|
-
inside_string_literal = false
|
|
366
|
-
inside_quoted_identifier = false
|
|
367
179
|
inside_between = false
|
|
368
|
-
position = 0
|
|
369
|
-
|
|
370
|
-
while position < text.length
|
|
371
|
-
character = text[position]
|
|
372
|
-
|
|
373
|
-
if inside_string_literal
|
|
374
|
-
if escaped_single_quote?(text, position)
|
|
375
|
-
position += 2
|
|
376
|
-
elsif character == Constants::SINGLE_QUOTE
|
|
377
|
-
inside_string_literal = false
|
|
378
|
-
position += 1
|
|
379
|
-
else
|
|
380
|
-
position += 1
|
|
381
|
-
end
|
|
382
|
-
next
|
|
383
|
-
end
|
|
384
180
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
position += 2
|
|
388
|
-
elsif character == Constants::DOUBLE_QUOTE
|
|
389
|
-
inside_quoted_identifier = false
|
|
390
|
-
position += 1
|
|
391
|
-
else
|
|
392
|
-
position += 1
|
|
393
|
-
end
|
|
394
|
-
next
|
|
395
|
-
end
|
|
181
|
+
until scanner.finished?
|
|
182
|
+
next if scanner.skip_quoted_or_sentinel!
|
|
396
183
|
|
|
397
|
-
|
|
398
|
-
position = sentinel_end_position(text, position)
|
|
399
|
-
next
|
|
400
|
-
end
|
|
401
|
-
|
|
402
|
-
case character
|
|
184
|
+
case scanner.current_char
|
|
403
185
|
when Constants::SINGLE_QUOTE
|
|
404
|
-
|
|
186
|
+
scanner.enter_single_quote!
|
|
405
187
|
when Constants::DOUBLE_QUOTE
|
|
406
|
-
|
|
188
|
+
scanner.enter_double_quote!
|
|
407
189
|
when Constants::OPEN_PARENTHESIS
|
|
408
|
-
|
|
190
|
+
scanner.increment_depth!
|
|
191
|
+
scanner.advance!
|
|
409
192
|
when Constants::CLOSE_PARENTHESIS
|
|
410
|
-
|
|
193
|
+
scanner.decrement_depth!
|
|
194
|
+
scanner.advance!
|
|
411
195
|
else
|
|
412
|
-
if parenthesis_depth.zero?
|
|
413
|
-
inside_between = true if keyword_at?(
|
|
196
|
+
if scanner.parenthesis_depth.zero?
|
|
197
|
+
inside_between = true if scanner.keyword_at?(Constants::BETWEEN_KEYWORD)
|
|
414
198
|
|
|
415
|
-
matched_conjunction = detect_conjunction_at
|
|
199
|
+
matched_conjunction = scanner.detect_conjunction_at
|
|
416
200
|
|
|
417
201
|
if matched_conjunction
|
|
418
202
|
if matched_conjunction == "and" && inside_between
|
|
@@ -420,35 +204,20 @@ module SqlBeautifier
|
|
|
420
204
|
else
|
|
421
205
|
conjunction_boundaries << {
|
|
422
206
|
conjunction: matched_conjunction,
|
|
423
|
-
position: position,
|
|
207
|
+
position: scanner.position,
|
|
424
208
|
}
|
|
425
209
|
end
|
|
426
210
|
|
|
427
|
-
|
|
211
|
+
scanner.advance!(matched_conjunction.length)
|
|
428
212
|
next
|
|
429
213
|
end
|
|
430
214
|
end
|
|
431
|
-
end
|
|
432
215
|
|
|
433
|
-
|
|
216
|
+
scanner.advance!
|
|
217
|
+
end
|
|
434
218
|
end
|
|
435
219
|
|
|
436
220
|
conjunction_boundaries
|
|
437
221
|
end
|
|
438
|
-
|
|
439
|
-
def keyword_at?(text, position, keyword)
|
|
440
|
-
return false unless text[position, keyword.length]&.downcase == keyword
|
|
441
|
-
|
|
442
|
-
previous_character = character_before(text, position)
|
|
443
|
-
next_character = character_after(text, position, keyword.length)
|
|
444
|
-
|
|
445
|
-
word_boundary?(previous_character) && word_boundary?(next_character)
|
|
446
|
-
end
|
|
447
|
-
|
|
448
|
-
def detect_conjunction_at(text, position)
|
|
449
|
-
Constants::CONJUNCTIONS.detect do |conjunction|
|
|
450
|
-
keyword_at?(text, position, conjunction)
|
|
451
|
-
end
|
|
452
|
-
end
|
|
453
222
|
end
|
|
454
223
|
end
|
data/lib/sql_beautifier.rb
CHANGED
|
@@ -5,18 +5,25 @@ require "active_support/core_ext/object/blank"
|
|
|
5
5
|
require_relative "sql_beautifier/version"
|
|
6
6
|
require_relative "sql_beautifier/constants"
|
|
7
7
|
require_relative "sql_beautifier/util"
|
|
8
|
+
require_relative "sql_beautifier/base"
|
|
8
9
|
require_relative "sql_beautifier/configuration"
|
|
10
|
+
require_relative "sql_beautifier/types"
|
|
9
11
|
|
|
10
|
-
require_relative "sql_beautifier/
|
|
11
|
-
require_relative "sql_beautifier/
|
|
12
|
+
require_relative "sql_beautifier/scanner"
|
|
13
|
+
require_relative "sql_beautifier/comment"
|
|
14
|
+
require_relative "sql_beautifier/comment_parser"
|
|
12
15
|
require_relative "sql_beautifier/normalizer"
|
|
13
16
|
require_relative "sql_beautifier/tokenizer"
|
|
14
17
|
require_relative "sql_beautifier/statement_splitter"
|
|
18
|
+
require_relative "sql_beautifier/table_reference"
|
|
15
19
|
require_relative "sql_beautifier/table_registry"
|
|
16
|
-
require_relative "sql_beautifier/
|
|
17
|
-
require_relative "sql_beautifier/
|
|
18
|
-
require_relative "sql_beautifier/
|
|
19
|
-
require_relative "sql_beautifier/
|
|
20
|
+
require_relative "sql_beautifier/join"
|
|
21
|
+
require_relative "sql_beautifier/expression"
|
|
22
|
+
require_relative "sql_beautifier/sort_expression"
|
|
23
|
+
require_relative "sql_beautifier/condition"
|
|
24
|
+
require_relative "sql_beautifier/cte_definition"
|
|
25
|
+
require_relative "sql_beautifier/cte_query"
|
|
26
|
+
require_relative "sql_beautifier/create_table_as"
|
|
20
27
|
require_relative "sql_beautifier/clauses/base"
|
|
21
28
|
require_relative "sql_beautifier/clauses/condition_clause"
|
|
22
29
|
require_relative "sql_beautifier/clauses/select"
|
|
@@ -26,6 +33,7 @@ require_relative "sql_beautifier/clauses/group_by"
|
|
|
26
33
|
require_relative "sql_beautifier/clauses/order_by"
|
|
27
34
|
require_relative "sql_beautifier/clauses/having"
|
|
28
35
|
require_relative "sql_beautifier/clauses/limit"
|
|
36
|
+
require_relative "sql_beautifier/query"
|
|
29
37
|
require_relative "sql_beautifier/formatter"
|
|
30
38
|
require_relative "sql_beautifier/statement_assembler"
|
|
31
39
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sql_beautifier
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.7.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Kinnell Shah
|
|
@@ -23,6 +23,34 @@ dependencies:
|
|
|
23
23
|
- - ">="
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
25
|
version: '6.0'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: dry-initializer
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '3.2'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - ">="
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '3.2'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: dry-types
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - ">="
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '1.9'
|
|
47
|
+
type: :runtime
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - ">="
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '1.9'
|
|
26
54
|
description: 'Formats raw SQL into a clean, consistent style with lowercase keywords,
|
|
27
55
|
padded keyword alignment, and vertically separated clauses.
|
|
28
56
|
|
|
@@ -37,6 +65,7 @@ files:
|
|
|
37
65
|
- LICENSE.txt
|
|
38
66
|
- README.md
|
|
39
67
|
- lib/sql_beautifier.rb
|
|
68
|
+
- lib/sql_beautifier/base.rb
|
|
40
69
|
- lib/sql_beautifier/clauses/base.rb
|
|
41
70
|
- lib/sql_beautifier/clauses/condition_clause.rb
|
|
42
71
|
- lib/sql_beautifier/clauses/from.rb
|
|
@@ -46,20 +75,27 @@ files:
|
|
|
46
75
|
- lib/sql_beautifier/clauses/order_by.rb
|
|
47
76
|
- lib/sql_beautifier/clauses/select.rb
|
|
48
77
|
- lib/sql_beautifier/clauses/where.rb
|
|
49
|
-
- lib/sql_beautifier/
|
|
50
|
-
- lib/sql_beautifier/
|
|
51
|
-
- lib/sql_beautifier/
|
|
78
|
+
- lib/sql_beautifier/comment.rb
|
|
79
|
+
- lib/sql_beautifier/comment_parser.rb
|
|
80
|
+
- lib/sql_beautifier/condition.rb
|
|
52
81
|
- lib/sql_beautifier/configuration.rb
|
|
53
82
|
- lib/sql_beautifier/constants.rb
|
|
54
|
-
- lib/sql_beautifier/
|
|
55
|
-
- lib/sql_beautifier/
|
|
83
|
+
- lib/sql_beautifier/create_table_as.rb
|
|
84
|
+
- lib/sql_beautifier/cte_definition.rb
|
|
85
|
+
- lib/sql_beautifier/cte_query.rb
|
|
86
|
+
- lib/sql_beautifier/expression.rb
|
|
56
87
|
- lib/sql_beautifier/formatter.rb
|
|
88
|
+
- lib/sql_beautifier/join.rb
|
|
57
89
|
- lib/sql_beautifier/normalizer.rb
|
|
90
|
+
- lib/sql_beautifier/query.rb
|
|
91
|
+
- lib/sql_beautifier/scanner.rb
|
|
92
|
+
- lib/sql_beautifier/sort_expression.rb
|
|
58
93
|
- lib/sql_beautifier/statement_assembler.rb
|
|
59
94
|
- lib/sql_beautifier/statement_splitter.rb
|
|
60
|
-
- lib/sql_beautifier/
|
|
95
|
+
- lib/sql_beautifier/table_reference.rb
|
|
61
96
|
- lib/sql_beautifier/table_registry.rb
|
|
62
97
|
- lib/sql_beautifier/tokenizer.rb
|
|
98
|
+
- lib/sql_beautifier/types.rb
|
|
63
99
|
- lib/sql_beautifier/util.rb
|
|
64
100
|
- lib/sql_beautifier/version.rb
|
|
65
101
|
homepage: https://github.com/kinnell/sql_beautifier
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module SqlBeautifier
|
|
4
|
-
class CommentRestorer
|
|
5
|
-
def self.call(formatted_sql, comment_map)
|
|
6
|
-
return formatted_sql if comment_map.empty?
|
|
7
|
-
|
|
8
|
-
new(formatted_sql, comment_map).call
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def initialize(formatted_sql, comment_map)
|
|
12
|
-
@formatted_sql = formatted_sql
|
|
13
|
-
@comment_map = comment_map
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def call
|
|
17
|
-
result = @formatted_sql
|
|
18
|
-
|
|
19
|
-
@comment_map.each do |index, entry|
|
|
20
|
-
sentinel = "#{CommentStripper::SENTINEL_PREFIX}#{index}#{CommentStripper::SENTINEL_SUFFIX}"
|
|
21
|
-
|
|
22
|
-
result = begin
|
|
23
|
-
case entry[:type]
|
|
24
|
-
when :blocks
|
|
25
|
-
restore_block_comment(result, sentinel, entry[:text])
|
|
26
|
-
when :separate_line
|
|
27
|
-
restore_separate_line_comment(result, sentinel, entry[:text])
|
|
28
|
-
when :inline
|
|
29
|
-
restore_inline_comment(result, sentinel, entry[:text])
|
|
30
|
-
else
|
|
31
|
-
result
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
result
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
private
|
|
40
|
-
|
|
41
|
-
def restore_block_comment(sql, sentinel, comment_text)
|
|
42
|
-
sql.sub(sentinel, comment_text)
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def restore_separate_line_comment(sql, sentinel, comment_text)
|
|
46
|
-
sql.sub(%r{#{Regexp.escape(sentinel)}[ \n]?}, "#{comment_text}\n")
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def restore_inline_comment(sql, sentinel, comment_text)
|
|
50
|
-
pattern = %r{ ?#{Regexp.escape(sentinel)}([^\n]*)}
|
|
51
|
-
sql.sub(pattern) do
|
|
52
|
-
trailing_content = Regexp.last_match(1)
|
|
53
|
-
|
|
54
|
-
if trailing_content.strip.empty?
|
|
55
|
-
" #{comment_text}"
|
|
56
|
-
else
|
|
57
|
-
"#{trailing_content.strip} #{comment_text}"
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
end
|