tsql_parser 0.1.0 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a0a85b6dba179ecd613d8c18923b25c14ea4ae1b7a06f0ddba09eb212c21502b
4
- data.tar.gz: dbc151c034be90b2837d133b3c87e4fe476585b0108f9afd382f01a0471d4259
3
+ metadata.gz: 62f81b6f4b6195e663c823dbb1fda82a8a7530d534ed73a9ba27a048fdacb42d
4
+ data.tar.gz: c1af50b7c5421316290044ca548bd9983b568c8f6446402ba1d6b25ef46920ea
5
5
  SHA512:
6
- metadata.gz: f77f801453284b9a941b2d1f8ca22718e6783a3b733181c697f0f6ff09bfc0373afdc50b39ea7915006c16c81b0b60b2641dd0926ecd13df5800c6a65a6a9a4f
7
- data.tar.gz: eaf630332538b7cf7fa6d677d400882a1f7f194c95882f1f630fbbb59e3d3b902f3bc8708eecd792e1d8f51489c79831298d4673589a2d6583ceea975bf3b038
6
+ metadata.gz: 24c95e57e20af4b3dff6d7b15cb38e0736bddc683f025c9bc5300e6662992045e110990343497c13952524de2868fdc5341214ab744d6305416a2f001388d555
7
+ data.tar.gz: 06d257666a82067a42990e8c0f9a4ac8dd1644ec399f7f8aa453cfe7d2465dc680a349c7623bcf92e6f1f0d412a6a4ea2440f818bdf1b239510896b601e891cd
@@ -17,7 +17,7 @@
17
17
  module TSqlParser::Parsing
18
18
  require_relative "iterator"
19
19
  require_relative "parser"
20
- require_relative "text_formatter"
20
+ require_relative "formatters/text_formatter"
21
21
  require_relative "model/sql_container"
22
22
  require_relative "model/flat_sql_container"
23
23
 
