tsql_parser 0.0.9 → 0.1.1

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: 3e2633fba3d6e5113119872e1fad4618da4a7f404436e2e5d86137ae82516db3
4
- data.tar.gz: a27d777e1a54c8eba9803158b121d7c74b39ca004d4d0e49b242194f9095e125
3
+ metadata.gz: e1f673c238a4d2ba62893cc40d1b9cba39ec670d89637dcbf414cc25d72ff796
4
+ data.tar.gz: f08c8c2f290a5c66193ab8afa2c9e17095f801bb8d3793af09919e11f379c7e5
5
5
  SHA512:
6
- metadata.gz: 71667cfc1e258bcf400ce64af5a5f49747eec77e4fa4399444bc7f2b41e1757a2dc920b7273564fbf7b430928299bbf5f2a06074c6ed5e786baae44774051e2b
7
- data.tar.gz: 7dc006e6d915670337661dd6829e95942984d48d6ddc28ebfc3ae6332a348337fbd629fa50da81882ac2a717e9a9bf9c17507b93b8db69bb4a26ed7e2ba9094c
6
+ metadata.gz: e71435ffd85aea0165c31b32f38c685daa3f2057dbb2b123628eb5b54b077836f679c5792580277997321da7514c5ffcb0f3c7a567a75d20a91de65609dae5d7
7
+ data.tar.gz: c309fa288ffdeb797c7807293846fb641e49ae9c3cdc043cdedf9acd7823bb2d66c831d1212a38c17fb9c5961f6210213a696d3f694729d216e826ee82ff9d8e
@@ -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
 
@@ -78,13 +78,21 @@ module TSqlParser::Parsing
78
78
  next_line = work_lines[index + 1] unless index + 1 > work_lines.size
79
79
  next_line_first = next_line.strip.split(" ").first unless next_line.nil?
80
80
 
81
+ if first.nil?
82
+ #tab_count -= 1 if tab_count > 0
83
+ next
84
+ end
85
+
81
86
  if Parser.is_label? first
82
87
  indented_lines << "#{tab * tab_count}#{line}"
83
- tab_count += 1
88
+ #tab_count += 1
84
89
  elsif %w[CASE BEGIN SELECT].include? first or line.strip.start_with? "CREATE PROCEDURE"
85
90
  indented_lines << "#{tab * tab_count}#{line}"
86
91
  tab_count += 1
87
- elsif %w[FROM END GO].include? first and not %w[DELETE UPDATE INSERT SET].include? last
92
+ elsif %w[FROM GO].include? first and not %w[DELETE UPDATE INSERT FROM FETCH].include? last
93
+ tab_count -= 1 if tab_count > 0
94
+ indented_lines << "#{tab * tab_count}#{line}"
95
+ elsif %w[END END;].include? first
88
96
  tab_count -= 1 if tab_count > 0
89
97
  indented_lines << "#{tab * tab_count}#{line}"
90
98
  else
@@ -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,120 @@
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
+ lines.each do |line|
27
+ first = line.strip.split(" ").first
28
+ if %w[FROM WHERE].include? first and wait
29
+ wait = false
30
+ tab_count = self.get_tab_count(line, tab)
31
+ set_text = set_lines.join("\n")
32
+ first = set_text.strip.split(" ").first
33
+ set = set_text.strip[first.size + 1..]
34
+ new_set = self.format_set(set, tab_count, tab)
35
+ if new_set.nil?
36
+ formatted << line
37
+ next
38
+ end
39
+ formatted << "#{tab * tab_count}SET #{new_set}"
40
+ formatted << line
41
+ set_lines = []
42
+ next
43
+ end
44
+
45
+ if first == "SET" and not line.strip.start_with? "SET @" and not %w[ON OFF].include? line.strip.split(" ").last
46
+ wait = true
47
+ set_lines << line
48
+ elsif first != "SET" and line.include? " SET "
49
+ parts = line.strip.split(" SET ")
50
+ tab_count = self.get_tab_count(line, tab)
51
+ formatted << "#{tab * tab_count}#{parts[0]}\n"
52
+ parts[1..].each { |p| formatted << "#{tab * tab_count}SET #{p}" }
53
+ elsif wait
54
+ set_lines << line
55
+ else
56
+ formatted << line
57
+ end
58
+ end
59
+ formatted.join("\n")
60
+ end
61
+
62
+ private
63
+
64
+ def self.format_set(s, tab_count = 0, tab = " ")
65
+ return s if s.nil?
66
+ parts = []
67
+ builder = ""
68
+ parenthesis = 0
69
+ tokens = s.split("")
70
+ comment = false
71
+ skip_count = 0
72
+ tokens.each_with_index do |c, i|
73
+ if skip_count > 0
74
+ skip_count -= 1
75
+ next
76
+ end
77
+
78
+ if comment
79
+ if c == "\n"
80
+ comment = false
81
+ parts << builder unless builder.empty?
82
+ builder = ""
83
+ else
84
+ builder << c
85
+ end
86
+ next
87
+ end
88
+
89
+ parenthesis += 1 if c == "("
90
+ parenthesis -= 1 if c == ")"
91
+ next_c = tokens[i + 1] if tokens.size > i + 1
92
+ if c == ","
93
+ if parenthesis > 0
94
+ builder << c
95
+ else
96
+ parts << builder unless builder.empty?
97
+ builder = ""
98
+ end
99
+ elsif c == "\n"
100
+ parts << builder unless builder.empty?
101
+ builder = ""
102
+ elsif c == "-"
103
+ if next_c == "-"
104
+ comment = true
105
+ skip_count = 1
106
+ parts << builder unless builder.empty?
107
+ builder = "--"
108
+ else
109
+ builder << c
110
+ end
111
+ else
112
+ builder << c
113
+ end
114
+ end
115
+ parts << builder unless builder.empty?
116
+ parts = parts.map { |p| p.strip }.select { |p| not p.empty? }
117
+ "\n#{parts.map { |p| "#{tab * (tab_count + 1)}#{p.strip}" }.join(",\n")}"
118
+ end
119
+ end
120
+ 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
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.0.9
4
+ version: 0.1.1
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