ronin-sql 0.2.4 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (154) hide show
  1. data/.document +4 -0
  2. data/.gitignore +11 -0
  3. data/.rspec +1 -0
  4. data/.yardopts +1 -0
  5. data/COPYING.txt +623 -288
  6. data/{History.txt → ChangeLog.md} +33 -35
  7. data/Gemfile +25 -0
  8. data/README.md +110 -0
  9. data/Rakefile +30 -20
  10. data/bin/ronin-sql +18 -5
  11. data/gemspec.yml +16 -0
  12. data/lib/ronin/formatting/extensions/sql.rb +4 -3
  13. data/lib/ronin/formatting/extensions/sql/string.rb +83 -10
  14. data/lib/ronin/formatting/sql.rb +4 -3
  15. data/lib/ronin/sql.rb +5 -12
  16. data/lib/ronin/{code/sql/create_index.rb → sql/binary_expr.rb} +25 -18
  17. data/lib/ronin/sql/clause.rb +72 -0
  18. data/lib/ronin/sql/clauses.rb +297 -0
  19. data/lib/ronin/sql/emittable.rb +84 -0
  20. data/lib/ronin/sql/emitter.rb +375 -0
  21. data/lib/ronin/sql/field.rb +106 -0
  22. data/lib/ronin/{code/sql/as.rb → sql/fields.rb} +36 -17
  23. data/lib/ronin/{code/sql/binary_expr.rb → sql/function.rb} +27 -27
  24. data/lib/ronin/sql/functions.rb +989 -0
  25. data/lib/ronin/sql/injection.rb +125 -157
  26. data/lib/ronin/{code/sql/default_values_clause.rb → sql/literal.rb} +13 -11
  27. data/lib/ronin/sql/literals.rb +72 -0
  28. data/lib/ronin/sql/operators.rb +332 -0
  29. data/lib/ronin/sql/sql.rb +86 -0
  30. data/lib/ronin/sql/statement.rb +70 -0
  31. data/lib/ronin/sql/statement_list.rb +110 -0
  32. data/lib/ronin/sql/statements.rb +115 -0
  33. data/lib/ronin/{code/sql/desc.rb → sql/unary_expr.rb} +11 -11
  34. data/lib/ronin/sql/version.rb +5 -4
  35. data/ronin-sql.gemspec +61 -0
  36. data/spec/formatting/sql/string_spec.rb +172 -0
  37. data/spec/spec_helper.rb +1 -4
  38. data/spec/sql/binary_expr.rb +5 -0
  39. data/spec/sql/binary_expr_examples.rb +25 -0
  40. data/spec/sql/clause_examples.rb +43 -0
  41. data/spec/sql/clause_spec.rb +31 -0
  42. data/spec/sql/clauses_spec.rb +43 -0
  43. data/spec/sql/emittable_spec.rb +41 -0
  44. data/spec/sql/emitter_spec.rb +472 -0
  45. data/spec/sql/field_spec.rb +103 -0
  46. data/spec/sql/fields_spec.rb +40 -0
  47. data/spec/sql/function_examples.rb +30 -0
  48. data/spec/sql/function_spec.rb +25 -0
  49. data/spec/sql/functions_spec.rb +110 -0
  50. data/spec/sql/injection_spec.rb +233 -0
  51. data/spec/sql/literal_spec.rb +5 -0
  52. data/spec/sql/literals_spec.rb +46 -0
  53. data/spec/sql/operators_spec.rb +44 -0
  54. data/spec/sql/sql_spec.rb +18 -0
  55. data/spec/sql/statement_examples.rb +39 -0
  56. data/spec/sql/statement_list_spec.rb +48 -0
  57. data/spec/sql/statement_sql.rb +38 -0
  58. data/spec/sql/statements_spec.rb +22 -0
  59. data/spec/sql/unary_expr.rb +5 -0
  60. data/spec/sql/unary_expr_examples.rb +20 -0
  61. metadata +116 -217
  62. data.tar.gz.sig +0 -0
  63. data/Manifest.txt +0 -108
  64. data/README.txt +0 -112
  65. data/lib/ronin/code/sql.rb +0 -22
  66. data/lib/ronin/code/sql/add_column_clause.rb +0 -42
  67. data/lib/ronin/code/sql/alter_table.rb +0 -52
  68. data/lib/ronin/code/sql/asc.rb +0 -36
  69. data/lib/ronin/code/sql/between.rb +0 -66
  70. data/lib/ronin/code/sql/clause.rb +0 -35
  71. data/lib/ronin/code/sql/code.rb +0 -35
  72. data/lib/ronin/code/sql/common_dialect.rb +0 -66
  73. data/lib/ronin/code/sql/create.rb +0 -74
  74. data/lib/ronin/code/sql/create_table.rb +0 -44
  75. data/lib/ronin/code/sql/create_view.rb +0 -41
  76. data/lib/ronin/code/sql/delete.rb +0 -52
  77. data/lib/ronin/code/sql/dialect.rb +0 -282
  78. data/lib/ronin/code/sql/drop.rb +0 -55
  79. data/lib/ronin/code/sql/drop_index.rb +0 -41
  80. data/lib/ronin/code/sql/drop_table.rb +0 -41
  81. data/lib/ronin/code/sql/drop_view.rb +0 -41
  82. data/lib/ronin/code/sql/emittable.rb +0 -100
  83. data/lib/ronin/code/sql/exceptions.rb +0 -24
  84. data/lib/ronin/code/sql/exceptions/unknown_clause.rb +0 -29
  85. data/lib/ronin/code/sql/exceptions/unknown_dialect.rb +0 -29
  86. data/lib/ronin/code/sql/exceptions/unknown_statement.rb +0 -29
  87. data/lib/ronin/code/sql/expr.rb +0 -102
  88. data/lib/ronin/code/sql/field.rb +0 -101
  89. data/lib/ronin/code/sql/fields_clause.rb +0 -46
  90. data/lib/ronin/code/sql/from_clause.rb +0 -42
  91. data/lib/ronin/code/sql/function.rb +0 -53
  92. data/lib/ronin/code/sql/group_by_clause.rb +0 -46
  93. data/lib/ronin/code/sql/having_clause.rb +0 -46
  94. data/lib/ronin/code/sql/in.rb +0 -47
  95. data/lib/ronin/code/sql/injected_statement.rb +0 -100
  96. data/lib/ronin/code/sql/injection.rb +0 -203
  97. data/lib/ronin/code/sql/insert.rb +0 -54
  98. data/lib/ronin/code/sql/intersect_clause.rb +0 -42
  99. data/lib/ronin/code/sql/join_clause.rb +0 -123
  100. data/lib/ronin/code/sql/like.rb +0 -73
  101. data/lib/ronin/code/sql/limit_clause.rb +0 -42
  102. data/lib/ronin/code/sql/modifier.rb +0 -48
  103. data/lib/ronin/code/sql/offset_clause.rb +0 -42
  104. data/lib/ronin/code/sql/on_clause.rb +0 -55
  105. data/lib/ronin/code/sql/order_by_clause.rb +0 -42
  106. data/lib/ronin/code/sql/program.rb +0 -225
  107. data/lib/ronin/code/sql/rename_to_clause.rb +0 -42
  108. data/lib/ronin/code/sql/replace.rb +0 -54
  109. data/lib/ronin/code/sql/select.rb +0 -103
  110. data/lib/ronin/code/sql/set_clause.rb +0 -42
  111. data/lib/ronin/code/sql/statement.rb +0 -180
  112. data/lib/ronin/code/sql/token.rb +0 -62
  113. data/lib/ronin/code/sql/unary_expr.rb +0 -47
  114. data/lib/ronin/code/sql/union_all_clause.rb +0 -42
  115. data/lib/ronin/code/sql/union_clause.rb +0 -42
  116. data/lib/ronin/code/sql/update.rb +0 -52
  117. data/lib/ronin/code/sql/values_clause.rb +0 -46
  118. data/lib/ronin/code/sql/where_clause.rb +0 -42
  119. data/lib/ronin/sql/error.rb +0 -26
  120. data/lib/ronin/sql/error/error.rb +0 -62
  121. data/lib/ronin/sql/error/extensions.rb +0 -22
  122. data/lib/ronin/sql/error/extensions/string.rb +0 -77
  123. data/lib/ronin/sql/error/message.rb +0 -62
  124. data/lib/ronin/sql/error/pattern.rb +0 -104
  125. data/lib/ronin/sql/error/patterns.rb +0 -99
  126. data/lib/ronin/sql/extensions.rb +0 -22
  127. data/lib/ronin/sql/extensions/uri.rb +0 -22
  128. data/lib/ronin/sql/extensions/uri/http.rb +0 -107
  129. data/spec/code/sql/common_dialect_spec.rb +0 -205
  130. data/spec/code/sql/create_examples.rb +0 -19
  131. data/spec/code/sql/create_index_spec.rb +0 -25
  132. data/spec/code/sql/create_table_spec.rb +0 -27
  133. data/spec/code/sql/create_view_spec.rb +0 -16
  134. data/spec/code/sql/delete_spec.rb +0 -14
  135. data/spec/code/sql/drop_examples.rb +0 -10
  136. data/spec/code/sql/drop_index_spec.rb +0 -16
  137. data/spec/code/sql/drop_table_spec.rb +0 -16
  138. data/spec/code/sql/drop_view_spec.rb +0 -16
  139. data/spec/code/sql/has_default_values_clause_examples.rb +0 -10
  140. data/spec/code/sql/has_fields_clause_examples.rb +0 -15
  141. data/spec/code/sql/has_from_clause_examples.rb +0 -13
  142. data/spec/code/sql/has_values_clause_examples.rb +0 -15
  143. data/spec/code/sql/has_where_clause_examples.rb +0 -15
  144. data/spec/code/sql/insert_spec.rb +0 -21
  145. data/spec/code/sql/replace_spec.rb +0 -21
  146. data/spec/code/sql/select_spec.rb +0 -105
  147. data/spec/code/sql/update_spec.rb +0 -26
  148. data/spec/helpers/code.rb +0 -14
  149. data/spec/sql/error_spec.rb +0 -24
  150. data/spec/sql/extensions/uri/http_spec.rb +0 -34
  151. data/spec/sql_spec.rb +0 -9
  152. data/tasks/spec.rb +0 -10
  153. data/tasks/yard.rb +0 -13
  154. metadata.gz.sig +0 -0