@@ -0,0 +1,28 @@
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/base_formatter.rb
14
+ # object:
15
+ # TSqlParser::Parsing::Formatters::SetFormatter
16
+
17
+ module TSqlParser::Parsing::Formatters
18
+ class BaseFormatter
19
+ def self.get_tab_count(line, tab = " ")
20
+ tab_count = 0
21
+ while line.start_with? tab
22
+ tab_count += 1
23
+ line = line.sub(tab, "")
24
+ end
25
+ tab_count
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,66 @@
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/insert_formatter.rb
14
+ # object:
15
+ # TSqlParser::Parsing::Formatters::InsertFormatter
16
+
17
+ module TSqlParser::Parsing::Formatters
18
+ require_relative "base_formatter"
19
+
20
+ class InsertFormatter < BaseFormatter
21
+ def self.format(text, tab = " ")
22
+ formatted = []
23
+ lines = text.split("\n")
24
+ search = "INSERT INTO"
25
+ lines.each do |line|
26
+ first = line.strip.split(" ").first
27
+ if first != "INSERT"
28
+ formatted << line
29
+ next
30
+ end
31
+
32
+ tab_count = self.get_tab_count(line, tab)
33
+ insert = line.strip[search.size + 1..]
34
+ new_insert = self.format_insert(insert, tab_count, tab)
35
+ if new_insert.nil?
36
+ formatted << line
37
+ next
38
+ end
39
+ formatted << line.sub(insert, new_insert)
40
+ end
41
+ formatted.join("\n")
42
+ end
43
+
44
+ private
45
+
46
+ def self.format_insert(s, tab_count = 0, tab = " ")
47
+ return s if s.nil?
48
+ formatted = []
49
+ if s.include? ") VALUES ("
50
+ tokens = s.split(") VALUES (")
51
+ table = tokens[0][..tokens[0].index("(") - 2]
52
+ columns = tokens[0][tokens[0].index("(") + 1..]
53
+ values = tokens[1][..-2]
54
+ formatted << "\n#{tab * (tab_count + 1)}#{table}"
55
+ formatted << "#{tab * (tab_count + 2)}(#{columns})"
56
+ formatted << "#{tab * (tab_count + 1)}VALUES"
57
+ if s.end_with? ");"
58
+ formatted << "#{tab * (tab_count + 2)}(#{values}"
59
+ else
60
+ formatted << "#{tab * (tab_count + 2)}(#{values})"
61
+ end
62
+ end
63
+ formatted.join("\n") unless formatted.empty?
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,44 @@
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/join_formatter.rb
14
+ # object:
15
+ # TSqlParser::Parsing::Formatters::JoinFormatter
16
+
17
+ module TSqlParser::Parsing::Formatters
18
+ require_relative "base_formatter"
19
+
20
+ class JoinFormatter < BaseFormatter
21
+ def self.format(text, tab = " ")
22
+ text = text.gsub(/INNER\s+JOIN/, "INNER JOIN")
23
+ .gsub(/LEFT\s+JOIN/, "LEFT JOIN")
24
+ lines = text.split("\n")
25
+ new_text = []
26
+
27
+ lines.each do |line|
28
+ first = line.strip.split(" ").first
29
+ if line.include? " WHERE " and first != "WHERE" and not first.start_with? "--" and not first.start_with? "/*"
30
+ tab_count = self.get_tab_count(line, tab)
31
+ where_parts = line.strip.split(" WHERE ")
32
+ where_text = []
33
+ where_text << "#{tab * tab_count}#{where_parts[0]}"
34
+ where_text << "#{tab * tab_count}WHERE #{where_parts[1]}"
35
+ new_text << where_text.join("\n")
36
+ else
37
+ new_text << line
38
+ end
39
+ end
40
+
41
+ new_text.join("\n")
42
+ end
43
+ end
44
+ 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/formatters/select_formatter.rb
14
+ # object:
15
+ # TSqlParser::Parsing::Formatters::SelectFormatter
16
+
17
+ module TSqlParser::Parsing::Formatters
18
+ require_relative "base_formatter"
19
+
20
+ class SelectFormatter < BaseFormatter
21
+ def self.format(text, tab = " ")
22
+ formatted = []
23
+ lines = text.split("\n")
24
+ lines.each do |line|
25
+ first = line.strip.split(" ").first
26
+ if first != "SELECT"
27
+ formatted << line
28
+ next
29
+ end
30
+
31
+ tab_count = self.get_tab_count(line, tab)
32
+ select_sql = line.strip[first.size + 1..]
33
+ new_select = self.format_select(select_sql, tab_count, tab)
34
+ if new_select.nil?
35
+ formatted << line
36
+ next
37
+ end
38
+ formatted << line.sub(select_sql, new_select)
39
+ end
40
+ formatted.join("\n")
41
+ end
42
+
43
+ private
44
+
45
+ def self.format_select(s, tab_count = 0, tab = " ")
46
+ return s if s.nil?
47
+
48
+ tokens = s.split(", ")
49
+ "\n#{tokens.map { |t| "#{tab * (tab_count + 1)}#{t}" }.join(",\n")}"
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,130 @@
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/set_formatter.rb
14
+ # object:
15
+ # TSqlParser::Parsing::Formatters::SetFormatter
16
+
17
+ module TSqlParser::Parsing::Formatters
18
+ require_relative 'base_formatter'
19
+
20
+ class SetFormatter < BaseFormatter
21
+ def self.format(text, tab = " ")
22
+ formatted = []
23
+ lines = text.split("\n")
24
+ wait = false
25
+ set_lines = []
26
+ special_set_keywords = %w[ANSI_DEFAULTS ANSI_NULL_DFLT_OFF ANSI_NULL_DFLT_ON ANSI_NULLS ANSI_PADDING ANSI_WARNINGS ARITHABORT ARITHIGNORE CONCAT_NULL_YIELDS_NULL CURSOR_CLOSE_ON_COMMIT DATEFIRST DATEFORMAT DEADLOCK_PRIORITY FIPS_FLAGGER FMTONLY FORCEPLAN IDENTITY_INSERT IMPLICIT_TRANSACTIONS LANGUAGE LOCK_TIMEOUT NOCOUNT NOEXEC NUMERIC_ROUNDABORT OFFSETS PARSEONLY QUERY_GOVERNOR_COST_LIMIT QUOTED_IDENTIFIER REMOTE_PROC_TRANSACTIONS ROWCOUNT SHOWPLAN_ALL SHOWPLAN_TEXT SHOWPLAN_XML STATISTICS TEXTSIZE TRANSACTION XACT_ABORT]
27
+
28
+ lines.each do |line|
29
+ tokens = line.strip.split(" ")
30
+ first = tokens.first
31
+ next_token = tokens[1] if tokens.size > 1
32
+
33
+ if %w[FROM WHERE].include? first and wait
34
+ wait = false
35
+ tab_count = self.get_tab_count(line, tab)
36
+ set_text = set_lines.join("\n")
37
+ first = set_text.strip.split(" ").first
38
+ set = set_text.strip[first.size + 1..]
39
+ new_set = self.format_set(set, tab_count, tab)
40
+ if new_set.nil?
41
+ formatted << line
42
+ next
43
+ end
44
+ formatted << "#{tab * tab_count}SET #{new_set}"
45
+ formatted << line
46
+ set_lines = []
47
+ next
48
+ end
49
+
50
+ if first == "SET" and not line.strip.start_with? "SET @"
51
+ if not next_token.nil? and not special_set_keywords.include? next_token
52
+ wait = true
53
+ set_lines << line
54
+ else
55
+ formatted << line
56
+ formatted << ""
57
+ end
58
+ elsif first != "SET" and line.include? " SET "
59
+ parts = line.strip.split(" SET ")
60
+ tab_count = self.get_tab_count(line, tab)
61
+ formatted << "#{tab * tab_count}#{parts[0]}\n"
62
+ parts[1..].each { |p| formatted << "#{tab * tab_count}SET #{p}" }
63
+ elsif wait
64
+ set_lines << line
65
+ else
66
+ formatted << line
67
+ end
68
+ end
69
+ formatted.join("\n")
70
+ end
71
+
72
+ private
73
+
74
+ def self.format_set(s, tab_count = 0, tab = " ")
75
+ return s if s.nil?
76
+ parts = []
77
+ builder = ""
78
+ parenthesis = 0
79
+ tokens = s.split("")
80
+ comment = false
81
+ skip_count = 0
82
+ tokens.each_with_index do |c, i|
83
+ if skip_count > 0
84
+ skip_count -= 1
85
+ next
86
+ end
87
+
88
+ if comment
89
+ if c == "\n"
90
+ comment = false
91
+ parts << builder unless builder.empty?
92
+ builder = ""
93
+ else
94
+ builder << c
95
+ end
96
+ next
97
+ end
98
+
99
+ parenthesis += 1 if c == "("
100
+ parenthesis -= 1 if c == ")"
101
+ next_c = tokens[i + 1] if tokens.size > i + 1
102
+ if c == ","
103
+ if parenthesis > 0
104
+ builder << c
105
+ else
106
+ parts << builder unless builder.empty?
107
+ builder = ""
108
+ end
109
+ elsif c == "\n"
110
+ parts << builder unless builder.empty?
111
+ builder = ""
112
+ elsif c == "-"
113
+ if next_c == "-"
114
+ comment = true
115
+ skip_count = 1
116
+ parts << builder unless builder.empty?
117
+ builder = "--"
118
+ else
119
+ builder << c
120
+ end
121
+ else
122
+ builder << c
123
+ end
124
+ end
125
+ parts << builder unless builder.empty?
126
+ parts = parts.map { |p| p.strip }.select { |p| not p.empty? }
127
+ "\n#{parts.map { |p| "#{tab * (tab_count + 1)}#{p.strip}" }.join(",\n")}"
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,50 @@
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/update_formatter.rb
14
+ # object:
15
+ # TSqlParser::Parsing::Formatters::UpdateFormatter
16
+
17
+ module TSqlParser::Parsing::Formatters
18
+ require_relative "base_formatter"
19
+
20
+ class UpdateFormatter < BaseFormatter
21
+ def self.format(text, tab = " ")
22
+ formatted = []
23
+ lines = text.split("\n")
24
+ lines.each do |line|
25
+ first = line.strip.split(" ").first
26
+ if first != "UPDATE"
27
+ formatted << line
28
+ next
29
+ end
30
+
31
+ tab_count = self.get_tab_count(line, tab)
32
+ update = line.strip[first.size + 1..]
33
+ new_update = self.format_update(update, tab_count, tab)
34
+ if new_update.nil?
35
+ formatted << line
36
+ next
37
+ end
38
+ formatted << line.sub(update, new_update)
39
+ end
40
+ formatted.join("\n")
41
+ end
42
+
43
+ private
44
+
45
+ def self.format_update(s, tab_count = 0, tab = " ")
46
+ return s if s.nil?
47
+ "\n#{tab * (tab_count + 1)}#{s}"
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,72 @@
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/where_formatter.rb
14
+ # object:
15
+ # TSqlParser::Parsing::Formatters::WhereFormatter
16
+
17
+ module TSqlParser::Parsing::Formatters
18
+ require_relative "base_formatter"
19
+
20
+ class WhereFormatter < BaseFormatter
21
+ def self.format(text, tab = " ")
22
+ formatted = []
23
+ text.split("\n").each do |line|
24
+ first = line.strip.split(" ").first
25
+ if first != "WHERE"
26
+ formatted << line
27
+ next
28
+ end
29
+
30
+ tab_count = self.get_tab_count(line, tab)
31
+ predicate = line.strip[first.size + 1..]
32
+ new_predicate = self.format_predicate(predicate, tab_count, tab)
33
+ if new_predicate.nil?
34
+ formatted << line
35
+ next
36
+ end
37
+ formatted << line.sub(predicate, new_predicate)
38
+ end
39
+
40
+ formatted.join("\n")
41
+ end
42
+
43
+ private
44
+
45
+ def self.format_predicate(s, tab_count = 0, tab = " ")
46
+ return s if s.nil?
47
+ indented = []
48
+ formatted = []
49
+ builder = []
50
+
51
+ tokens = s.split(" ")
52
+ tokens.each do |t|
53
+ if %w[AND OR].include? t
54
+ formatted << builder.join(" ") unless builder.empty?
55
+ builder = [t]
56
+ else
57
+ builder << t
58
+ end
59
+ end
60
+ formatted << builder.join(" ")
61
+
62
+ level = tab_count
63
+ formatted.each_with_index do |f, i|
64
+ indented << "#{tab * (level + 1)}#{f}"
65
+ level -= f.count(")")
66
+ level += f.count("(")
67
+ end
68
+
69
+ "\n#{indented.join("\n")}"
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,50 @@
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/formatter.rb
14
+ # object:
15
+ # TSqlParser::Parsing::Formatter
16
+
17
+ module TSqlParser::Parsing
18
+ require_relative 'strategy/set_formatter'
19
+ require_relative 'strategy/join_formatter'
20
+ require_relative 'strategy/insert_formatter'
21
+ require_relative 'strategy/select_formatter'
22
+ require_relative 'strategy/update_formatter'
23
+ require_relative 'strategy/where_formatter'
24
+
25
+ class TextFormatter
26
+ def self.format_sets(text, tab = " ")
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
41
+
42
+ def self.format_selects(text, tab = " ")
43
+ Formatters::SelectFormatter.format(text, tab)
44
+ end
45
+
46
+ def self.format_wheres(text, tab = " ")
47
+ Formatters::WhereFormatter.format(text, tab)
48
+ end
49
+ end
50
+ end
@@ -94,7 +94,7 @@ module TSqlParser::Parsing
94
94
  next
