tsql_parser 0.1.4 → 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/parsing/config/defaults.rb +56 -0
- data/lib/parsing/formatter.rb +14 -75
- data/lib/parsing/formatters/format_factory.rb +32 -0
- data/lib/parsing/formatters/strategy/__defaults.rb +16 -0
- data/lib/parsing/formatters/strategy/__formatters.rb +31 -0
- data/lib/parsing/formatters/strategy/base_formatter.rb +12 -2
- data/lib/parsing/formatters/strategy/cte_formatter.rb +25 -0
- data/lib/parsing/formatters/strategy/insert_formatter.rb +2 -2
- data/lib/parsing/formatters/strategy/join_formatter.rb +4 -2
- data/lib/parsing/formatters/strategy/select_formatter.rb +2 -2
- data/lib/parsing/formatters/strategy/set_formatter.rb +3 -3
- data/lib/parsing/formatters/strategy/update_formatter.rb +2 -2
- data/lib/parsing/formatters/strategy/where_formatter.rb +2 -2
- data/lib/parsing/formatters/text_formatter.rb +9 -25
- data/lib/parsing/keyword.rb +1 -1
- data/lib/parsing/parser.rb +2 -2
- data/lib/parsing/tokenizer.rb +139 -110
- data/lib/parsing/transformers/token_categorizer.rb +52 -0
- data/lib/parsing/transformers/token_transformer.rb +153 -0
- data/lib/tsql_parser.rb +3 -1
- metadata +11 -5
- 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: d67275fb1f5b1ff478b0e8a79d99af69a2d33b53059822e882b6a0c94e68d0a1
|
4
|
+
data.tar.gz: 50b27357c58d8c0ca89b069ddef3a03e4565b1e354a7e322d79c9ba64440895d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dd4314846a33bd5b4c0e99dd41ecb67c65494faf015fc5ec81ffcf74cd5f98c52215bc28fd1a8729e0a1694ad7a055b09f51b724b0d7f27ae945a3ed2f778d13
|
7
|
+
data.tar.gz: 664dce679b765bf73e229f5cafc4eb0059f540c85674d4b6d41f1e3508e7536d512c457b64075d6c0f12b70bf7d3bfabdf4887466894beceec4182f444a5b986
|
@@ -0,0 +1,56 @@
|
|
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/config/defaults.rb
|
14
|
+
# object:
|
15
|
+
# TSqlParser::Parsing::Defaults
|
16
|
+
|
17
|
+
module TSqlParser::Parsing
|
18
|
+
class Defaults
|
19
|
+
@@default_single_char_tokens = ["(", ",", ")", "=", "+", "-", "%", "/", "*", "<", "!", ">", "'", "[", "]", ";"]
|
20
|
+
@@default_delimiters = [" ", "\n", "\t"]
|
21
|
+
@@default_tab_count = 0
|
22
|
+
@@default_tab = " "
|
23
|
+
|
24
|
+
def self.set_default_tab_count(tab_count = 0)
|
25
|
+
@@default_tab_count = tab_count
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.set_default_tab(tab = " ")
|
29
|
+
@@default_tab = tab
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.set_default_single_char_tokens(single_char_tokens = ["(", ",", ")", "=", "+", "-", "%", "/", "*", "<", "!", ">", "'", "[", "]", ";"])
|
33
|
+
@@default_single_char_tokens = single_char_tokens
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.set_default_delimiters(delimiters = [" ", "\n", "\t"])
|
37
|
+
@@default_delimiters = delimiters
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.get_default_single_char_tokens
|
41
|
+
@@default_single_char_tokens
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.get_default_delimiters
|
45
|
+
@@default_delimiters
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.get_default_tab_count
|
49
|
+
@@default_tab_count
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.get_default_tab
|
53
|
+
@@default_tab
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/lib/parsing/formatter.rb
CHANGED
@@ -15,26 +15,25 @@
|
|
15
15
|
# TSqlParser::Parsing::Formatter
|
16
16
|
|
17
17
|
module TSqlParser::Parsing
|
18
|
-
require_relative "
|
18
|
+
require_relative "config/defaults"
|
19
19
|
require_relative "parser"
|
20
20
|
require_relative "formatters/text_formatter"
|
21
|
-
require_relative "
|
22
|
-
|
23
|
-
|
21
|
+
require_relative "transformers/token_transformer"
|
22
|
+
|
24
23
|
class Formatter
|
25
|
-
def self.format(tokens, tab_count =
|
26
|
-
|
27
|
-
lines = self.combine_containers(containers)
|
24
|
+
def self.format(tokens, tab_count = Defaults.get_default_tab_count, tab = Defaults.get_default_tab)
|
25
|
+
lines = TokenTransformer.transform(tokens)
|
28
26
|
lines = self.cleanup_whitespace(lines)
|
29
27
|
lines = self.insert_indentation(lines, tab_count, tab)
|
30
|
-
lines = self.insert_newlines(lines)
|
28
|
+
#lines = self.insert_newlines(lines)
|
31
29
|
text = lines.join("\n")
|
32
|
-
text = TextFormatter.
|
33
|
-
text = TextFormatter.
|
34
|
-
text = TextFormatter.
|
35
|
-
text = TextFormatter.
|
36
|
-
text = TextFormatter.
|
37
|
-
text = TextFormatter.
|
30
|
+
text = TextFormatter.new(JOIN, text, tab).format
|
31
|
+
text = TextFormatter.new(INSERT, text, tab).format
|
32
|
+
text = TextFormatter.new(UPDATE, text, tab).format
|
33
|
+
text = TextFormatter.new(WHERE, text, tab).format
|
34
|
+
text = TextFormatter.new(SELECT, text, tab).format
|
35
|
+
text = TextFormatter.new(SET, text, tab).format
|
36
|
+
puts text
|
38
37
|
text
|
39
38
|
end
|
40
39
|
|
@@ -63,7 +62,7 @@ module TSqlParser::Parsing
|
|
63
62
|
new_lines
|
64
63
|
end
|
65
64
|
|
66
|
-
def self.insert_indentation(lines, tab_count =
|
65
|
+
def self.insert_indentation(lines, tab_count = Defaults.get_default_tab_count, tab = Defaults.get_default_tab)
|
67
66
|
indented_lines = []
|
68
67
|
work_lines = []
|
69
68
|
lines.each do |line|
|
@@ -116,66 +115,6 @@ module TSqlParser::Parsing
|
|
116
115
|
lines
|
117
116
|
end
|
118
117
|
|
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
118
|
def self.safe_ws_cleanup(line)
|
180
119
|
parts = []
|
181
120
|
builder = ""
|
@@ -0,0 +1,32 @@
|
|
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/formatters/format_factory.rb
|
14
|
+
# object:
|
15
|
+
# TSqlParser::Parsing::FormatFactory
|
16
|
+
|
17
|
+
module TSqlParser::Parsing
|
18
|
+
require_relative "strategy/__formatters"
|
19
|
+
class FormatFactory
|
20
|
+
def self.get(type)
|
21
|
+
case type
|
22
|
+
when CTE then Formatters::CommonTableExpressionFormatter.new
|
23
|
+
when INSERT then Formatters::InsertFormatter.new
|
24
|
+
when JOIN then Formatters::JoinFormatter.new
|
25
|
+
when SELECT then Formatters::SelectFormatter.new
|
26
|
+
when SET then Formatters::SetFormatter.new
|
27
|
+
when UPDATE then Formatters::UpdateFormatter.new
|
28
|
+
when WHERE then Formatters::WhereFormatter.new
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,16 @@
|
|
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/formatters/strategy/__defaults.rb
|
14
|
+
|
15
|
+
require_relative "../../config/defaults"
|
16
|
+
Defaults = TSqlParser::Parsing::Defaults
|
@@ -0,0 +1,31 @@
|
|
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/formatters/strategy/__formatters.rb
|
14
|
+
|
15
|
+
module TSqlParser::Parsing
|
16
|
+
require_relative "cte_formatter"
|
17
|
+
require_relative "set_formatter"
|
18
|
+
require_relative "join_formatter"
|
19
|
+
require_relative "insert_formatter"
|
20
|
+
require_relative "select_formatter"
|
21
|
+
require_relative "update_formatter"
|
22
|
+
require_relative "where_formatter"
|
23
|
+
|
24
|
+
CTE = 0
|
25
|
+
INSERT = 1
|
26
|
+
JOIN = 2
|
27
|
+
SELECT = 3
|
28
|
+
SET = 4
|
29
|
+
UPDATE = 5
|
30
|
+
WHERE = 6
|
31
|
+
end
|
@@ -15,14 +15,24 @@
|
|
15
15
|
# TSqlParser::Parsing::Formatters::SetFormatter
|
16
16
|
|
17
17
|
module TSqlParser::Parsing::Formatters
|
18
|
+
require_relative "__defaults"
|
19
|
+
|
18
20
|
class BaseFormatter
|
19
|
-
def
|
20
|
-
tab_count =
|
21
|
+
def get_tab_count(line, tab = Defaults.get_default_tab)
|
22
|
+
tab_count = Defaults.get_default_tab_count
|
21
23
|
while line.start_with? tab
|
22
24
|
tab_count += 1
|
23
25
|
line = line.sub(tab, "")
|
24
26
|
end
|
25
27
|
tab_count
|
26
28
|
end
|
29
|
+
|
30
|
+
# @abstract
|
31
|
+
#
|
32
|
+
# @param [String] text
|
33
|
+
# @param [String] tab
|
34
|
+
def format(text, tab = Defaults.get_default_tab)
|
35
|
+
raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
|
36
|
+
end
|
27
37
|
end
|
28
38
|
end
|
@@ -0,0 +1,25 @@
|
|
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/formatters/cte_formatter.rb
|
14
|
+
# object:
|
15
|
+
# TSqlParser::Parsing::Formatters::CommonTableExpressionFormatter
|
16
|
+
|
17
|
+
module TSqlParser::Parsing::Formatters
|
18
|
+
require_relative "base_formatter"
|
19
|
+
|
20
|
+
class CommonTableExpressionFormatter < BaseFormatter
|
21
|
+
def format(text, tab = Defaults.get_default_tab)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
@@ -18,7 +18,7 @@ module TSqlParser::Parsing::Formatters
|
|
18
18
|
require_relative "base_formatter"
|
19
19
|
|
20
20
|
class InsertFormatter < BaseFormatter
|
21
|
-
def
|
21
|
+
def format(text, tab = Defaults.get_default_tab)
|
22
22
|
formatted = []
|
23
23
|
lines = text.split("\n")
|
24
24
|
search = "INSERT INTO"
|
@@ -43,7 +43,7 @@ module TSqlParser::Parsing::Formatters
|
|
43
43
|
|
44
44
|
private
|
45
45
|
|
46
|
-
def
|
46
|
+
def format_insert(s, tab_count = Defaults.get_default_tab_count, tab = Defaults.get_default_tab)
|
47
47
|
return s if s.nil?
|
48
48
|
formatted = []
|
49
49
|
if s.include? ") VALUES ("
|
@@ -18,15 +18,17 @@ module TSqlParser::Parsing::Formatters
|
|
18
18
|
require_relative "base_formatter"
|
19
19
|
|
20
20
|
class JoinFormatter < BaseFormatter
|
21
|
-
def
|
21
|
+
def format(text, tab = Defaults.get_default_tab)
|
22
22
|
text = text.gsub(/INNER\s+JOIN/, "INNER JOIN")
|
23
23
|
.gsub(/LEFT\s+JOIN/, "LEFT JOIN")
|
24
|
+
.gsub(/RIGHT\s+JOIN/, "RIGHT JOIN")
|
25
|
+
.gsub(/CROSS\s+JOIN/, "CROSS JOIN")
|
24
26
|
lines = text.split("\n")
|
25
27
|
new_text = []
|
26
28
|
|
27
29
|
lines.each do |line|
|
28
30
|
first = line.strip.split(" ").first
|
29
|
-
if line.include? " WHERE " and first != "WHERE" and not first.start_with? "--" and not first.start_with? "/*"
|
31
|
+
if line.include? " WHERE " and first != "WHERE" and not first.start_with? "--" and not first.start_with? "/*" and not line.strip.end_with? "'"
|
30
32
|
tab_count = self.get_tab_count(line, tab)
|
31
33
|
where_parts = line.strip.split(" WHERE ")
|
32
34
|
where_text = []
|
@@ -18,7 +18,7 @@ module TSqlParser::Parsing::Formatters
|
|
18
18
|
require_relative "base_formatter"
|
19
19
|
|
20
20
|
class SelectFormatter < BaseFormatter
|
21
|
-
def
|
21
|
+
def format(text, tab = Defaults.get_default_tab)
|
22
22
|
formatted = []
|
23
23
|
lines = text.split("\n")
|
24
24
|
lines.each do |line|
|
@@ -42,7 +42,7 @@ module TSqlParser::Parsing::Formatters
|
|
42
42
|
|
43
43
|
private
|
44
44
|
|
45
|
-
def
|
45
|
+
def format_select(s, tab_count = Defaults.get_default_tab_count, tab = Defaults.get_default_tab)
|
46
46
|
return s if s.nil?
|
47
47
|
|
48
48
|
tokens = s.split(", ")
|
@@ -15,10 +15,10 @@
|
|
15
15
|
# TSqlParser::Parsing::Formatters::SetFormatter
|
16
16
|
|
17
17
|
module TSqlParser::Parsing::Formatters
|
18
|
-
require_relative
|
18
|
+
require_relative "base_formatter"
|
19
19
|
|
20
20
|
class SetFormatter < BaseFormatter
|
21
|
-
def
|
21
|
+
def format(text, tab = Defaults.get_default_tab)
|
22
22
|
formatted = []
|
23
23
|
lines = text.split("\n")
|
24
24
|
wait = false
|
@@ -71,7 +71,7 @@ module TSqlParser::Parsing::Formatters
|
|
71
71
|
|
72
72
|
private
|
73
73
|
|
74
|
-
def
|
74
|
+
def format_set(s, tab_count = Defaults.get_default_tab_count, tab = Defaults.get_default_tab)
|
75
75
|
return s if s.nil?
|
76
76
|
parts = []
|
77
77
|
builder = ""
|
@@ -18,7 +18,7 @@ module TSqlParser::Parsing::Formatters
|
|
18
18
|
require_relative "base_formatter"
|
19
19
|
|
20
20
|
class UpdateFormatter < BaseFormatter
|
21
|
-
def
|
21
|
+
def format(text, tab = Defaults.get_default_tab)
|
22
22
|
formatted = []
|
23
23
|
lines = text.split("\n")
|
24
24
|
lines.each do |line|
|
@@ -42,7 +42,7 @@ module TSqlParser::Parsing::Formatters
|
|
42
42
|
|
43
43
|
private
|
44
44
|
|
45
|
-
def
|
45
|
+
def format_update(s, tab_count = Defaults.get_default_tab_count, tab = Defaults.get_default_tab)
|
46
46
|
return s if s.nil?
|
47
47
|
"\n#{tab * (tab_count + 1)}#{s}"
|
48
48
|
end
|
@@ -18,7 +18,7 @@ module TSqlParser::Parsing::Formatters
|
|
18
18
|
require_relative "base_formatter"
|
19
19
|
|
20
20
|
class WhereFormatter < BaseFormatter
|
21
|
-
def
|
21
|
+
def format(text, tab = Defaults.get_default_tab)
|
22
22
|
formatted = []
|
23
23
|
text.split("\n").each do |line|
|
24
24
|
first = line.strip.split(" ").first
|
@@ -42,7 +42,7 @@ module TSqlParser::Parsing::Formatters
|
|
42
42
|
|
43
43
|
private
|
44
44
|
|
45
|
-
def
|
45
|
+
def format_predicate(s, tab_count = Defaults.get_default_tab_count, tab = Defaults.get_default_tab)
|
46
46
|
return s if s.nil?
|
47
47
|
indented = []
|
48
48
|
formatted = []
|
@@ -15,36 +15,20 @@
|
|
15
15
|
# TSqlParser::Parsing::Formatter
|
16
16
|
|
17
17
|
module TSqlParser::Parsing
|
18
|
-
require_relative
|
19
|
-
require_relative
|
20
|
-
require_relative 'strategy/insert_formatter'
|
21
|
-
require_relative 'strategy/select_formatter'
|
22
|
-
require_relative 'strategy/update_formatter'
|
23
|
-
require_relative 'strategy/where_formatter'
|
18
|
+
require_relative "strategy/__defaults"
|
19
|
+
require_relative "format_factory"
|
24
20
|
|
25
21
|
class TextFormatter
|
26
|
-
|
27
|
-
Formatters::SetFormatter.format(text, tab)
|
28
|
-
end
|
29
|
-
|
30
|
-
def self.format_joins(text, tab = " ")
|
31
|
-
Formatters::JoinFormatter.format(text, tab)
|
32
|
-
end
|
33
|
-
|
34
|
-
def self.format_updates(text, tab = " ")
|
35
|
-
Formatters::UpdateFormatter.format(text, tab)
|
36
|
-
end
|
37
|
-
|
38
|
-
def self.format_inserts(text, tab = " ")
|
39
|
-
Formatters::InsertFormatter.format(text, tab)
|
40
|
-
end
|
22
|
+
attr_writer :strategy
|
41
23
|
|
42
|
-
def
|
43
|
-
|
24
|
+
def initialize(strategy, text, tab = Defaults.get_default_tab)
|
25
|
+
@strategy = FormatFactory.get(strategy)
|
26
|
+
@text = text
|
27
|
+
@tab = tab
|
44
28
|
end
|
45
29
|
|
46
|
-
def
|
47
|
-
|
30
|
+
def format
|
31
|
+
@strategy.format(@text, @tab)
|
48
32
|
end
|
49
33
|
end
|
50
34
|
end
|
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,166 @@
|
|
15
15
|
# TSqlParser::Parsing::Tokenizer
|
16
16
|
|
17
17
|
module TSqlParser::Parsing
|
18
|
-
require_relative "
|
18
|
+
require_relative "config/defaults"
|
19
|
+
require_relative "transformers/token_categorizer"
|
19
20
|
|
20
21
|
class Tokenizer
|
21
22
|
def self.tokenize(tsql_string)
|
22
|
-
|
23
|
-
tsql_string,
|
24
|
-
["(", ",", ")", "=", "+", "-", "%", "/", "*", "<", "!", ">", "'", "[", "]", ";"],
|
25
|
-
[" ", "\n", "\t"]
|
26
|
-
)
|
27
|
-
tokens.map do |t|
|
28
|
-
categorize(t)
|
29
|
-
end
|
23
|
+
Tokenizer.new.basic_tokenize(tsql_string).map { |t| TokenCategorizer.categorize(t) }
|
30
24
|
end
|
31
25
|
|
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 = ""
|
26
|
+
def basic_tokenize(tsql_string)
|
27
|
+
self.reset
|
67
28
|
tsql_chars = tsql_string.split("")
|
68
|
-
|
69
|
-
comment = false
|
70
|
-
string = false
|
71
|
-
string_count = 0
|
72
|
-
skip_count = 0
|
29
|
+
|
73
30
|
tsql_chars.each_with_index do |c, i|
|
74
|
-
if skip_count > 0
|
75
|
-
skip_count -= 1
|
31
|
+
if @skip_count > 0
|
32
|
+
@skip_count -= 1
|
76
33
|
next
|
77
34
|
end
|
78
35
|
|
79
|
-
|
36
|
+
# get last and next char
|
37
|
+
@c = c
|
38
|
+
@last_c = tsql_chars[i - 1] unless i - 1 < 0
|
39
|
+
@next_c = tsql_chars[i + 1] unless i + 1 > tsql_chars.size
|
80
40
|
|
81
|
-
if
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
next
|
41
|
+
# if we aren't in a string.
|
42
|
+
unless @string
|
43
|
+
next if self.handle_multicomment_start
|
44
|
+
next if self.handle_multicomment_end
|
45
|
+
next if self.handle_singlecomment_start
|
46
|
+
next if self.build_comment
|
86
47
|
end
|
87
48
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
specific_tokens << builder unless builder.empty?
|
93
|
-
builder = ""
|
94
|
-
next
|
49
|
+
unless @multiline_comment or @comment
|
50
|
+
next if self.handle_string_char
|
51
|
+
next if self.handle_two_char_op
|
52
|
+
next if self.handle_delimiter
|
95
53
|
end
|
96
54
|
|
97
|
-
|
98
|
-
|
99
|
-
skip_count = 1
|
100
|
-
specific_tokens << builder unless builder.empty?
|
101
|
-
builder = "--"
|
102
|
-
next
|
103
|
-
end
|
55
|
+
self.build
|
56
|
+
end
|
104
57
|
|
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
|
58
|
+
self.flush_builder
|
59
|
+
@tokens
|
60
|
+
end
|
114
61
|
|
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
|
62
|
+
private
|
129
63
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
64
|
+
def handle_multicomment_start
|
65
|
+
if Parser.is_multiline_comment_start?(@c, @next_c)
|
66
|
+
@multiline_comment = true
|
67
|
+
self.flush_builder(c)
|
68
|
+
return true
|
69
|
+
end
|
70
|
+
end
|
137
71
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
72
|
+
def handle_multicomment_end
|
73
|
+
if Parser.is_multiline_comment_end?(@c, @next_c)
|
74
|
+
@skip_count = 1
|
75
|
+
@multiline_comment = false
|
76
|
+
self.build
|
77
|
+
self.build(@next_c)
|
78
|
+
self.flush_builder("")
|
79
|
+
return true
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def handle_singlecomment_start
|
84
|
+
if Parser.is_comment_start?(@c, @next_c) and not @comment
|
85
|
+
@comment = true
|
86
|
+
@skip_count = 1
|
87
|
+
self.flush_builder("--")
|
88
|
+
return true
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def handle_singlecomment_end
|
93
|
+
if @c == "\n"
|
94
|
+
self.flush_builder("")
|
95
|
+
@comment = false
|
96
|
+
return true
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def handle_string_char
|
101
|
+
if @c == "'"
|
102
|
+
@string_count += 1
|
103
|
+
return true if self.handle_string_start
|
104
|
+
@string_count += 1 if @next_c == "'"
|
105
|
+
return true if self.handle_string_end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def handle_string_start
|
110
|
+
if not @string
|
111
|
+
@string = true
|
112
|
+
self.flush_builder(@c)
|
113
|
+
return true
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def handle_string_end
|
118
|
+
if @string_count % 2 == 0
|
119
|
+
@string = false
|
120
|
+
@string_count = 0
|
121
|
+
self.build
|
122
|
+
self.flush_builder("")
|
123
|
+
return true
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def handle_two_char_op
|
128
|
+
if Parser.is_two_char_op?(@c, @next_c)
|
129
|
+
@skip_count = 1
|
130
|
+
self.flush_builder("")
|
131
|
+
@tokens << "#{@c}#{@next_c}"
|
132
|
+
return true
|
133
|
+
end
|
134
|
+
end
|
144
135
|
|
145
|
-
|
136
|
+
def handle_delimiter
|
137
|
+
if @delimiters.include? @c and !@multiline_comment and !@comment and !@string
|
138
|
+
self.flush_builder("")
|
139
|
+
@tokens << @c unless @skip_delimiters.include? @c
|
140
|
+
return true
|
146
141
|
end
|
147
|
-
|
148
|
-
|
142
|
+
end
|
143
|
+
|
144
|
+
def build(value = nil)
|
145
|
+
@builder << @c if value.nil?
|
146
|
+
@builder << value unless value.nil?
|
147
|
+
end
|
148
|
+
|
149
|
+
def build_comment
|
150
|
+
if @comment
|
151
|
+
return true if self.handle_singlecomment_end
|
152
|
+
|
153
|
+
self.build
|
154
|
+
return true
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def flush_builder(value = nil)
|
159
|
+
@tokens << @builder unless @builder.empty?
|
160
|
+
@builder = value
|
161
|
+
end
|
162
|
+
|
163
|
+
def initialize
|
164
|
+
self.reset
|
165
|
+
end
|
166
|
+
|
167
|
+
def reset
|
168
|
+
@tokens = []
|
169
|
+
@multiline_comment = false
|
170
|
+
@comment = false
|
171
|
+
@string = false
|
172
|
+
@string_count = 0
|
173
|
+
@skip_count = 0
|
174
|
+
@char_delimiters = Defaults.get_default_single_char_tokens
|
175
|
+
@skip_delimiters = Defaults.get_default_delimiters
|
176
|
+
@delimiters = ([] << @char_delimiters << @skip_delimiters).flatten.uniq
|
177
|
+
@builder = ""
|
149
178
|
end
|
150
179
|
end
|
151
180
|
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,153 @@
|
|
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 initialize(tokens = [])
|
23
|
+
@containers = []
|
24
|
+
@container = nil
|
25
|
+
@skip_count = 0
|
26
|
+
@cte = ""
|
27
|
+
@parenthesis = 0
|
28
|
+
@tokens = tokens
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.transform(tokens)
|
32
|
+
TokenTransformer.new(tokens).transform
|
33
|
+
end
|
34
|
+
|
35
|
+
def transform
|
36
|
+
@tokens.each_with_index do |t, index|
|
37
|
+
@parenthesis += 1 if t[:open_parenthesis]
|
38
|
+
@parenthesis -= 1 if t[:close_parenthesis]
|
39
|
+
|
40
|
+
next if self.handle_skip
|
41
|
+
|
42
|
+
@t = t
|
43
|
+
@last_token = @tokens[index - 1] unless index - 1 < 0
|
44
|
+
@next_token = @tokens[index + 1] unless index + 1 > @tokens.size
|
45
|
+
|
46
|
+
next if self.handle_cte_end
|
47
|
+
|
48
|
+
if t[:string]
|
49
|
+
self.add_to_container
|
50
|
+
elsif Parser.is_new_node_keyword? t[:value]
|
51
|
+
if not @next_token.nil? and Parser.is_new_node_keyword? @next_token[:value]
|
52
|
+
if Parser.is_new_node_composite?(@t[:value], @next_token[:value])
|
53
|
+
self.add_container
|
54
|
+
@container = SqlContainer.combine(@t, @next_token)
|
55
|
+
@skip_count = 1
|
56
|
+
next
|
57
|
+
end
|
58
|
+
end
|
59
|
+
self.add_container
|
60
|
+
self.new_container
|
61
|
+
elsif t[:value] == "WITH"
|
62
|
+
if not @next_token.nil? and not @next_token[:keyword] and not @next_token[:parenthesis]
|
63
|
+
self.add_container
|
64
|
+
self.new_container
|
65
|
+
@cte = @next_token[:value]
|
66
|
+
else
|
67
|
+
self.add_to_container
|
68
|
+
end
|
69
|
+
elsif @t[:label]
|
70
|
+
self.add_container
|
71
|
+
self.new_container
|
72
|
+
else
|
73
|
+
self.add_to_container
|
74
|
+
end
|
75
|
+
end
|
76
|
+
self.add_container
|
77
|
+
self.get_lines_from_containers
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def handle_skip
|
83
|
+
if @skip_count > 0
|
84
|
+
@skip_count -= 1
|
85
|
+
return true
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def add_to_container
|
90
|
+
@container.add @t unless @container.nil?
|
91
|
+
end
|
92
|
+
|
93
|
+
def add_container
|
94
|
+
@containers << @container unless @container.nil?
|
95
|
+
end
|
96
|
+
|
97
|
+
def new_container
|
98
|
+
@container = SqlContainer.new(@t)
|
99
|
+
end
|
100
|
+
|
101
|
+
def handle_cte_end
|
102
|
+
if not @cte.empty?
|
103
|
+
if not @last_token.nil? and @last_token[:close_parenthesis] and @parenthesis == 0
|
104
|
+
if @t[:keyword]
|
105
|
+
self.add_container
|
106
|
+
self.new_container
|
107
|
+
@cte = ""
|
108
|
+
else
|
109
|
+
self.add_to_container
|
110
|
+
end
|
111
|
+
elsif not @last_token.nil? and not @last_token[:keyword] and @t[:value] == "AS"
|
112
|
+
self.add_to_container
|
113
|
+
elsif not @last_token.nil? and @last_token[:comma] and not @t[:keyword] and not @next_token.nil? and @next_token[:value] == "AS"
|
114
|
+
self.add_container
|
115
|
+
self.new_container
|
116
|
+
@cte = @t[:value]
|
117
|
+
else
|
118
|
+
self.add_to_container
|
119
|
+
end
|
120
|
+
return true
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def get_lines_from_containers
|
125
|
+
@containers = FlatSqlContainer.flatten_containers(@containers)
|
126
|
+
|
127
|
+
lines = []
|
128
|
+
@containers.each do |c|
|
129
|
+
ct = c.get_token
|
130
|
+
|
131
|
+
builder = []
|
132
|
+
builder << ct[:value]
|
133
|
+
|
134
|
+
if c.has_siblings?
|
135
|
+
c.get_siblings.each do |sibling|
|
136
|
+
st = sibling.get_token
|
137
|
+
|
138
|
+
if st[:comment]
|
139
|
+
builder << "\n#{st[:value]}"
|
140
|
+
next
|
141
|
+
end
|
142
|
+
|
143
|
+
builder << st[:value]
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
lines << builder.join(" ")
|
148
|
+
end
|
149
|
+
|
150
|
+
lines
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
data/lib/tsql_parser.rb
CHANGED
@@ -15,13 +15,15 @@
|
|
15
15
|
# TSqlParser
|
16
16
|
|
17
17
|
module TSqlParser
|
18
|
+
require_relative "parsing/config/defaults"
|
19
|
+
|
18
20
|
# Formats a SQL string.
|
19
21
|
#
|
20
22
|
# @param sql [String] the SQL string to format.
|
21
23
|
# @param tab_count [Integer] the number of tabs to start with.
|
22
24
|
# @param tab [String] the tab string.
|
23
25
|
# @return [String] the formatted SQL string.
|
24
|
-
def self.format(sql, tab_count =
|
26
|
+
def self.format(sql, tab_count = Parsing::Defaults.get_default_tab_count, tab = Parsing::Defaults.get_default_tab)
|
25
27
|
require_relative "parsing/formatter"
|
26
28
|
tokens = self.parse(sql)
|
27
29
|
Parsing::Formatter.format(tokens, tab_count, tab)
|
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.6
|
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
|
@@ -16,8 +16,13 @@ executables: []
|
|
16
16
|
extensions: []
|
17
17
|
extra_rdoc_files: []
|
18
18
|
files:
|
19
|
+
- lib/parsing/config/defaults.rb
|
19
20
|
- lib/parsing/formatter.rb
|
21
|
+
- lib/parsing/formatters/format_factory.rb
|
22
|
+
- lib/parsing/formatters/strategy/__defaults.rb
|
23
|
+
- lib/parsing/formatters/strategy/__formatters.rb
|
20
24
|
- lib/parsing/formatters/strategy/base_formatter.rb
|
25
|
+
- lib/parsing/formatters/strategy/cte_formatter.rb
|
21
26
|
- lib/parsing/formatters/strategy/insert_formatter.rb
|
22
27
|
- lib/parsing/formatters/strategy/join_formatter.rb
|
23
28
|
- lib/parsing/formatters/strategy/select_formatter.rb
|
@@ -25,12 +30,13 @@ files:
|
|
25
30
|
- lib/parsing/formatters/strategy/update_formatter.rb
|
26
31
|
- lib/parsing/formatters/strategy/where_formatter.rb
|
27
32
|
- lib/parsing/formatters/text_formatter.rb
|
28
|
-
- lib/parsing/iterator.rb
|
29
33
|
- lib/parsing/keyword.rb
|
30
|
-
- lib/parsing/
|
31
|
-
- lib/parsing/
|
34
|
+
- lib/parsing/models/flat_sql_container.rb
|
35
|
+
- lib/parsing/models/sql_container.rb
|
32
36
|
- lib/parsing/parser.rb
|
33
37
|
- lib/parsing/tokenizer.rb
|
38
|
+
- lib/parsing/transformers/token_categorizer.rb
|
39
|
+
- lib/parsing/transformers/token_transformer.rb
|
34
40
|
- lib/tsql_parser.rb
|
35
41
|
homepage: https://rubygems.org/gems/tsql_parser
|
36
42
|
licenses:
|
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
|