tsql_parser 0.1.3 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/parsing/formatter.rb +3 -66
- data/lib/parsing/formatters/strategy/join_formatter.rb +1 -1
- data/lib/parsing/formatters/strategy/set_formatter.rb +1 -1
- data/lib/parsing/keyword.rb +1 -1
- data/lib/parsing/parser.rb +2 -2
- data/lib/parsing/tokenizer.rb +149 -110
- data/lib/parsing/transformers/token_categorizer.rb +52 -0
- data/lib/parsing/transformers/token_transformer.rb +99 -0
- metadata +7 -6
- data/lib/parsing/iterator.rb +0 -54
- /data/lib/parsing/{model → models}/flat_sql_container.rb +0 -0
- /data/lib/parsing/{model → models}/sql_container.rb +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 81a892f94d3a26de7e1b77b16c723b67ec1ccddc8a8c6dc4251300792be75c75
|
4
|
+
data.tar.gz: 1a326f8c1f465444144d436d69c95180c4a6d6ff19cc90e3db93afa9e7f7484e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 240fb09638d5005e9cce7ba057666c8fc3a5167e10071e0affd78af39a962b253914b392022ee54449f3126abbea32e70ef6a3d2c3c151607b0ac46703c9605e
|
7
|
+
data.tar.gz: 71dc6419e1a96499521158f1e25023afa53488f4a94fd5ff33cc46e15664533f0e6dd19a57c71fd866537c8b12ca70c64e7b72d08e0841f9aa5cbaa5c6e12667
|
data/lib/parsing/formatter.rb
CHANGED
@@ -15,16 +15,13 @@
|
|
15
15
|
# TSqlParser::Parsing::Formatter
|
16
16
|
|
17
17
|
module TSqlParser::Parsing
|
18
|
-
require_relative "iterator"
|
19
18
|
require_relative "parser"
|
20
19
|
require_relative "formatters/text_formatter"
|
21
|
-
require_relative "
|
22
|
-
|
23
|
-
|
20
|
+
require_relative "transformers/token_transformer"
|
21
|
+
|
24
22
|
class Formatter
|
25
23
|
def self.format(tokens, tab_count = 0, tab = " ")
|
26
|
-
|
27
|
-
lines = self.combine_containers(containers)
|
24
|
+
lines = TokenTransformer.transform(tokens)
|
28
25
|
lines = self.cleanup_whitespace(lines)
|
29
26
|
lines = self.insert_indentation(lines, tab_count, tab)
|
30
27
|
lines = self.insert_newlines(lines)
|
@@ -116,66 +113,6 @@ module TSqlParser::Parsing
|
|
116
113
|
lines
|
117
114
|
end
|
118
115
|
|
119
|
-
def self.combine_containers(containers)
|
120
|
-
lines = []
|
121
|
-
containers.each do |c|
|
122
|
-
ct = c.get_token
|
123
|
-
|
124
|
-
builder = []
|
125
|
-
builder << ct[:value]
|
126
|
-
|
127
|
-
if c.has_siblings?
|
128
|
-
c.get_siblings.each do |sibling|
|
129
|
-
st = sibling.get_token
|
130
|
-
|
131
|
-
if st[:comment]
|
132
|
-
builder << "\n#{st[:value]}"
|
133
|
-
next
|
134
|
-
end
|
135
|
-
|
136
|
-
builder << st[:value]
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
lines << builder.join(" ")
|
141
|
-
end
|
142
|
-
|
143
|
-
lines
|
144
|
-
end
|
145
|
-
|
146
|
-
def self.as_containers(tokens)
|
147
|
-
containers = []
|
148
|
-
container = nil
|
149
|
-
skip_count = 0
|
150
|
-
tokens.each_with_index do |t, index|
|
151
|
-
if skip_count > 0
|
152
|
-
skip_count -= 1
|
153
|
-
next
|
154
|
-
end
|
155
|
-
|
156
|
-
next_token = tokens[index + 1]
|
157
|
-
if Parser.is_new_node_keyword? t[:value]
|
158
|
-
if not next_token.nil? and Parser.is_new_node_keyword? next_token[:value]
|
159
|
-
if Parser.is_new_node_composite?(t[:value], next_token[:value])
|
160
|
-
containers << container unless container.nil?
|
161
|
-
container = SqlContainer.combine(t, next_token)
|
162
|
-
skip_count = 1
|
163
|
-
next
|
164
|
-
end
|
165
|
-
end
|
166
|
-
containers << container unless container.nil?
|
167
|
-
container = SqlContainer.new(t)
|
168
|
-
elsif t[:label]
|
169
|
-
containers << container unless container.nil?
|
170
|
-
container = SqlContainer.new(t)
|
171
|
-
else
|
172
|
-
container.add t unless container.nil?
|
173
|
-
end
|
174
|
-
end
|
175
|
-
containers << container unless container.nil?
|
176
|
-
FlatSqlContainer.flatten_containers(containers)
|
177
|
-
end
|
178
|
-
|
179
116
|
def self.safe_ws_cleanup(line)
|
180
117
|
parts = []
|
181
118
|
builder = ""
|
@@ -26,7 +26,7 @@ module TSqlParser::Parsing::Formatters
|
|
26
26
|
|
27
27
|
lines.each do |line|
|
28
28
|
first = line.strip.split(" ").first
|
29
|
-
if line.include? " WHERE " and first != "WHERE" and not first.start_with? "--" and not first.start_with? "/*"
|
29
|
+
if line.include? " WHERE " and first != "WHERE" and not first.start_with? "--" and not first.start_with? "/*" and not line.strip.end_with? "'"
|
30
30
|
tab_count = self.get_tab_count(line, tab)
|
31
31
|
where_parts = line.strip.split(" WHERE ")
|
32
32
|
where_text = []
|
@@ -55,7 +55,7 @@ module TSqlParser::Parsing::Formatters
|
|
55
55
|
formatted << line
|
56
56
|
formatted << ""
|
57
57
|
end
|
58
|
-
elsif first != "SET" and line.include? " SET "
|
58
|
+
elsif first != "SET" and line.include? " SET " and not line.strip.start_with? "--"
|
59
59
|
parts = line.strip.split(" SET ")
|
60
60
|
tab_count = self.get_tab_count(line, tab)
|
61
61
|
formatted << "#{tab * tab_count}#{parts[0]}\n"
|
data/lib/parsing/keyword.rb
CHANGED
@@ -24,7 +24,7 @@ module TSqlParser::Parsing
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def self.get_new_node_keywords
|
27
|
-
%w[CREATE ALTER DROP RENAME SELECT INSERT UPDATE DELETE WHILE IF ELSE DECLARE SET WITH BEGIN FROM WHERE INNER LEFT JOIN END GO GROUP ORDER CASE PRINT RETURN GOTO OPEN CLOSE DEALLOCATE FETCH] \
|
27
|
+
%w[CREATE ALTER DROP RENAME SELECT INSERT UPDATE DELETE WHILE IF ELSE DECLARE SET WITH BEGIN FROM WHERE INNER LEFT JOIN END GO GROUP ORDER CASE PRINT RETURN GOTO OPEN CLOSE DEALLOCATE FETCH USE EXEC] \
|
28
28
|
- %w[WITH LEFT RIGHT]
|
29
29
|
end
|
30
30
|
|
data/lib/parsing/parser.rb
CHANGED
data/lib/parsing/tokenizer.rb
CHANGED
@@ -15,137 +15,176 @@
|
|
15
15
|
# TSqlParser::Parsing::Tokenizer
|
16
16
|
|
17
17
|
module TSqlParser::Parsing
|
18
|
-
require_relative "
|
18
|
+
require_relative "transformers/token_categorizer"
|
19
19
|
|
20
20
|
class Tokenizer
|
21
|
+
@@default_char_delimiters = ["(", ",", ")", "=", "+", "-", "%", "/", "*", "<", "!", ">", "'", "[", "]", ";"]
|
22
|
+
@@default_skip_delimiters = [" ", "\n", "\t"]
|
23
|
+
|
24
|
+
def self.set_default_char_delimiters(char_delimiters = [])
|
25
|
+
@@default_char_delimiters = char_delimiters
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.set_default_skip_delimiters(skip_delimiters = [])
|
29
|
+
@@default_skip_delimiters = skip_delimiters
|
30
|
+
end
|
31
|
+
|
21
32
|
def self.tokenize(tsql_string)
|
22
|
-
|
23
|
-
tsql_string,
|
24
|
-
["(", ",", ")", "=", "+", "-", "%", "/", "*", "<", "!", ">", "'", "[", "]", ";"],
|
25
|
-
[" ", "\n", "\t"]
|
26
|
-
)
|
27
|
-
tokens.map do |t|
|
28
|
-
categorize(t)
|
29
|
-
end
|
33
|
+
Tokenizer.new.basic_tokenize(tsql_string).map { |t| TokenCategorizer.categorize(t) }
|
30
34
|
end
|
31
35
|
|
32
|
-
def
|
33
|
-
|
34
|
-
data[:value] = s
|
35
|
-
data[:keyword] = true if Parser.is_keyword? s
|
36
|
-
data[:operator] = true if Parser.is_operator? s
|
37
|
-
data[:function] = true if Parser.is_function? s
|
38
|
-
data[:type] = true if Parser.is_type? s
|
39
|
-
data[:comment] = true if Parser.is_comment? s
|
40
|
-
data[:numeric] = true if Parser.is_numeric? s
|
41
|
-
data[:special_variable] = true if Parser.is_special_variable? s
|
42
|
-
data[:variable] = true if Parser.is_variable? s
|
43
|
-
data[:temporary_table] = true if Parser.is_temp_table? s
|
44
|
-
data[:label] = true if Parser.is_label? s
|
45
|
-
data[:parenthesis] = true if Parser.is_parenthesis? s
|
46
|
-
data[:open_parenthesis] = true if Parser.is_open_parenthesis? s
|
47
|
-
data[:close_parenthesis] = true if Parser.is_close_parenthesis? s
|
48
|
-
data[:bracket] = true if Parser.is_bracket? s
|
49
|
-
data[:open_bracket] = true if Parser.is_open_bracket? s
|
50
|
-
data[:close_bracket] = true if Parser.is_close_bracket? s
|
51
|
-
data[:string_mark] = true if Parser.is_string_mark? s
|
52
|
-
data[:comma] = true if Parser.is_comma? s
|
53
|
-
data[:join] = true if Parser.is_join? s
|
54
|
-
data[:join_type] = true if Parser.is_join_type? s
|
55
|
-
data[:begin] = true if Parser.is_begin? s
|
56
|
-
data[:end] = true if Parser.is_end? s
|
57
|
-
data[:terminator] = true if Parser.is_terminator? s
|
58
|
-
data[:value] = data[:value].upcase if data[:keyword] or data[:function] or data[:type]
|
59
|
-
data[:needs_newline] = true if data[:keyword] and Parser.is_newline_required? s
|
60
|
-
data
|
61
|
-
end
|
62
|
-
|
63
|
-
def self.basic_tokenize(tsql_string, char_delimiters, skip_delimiters)
|
64
|
-
specific_tokens = []
|
65
|
-
delimiters = ([] << char_delimiters << skip_delimiters).flatten
|
66
|
-
builder = ""
|
36
|
+
def basic_tokenize(tsql_string)
|
37
|
+
self.reset
|
67
38
|
tsql_chars = tsql_string.split("")
|
68
|
-
|
69
|
-
comment = false
|
70
|
-
string = false
|
71
|
-
string_count = 0
|
72
|
-
skip_count = 0
|
39
|
+
|
73
40
|
tsql_chars.each_with_index do |c, i|
|
74
|
-
if skip_count > 0
|
75
|
-
skip_count -= 1
|
41
|
+
if @skip_count > 0
|
42
|
+
@skip_count -= 1
|
76
43
|
next
|
77
44
|
end
|
78
45
|
|
79
|
-
|
46
|
+
# get last and next char
|
47
|
+
@c = c
|
48
|
+
@last_c = tsql_chars[i - 1] unless i - 1 < 0
|
49
|
+
@next_c = tsql_chars[i + 1] unless i + 1 > tsql_chars.size
|
80
50
|
|
81
|
-
if
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
next
|
51
|
+
# if we aren't in a string.
|
52
|
+
unless @string
|
53
|
+
next if self.handle_multicomment_start
|
54
|
+
next if self.handle_multicomment_end
|
55
|
+
next if self.handle_singlecomment_start
|
56
|
+
next if self.build_comment
|
86
57
|
end
|
87
58
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
specific_tokens << builder unless builder.empty?
|
93
|
-
builder = ""
|
94
|
-
next
|
59
|
+
unless @multiline_comment or @comment
|
60
|
+
next if self.handle_string_char
|
61
|
+
next if self.handle_two_char_op
|
62
|
+
next if self.handle_delimiter
|
95
63
|
end
|
96
64
|
|
97
|
-
|
98
|
-
|
99
|
-
skip_count = 1
|
100
|
-
specific_tokens << builder unless builder.empty?
|
101
|
-
builder = "--"
|
102
|
-
next
|
103
|
-
end
|
65
|
+
self.build
|
66
|
+
end
|
104
67
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
elsif comment and c == "\n"
|
109
|
-
specific_tokens << builder unless builder.empty?
|
110
|
-
builder = ""
|
111
|
-
comment = false
|
112
|
-
next
|
113
|
-
end
|
68
|
+
self.flush_builder
|
69
|
+
@tokens
|
70
|
+
end
|
114
71
|
|
115
|
-
|
116
|
-
if not string
|
117
|
-
string = true
|
118
|
-
specific_tokens << builder unless builder.empty?
|
119
|
-
builder = c
|
120
|
-
next
|
121
|
-
else
|
122
|
-
string = false
|
123
|
-
builder << c
|
124
|
-
specific_tokens << builder unless builder.empty?
|
125
|
-
builder = ""
|
126
|
-
next
|
127
|
-
end
|
128
|
-
end
|
72
|
+
private
|
129
73
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
74
|
+
def handle_multicomment_start
|
75
|
+
if Parser.is_multiline_comment_start?(@c, @next_c)
|
76
|
+
@multiline_comment = true
|
77
|
+
self.flush_builder(c)
|
78
|
+
return true
|
79
|
+
end
|
80
|
+
end
|
137
81
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
82
|
+
def handle_multicomment_end
|
83
|
+
if Parser.is_multiline_comment_end?(@c, @next_c)
|
84
|
+
@skip_count = 1
|
85
|
+
@multiline_comment = false
|
86
|
+
self.build
|
87
|
+
self.build(@next_c)
|
88
|
+
self.flush_builder("")
|
89
|
+
return true
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def handle_singlecomment_start
|
94
|
+
if Parser.is_comment_start?(@c, @next_c) and not @comment
|
95
|
+
@comment = true
|
96
|
+
@skip_count = 1
|
97
|
+
self.flush_builder("--")
|
98
|
+
return true
|
99
|
+
end
|
100
|
+
end
|
144
101
|
|
145
|
-
|
102
|
+
def handle_singlecomment_end
|
103
|
+
if @c == "\n"
|
104
|
+
self.flush_builder("")
|
105
|
+
@comment = false
|
106
|
+
return true
|
146
107
|
end
|
147
|
-
|
148
|
-
|
108
|
+
end
|
109
|
+
|
110
|
+
def handle_string_char
|
111
|
+
if @c == "'"
|
112
|
+
@string_count += 1
|
113
|
+
return true if self.handle_string_start
|
114
|
+
@string_count += 1 if @next_c == "'"
|
115
|
+
return true if self.handle_string_end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def handle_string_start
|
120
|
+
if not @string
|
121
|
+
@string = true
|
122
|
+
self.flush_builder(@c)
|
123
|
+
return true
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def handle_string_end
|
128
|
+
if @string_count % 2 == 0
|
129
|
+
@string = false
|
130
|
+
@string_count = 0
|
131
|
+
self.build
|
132
|
+
self.flush_builder("")
|
133
|
+
return true
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def handle_two_char_op
|
138
|
+
if Parser.is_two_char_op?(@c, @next_c)
|
139
|
+
@skip_count = 1
|
140
|
+
self.flush_builder("")
|
141
|
+
@tokens << "#{@c}#{@next_c}"
|
142
|
+
return true
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def handle_delimiter
|
147
|
+
if @delimiters.include? @c and !@multiline_comment and !@comment and !@string
|
148
|
+
self.flush_builder("")
|
149
|
+
@tokens << @c unless @skip_delimiters.include? @c
|
150
|
+
return true
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def build(value = nil)
|
155
|
+
@builder << @c if value.nil?
|
156
|
+
@builder << value unless value.nil?
|
157
|
+
end
|
158
|
+
|
159
|
+
def build_comment
|
160
|
+
if @comment
|
161
|
+
return true if self.handle_singlecomment_end
|
162
|
+
|
163
|
+
self.build
|
164
|
+
return true
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def flush_builder(value = nil)
|
169
|
+
@tokens << @builder unless @builder.empty?
|
170
|
+
@builder = value
|
171
|
+
end
|
172
|
+
|
173
|
+
def initialize
|
174
|
+
self.reset
|
175
|
+
end
|
176
|
+
|
177
|
+
def reset
|
178
|
+
@tokens = []
|
179
|
+
@multiline_comment = false
|
180
|
+
@comment = false
|
181
|
+
@string = false
|
182
|
+
@string_count = 0
|
183
|
+
@skip_count = 0
|
184
|
+
@char_delimiters = @@default_char_delimiters
|
185
|
+
@skip_delimiters = @@default_skip_delimiters
|
186
|
+
@delimiters = ([] << @char_delimiters << @skip_delimiters).flatten.uniq
|
187
|
+
@builder = ""
|
149
188
|
end
|
150
189
|
end
|
151
190
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# __ .__
|
2
|
+
# _/ |_ ___________| | ___________ _______ ______ ___________
|
3
|
+
# \ __\/ ___/ ____/ | ______ \____ \__ \\_ __ \/ ___// __ \_ __ \
|
4
|
+
# | | \___ < <_| | |__ /_____/ | |_> > __ \| | \/\___ \\ ___/| | \/
|
5
|
+
# |__| /____ >__ |____/ | __(____ /__| /____ >\___ >__|
|
6
|
+
# \/ |__| |__| \/ \/ \/
|
7
|
+
#
|
8
|
+
# A very light-weight and opinionated T-SQL parser and formatter.
|
9
|
+
#
|
10
|
+
# github.com/scstauf
|
11
|
+
#
|
12
|
+
# path:
|
13
|
+
# parsing/transformers/token_categorizer.rb
|
14
|
+
# object:
|
15
|
+
# TSqlParser::Parsing::TokenCategorizer
|
16
|
+
|
17
|
+
module TSqlParser::Parsing
|
18
|
+
require_relative "../parser"
|
19
|
+
|
20
|
+
class TokenCategorizer
|
21
|
+
def self.categorize(s)
|
22
|
+
data = {}
|
23
|
+
data[:value] = s
|
24
|
+
data[:keyword] = true if Parser.is_keyword? s
|
25
|
+
data[:operator] = true if Parser.is_operator? s
|
26
|
+
data[:function] = true if Parser.is_function? s
|
27
|
+
data[:type] = true if Parser.is_type? s
|
28
|
+
data[:comment] = true if Parser.is_comment? s
|
29
|
+
data[:numeric] = true if Parser.is_numeric? s
|
30
|
+
data[:special_variable] = true if Parser.is_special_variable? s
|
31
|
+
data[:variable] = true if Parser.is_variable? s
|
32
|
+
data[:temporary_table] = true if Parser.is_temp_table? s
|
33
|
+
data[:label] = true if Parser.is_label? s
|
34
|
+
data[:parenthesis] = true if Parser.is_parenthesis? s
|
35
|
+
data[:open_parenthesis] = true if Parser.is_open_parenthesis? s
|
36
|
+
data[:close_parenthesis] = true if Parser.is_close_parenthesis? s
|
37
|
+
data[:bracket] = true if Parser.is_bracket? s
|
38
|
+
data[:open_bracket] = true if Parser.is_open_bracket? s
|
39
|
+
data[:close_bracket] = true if Parser.is_close_bracket? s
|
40
|
+
data[:string] = true if Parser.is_string? s
|
41
|
+
data[:comma] = true if Parser.is_comma? s
|
42
|
+
data[:join] = true if Parser.is_join? s
|
43
|
+
data[:join_type] = true if Parser.is_join_type? s
|
44
|
+
data[:begin] = true if Parser.is_begin? s
|
45
|
+
data[:end] = true if Parser.is_end? s
|
46
|
+
data[:terminator] = true if Parser.is_terminator? s
|
47
|
+
data[:value] = data[:value].upcase if data[:keyword] or data[:function] or data[:type]
|
48
|
+
data[:needs_newline] = true if data[:keyword] and Parser.is_newline_required? s
|
49
|
+
data
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# __ .__
|
2
|
+
# _/ |_ ___________| | ___________ _______ ______ ___________
|
3
|
+
# \ __\/ ___/ ____/ | ______ \____ \__ \\_ __ \/ ___// __ \_ __ \
|
4
|
+
# | | \___ < <_| | |__ /_____/ | |_> > __ \| | \/\___ \\ ___/| | \/
|
5
|
+
# |__| /____ >__ |____/ | __(____ /__| /____ >\___ >__|
|
6
|
+
# \/ |__| |__| \/ \/ \/
|
7
|
+
#
|
8
|
+
# A very light-weight and opinionated T-SQL parser and formatter.
|
9
|
+
#
|
10
|
+
# github.com/scstauf
|
11
|
+
#
|
12
|
+
# path:
|
13
|
+
# parsing/model/token_transformer.rb
|
14
|
+
# object:
|
15
|
+
# TSqlParser::Parsing::TokenTransformer
|
16
|
+
|
17
|
+
module TSqlParser::Parsing
|
18
|
+
require_relative "../models/sql_container"
|
19
|
+
require_relative "../models/flat_sql_container"
|
20
|
+
|
21
|
+
class TokenTransformer
|
22
|
+
def self.transform(tokens)
|
23
|
+
containers = self.as_containers(tokens)
|
24
|
+
self.combine_containers(containers)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def self.as_containers(tokens)
|
30
|
+
containers = []
|
31
|
+
container = nil
|
32
|
+
skip_count = 0
|
33
|
+
tokens.each_with_index do |t, index|
|
34
|
+
if skip_count > 0
|
35
|
+
skip_count -= 1
|
36
|
+
next
|
37
|
+
end
|
38
|
+
|
39
|
+
next_token = tokens[index + 1]
|
40
|
+
|
41
|
+
if t[:string]
|
42
|
+
container.add t unless container.nil?
|
43
|
+
elsif Parser.is_new_node_keyword? t[:value]
|
44
|
+
if not next_token.nil? and Parser.is_new_node_keyword? next_token[:value]
|
45
|
+
if Parser.is_new_node_composite?(t[:value], next_token[:value])
|
46
|
+
containers << container unless container.nil?
|
47
|
+
container = SqlContainer.combine(t, next_token)
|
48
|
+
skip_count = 1
|
49
|
+
next
|
50
|
+
end
|
51
|
+
end
|
52
|
+
containers << container unless container.nil?
|
53
|
+
container = SqlContainer.new(t)
|
54
|
+
elsif t[:value] == "WITH"
|
55
|
+
if not next_token.nil? and not next_token[:keyword] and not next_token[:parenthesis]
|
56
|
+
containers << container unless container.nil?
|
57
|
+
container = SqlContainer.new(t)
|
58
|
+
else
|
59
|
+
container.add t unless container.nil?
|
60
|
+
end
|
61
|
+
elsif t[:label]
|
62
|
+
containers << container unless container.nil?
|
63
|
+
container = SqlContainer.new(t)
|
64
|
+
else
|
65
|
+
container.add t unless container.nil?
|
66
|
+
end
|
67
|
+
end
|
68
|
+
containers << container unless container.nil?
|
69
|
+
FlatSqlContainer.flatten_containers(containers)
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.combine_containers(containers)
|
73
|
+
lines = []
|
74
|
+
containers.each do |c|
|
75
|
+
ct = c.get_token
|
76
|
+
|
77
|
+
builder = []
|
78
|
+
builder << ct[:value]
|
79
|
+
|
80
|
+
if c.has_siblings?
|
81
|
+
c.get_siblings.each do |sibling|
|
82
|
+
st = sibling.get_token
|
83
|
+
|
84
|
+
if st[:comment]
|
85
|
+
builder << "\n#{st[:value]}"
|
86
|
+
next
|
87
|
+
end
|
88
|
+
|
89
|
+
builder << st[:value]
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
lines << builder.join(" ")
|
94
|
+
end
|
95
|
+
|
96
|
+
lines
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tsql_parser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Scott Stauffer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-03
|
11
|
+
date: 2023-04-03 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: A very light-weight and opinionated T-SQL parser and formatter.
|
14
14
|
email: scott@fuseraft.com
|
@@ -25,12 +25,13 @@ files:
|
|
25
25
|
- lib/parsing/formatters/strategy/update_formatter.rb
|
26
26
|
- lib/parsing/formatters/strategy/where_formatter.rb
|
27
27
|
- lib/parsing/formatters/text_formatter.rb
|
28
|
-
- lib/parsing/iterator.rb
|
29
28
|
- lib/parsing/keyword.rb
|
30
|
-
- lib/parsing/
|
31
|
-
- lib/parsing/
|
29
|
+
- lib/parsing/models/flat_sql_container.rb
|
30
|
+
- lib/parsing/models/sql_container.rb
|
32
31
|
- lib/parsing/parser.rb
|
33
32
|
- lib/parsing/tokenizer.rb
|
33
|
+
- lib/parsing/transformers/token_categorizer.rb
|
34
|
+
- lib/parsing/transformers/token_transformer.rb
|
34
35
|
- lib/tsql_parser.rb
|
35
36
|
homepage: https://rubygems.org/gems/tsql_parser
|
36
37
|
licenses:
|
@@ -53,7 +54,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
53
54
|
- !ruby/object:Gem::Version
|
54
55
|
version: '0'
|
55
56
|
requirements: []
|
56
|
-
rubygems_version: 3.
|
57
|
+
rubygems_version: 3.1.6
|
57
58
|
signing_key:
|
58
59
|
specification_version: 4
|
59
60
|
summary: A very light-weight and opinionated T-SQL parser and formatter.
|
data/lib/parsing/iterator.rb
DELETED
@@ -1,54 +0,0 @@
|
|
1
|
-
# __ .__
|
2
|
-
# _/ |_ ___________| | ___________ _______ ______ ___________
|
3
|
-
# \ __\/ ___/ ____/ | ______ \____ \__ \\_ __ \/ ___// __ \_ __ \
|
4
|
-
# | | \___ < <_| | |__ /_____/ | |_> > __ \| | \/\___ \\ ___/| | \/
|
5
|
-
# |__| /____ >__ |____/ | __(____ /__| /____ >\___ >__|
|
6
|
-
# \/ |__| |__| \/ \/ \/
|
7
|
-
#
|
8
|
-
# A very light-weight and opinionated T-SQL parser and formatter.
|
9
|
-
#
|
10
|
-
# github.com/scstauf
|
11
|
-
#
|
12
|
-
# path:
|
13
|
-
# parsing/iterator.rb
|
14
|
-
# object:
|
15
|
-
# TSqlParser::Parsing::TokenIterator
|
16
|
-
|
17
|
-
module TSqlParser::Parsing
|
18
|
-
class TokenIterator
|
19
|
-
def initialize(tokens)
|
20
|
-
@tokens = tokens
|
21
|
-
@size = tokens.size
|
22
|
-
@iter = -1
|
23
|
-
end
|
24
|
-
|
25
|
-
def has_next?
|
26
|
-
@iter < @size - 1
|
27
|
-
end
|
28
|
-
|
29
|
-
def get!
|
30
|
-
@tokens[@iter]
|
31
|
-
end
|
32
|
-
|
33
|
-
def peek!
|
34
|
-
@tokens[@iter + 1]
|
35
|
-
end
|
36
|
-
|
37
|
-
def peek_ahead!(length)
|
38
|
-
@tokens[@iter + length]
|
39
|
-
end
|
40
|
-
|
41
|
-
def peek_value!
|
42
|
-
self.peek![:value]
|
43
|
-
end
|
44
|
-
|
45
|
-
def peek_ahead_value!(length)
|
46
|
-
self.peek_ahead!(length)[:value]
|
47
|
-
end
|
48
|
-
|
49
|
-
def next!
|
50
|
-
@iter += 1
|
51
|
-
self.get!
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
File without changes
|
File without changes
|