95
95
  end
96
96
 
97
- if Parser.is_comment_start?(c, next_c)
97
+ if Parser.is_comment_start?(c, next_c) and not comment
98
98
  comment = true
99
99
  skip_count = 1
100
100
  specific_tokens << builder unless builder.empty?
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tsql_parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Scott Stauffer
@@ -17,12 +17,19 @@ extensions: []
17
17
  extra_rdoc_files: []
18
18
  files:
19
19
  - lib/parsing/formatter.rb
20
+ - lib/parsing/formatters/strategy/base_formatter.rb
21
+ - lib/parsing/formatters/strategy/insert_formatter.rb
22
+ - lib/parsing/formatters/strategy/join_formatter.rb
23
+ - lib/parsing/formatters/strategy/select_formatter.rb
24
+ - lib/parsing/formatters/strategy/set_formatter.rb
25
+ - lib/parsing/formatters/strategy/update_formatter.rb
26
+ - lib/parsing/formatters/strategy/where_formatter.rb
27
+ - lib/parsing/formatters/text_formatter.rb
20
28
  - lib/parsing/iterator.rb
21
29
  - lib/parsing/keyword.rb
22
30
  - lib/parsing/model/flat_sql_container.rb
23
31
  - lib/parsing/model/sql_container.rb
24
32
  - lib/parsing/parser.rb