@@ -1,8 +1,9 @@
1
1
  #
2
- # Ronin SQL - A Ronin library providing support for SQL related security
3
- # tasks.
2
+ # Ronin SQL - A Ruby DSL for crafting SQL Injections.
4
3
  #
5
- # Copyright (c) 2007-2009 Hal Brodigan (postmodern.mod3 at gmail.com)
4
+ # Copyright (c) 2007-2013 Hal Brodigan (postmodern.mod3 at gmail.com)
5
+ #
6
+ # This file is part of Ronin SQL.
6
7
  #
7
8
  # This program is free software; you can redistribute it and/or modify
8
9
  # it under the terms of the GNU General Public License as published by
@@ -19,195 +20,162 @@
19
20
  # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
21
  #
21
22
 
22
- require 'ronin/sql/error'
23
- require 'ronin/code/sql/injection'
24
- require 'ronin/sessions/http'
25
- require 'ronin/extensions/uri'
26
- require 'ronin/web/extensions/nokogiri'
27
- require 'ronin/web/spider'
28
-
29
- require 'parameters'
30
- require 'nokogiri'
23
+ require 'ronin/sql/binary_expr'
24
+ require 'ronin/sql/literals'
25
+ require 'ronin/sql/clauses'
26
+ require 'ronin/sql/statement_list'
31
27
 
