ronin-sql 0.2.4 → 1.0.0
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.
- data/.document +4 -0
- data/.gitignore +11 -0
- data/.rspec +1 -0
- data/.yardopts +1 -0
- data/COPYING.txt +623 -288
- data/{History.txt → ChangeLog.md} +33 -35
- data/Gemfile +25 -0
- data/README.md +110 -0
- data/Rakefile +30 -20
- data/bin/ronin-sql +18 -5
- data/gemspec.yml +16 -0
- data/lib/ronin/formatting/extensions/sql.rb +4 -3
- data/lib/ronin/formatting/extensions/sql/string.rb +83 -10
- data/lib/ronin/formatting/sql.rb +4 -3
- data/lib/ronin/sql.rb +5 -12
- data/lib/ronin/{code/sql/create_index.rb → sql/binary_expr.rb} +25 -18
- data/lib/ronin/sql/clause.rb +72 -0
- data/lib/ronin/sql/clauses.rb +297 -0
- data/lib/ronin/sql/emittable.rb +84 -0
- data/lib/ronin/sql/emitter.rb +375 -0
- data/lib/ronin/sql/field.rb +106 -0
- data/lib/ronin/{code/sql/as.rb → sql/fields.rb} +36 -17
- data/lib/ronin/{code/sql/binary_expr.rb → sql/function.rb} +27 -27
- data/lib/ronin/sql/functions.rb +989 -0
- data/lib/ronin/sql/injection.rb +125 -157
- data/lib/ronin/{code/sql/default_values_clause.rb → sql/literal.rb} +13 -11
- data/lib/ronin/sql/literals.rb +72 -0
- data/lib/ronin/sql/operators.rb +332 -0
- data/lib/ronin/sql/sql.rb +86 -0
- data/lib/ronin/sql/statement.rb +70 -0
- data/lib/ronin/sql/statement_list.rb +110 -0
- data/lib/ronin/sql/statements.rb +115 -0
- data/lib/ronin/{code/sql/desc.rb → sql/unary_expr.rb} +11 -11
- data/lib/ronin/sql/version.rb +5 -4
- data/ronin-sql.gemspec +61 -0
- data/spec/formatting/sql/string_spec.rb +172 -0
- data/spec/spec_helper.rb +1 -4
- data/spec/sql/binary_expr.rb +5 -0
- data/spec/sql/binary_expr_examples.rb +25 -0
- data/spec/sql/clause_examples.rb +43 -0
- data/spec/sql/clause_spec.rb +31 -0
- data/spec/sql/clauses_spec.rb +43 -0
- data/spec/sql/emittable_spec.rb +41 -0
- data/spec/sql/emitter_spec.rb +472 -0
- data/spec/sql/field_spec.rb +103 -0
- data/spec/sql/fields_spec.rb +40 -0
- data/spec/sql/function_examples.rb +30 -0
- data/spec/sql/function_spec.rb +25 -0
- data/spec/sql/functions_spec.rb +110 -0
- data/spec/sql/injection_spec.rb +233 -0
- data/spec/sql/literal_spec.rb +5 -0
- data/spec/sql/literals_spec.rb +46 -0
- data/spec/sql/operators_spec.rb +44 -0
- data/spec/sql/sql_spec.rb +18 -0
- data/spec/sql/statement_examples.rb +39 -0
- data/spec/sql/statement_list_spec.rb +48 -0
- data/spec/sql/statement_sql.rb +38 -0
- data/spec/sql/statements_spec.rb +22 -0
- data/spec/sql/unary_expr.rb +5 -0
- data/spec/sql/unary_expr_examples.rb +20 -0
- metadata +116 -217
- data.tar.gz.sig +0 -0
- data/Manifest.txt +0 -108
- data/README.txt +0 -112
- data/lib/ronin/code/sql.rb +0 -22
- data/lib/ronin/code/sql/add_column_clause.rb +0 -42
- data/lib/ronin/code/sql/alter_table.rb +0 -52
- data/lib/ronin/code/sql/asc.rb +0 -36
- data/lib/ronin/code/sql/between.rb +0 -66
- data/lib/ronin/code/sql/clause.rb +0 -35
- data/lib/ronin/code/sql/code.rb +0 -35
- data/lib/ronin/code/sql/common_dialect.rb +0 -66
- data/lib/ronin/code/sql/create.rb +0 -74
- data/lib/ronin/code/sql/create_table.rb +0 -44
- data/lib/ronin/code/sql/create_view.rb +0 -41
- data/lib/ronin/code/sql/delete.rb +0 -52
- data/lib/ronin/code/sql/dialect.rb +0 -282
- data/lib/ronin/code/sql/drop.rb +0 -55
- data/lib/ronin/code/sql/drop_index.rb +0 -41
- data/lib/ronin/code/sql/drop_table.rb +0 -41
- data/lib/ronin/code/sql/drop_view.rb +0 -41
- data/lib/ronin/code/sql/emittable.rb +0 -100
- data/lib/ronin/code/sql/exceptions.rb +0 -24
- data/lib/ronin/code/sql/exceptions/unknown_clause.rb +0 -29
- data/lib/ronin/code/sql/exceptions/unknown_dialect.rb +0 -29
- data/lib/ronin/code/sql/exceptions/unknown_statement.rb +0 -29
- data/lib/ronin/code/sql/expr.rb +0 -102
- data/lib/ronin/code/sql/field.rb +0 -101
- data/lib/ronin/code/sql/fields_clause.rb +0 -46
- data/lib/ronin/code/sql/from_clause.rb +0 -42
- data/lib/ronin/code/sql/function.rb +0 -53
- data/lib/ronin/code/sql/group_by_clause.rb +0 -46
- data/lib/ronin/code/sql/having_clause.rb +0 -46
- data/lib/ronin/code/sql/in.rb +0 -47
- data/lib/ronin/code/sql/injected_statement.rb +0 -100
- data/lib/ronin/code/sql/injection.rb +0 -203
- data/lib/ronin/code/sql/insert.rb +0 -54
- data/lib/ronin/code/sql/intersect_clause.rb +0 -42
- data/lib/ronin/code/sql/join_clause.rb +0 -123
- data/lib/ronin/code/sql/like.rb +0 -73
- data/lib/ronin/code/sql/limit_clause.rb +0 -42
- data/lib/ronin/code/sql/modifier.rb +0 -48
- data/lib/ronin/code/sql/offset_clause.rb +0 -42
- data/lib/ronin/code/sql/on_clause.rb +0 -55
- data/lib/ronin/code/sql/order_by_clause.rb +0 -42
- data/lib/ronin/code/sql/program.rb +0 -225
- data/lib/ronin/code/sql/rename_to_clause.rb +0 -42
- data/lib/ronin/code/sql/replace.rb +0 -54
- data/lib/ronin/code/sql/select.rb +0 -103
- data/lib/ronin/code/sql/set_clause.rb +0 -42
- data/lib/ronin/code/sql/statement.rb +0 -180
- data/lib/ronin/code/sql/token.rb +0 -62
- data/lib/ronin/code/sql/unary_expr.rb +0 -47
- data/lib/ronin/code/sql/union_all_clause.rb +0 -42
- data/lib/ronin/code/sql/union_clause.rb +0 -42
- data/lib/ronin/code/sql/update.rb +0 -52
- data/lib/ronin/code/sql/values_clause.rb +0 -46
- data/lib/ronin/code/sql/where_clause.rb +0 -42
- data/lib/ronin/sql/error.rb +0 -26
- data/lib/ronin/sql/error/error.rb +0 -62
- data/lib/ronin/sql/error/extensions.rb +0 -22
- data/lib/ronin/sql/error/extensions/string.rb +0 -77
- data/lib/ronin/sql/error/message.rb +0 -62
- data/lib/ronin/sql/error/pattern.rb +0 -104
- data/lib/ronin/sql/error/patterns.rb +0 -99
- data/lib/ronin/sql/extensions.rb +0 -22
- data/lib/ronin/sql/extensions/uri.rb +0 -22
- data/lib/ronin/sql/extensions/uri/http.rb +0 -107
- data/spec/code/sql/common_dialect_spec.rb +0 -205
- data/spec/code/sql/create_examples.rb +0 -19
- data/spec/code/sql/create_index_spec.rb +0 -25
- data/spec/code/sql/create_table_spec.rb +0 -27
- data/spec/code/sql/create_view_spec.rb +0 -16
- data/spec/code/sql/delete_spec.rb +0 -14
- data/spec/code/sql/drop_examples.rb +0 -10
- data/spec/code/sql/drop_index_spec.rb +0 -16
- data/spec/code/sql/drop_table_spec.rb +0 -16
- data/spec/code/sql/drop_view_spec.rb +0 -16
- data/spec/code/sql/has_default_values_clause_examples.rb +0 -10
- data/spec/code/sql/has_fields_clause_examples.rb +0 -15
- data/spec/code/sql/has_from_clause_examples.rb +0 -13
- data/spec/code/sql/has_values_clause_examples.rb +0 -15
- data/spec/code/sql/has_where_clause_examples.rb +0 -15
- data/spec/code/sql/insert_spec.rb +0 -21
- data/spec/code/sql/replace_spec.rb +0 -21
- data/spec/code/sql/select_spec.rb +0 -105
- data/spec/code/sql/update_spec.rb +0 -26
- data/spec/helpers/code.rb +0 -14
- data/spec/sql/error_spec.rb +0 -24
- data/spec/sql/extensions/uri/http_spec.rb +0 -34
- data/spec/sql_spec.rb +0 -9
- data/tasks/spec.rb +0 -10
- data/tasks/yard.rb +0 -13
- metadata.gz.sig +0 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Ronin SQL - A Ruby DSL for crafting SQL Injections.
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2007-2013 Hal Brodigan (postmodern.mod3 at gmail.com)
|
|
5
|
+
#
|
|
6
|
+
# This file is part of Ronin SQL.
|
|
7
|
+
#
|
|
8
|
+
# This program is free software; you can redistribute it and/or modify
|
|
9
|
+
# it under the terms of the GNU General Public License as published by
|
|
10
|
+
# the Free Software Foundation; either version 2 of the License, or
|
|
11
|
+
# (at your option) any later version.
|
|
12
|
+
#
|
|
13
|
+
# This program is distributed in the hope that it will be useful,
|
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
|
+
# GNU General Public License for more details.
|
|
17
|
+
#
|
|
18
|
+
# You should have received a copy of the GNU General Public License
|
|
19
|
+
# along with this program; if not, write to the Free Software
|
|
20
|
+
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
21
|
+
#
|
|
22
|
+
|
|
23
|
+
require 'ronin/sql/emitter'
|
|
24
|
+
|
|
25
|
+
module Ronin
|
|
26
|
+
module SQL
|
|
27
|
+
#
|
|
28
|
+
# Allows an object to be converted to raw SQL.
|
|
29
|
+
#
|
|
30
|
+
module Emittable
|
|
31
|
+
#
|
|
32
|
+
# Creates a new emitter.
|
|
33
|
+
#
|
|
34
|
+
# @param [Hash] options
|
|
35
|
+
# Additional options for {Emitter#initialize}.
|
|
36
|
+
#
|
|
37
|
+
def emitter(options={})
|
|
38
|
+
Emitter.new(options)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
#
|
|
42
|
+
# The default `to_sql` method.
|
|
43
|
+
#
|
|
44
|
+
# @param [Hash] options
|
|
45
|
+
# Additional options for {#emitter}.
|
|
46
|
+
#
|
|
47
|
+
# @option options [:lower, :upper, :random, nil] :case
|
|
48
|
+
# Case for keywords.
|
|
49
|
+
#
|
|
50
|
+
# @option options [String] :space (' ')
|
|
51
|
+
# String to use for white-space.
|
|
52
|
+
#
|
|
53
|
+
# @option options [:single, :double] :quotes (:single)
|
|
54
|
+
# Type of quotes to use for Strings.
|
|
55
|
+
#
|
|
56
|
+
# @return [String]
|
|
57
|
+
# The raw SQL.
|
|
58
|
+
#
|
|
59
|
+
# @raise [ArgumentError]
|
|
60
|
+
# Could not emit an unknown SQL object.
|
|
61
|
+
#
|
|
62
|
+
def to_sql(options={})
|
|
63
|
+
emitter(options).emit(self)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
#
|
|
67
|
+
# @see #to_sql
|
|
68
|
+
#
|
|
69
|
+
def to_s
|
|
70
|
+
to_sql
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
#
|
|
74
|
+
# Inspects the object.
|
|
75
|
+
#
|
|
76
|
+
# @return [String]
|
|
77
|
+
# The inspected object.
|
|
78
|
+
#
|
|
79
|
+
def inspect
|
|
80
|
+
"#<#{self.class}: #{to_sql}>"
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Ronin SQL - A Ruby DSL for crafting SQL Injections.
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2007-2013 Hal Brodigan (postmodern.mod3 at gmail.com)
|
|
5
|
+
#
|
|
6
|
+
# This file is part of Ronin SQL.
|
|
7
|
+
#
|
|
8
|
+
# This program is free software; you can redistribute it and/or modify
|
|
9
|
+
# it under the terms of the GNU General Public License as published by
|
|
10
|
+
# the Free Software Foundation; either version 2 of the License, or
|
|
11
|
+
# (at your option) any later version.
|
|
12
|
+
#
|
|
13
|
+
# This program is distributed in the hope that it will be useful,
|
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
|
+
# GNU General Public License for more details.
|
|
17
|
+
#
|
|
18
|
+
# You should have received a copy of the GNU General Public License
|
|
19
|
+
# along with this program; if not, write to the Free Software
|
|
20
|
+
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
21
|
+
#
|
|
22
|
+
|
|
23
|
+
require 'ronin/formatting/sql'
|
|
24
|
+
|
|
25
|
+
module Ronin
|
|
26
|
+
module SQL
|
|
27
|
+
#
|
|
28
|
+
# Generates raw SQL.
|
|
29
|
+
#
|
|
30
|
+
class Emitter
|
|
31
|
+
|
|
32
|
+
# The case to use when emitting keywords
|
|
33
|
+
attr_reader :case
|
|
34
|
+
|
|
35
|
+
# String to use for white-space
|
|
36
|
+
attr_reader :space
|
|
37
|
+
|
|
38
|
+
# Type of String quotes to use
|
|
39
|
+
attr_reader :quotes
|
|
40
|
+
|
|
41
|
+
#
|
|
42
|
+
# Initializes the SQL Emitter.
|
|
43
|
+
#
|
|
44
|
+
# @param [Hash] options
|
|
45
|
+
# Emitter options.
|
|
46
|
+
#
|
|
47
|
+
# @option options [:lower, :upper, :random, nil] :case
|
|
48
|
+
# Case for keywords.
|
|
49
|
+
#
|
|
50
|
+
# @option options [String] :space (' ')
|
|
51
|
+
# String to use for white-space.
|
|
52
|
+
#
|
|
53
|
+
# @option options [:single, :double] :quotes (:single)
|
|
54
|
+
# Type of quotes to use for Strings.
|
|
55
|
+
#
|
|
56
|
+
def initialize(options={})
|
|
57
|
+
@case = options[:case]
|
|
58
|
+
@space = options.fetch(:space,' ')
|
|
59
|
+
@quotes = options.fetch(:quotes,:single)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
#
|
|
63
|
+
# Emits a SQL keyword.
|
|
64
|
+
#
|
|
65
|
+
# @param [Symbol, Array<Symbol>] keyword
|
|
66
|
+
# The SQL keyword.
|
|
67
|
+
#
|
|
68
|
+
# @return [String]
|
|
69
|
+
# The raw SQL.
|
|
70
|
+
#
|
|
71
|
+
def emit_keyword(keyword)
|
|
72
|
+
keyword = Array(keyword).join(@space)
|
|
73
|
+
|
|
74
|
+
case @case
|
|
75
|
+
when :upper then keyword.upcase
|
|
76
|
+
when :lower then keyword.downcase
|
|
77
|
+
when :random
|
|
78
|
+
keyword.tap do
|
|
79
|
+
(keyword.length / 2).times do
|
|
80
|
+
index = rand(keyword.length)
|
|
81
|
+
keyword[index] = keyword[index].swapcase
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
else
|
|
85
|
+
keyword
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
#
|
|
90
|
+
# Emits a SQL operator.
|
|
91
|
+
#
|
|
92
|
+
# @param [Symbol] op
|
|
93
|
+
# The operator symbol.
|
|
94
|
+
#
|
|
95
|
+
# @return [String]
|
|
96
|
+
# The raw SQL.
|
|
97
|
+
#
|
|
98
|
+
def emit_operator(op)
|
|
99
|
+
op = op.to_s
|
|
100
|
+
|
|
101
|
+
case op
|
|
102
|
+
when /^[a-zA-Z]+$/ then emit_keyword(op)
|
|
103
|
+
else op
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
#
|
|
108
|
+
# Emits the `NULL` value.
|
|
109
|
+
#
|
|
110
|
+
# @return ["NULL"]
|
|
111
|
+
#
|
|
112
|
+
def emit_null
|
|
113
|
+
emit_keyword(:NULL)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
#
|
|
117
|
+
# Emits a `false` value.
|
|
118
|
+
#
|
|
119
|
+
# @return [String]
|
|
120
|
+
# The raw SQL.
|
|
121
|
+
#
|
|
122
|
+
def emit_false
|
|
123
|
+
"1=0"
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
#
|
|
127
|
+
# Emits a `true` value.
|
|
128
|
+
#
|
|
129
|
+
# @return [String]
|
|
130
|
+
# The raw SQL.
|
|
131
|
+
#
|
|
132
|
+
def emit_true
|
|
133
|
+
"1=1"
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
#
|
|
137
|
+
# Emits a SQL Integer.
|
|
138
|
+
#
|
|
139
|
+
# @param [Integer] int
|
|
140
|
+
# The Integer.
|
|
141
|
+
#
|
|
142
|
+
# @return [String]
|
|
143
|
+
# The raw SQL.
|
|
144
|
+
#
|
|
145
|
+
def emit_integer(int)
|
|
146
|
+
int.to_s
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
#
|
|
150
|
+
# Emits a SQL Decimal.
|
|
151
|
+
#
|
|
152
|
+
# @param [Float] decimal
|
|
153
|
+
# The decimal.
|
|
154
|
+
#
|
|
155
|
+
# @return [String]
|
|
156
|
+
# The raw SQL.
|
|
157
|
+
#
|
|
158
|
+
def emit_decimal(decimal)
|
|
159
|
+
decimal.to_s
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
#
|
|
163
|
+
# Emits a SQL String.
|
|
164
|
+
#
|
|
165
|
+
# @param [String] string
|
|
166
|
+
# The String.
|
|
167
|
+
#
|
|
168
|
+
# @return [String]
|
|
169
|
+
# The raw SQL.
|
|
170
|
+
#
|
|
171
|
+
def emit_string(string)
|
|
172
|
+
string.sql_escape(@quotes)
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
#
|
|
176
|
+
# Emits a SQL field.
|
|
177
|
+
#
|
|
178
|
+
# @param [Field, Symbol, String] field
|
|
179
|
+
# The SQL field.
|
|
180
|
+
#
|
|
181
|
+
# @return [String]
|
|
182
|
+
# The raw SQL.
|
|
183
|
+
#
|
|
184
|
+
def emit_field(field)
|
|
185
|
+
field.to_s
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
#
|
|
189
|
+
# Emits a list of elements.
|
|
190
|
+
#
|
|
191
|
+
# @param [#map] list
|
|
192
|
+
# The list of elements.
|
|
193
|
+
#
|
|
194
|
+
# @return [String]
|
|
195
|
+
# The raw SQL.
|
|
196
|
+
#
|
|
197
|
+
def emit_list(list)
|
|
198
|
+
'(' + list.map { |element| emit(element) }.join(',') + ')'
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
#
|
|
202
|
+
# Emits a list of columns and assigned values.
|
|
203
|
+
#
|
|
204
|
+
# @param [Hash{Field,Symbol => Object}] values
|
|
205
|
+
# The column names and values.
|
|
206
|
+
#
|
|
207
|
+
# @return [String]
|
|
208
|
+
# The raw SQL.
|
|
209
|
+
#
|
|
210
|
+
def emit_assignments(values)
|
|
211
|
+
values.map { |key,value|
|
|
212
|
+
"#{emit_keyword(key)}=#{emit(value)}"
|
|
213
|
+
}.join(',')
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
#
|
|
217
|
+
# Emits a SQL expression.
|
|
218
|
+
#
|
|
219
|
+
# @param [BinaryExpr, UnaryExpr] expr
|
|
220
|
+
# The SQL expression.
|
|
221
|
+
#
|
|
222
|
+
# @return [String]
|
|
223
|
+
# The raw SQL.
|
|
224
|
+
#
|
|
225
|
+
def emit_expression(expr)
|
|
226
|
+
op = emit_operator(expr.operator)
|
|
227
|
+
|
|
228
|
+
case expr
|
|
229
|
+
when BinaryExpr
|
|
230
|
+
left, right = emit(expr.left), emit(expr.right)
|
|
231
|
+
|
|
232
|
+
left = "(#{left})" if expr.left.kind_of?(Statement)
|
|
233
|
+
right = "(#{right})" if expr.right.kind_of?(Statement)
|
|
234
|
+
|
|
235
|
+
case op
|
|
236
|
+
when /^\w+$/ then [left, op, right].join(@space)
|
|
237
|
+
else "#{left}#{op}#{right}"
|
|
238
|
+
end
|
|
239
|
+
when UnaryExpr
|
|
240
|
+
operand = emit(expr.operand)
|
|
241
|
+
operand = "(#{operand})" if expr.operand.kind_of?(Statement)
|
|
242
|
+
|
|
243
|
+
case op
|
|
244
|
+
when /^\w+$/ then [op, operand].join(@space)
|
|
245
|
+
else "#{op}#{operand}"
|
|
246
|
+
end
|
|
247
|
+
end
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
#
|
|
251
|
+
# Emits a SQL function.
|
|
252
|
+
#
|
|
253
|
+
# @param [Function] function
|
|
254
|
+
# The SQL function.
|
|
255
|
+
#
|
|
256
|
+
# @return [String]
|
|
257
|
+
# The raw SQL.
|
|
258
|
+
#
|
|
259
|
+
def emit_function(function)
|
|
260
|
+
name = emit_keyword(function.name)
|
|
261
|
+
arguments = function.arguments.map { |argument| emit(argument) }
|
|
262
|
+
|
|
263
|
+
return "#{name}(#{arguments.join(',')})"
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
#
|
|
267
|
+
# Emits a SQL object.
|
|
268
|
+
#
|
|
269
|
+
# @param [#to_sql] object
|
|
270
|
+
# The SQL object.
|
|
271
|
+
#
|
|
272
|
+
# @return [String]
|
|
273
|
+
# The raw SQL.
|
|
274
|
+
#
|
|
275
|
+
# @raise [ArgumentError]
|
|
276
|
+
# Could not emit an unknown SQL object.
|
|
277
|
+
#
|
|
278
|
+
def emit(object)
|
|
279
|
+
case object
|
|
280
|
+
when NilClass then emit_null
|
|
281
|
+
when TrueClass then emit_true
|
|
282
|
+
when FalseClass then emit_false
|
|
283
|
+
when Integer then emit_integer(object)
|
|
284
|
+
when Float then emit_decimal(object)
|
|
285
|
+
when String then emit_string(object)
|
|
286
|
+
when Literal then emit(object.value)
|
|
287
|
+
when Field, Symbol then emit_field(object)
|
|
288
|
+
when Array then emit_list(object)
|
|
289
|
+
when Hash then emit_assignments(object)
|
|
290
|
+
when BinaryExpr, UnaryExpr then emit_expression(object)
|
|
291
|
+
when Clause then emit_clause(object)
|
|
292
|
+
when Statement then emit_statement(object)
|
|
293
|
+
when StatementList then emit_statement_list(object)
|
|
294
|
+
else
|
|
295
|
+
if object.respond_to?(:to_sql)
|
|
296
|
+
object.to_sql
|
|
297
|
+
else
|
|
298
|
+
raise(ArgumentError,"cannot emit #{object.class}")
|
|
299
|
+
end
|
|
300
|
+
end
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
#
|
|
304
|
+
# Emits a SQL Clause.
|
|
305
|
+
#
|
|
306
|
+
# @param [Clause] clause
|
|
307
|
+
# The SQL Clause.
|
|
308
|
+
#
|
|
309
|
+
# @return [String]
|
|
310
|
+
# The raw SQL.
|
|
311
|
+
#
|
|
312
|
+
def emit_clause(clause)
|
|
313
|
+
sql = emit_keyword(clause.keyword)
|
|
314
|
+
|
|
315
|
+
unless clause.argument.nil?
|
|
316
|
+
sql << @space << emit(clause.argument)
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
return sql
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
#
|
|
323
|
+
# Emits multiple SQL Clauses.
|
|
324
|
+
#
|
|
325
|
+
# @param [Array<Clause>] clauses
|
|
326
|
+
# The clauses to emit.
|
|
327
|
+
#
|
|
328
|
+
# @return [String]
|
|
329
|
+
# The emitted clauses.
|
|
330
|
+
#
|
|
331
|
+
def emit_clauses(clauses)
|
|
332
|
+
clauses.map { |clause| emit_clause(clause) }.join(@space)
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
#
|
|
336
|
+
# Emits a SQL Statement.
|
|
337
|
+
#
|
|
338
|
+
# @param [Statement] stmt
|
|
339
|
+
# The SQL Statement.
|
|
340
|
+
#
|
|
341
|
+
# @return [String]
|
|
342
|
+
# The raw SQL.
|
|
343
|
+
#
|
|
344
|
+
def emit_statement(stmt)
|
|
345
|
+
sql = emit_keyword(stmt.keyword)
|
|
346
|
+
|
|
347
|
+
unless stmt.argument.nil?
|
|
348
|
+
sql << @space << emit(stmt.argument)
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
unless stmt.clauses.empty?
|
|
352
|
+
sql << @space << emit_clauses(stmt.clauses)
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
return sql
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
#
|
|
359
|
+
# Emits a full SQL statement list.
|
|
360
|
+
#
|
|
361
|
+
# @param [StatementList] list
|
|
362
|
+
# The SQL statement list.
|
|
363
|
+
#
|
|
364
|
+
# @return [String]
|
|
365
|
+
# The raw SQL.
|
|
366
|
+
#
|
|
367
|
+
def emit_statement_list(list)
|
|
368
|
+
list.statements.map { |stmt|
|
|
369
|
+
emit_statement(stmt)
|
|
370
|
+
}.join(";#{@space}")
|
|
371
|
+
end
|
|
372
|
+
|
|
373
|
+
end
|
|
374
|
+
end
|
|
375
|
+
end
|