tsql_parser 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a0a85b6dba179ecd613d8c18923b25c14ea4ae1b7a06f0ddba09eb212c21502b
4
- data.tar.gz: dbc151c034be90b2837d133b3c87e4fe476585b0108f9afd382f01a0471d4259
3
+ metadata.gz: e1f673c238a4d2ba62893cc40d1b9cba39ec670d89637dcbf414cc25d72ff796
4
+ data.tar.gz: f08c8c2f290a5c66193ab8afa2c9e17095f801bb8d3793af09919e11f379c7e5
5
5
  SHA512:
6
- metadata.gz: f77f801453284b9a941b2d1f8ca22718e6783a3b733181c697f0f6ff09bfc0373afdc50b39ea7915006c16c81b0b60b2641dd0926ecd13df5800c6a65a6a9a4f
7
- data.tar.gz: eaf630332538b7cf7fa6d677d400882a1f7f194c95882f1f630fbbb59e3d3b902f3bc8708eecd792e1d8f51489c79831298d4673589a2d6583ceea975bf3b038
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
 
@@ -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.1.0
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