32
28
  module Ronin
33
29
  module SQL
34
- class Injection
30
+ #
31
+ # Represents a SQL injection (SQLi).
32
+ #
33
+ class Injection < StatementList
35
34
 
36
- include Parameters
37
- include Sessions::HTTP
35
+ include Literals
36
+ include Clauses
38
37
 
39
- # The URL to inject upon
40
- attr_reader :url
38
+ # Default place holder values.
39
+ PLACE_HOLDERS = {
40
+ integer: 1,
41
+ decimal: 1.0,
42
+ string: '1',
43
+ list: [nil],
44
+ column: :id
45
+ }
41
46
 
42
- # The URL query param to inject into
43
- attr_reader :param
47
+ # The type of element to escape out of
48
+ attr_reader :escape
44
49
 
45
- # Options for crafting SQL injections
46
- attr_reader :sql_options
50
+ # The place holder data
51
+ attr_reader :place_holder
47
52
 
48
- # HTTP request method (either :get or :post)
49
- parameter :http_method,
50
- :default => :get,
51
- :description => 'HTTP request method to use'
53
+ # The expression that will be injected
54
+ attr_reader :expression
52
55
 
53
56
  #
54
- # Creates a new Injection object with the specified _url_, _param_
55
- # to inject upon and the given _options_ which will be used
56
- # for crafting SQL injections.
57
+ # Initializes a new SQL injection.
57
58
  #