25
- - lib/parsing/text_formatter.rb
26
33
  - lib/parsing/tokenizer.rb
27
34
  - lib/tsql_parser.rb
28
35
  homepage: https://rubygems.org/gems/tsql_parser
@@ -1,250 +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/formatter.rb
14
- # object:
15
- # TSqlParser::Parsing::Formatter
16
-
17
- module TSqlParser::Parsing
18
- class TextFormatter
19
- def self.format_sets(text, tab = " ")
20
- formatted = []
21
- lines = text.split("\n")
22
- lines.each do |line|
23
- first = line.strip.split(" ").first
24
- if first == "SET" and not line.strip.start_with? "SET @"
25
- tab_count = self.get_tab_count(line, tab)
26
- set = line.strip[first.size + 1..]
27
- new_set = self.format_set(set, tab_count, tab)
28
- if new_set.nil?
29
- formatted << line
30
- next
31
- end
32
- formatted << line.sub(set, new_set)
33
- elsif first != "SET" and line.include? " SET "
34
- parts = line.strip.split(" SET ")
35
- tab_count = self.get_tab_count(line, tab)
36
- formatted << "#{tab * tab_count}#{parts[0]}\n"
37
- parts[1..].each { |p| formatted << "#{tab * tab_count}SET #{p}" }
38
- else
39
- formatted << line
40
- end
41
- end
42
- formatted.join("\n")
43
- end
44
-
45
- def self.format_joins(text, tab = " ")
46
- text = text.gsub(/INNER\s+JOIN/, "INNER JOIN")
47
- .gsub(/LEFT\s+JOIN/, "LEFT JOIN")
48
- lines = text.split("\n")
49
- new_text = []
50
-
51
- lines.each do |line|
52
- first = line.strip.split(" ").first
53
- if line.include? " WHERE " and first != "WHERE" and not first.start_with? "--" and not first.start_with? "/*"
54
- tab_count = self.get_tab_count(line, tab)
55
- where_parts = line.strip.split(" WHERE ")
56
- where_text = []
57
- where_text << "#{tab * tab_count}#{where_parts[0]}"
58
- where_text << "#{tab * tab_count}WHERE #{where_parts[1]}"
59
- new_text << where_text.join("\n")
60
- else
61
- new_text << line
62
- end
63
- end
64
-
65
- new_text.join("\n")
66
- end
67
-
68
- def self.format_updates(text, tab = " ")
69
- formatted = []
70
- lines = text.split("\n")
71
- lines.each do |line|
72
- first = line.strip.split(" ").first
73
- if first != "UPDATE"
74
- formatted << line
75
- next
76
- end
77
-
78
- tab_count = self.get_tab_count(line, tab)
79
- update = line.strip[first.size + 1..]
80
- new_update = self.format_update(update, tab_count, tab)
81
- if new_update.nil?
82
- formatted << line
83
- next
84
- end
85
- formatted << line.sub(update, new_update)
86
- end
87
- formatted.join("\n")
88
- end
89
-
90
- def self.format_inserts(text, tab = " ")
91
- formatted = []
92
- lines = text.split("\n")
93
- search = "INSERT INTO"
94
- lines.each do |line|
95
- first = line.strip.split(" ").first
96
- if first != "INSERT"
97
- formatted << line
98
- next
99
- end
100
-
101
- tab_count = self.get_tab_count(line, tab)
102
- insert = line.strip[search.size + 1..]
103
- new_insert = self.format_insert(insert, tab_count, tab)
104
- if new_insert.nil?
105
- formatted << line
106
- next
107
- end
108
- formatted << line.sub(insert, new_insert)
109
- end
110
- formatted.join("\n")
111
- end
112
-
113
- def self.format_selects(text, tab = " ")
114
- formatted = []
115
- lines = text.split("\n")
116
- lines.each do |line|
117
- first = line.strip.split(" ").first
118
- if first != "SELECT"
119
- formatted << line
120
- next
121
- end
122
-
123
- tab_count = self.get_tab_count(line, tab)
124
- select_sql = line.strip[first.size + 1..]
125
- new_select = self.format_select(select_sql, tab_count, tab)
126
- if new_select.nil?
127
- formatted << line
128
- next
129
- end
130
- formatted << line.sub(select_sql, new_select)
131
- end
132
- formatted.join("\n")
133
- end
134
-
135
- def self.format_wheres(text, tab = " ")
136
- formatted = []
137
- text.split("\n").each do |line|
138
- first = line.strip.split(" ").first
139
- if first != "WHERE"
140
- formatted << line
141
- next
142
- end
143
-
144
- tab_count = self.get_tab_count(line, tab)
145
- predicate = line.strip[first.size + 1..]
146
- new_predicate = self.format_predicate(predicate, tab_count, tab)
147
- if new_predicate.nil?
148
- formatted << line
149
- next
150
- end
151
- formatted << line.sub(predicate, new_predicate)
152
- end
153
-
154
- formatted.join("\n")
155
- end
156
-
157
- private
158
-
159
- def self.format_set(s, tab_count = 0, tab = " ")
160
- return s if s.nil?
161
- parts = []
162
- builder = ""
163
- parenthesis = 0
164
- s.split("").each do |c|
165
- parenthesis += 1 if c == "("
166
- parenthesis -= 1 if c == ")"
167
- if c == ","
168
- if parenthesis > 0
169
- builder << c
170
- else
171
- parts << builder
172
- builder = ""
173
- end
174
- else
175
- builder << c
176
- end
177
- end
178
- parts << builder unless builder.empty?
179
- "\n#{parts.map { |p| "#{tab * (tab_count + 1)}#{p.strip}" }.join(",\n")}"
180
- end
181
-
182
- def self.format_update(s, tab_count = 0, tab = " ")
183
- return s if s.nil?
184
- "\n#{tab * (tab_count + 1)}#{s}"
185
- end
186
-
187
- def self.format_insert(s, tab_count = 0, tab = " ")
188
- return s if s.nil?
189
- formatted = []
190
- if s.include? ") VALUES ("
191
- tokens = s.split(") VALUES (")
192
- table = tokens[0][..tokens[0].index("(") - 2]
193
- columns = tokens[0][tokens[0].index("(") + 1..]
194
- values = tokens[1][..-2]
195
- formatted << "\n#{tab * (tab_count + 1)}#{table}"
196
- formatted << "#{tab * (tab_count + 2)}(#{columns})"
197
- formatted << "#{tab * (tab_count + 1)}VALUES"
198
- if s.end_with? ");"
199
- formatted << "#{tab * (tab_count + 2)}(#{values}"
200
- else
201
- formatted << "#{tab * (tab_count + 2)}(#{values})"
202
- end
203
- end
204
- formatted.join("\n") unless formatted.empty?
205
- end
206
-
207
- def self.format_select(s, tab_count = 0, tab = " ")
208
- return s if s.nil?
209
-
210
- tokens = s.split(", ")
211
- "\n#{tokens.map { |t| "#{tab * (tab_count + 1)}#{t}" }.join(",\n")}"
212
- end
213
-
214
- def self.format_predicate(s, tab_count = 0, tab = " ")
215
- return s if s.nil?
216
- indented = []
217
- formatted = []
218
- builder = []
219
-
220
- tokens = s.split(" ")
221
- tokens.each do |t|
222
- if %w[AND OR].include? t
223
- formatted << builder.join(" ") unless builder.empty?
224
- builder = [t]
225
- else
226
- builder << t
227
- end
228
- end
229
- formatted << builder.join(" ")
230
-
231
- level = tab_count
232
- formatted.each_with_index do |f, i|
233
- indented << "#{tab * (level + 1)}#{f}"
234
- level -= f.count(")")
235
- level += f.count("(")
236
- end
237
-
238
- "\n#{indented.join("\n")}"
239
- end
240
-
241
- def self.get_tab_count(line, tab = " ")
242
- tab_count = 0
243
- while line.start_with? tab
244
- tab_count += 1
245
- line = line.sub(tab, "")
246
- end
247
- tab_count
248
- end
249
- end
250
- end