58
- def initialize(url,param,options={})
59
- super()
60
-
61
- @url = url
62
- @param = param
63
- @sql_options = options
64
- end
65
-
59
+ # @param [Hash] options
60
+ # Additional injection options.
66
61
  #
67
- # Spider a site starting at the specified _url_ using the given
68
- # _options_ and return an Array of URLs which are vulnerable to SQL
69
- # Injection. If a _block_ is given, it will be passed vulnerable SQL
70
- # Injection objects as they are found.
62
+ # @option options [:integer, :decimal, :string, :column] :escape (:integer)
63
+ # The type of element to escape out of.
71
64
  #
72
- # Injection.spider('http://www.target.com/contact/')
73
- # # => [...]
65
+ # @option options [Boolean] :terminate
66
+ # Specifies whether to terminate the SQLi with a comment.
74
67
  #
75
- # Injection.spider('http://www.target.com/') do |injection|
76
- # ...
77
- # end
68
+ # @option options [String, Symbol, Integer] :place_holder
69
+ # Place-holder data.
78
70
  #
79
- def Injection.spider(url,options={},&block)
80
- injections = []
81
-
82
- Web::Spider.site(url,options) do |spider|
83
- spider.every_url_like(/\?[a-zA-Z0-9_]/) do |vuln_url|
84
- found = vuln_url.sql_injections
85
-
86
- found.each(&block) if block
87
- injections += found
88
- end
89
- end
90
-
91
- return injections
92
- end
93
-
71
+ # @yield [(injection)]
72
+ # If a block is given, it will be evaluated within the injection.
73
+ # If the block accepts an argument, the block will be called with the
74
+ # new injection.
94
75
  #
95
- # Creates a new Code::SQL::Injection object using the given _options_
96
- # and _block_. The given _options_ will be merged with the injections
97
- # sql_options, to create a tailored Code::SQL::Injection object.
76
+ # @yieldparam [Injection] injection
77
+ # The new injection.
98
78
  #
99
- def sql(options={},&block)
100
- Code::SQL::Injection.new(@sql_options.merge(options),&block)
101
- end
102
-
103
- def inject(options={},&block)
104
- injection = (options[:sql] || sql(options,&block))
105
-
106
- injection_url = URI(@url.to_s)
107
- injection_url.query_params[@param.to_s] = injection
108
-
109
- request_method = (options[:method] || @http_method)
110
- options = options.merge(:url => injection_url)
111
-
112
- if request_method == :post
113
- return http_post_body(options)
114
- else
115
- return http_get_body(options)
79
+ def initialize(options={},&block)
80
+ @escape = options.fetch(:escape,:integer)
81
+ @place_holder = options.fetch(:place_holder) do
82
+ PLACE_HOLDERS.fetch(@escape)
116
83
  end
117
- end
118
-
119
- def inject_error(options={})
120
- inject({:sql => "'"}.merge(options))
121
- end
122
84
 
123
- def error(options={})
124
- inject_error(options).sql_error
125
- end
85
+ @expression = @place_holder
126
86
 
127
- def has_error?(options={})
128
- Error.has_message?(inject_error(options))
87
+ super(&block)
129
88
  end
130
89
 
131
- def vulnerable?(options={})
132
- body1 = inject(options) { no_rows }
133
- body2 = inject(options) { all_rows }
134
-
135
- if (body1.sql_error? || body2.sql_error?)
136
- return false
137
- end
138
-
139
- body1 = Nokogiri::HTML(body1)
140
- body2 = Nokogiri::HTML(body2)
141
-
142
- return body1.total_children < body2.total_children
90
+ #
91
+ # Appends an `AND` expression to the injection.
92
+ #
93
+ # @yield [(injection)]
94
+ # The return value of the block will be used as the right-hand side
95
+ # operand. If the block accepts an argument, it will be called with
96
+ # the injection.
97
+ #
98
+ # @yieldparam [Injection] injection
99
+ #
100
+ # @return [self]
101
+ #
102
+ def and(&block)
103
+ value = case block.arity
104
+ when 0 then instance_eval(&block)
105
+ else block.call(self)
106
+ end
107
+
108
+ @expression = BinaryExpr.new(@expression,:AND,value)
109
+ return self
143
110
  end
144
111
 
145
- def has_column?(column,options={})
146
- body1 = inject(options)
147
- body2 = inject(options.merge(:symbols => {:column => column})) do
148
- has_column?(column)
149
- end
150
-
151
- if (body1.sql_error? || body2.sql_error?)
152
- return false
153
- end
154
-
155
- body1 = Nokogiri::HTML(body1)
156
- body2 = Nokogiri::HTML(body2)
157
-
158
- return body1.total_children == body2.total_children
112
+ #
113
+ # Appends an `OR` expression to the injection.
114
+ #
115
+ # @yield [(injection)]
116
+ # The return value of the block will be used as the right-hand side
117
+ # operand. If the block accepts an argument, it will be called with
118
+ # the injection.
119
+ #
120
+ # @yieldparam [Injection] injection
121
+ #
122
+ # @return [self]
123
+ #
124
+ def or(&block)
125
+ value = case block.arity
126
+ when 0 then instance_eval(&block)
127
+ else block.call(self)
128
+ end
129
+
130
+ @expression = BinaryExpr.new(@expression,:OR,value)
131
+ return self
159
132
  end
160
133
 
161
- def has_table?(table,options={})
162
- body1 = inject(options)
163
- body2 = inject(options.merge(:symbols => {:table => table})) do
164
- has_table?(table)
165
- end
166
-
167
- if (body1.sql_error? || body2.sql_error?)
168
- return false
169
- end
170
-
171
- body1 = Nokogiri::HTML(body1)
172
- body2 = Nokogiri::HTML(body2)
134
+ #
135
+ # Converts the SQL injection to SQL.
136
+ #
137
+ # @param [Hash] options
138
+ # Additional options for {Emitter#initialize}.
139
+ #
140
+ # @option options [Boolean] :terminate
141
+ # Specifies whether to terminate the injection with `;--`.
142
+ #
143
+ # @return [String]
144
+ # The raw SQL.
145
+ #
146
+ def to_sql(options={})
147
+ emitter = emitter(options)
148
+ sql = ''
173
149
 
174
- return body1.total_children == body2.total_children
175
- end
150
+ sql << emitter.emit(@expression)
176
151
 
177
- def uses_column?(column,options={})
178
- body1 = inject(options)
179
- body2 = inject(options.merge(:symbols => {:column => column})) do
180
- uses_column?(table)
152
+ unless clauses.empty?
153
+ sql << emitter.space << emitter.emit_clauses(clauses)
181
154
  end
182
155
 
183
- if (body1.sql_error? || body2.sql_error?)
184
- return false
156
+ unless statements.empty?
157
+ sql << ';' << emitter.space << emitter.emit_statement_list(self)
185
158
  end
186
159
 
187
- body1 = Nokogiri::HTML(body1)
188
- body2 = Nokogiri::HTML(body2)
189
-
190
- return body1.total_children == body2.total_children
191
- end
192
-
193
- def uses_table?(table,options={})
194
- body1 = inject(options)
195
- body2 = inject(options.merge(:symbols => {:table => table})) do
196
- uses_table?(table)
197
- end
160
+ case @escape
161
+ when :string, :list
162
+ if (options[:terminate] || (sql[0,1] != sql[-1,1]))
163
+ # terminate the expression
164
+ sql << ';--'
165
+ else
166
+ sql = sql[0..-2]
167
+ end
198
168
 
199
- if (body1.sql_error? || body2.sql_error?)
200
- return false
169
+ # balance the quotes
170
+ sql = sql[1..-1]
171
+ else
172
+ if options[:terminate]
173
+ # terminate the expression
174
+ sql << ';--'
175
+ end
201
176
  end
202
177
 
203
- body1 = Nokogiri::HTML(body1)
204
- body2 = Nokogiri::HTML(body2)
205
-
206
- return body1.total_children == body2.total_children
207
- end
208
-
209
- def to_s
210
- @url.to_s
178
+ return sql
211
179
  end
212
180
 
213
181
  end
@@ -1,8 +1,9 @@
1
1
  #
2
- # Ronin SQL - A Ronin library providing support for SQL related security
3
- # tasks.
2
+ # Ronin SQL - A Ruby DSL for crafting SQL Injections.
4
3
  #
5
- # Copyright (c) 2007-2009 Hal Brodigan (postmodern.mod3 at gmail.com)
4
+ # Copyright (c) 2007-2013 Hal Brodigan (postmodern.mod3 at gmail.com)
5
+ #
6
+ # This file is part of Ronin SQL.
6
7
  #
7
8
  # This program is free software; you can redistribute it and/or modify
8
9
  # it under the terms of the GNU General Public License as published by
@@ -19,18 +20,19 @@
19
20
  # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
21
  #
21
22
 
22
- require 'ronin/code/sql/default_values_clause'
23
+ require 'ronin/sql/emittable'
24
+ require 'ronin/sql/operators'
23
25
 
24
26
  module Ronin
25
- module Code
26
- module SQL
27
- class DefaultValuesClause < Clause
27
+ module SQL
28
+ #
29
+ # Represents SQL literals.
30
+ #
31
+ class Literal < Struct.new(:value)
28
32
 
29
- def emit
30
- emit_token('DEFAULT VALUES')
31
- end
33
+ include Operators
34
+ include Emittable
32
35
 
33
- end
34
36
  end
35
37
  end
36
38
  end
@@ -0,0 +1,72 @@
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/literal'
24
+
25
+ module Ronin
26
+ module SQL
27
+ #
28
+ # Methods for creating SQL {Literals Literal}.
29
+ #
30
+ module Literals
31
+ #
32
+ # Creates a `NULL` literal.
33
+ #
34
+ # @return [Literal]
35
+ # The `NULL` literal.
36
+ #
37
+ def null
38
+ Literal.new(:NULL)
39
+ end
40
+
41
+ #
42
+ # Creates an Integer literal.
43
+ #
44
+ # @return [Literal<Integer>]
45
+ # The Integer literal.
46
+ #
47
+ def int(value)
48
+ Literal.new(value.to_i)
49
+ end
50
+
51
+ #
52
+ # Creates an Float literal.
53
+ #
54
+ # @return [Literal<Float>]
55
+ # The Float literal.
56
+ #
57
+ def float(value)
58
+ Literal.new(value.to_f)
59
+ end
60
+
61
+ #
62
+ # Creates an String literal.
63
+ #
64
+ # @return [Literal<String>]
65
+ # The String literal.
66
+ #
67
+ def string(value)
68
+ Literal.new(value.to_s)
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,332 @@
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
+ module Ronin
24
+ module SQL
25
+ #
26
+ # Methods for creating SQL expressions.
27
+ #
28
+ # @see http://sqlite.org/lang_expr.html
29
+ #
30
+ module Operators
31
+ #
32
+ # Multiplication.
33
+ #
34
+ # @return [BinaryExpr]
35
+ # The new binary expression.
36
+ #
37
+ def *(other)
38
+ BinaryExpr.new(self,:*,other)
39
+ end
40
+
41
+ #
42
+ # Division.
43
+ #
44
+ # @return [BinaryExpr]
45
+ # The new binary expression.
46
+ #
47
+ def /(other)
48
+ BinaryExpr.new(self,:/,other)
49
+ end
50
+
51
+ #
52
+ # Modulus.
53
+ #
54
+ # @return [BinaryExpr]
55
+ # The new binary expression.
56
+ #
57
+ def %(other)
58
+ BinaryExpr.new(self,:%,other)
59
+ end
60
+
61
+ #
62
+ # Addition.
63
+ #
64
+ # @return [BinaryExpr]
65
+ # The new binary expression.
66
+ #
67
+ def +(other)
68
+ BinaryExpr.new(self,:+,other)
69
+ end
70
+
71
+ #
72
+ # Subtraction.
73
+ #
74
+ # @return [BinaryExpr]
75
+ # The new binary expression.
76
+ #
77
+ def -(other)
78
+ BinaryExpr.new(self,:-,other)
79
+ end
80
+
81
+ #
82
+ # Bit-wise left shift.
83
+ #
84
+ # @return [BinaryExpr]
85
+ # The new binary expression.
86
+ #
87
+ def <<(other)
88
+ BinaryExpr.new(self,:<<,other)
89
+ end
90
+
91
+ #
92
+ # Bit-wise right shift.
93
+ #
94
+ # @return [BinaryExpr]
95
+ # The new binary expression.
96
+ #
97
+ def >>(other)
98
+ BinaryExpr.new(self,:>>,other)
99
+ end
100
+
101
+ #
102
+ # Bit-wise `AND`.
103
+ #
104
+ # @return [BinaryExpr]
105
+ # The new binary expression.
106
+ #
107
+ def &(other)
108
+ BinaryExpr.new(self,:&,other)
109
+ end
110
+
111
+ #
112
+ # Bit-wise `OR`.
113
+ #
114
+ # @return [BinaryExpr]
115
+ # The new binary expression.
116
+ #
117
+ def |(other)
118
+ BinaryExpr.new(self,:|,other)
119
+ end
120
+
121
+ #
122
+ # Less than.
123
+ #
124
+ # @return [BinaryExpr]
125
+ # The new binary expression.
126
+ #
127
+ def <(other)
128
+ BinaryExpr.new(self,:<,other)
129
+ end
130
+
131
+ #
132
+ # Less than or equal to.
133
+ #
134
+ # @return [BinaryExpr]
135
+ # The new binary expression.
136
+ #
137
+ def <=(other)
138
+ BinaryExpr.new(self,:<=,other)
139
+ end
140
+
141
+ #
142
+ # Greater than.
143
+ #
144
+ # @return [BinaryExpr]
145
+ # The new binary expression.
146
+ #
147
+ def >(other)
148
+ BinaryExpr.new(self,:>,other)
149
+ end
150
+
151
+ #
152
+ # Greater than or equal to.
153
+ #
154
+ # @return [BinaryExpr]
155
+ # The new binary expression.
156
+ #
157
+ def >=(other)
158
+ BinaryExpr.new(self,:>=,other)
159
+ end
160
+
161
+ #
162
+ # Equal to.
163
+ #
164
+ # @return [BinaryExpr]
165
+ # The new binary expression.
166
+ #
167
+ def ==(other)
168
+ BinaryExpr.new(self,:"=",other)
169
+ end
170
+
171
+ #
172
+ # Not equal to.
173
+ #
174
+ # @return [BinaryExpr]
175
+ # The new binary expression.
176
+ #
177
+ def !=(other)
178
+ BinaryExpr.new(self,:!=,other)
179
+ end
180
+
181
+ #
182
+ # Alias.
183
+ #
184
+ # @return [BinaryExpr]
185
+ # The new binary expression.
186
+ #
187
+ def as(name)
188
+ BinaryExpr.new(self,:AS,name)
189
+ end
190
+
191
+ #
192
+ # `IS` comparison.
193
+ #
194
+ # @return [BinaryExpr]
195
+ # The new binary expression.
196
+ #
197
+ def is(other)
198
+ BinaryExpr.new(self,:IS,other)
199
+ end
200
+
201
+ #
202
+ # `IS NOT` comparison.
203
+ #
204
+ # @return [BinaryExpr]
205
+ # The new binary expression.
206
+ #
207
+ def is_not(other)
208
+ BinaryExpr.new(self,:"IS NOT",other)
209
+ end
210
+
211
+ #
212
+ # `LIKE` comparison.
213
+ #
214
+ # @return [BinaryExpr]
215
+ # The new binary expression.
216
+ #
217
+ def like(other)
218
+ BinaryExpr.new(self,:LIKE,other)
219
+ end
220
+
221
+ #
222
+ # `GLOB` comparison.
223
+ #
224
+ # @return [BinaryExpr]
225
+ # The new binary expression.
226
+ #
227
+ def glob(other)
228
+ BinaryExpr.new(self,:GLOB,other)
229
+ end
230
+
231
+ #
232
+ # `MATCH` comparison.
233
+ #
234
+ # @return [BinaryExpr]
235
+ # The new binary expression.
236
+ #
237
+ def match(other)
238
+ BinaryExpr.new(self,:MATCH,other)
239
+ end
240
+
241
+ #
242
+ # `REGEXP` comparison.
243
+ #
244
+ # @return [BinaryExpr]
245
+ # The new binary expression.
246
+ #
247
+ def regexp(other)
248
+ BinaryExpr.new(self,:REGEXP,other)
249
+ end
250
+
251
+ #
252
+ # `REGEXP` comparison.
253
+ #
254
+ # @return [BinaryExpr]
255
+ # The new binary expression.
256
+ #
257
+ def in(other)
258
+ BinaryExpr.new(self,:IN,other)
259
+ end
260
+
261
+ #
262
+ # Unary minus.
263
+ #
264
+ # @return [UnaryExpr]
265
+ # The new binary expression.
266
+ #
267
+ def -@
268
+ UnaryExpr.new(:-,self)
269
+ end
270
+
271
+ #
272
+ # Unary plus.
273
+ #
274
+ # @return [UnaryExpr]
275
+ # The new binary expression.
276
+ #
277
+ def +@
278
+ UnaryExpr.new(:+,self)
279
+ end
280
+
281
+ #
282
+ # Bit-wise negate.
283
+ #
284
+ # @return [UnaryExpr]
285
+ # The new binary expression.
286
+ #
287
+ def ~
288
+ UnaryExpr.new(:~,self)
289
+ end
290
+
291
+ #
292
+ # Logical negate.
293
+ #
294
+ # @return [UnaryExpr]
295
+ # The new binary expression.
296
+ #
297
+ def !
298
+ UnaryExpr.new(:!,self)
299
+ end
300
+
301
+ #
302
+ # Logical `NOT`.
303
+ #
304
+ # @return [UnaryExpr]
305
+ # The new binary expression.
306
+ #
307
+ def not
308
+ UnaryExpr.new(:NOT,self)
309
+ end
310
+
311
+ #
312
+ # `AND`.
313
+ #
314
+ # @return [BinaryExpr]
315
+ # The new binary expression.
316
+ #
317
+ def and(other)
318
+ BinaryExpr.new(self,:AND,other)
319
+ end
320
+
321
+ #
322
+ # `OR`.
323
+ #
324
+ # @return [BinaryExpr]
325
+ # The new binary expression.
326
+ #
327
+ def or(other)
328
+ BinaryExpr.new(self,:OR,other)
329
+ end
330
+ end
331
+ end
332
+ end