sequel_core 2.2.0 → 3.8.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.
- metadata +30 -101
- data/CHANGELOG +0 -1519
- data/COPYING +0 -19
- data/README +0 -313
- data/Rakefile +0 -158
- data/bin/sequel +0 -117
- data/doc/cheat_sheet.rdoc +0 -225
- data/doc/dataset_filtering.rdoc +0 -182
- data/lib/sequel_core.rb +0 -136
- data/lib/sequel_core/adapters/adapter_skeleton.rb +0 -68
- data/lib/sequel_core/adapters/ado.rb +0 -90
- data/lib/sequel_core/adapters/db2.rb +0 -160
- data/lib/sequel_core/adapters/dbi.rb +0 -127
- data/lib/sequel_core/adapters/informix.rb +0 -89
- data/lib/sequel_core/adapters/jdbc.rb +0 -110
- data/lib/sequel_core/adapters/mysql.rb +0 -486
- data/lib/sequel_core/adapters/odbc.rb +0 -167
- data/lib/sequel_core/adapters/odbc_mssql.rb +0 -106
- data/lib/sequel_core/adapters/openbase.rb +0 -76
- data/lib/sequel_core/adapters/oracle.rb +0 -182
- data/lib/sequel_core/adapters/postgres.rb +0 -560
- data/lib/sequel_core/adapters/sqlite.rb +0 -270
- data/lib/sequel_core/connection_pool.rb +0 -194
- data/lib/sequel_core/core_ext.rb +0 -197
- data/lib/sequel_core/core_sql.rb +0 -184
- data/lib/sequel_core/database.rb +0 -462
- data/lib/sequel_core/database/schema.rb +0 -156
- data/lib/sequel_core/dataset.rb +0 -457
- data/lib/sequel_core/dataset/callback.rb +0 -13
- data/lib/sequel_core/dataset/convenience.rb +0 -245
- data/lib/sequel_core/dataset/pagination.rb +0 -96
- data/lib/sequel_core/dataset/query.rb +0 -41
- data/lib/sequel_core/dataset/schema.rb +0 -15
- data/lib/sequel_core/dataset/sql.rb +0 -889
- data/lib/sequel_core/deprecated.rb +0 -26
- data/lib/sequel_core/exceptions.rb +0 -42
- data/lib/sequel_core/migration.rb +0 -187
- data/lib/sequel_core/object_graph.rb +0 -216
- data/lib/sequel_core/pretty_table.rb +0 -71
- data/lib/sequel_core/schema.rb +0 -2
- data/lib/sequel_core/schema/generator.rb +0 -239
- data/lib/sequel_core/schema/sql.rb +0 -326
- data/lib/sequel_core/sql.rb +0 -812
- data/lib/sequel_core/worker.rb +0 -68
- data/spec/adapters/informix_spec.rb +0 -96
- data/spec/adapters/mysql_spec.rb +0 -765
- data/spec/adapters/oracle_spec.rb +0 -222
- data/spec/adapters/postgres_spec.rb +0 -441
- data/spec/adapters/sqlite_spec.rb +0 -413
- data/spec/connection_pool_spec.rb +0 -363
- data/spec/core_ext_spec.rb +0 -156
- data/spec/core_sql_spec.rb +0 -427
- data/spec/database_spec.rb +0 -963
- data/spec/dataset_spec.rb +0 -2933
- data/spec/expression_filters_spec.rb +0 -316
- data/spec/migration_spec.rb +0 -261
- data/spec/object_graph_spec.rb +0 -230
- data/spec/pretty_table_spec.rb +0 -58
- data/spec/rcov.opts +0 -6
- data/spec/schema_generator_spec.rb +0 -122
- data/spec/schema_spec.rb +0 -422
- data/spec/spec.opts +0 -0
- data/spec/spec_config.rb +0 -7
- data/spec/spec_config.rb.example +0 -8
- data/spec/spec_helper.rb +0 -55
- data/spec/worker_spec.rb +0 -96
data/lib/sequel_core/sql.rb
DELETED
@@ -1,812 +0,0 @@
|
|
1
|
-
module Sequel
|
2
|
-
# The SQL module holds classes whose instances represent SQL fragments.
|
3
|
-
# It also holds modules that are included in core ruby classes that
|
4
|
-
# make Sequel a friendly DSL.
|
5
|
-
module SQL
|
6
|
-
### Parent Classes ###
|
7
|
-
|
8
|
-
# Classes/Modules aren't an alphabetical order due to the fact that
|
9
|
-
# some reference constants defined in others at load time.
|
10
|
-
|
11
|
-
# Base class for all SQL fragments
|
12
|
-
class Expression
|
13
|
-
# Returns self, because SQL::Expression already acts like
|
14
|
-
# LiteralString.
|
15
|
-
def lit
|
16
|
-
self
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
# Represents a complex SQL expression, with a given operator and one
|
21
|
-
# or more attributes (which may also be ComplexExpressions, forming
|
22
|
-
# a tree). This class is the backbone of the blockless filter support in
|
23
|
-
# Sequel.
|
24
|
-
#
|
25
|
-
# This is an abstract class that is not that useful by itself. The
|
26
|
-
# subclasses BooleanExpression, NumericExpression, and StringExpression
|
27
|
-
# define the behavior of the DSL via operators.
|
28
|
-
class ComplexExpression < Expression
|
29
|
-
# A hash of the opposite for each operator symbol, used for inverting
|
30
|
-
# objects.
|
31
|
-
OPERTATOR_INVERSIONS = {:AND => :OR, :OR => :AND, :< => :>=, :> => :<=,
|
32
|
-
:<= => :>, :>= => :<, :'=' => :'!=' , :'!=' => :'=', :LIKE => :'NOT LIKE',
|
33
|
-
:'NOT LIKE' => :LIKE, :~ => :'!~', :'!~' => :~, :IN => :'NOT IN',
|
34
|
-
:'NOT IN' => :IN, :IS => :'IS NOT', :'IS NOT' => :IS, :'~*' => :'!~*',
|
35
|
-
:'!~*' => :'~*', :NOT => :NOOP, :NOOP => :NOT, :ILIKE => :'NOT ILIKE',
|
36
|
-
:'NOT ILIKE'=>:ILIKE}
|
37
|
-
|
38
|
-
# Mathematical Operators used in NumericMethods
|
39
|
-
MATHEMATICAL_OPERATORS = [:+, :-, :/, :*]
|
40
|
-
|
41
|
-
# Mathematical Operators used in NumericMethods
|
42
|
-
BITWISE_OPERATORS = [:&, :|, :^, :<<, :>>]
|
43
|
-
|
44
|
-
# Inequality Operators used in InequalityMethods
|
45
|
-
INEQUALITY_OPERATORS = [:<, :>, :<=, :>=]
|
46
|
-
|
47
|
-
# Hash of ruby operator symbols to SQL operators, used in BooleanMethods
|
48
|
-
BOOLEAN_OPERATOR_METHODS = {:& => :AND, :| =>:OR}
|
49
|
-
|
50
|
-
# Operator symbols that take exactly two arguments
|
51
|
-
TWO_ARITY_OPERATORS = [:'=', :'!=', :IS, :'IS NOT', :LIKE, :'NOT LIKE', \
|
52
|
-
:~, :'!~', :'~*', :'!~*', :IN, :'NOT IN', :ILIKE, :'NOT ILIKE'] + \
|
53
|
-
INEQUALITY_OPERATORS + BITWISE_OPERATORS
|
54
|
-
|
55
|
-
# Operator symbols that take one or more arguments
|
56
|
-
N_ARITY_OPERATORS = [:AND, :OR, :'||'] + MATHEMATICAL_OPERATORS
|
57
|
-
|
58
|
-
# Operator symbols that take one argument
|
59
|
-
ONE_ARITY_OPERATORS = [:NOT, :NOOP, :'B~']
|
60
|
-
|
61
|
-
# An array of args for this object
|
62
|
-
attr_reader :args
|
63
|
-
|
64
|
-
# The operator symbol for this object
|
65
|
-
attr_reader :op
|
66
|
-
|
67
|
-
# Set the operator symbol and arguments for this object to the ones given.
|
68
|
-
# Convert all args that are hashes or arrays with all two pairs to ComplexExpressions.
|
69
|
-
# Raise an error if the operator doesn't allow boolean input and a boolean argument is given.
|
70
|
-
# Raise an error if the wrong number of arguments for a given operator is used.
|
71
|
-
def initialize(op, *args)
|
72
|
-
args.collect! do |a|
|
73
|
-
case a
|
74
|
-
when Hash
|
75
|
-
a.sql_expr
|
76
|
-
when Array
|
77
|
-
a.all_two_pairs? ? a.sql_expr : a
|
78
|
-
else
|
79
|
-
a
|
80
|
-
end
|
81
|
-
end
|
82
|
-
case op
|
83
|
-
when *N_ARITY_OPERATORS
|
84
|
-
raise(Error, "The #{op} operator requires at least 1 argument") unless args.length >= 1
|
85
|
-
when *TWO_ARITY_OPERATORS
|
86
|
-
raise(Error, "The #{op} operator requires precisely 2 arguments") unless args.length == 2
|
87
|
-
when *ONE_ARITY_OPERATORS
|
88
|
-
raise(Error, "The #{op} operator requires a single argument") unless args.length == 1
|
89
|
-
else
|
90
|
-
raise(Error, "Invalid operator #{op}")
|
91
|
-
end
|
92
|
-
@op = op
|
93
|
-
@args = args
|
94
|
-
end
|
95
|
-
|
96
|
-
# Delegate the creation of the resulting SQL to the given dataset,
|
97
|
-
# since it may be database dependent.
|
98
|
-
def to_s(ds)
|
99
|
-
ds.complex_expression_sql(@op, @args)
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
# The base class for expressions that can be used in multiple places in
|
104
|
-
# the SQL query.
|
105
|
-
class GenericExpression < Expression
|
106
|
-
end
|
107
|
-
|
108
|
-
# The base class for expressions that are specific and can only be used
|
109
|
-
# in a certain place in the SQL query (ordering, selecting).
|
110
|
-
class SpecificExpression < Expression
|
111
|
-
end
|
112
|
-
|
113
|
-
### Modules ###
|
114
|
-
|
115
|
-
# Methods the create aliased identifiers
|
116
|
-
module AliasMethods
|
117
|
-
# Create an SQL column alias of the receiving column to the given alias.
|
118
|
-
def as(aliaz)
|
119
|
-
AliasedExpression.new(self, aliaz)
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
# This defines the bitwise methods &, |, ^, ~, <<, and >>. Because these
|
124
|
-
# methods overlap with the standard BooleanMethods methods, and they only
|
125
|
-
# make sense for numbers, they are only included in NumericExpression.
|
126
|
-
module BitwiseMethods
|
127
|
-
ComplexExpression::BITWISE_OPERATORS.each do |o|
|
128
|
-
define_method(o) do |ce|
|
129
|
-
case ce
|
130
|
-
when NumericExpression
|
131
|
-
NumericExpression.new(o, self, ce)
|
132
|
-
when ComplexExpression
|
133
|
-
raise(Sequel::Error, "cannot apply #{o} to a non-numeric expression")
|
134
|
-
else
|
135
|
-
NumericExpression.new(o, self, ce)
|
136
|
-
end
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
# Do the bitwise compliment of the self
|
141
|
-
def ~
|
142
|
-
case self
|
143
|
-
when NumericExpression
|
144
|
-
NumericExpression.new(:'B~', self)
|
145
|
-
when ComplexExpression
|
146
|
-
raise(Sequel::Error, "cannot apply #{o} to a non-numeric expression")
|
147
|
-
else
|
148
|
-
NumericExpression.new(:'B~', self)
|
149
|
-
end
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
# This module includes the methods that are defined on objects that can be
|
154
|
-
# used in a boolean context in SQL (Symbol, LiteralString, SQL::Function,
|
155
|
-
# and SQL::BooleanExpression).
|
156
|
-
#
|
157
|
-
# This defines the ~ (NOT), & (AND), and | (OR) methods.
|
158
|
-
module BooleanMethods
|
159
|
-
# Create a new BooleanExpression with NOT, representing the inversion of whatever self represents.
|
160
|
-
def ~
|
161
|
-
BooleanExpression.invert(self)
|
162
|
-
end
|
163
|
-
|
164
|
-
ComplexExpression::BOOLEAN_OPERATOR_METHODS.each do |m, o|
|
165
|
-
define_method(m) do |ce|
|
166
|
-
case ce
|
167
|
-
when BooleanExpression
|
168
|
-
BooleanExpression.new(o, self, ce)
|
169
|
-
when ComplexExpression
|
170
|
-
raise(Sequel::Error, "cannot apply #{o} to a non-boolean expression")
|
171
|
-
else
|
172
|
-
BooleanExpression.new(o, self, ce)
|
173
|
-
end
|
174
|
-
end
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
# Holds methods that are used to cast objects to differen SQL types.
|
179
|
-
module CastMethods
|
180
|
-
# Cast the reciever to the given SQL type
|
181
|
-
def cast(sql_type)
|
182
|
-
IrregularFunction.new(:cast, self, :AS, sql_type.to_s.lit)
|
183
|
-
end
|
184
|
-
alias_method :cast_as, :cast
|
185
|
-
|
186
|
-
# Cast the reciever to the given SQL type (or integer if none given),
|
187
|
-
# and return the result as a NumericExpression.
|
188
|
-
def cast_numeric(sql_type = nil)
|
189
|
-
cast(sql_type || :integer).sql_number
|
190
|
-
end
|
191
|
-
|
192
|
-
# Cast the reciever to the given SQL type (or text if none given),
|
193
|
-
# and return the result as a StringExpression, so you can use +
|
194
|
-
# directly on the result for SQL string concatenation.
|
195
|
-
def cast_string(sql_type = nil)
|
196
|
-
cast(sql_type || :text).sql_string
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
|
-
# Includes a method that returns Identifiers.
|
201
|
-
module IdentifierMethods
|
202
|
-
# Return self wrapped as an identifier.
|
203
|
-
def identifier
|
204
|
-
Identifier.new(self)
|
205
|
-
end
|
206
|
-
end
|
207
|
-
|
208
|
-
# This module includes the methods that are defined on objects that can be
|
209
|
-
# used in a numeric or string context in SQL (Symbol, LiteralString,
|
210
|
-
# SQL::Function, and SQL::StringExpression).
|
211
|
-
#
|
212
|
-
# This defines the >, <, >=, and <= methods.
|
213
|
-
module InequalityMethods
|
214
|
-
ComplexExpression::INEQUALITY_OPERATORS.each do |o|
|
215
|
-
define_method(o) do |ce|
|
216
|
-
case ce
|
217
|
-
when BooleanExpression, TrueClass, FalseClass, NilClass, Hash, Array
|
218
|
-
raise(Error, "cannot apply #{o} to a boolean expression")
|
219
|
-
else
|
220
|
-
BooleanExpression.new(o, self, ce)
|
221
|
-
end
|
222
|
-
end
|
223
|
-
end
|
224
|
-
end
|
225
|
-
|
226
|
-
# This module augments the default initalize method for the
|
227
|
-
# ComplexExpression subclass it is included in, so that
|
228
|
-
# attempting to use boolean input when initializing a NumericExpression
|
229
|
-
# or StringExpression results in an error.
|
230
|
-
module NoBooleanInputMethods
|
231
|
-
# Raise an Error if one of the args would be boolean in an SQL
|
232
|
-
# context, otherwise call super.
|
233
|
-
def initialize(op, *args)
|
234
|
-
args.each do |a|
|
235
|
-
case a
|
236
|
-
when BooleanExpression, TrueClass, FalseClass, NilClass, Hash, Array
|
237
|
-
raise(Error, "cannot apply #{op} to a boolean expression")
|
238
|
-
end
|
239
|
-
end
|
240
|
-
super
|
241
|
-
end
|
242
|
-
end
|
243
|
-
|
244
|
-
# This module includes the methods that are defined on objects that can be
|
245
|
-
# used in a numeric context in SQL (Symbol, LiteralString, SQL::Function,
|
246
|
-
# and SQL::NumericExpression).
|
247
|
-
#
|
248
|
-
# This defines the +, -, *, and / methods.
|
249
|
-
module NumericMethods
|
250
|
-
ComplexExpression::MATHEMATICAL_OPERATORS.each do |o|
|
251
|
-
define_method(o) do |ce|
|
252
|
-
case ce
|
253
|
-
when NumericExpression
|
254
|
-
NumericExpression.new(o, self, ce)
|
255
|
-
when ComplexExpression
|
256
|
-
raise(Sequel::Error, "cannot apply #{o} to a non-numeric expression")
|
257
|
-
else
|
258
|
-
NumericExpression.new(o, self, ce)
|
259
|
-
end
|
260
|
-
end
|
261
|
-
end
|
262
|
-
end
|
263
|
-
|
264
|
-
# Methods that create OrderedExpressions, used for sorting by columns
|
265
|
-
# or more complex expressions.
|
266
|
-
module OrderMethods
|
267
|
-
# Mark the receiving SQL column as sorting in a descending fashion.
|
268
|
-
def desc
|
269
|
-
OrderedExpression.new(self)
|
270
|
-
end
|
271
|
-
|
272
|
-
# Mark the receiving SQL column as sorting in an ascending fashion (generally a no-op).
|
273
|
-
def asc
|
274
|
-
OrderedExpression.new(self, false)
|
275
|
-
end
|
276
|
-
end
|
277
|
-
|
278
|
-
# Methods that created QualifiedIdentifiers, used for qualifying column
|
279
|
-
# names with a table or table names with a schema.
|
280
|
-
module QualifyingMethods
|
281
|
-
# Qualify the current object with the given table/schema.
|
282
|
-
def qualify(ts)
|
283
|
-
QualifiedIdentifier.new(ts, self)
|
284
|
-
end
|
285
|
-
end
|
286
|
-
|
287
|
-
# This module includes the methods that are defined on objects that can be
|
288
|
-
# used in a numeric context in SQL (Symbol, LiteralString, SQL::Function,
|
289
|
-
# and SQL::StringExpression).
|
290
|
-
#
|
291
|
-
# This defines the like (LIKE) method, used for pattern matching.
|
292
|
-
module StringMethods
|
293
|
-
# Create a BooleanExpression case insensitive pattern match of self
|
294
|
-
# with the given patterns. See StringExpression.like.
|
295
|
-
def ilike(*ces)
|
296
|
-
StringExpression.like(self, *(ces << {:case_insensitive=>true}))
|
297
|
-
end
|
298
|
-
|
299
|
-
# Create a BooleanExpression case sensitive pattern match of self with
|
300
|
-
# the given patterns. See StringExpression.like.
|
301
|
-
def like(*ces)
|
302
|
-
StringExpression.like(self, *ces)
|
303
|
-
end
|
304
|
-
end
|
305
|
-
|
306
|
-
# This module is included in StringExpression and can be included elsewhere
|
307
|
-
# to allow the use of the + operator to represent concatenation of SQL
|
308
|
-
# Strings:
|
309
|
-
#
|
310
|
-
# :x.sql_string + :y => # SQL: x || y
|
311
|
-
module StringConcatenationMethods
|
312
|
-
def +(ce)
|
313
|
-
StringExpression.new(:'||', self, ce)
|
314
|
-
end
|
315
|
-
end
|
316
|
-
|
317
|
-
### Modules that include other modules ###
|
318
|
-
|
319
|
-
# This module includes other Sequel::SQL::*Methods modules and is
|
320
|
-
# included in other classes that are could be either booleans,
|
321
|
-
# strings, or numbers. It also adds three methods so that
|
322
|
-
# can specify behavior in case one of the operator methods has
|
323
|
-
# been overridden (such as Symbol#/).
|
324
|
-
#
|
325
|
-
# For example, if Symbol#/ is overridden to produce a string (for
|
326
|
-
# example, to make file system path creation easier), the
|
327
|
-
# following code will not do what you want:
|
328
|
-
#
|
329
|
-
# :price/10 > 100
|
330
|
-
#
|
331
|
-
# In that case, you need to do the following:
|
332
|
-
#
|
333
|
-
# :price.sql_number/10 > 100
|
334
|
-
module ComplexExpressionMethods
|
335
|
-
include BooleanMethods
|
336
|
-
include NumericMethods
|
337
|
-
include StringMethods
|
338
|
-
include InequalityMethods
|
339
|
-
|
340
|
-
# Extract a datetime_part (e.g. year, month) from self:
|
341
|
-
#
|
342
|
-
# :date.extract(:year) # SQL: extract(year FROM date)
|
343
|
-
#
|
344
|
-
# Also has the benefit of returning the result as a
|
345
|
-
# NumericExpression instead of a generic ComplexExpression.
|
346
|
-
def extract(datetime_part)
|
347
|
-
IrregularFunction.new(:extract, datetime_part.to_s.lit, :FROM, self).sql_number
|
348
|
-
end
|
349
|
-
|
350
|
-
# Return a BooleanExpression representation of self.
|
351
|
-
def sql_boolean
|
352
|
-
BooleanExpression.new(:NOOP, self)
|
353
|
-
end
|
354
|
-
|
355
|
-
# Return a NumericExpression representation of self.
|
356
|
-
def sql_number
|
357
|
-
NumericExpression.new(:NOOP, self)
|
358
|
-
end
|
359
|
-
|
360
|
-
# Return a StringExpression representation of self.
|
361
|
-
def sql_string
|
362
|
-
StringExpression.new(:NOOP, self)
|
363
|
-
end
|
364
|
-
end
|
365
|
-
|
366
|
-
module SpecificExpressionMethods
|
367
|
-
include AliasMethods
|
368
|
-
include CastMethods
|
369
|
-
include OrderMethods
|
370
|
-
end
|
371
|
-
|
372
|
-
module GenericExpressionMethods
|
373
|
-
include SpecificExpressionMethods
|
374
|
-
include ComplexExpressionMethods
|
375
|
-
end
|
376
|
-
|
377
|
-
class ComplexExpression
|
378
|
-
include SpecificExpressionMethods
|
379
|
-
end
|
380
|
-
|
381
|
-
class GenericExpression
|
382
|
-
include GenericExpressionMethods
|
383
|
-
end
|
384
|
-
|
385
|
-
### Classes ###
|
386
|
-
|
387
|
-
# Represents an aliasing of an expression/column to a given name.
|
388
|
-
class AliasedExpression < SpecificExpression
|
389
|
-
# The expression to alias
|
390
|
-
attr_reader :expression
|
391
|
-
|
392
|
-
# The alias to use for the expression, not alias since that is
|
393
|
-
# a keyword in ruby.
|
394
|
-
attr_reader :aliaz
|
395
|
-
|
396
|
-
# Create an object with the given expression and alias.
|
397
|
-
def initialize(expression, aliaz)
|
398
|
-
@expression, @aliaz = expression, aliaz
|
399
|
-
end
|
400
|
-
|
401
|
-
# Delegate the creation of the resulting SQL to the given dataset,
|
402
|
-
# since it may be database dependent.
|
403
|
-
def to_s(ds)
|
404
|
-
ds.aliased_expression_sql(self)
|
405
|
-
end
|
406
|
-
end
|
407
|
-
|
408
|
-
# Blob is used to represent binary data in the Ruby environment that is
|
409
|
-
# stored as a blob type in the database. In PostgreSQL, the blob type is
|
410
|
-
# called bytea. Sequel represents binary data as a Blob object because
|
411
|
-
# certain database engines, such as PostgreSQL, require binary data to be
|
412
|
-
# escaped.
|
413
|
-
class Blob < ::String
|
414
|
-
# return self.
|
415
|
-
def to_blob
|
416
|
-
self
|
417
|
-
end
|
418
|
-
end
|
419
|
-
|
420
|
-
# Subclass of ComplexExpression where the expression results
|
421
|
-
# in a boolean value in SQL.
|
422
|
-
class BooleanExpression < ComplexExpression
|
423
|
-
include BooleanMethods
|
424
|
-
|
425
|
-
# Take pairs of values (e.g. a hash or array of arrays of two pairs)
|
426
|
-
# and converts it to a BooleanExpression. The operator and args
|
427
|
-
# used depends on the case of the right (2nd) argument:
|
428
|
-
#
|
429
|
-
# * 0..10 - left >= 0 AND left <= 10
|
430
|
-
# * [1,2] - left IN (1,2)
|
431
|
-
# * nil - left IS NULL
|
432
|
-
# * /as/ - left ~ 'as'
|
433
|
-
# * :blah - left = blah
|
434
|
-
# * 'blah' - left = 'blah'
|
435
|
-
#
|
436
|
-
# If multiple arguments are given, they are joined with the op given (AND
|
437
|
-
# by default, OR possible). If negate is set to true,
|
438
|
-
# all subexpressions are inverted before used. Therefore, the following
|
439
|
-
# expressions are equivalent:
|
440
|
-
#
|
441
|
-
# ~from_value_pairs(hash)
|
442
|
-
# from_value_pairs(hash, :OR, true)
|
443
|
-
def self.from_value_pairs(pairs, op=:AND, negate=false)
|
444
|
-
pairs = pairs.collect do |l,r|
|
445
|
-
ce = case r
|
446
|
-
when Range
|
447
|
-
new(:AND, new(:>=, l, r.begin), new(r.exclude_end? ? :< : :<=, l, r.end))
|
448
|
-
when Array, ::Sequel::Dataset
|
449
|
-
new(:IN, l, r)
|
450
|
-
when NilClass
|
451
|
-
new(:IS, l, r)
|
452
|
-
when Regexp
|
453
|
-
StringExpression.like(l, r)
|
454
|
-
else
|
455
|
-
new(:'=', l, r)
|
456
|
-
end
|
457
|
-
negate ? invert(ce) : ce
|
458
|
-
end
|
459
|
-
pairs.length == 1 ? pairs.at(0) : new(op, *pairs)
|
460
|
-
end
|
461
|
-
|
462
|
-
# Invert the expression, if possible. If the expression cannot
|
463
|
-
# be inverted, raise an error. An inverted expression should match everything that the
|
464
|
-
# uninverted expression did not match, and vice-versa.
|
465
|
-
def self.invert(ce)
|
466
|
-
case ce
|
467
|
-
when BooleanExpression
|
468
|
-
case op = ce.op
|
469
|
-
when :AND, :OR
|
470
|
-
BooleanExpression.new(OPERTATOR_INVERSIONS[op], *ce.args.collect{|a| BooleanExpression.invert(a)})
|
471
|
-
else
|
472
|
-
BooleanExpression.new(OPERTATOR_INVERSIONS[op], *ce.args.dup)
|
473
|
-
end
|
474
|
-
when ComplexExpression
|
475
|
-
raise(Sequel::Error, "operator #{ce.op} cannot be inverted")
|
476
|
-
else
|
477
|
-
BooleanExpression.new(:NOT, ce)
|
478
|
-
end
|
479
|
-
end
|
480
|
-
end
|
481
|
-
|
482
|
-
# Represents an SQL CASE expression, used for conditions.
|
483
|
-
class CaseExpression < GenericExpression
|
484
|
-
# An array of all two pairs with the first element specifying the
|
485
|
-
# condition and the second element specifying the result.
|
486
|
-
attr_reader :conditions
|
487
|
-
|
488
|
-
# The default value if no conditions are true
|
489
|
-
attr_reader :default
|
490
|
-
|
491
|
-
# Create an object with the given conditions and
|
492
|
-
# default value.
|
493
|
-
def initialize(conditions, default)
|
494
|
-
raise(Sequel::Error, 'CaseExpression conditions must be an array with all_two_pairs') unless Array === conditions and conditions.all_two_pairs?
|
495
|
-
@conditions, @default = conditions, default
|
496
|
-
end
|
497
|
-
|
498
|
-
# Delegate the creation of the resulting SQL to the given dataset,
|
499
|
-
# since it may be database dependent.
|
500
|
-
def to_s(ds)
|
501
|
-
ds.case_expression_sql(self)
|
502
|
-
end
|
503
|
-
end
|
504
|
-
|
505
|
-
# Represents all columns in a given table, table.* in SQL
|
506
|
-
class ColumnAll < SpecificExpression
|
507
|
-
# The table containing the columns being selected
|
508
|
-
attr_reader :table
|
509
|
-
|
510
|
-
# Create an object with the given table
|
511
|
-
def initialize(table)
|
512
|
-
@table = table
|
513
|
-
end
|
514
|
-
|
515
|
-
# ColumnAll expressions are considered equivalent if they
|
516
|
-
# have the same class and string representation
|
517
|
-
def ==(x)
|
518
|
-
x.class == self.class && @table == x.table
|
519
|
-
end
|
520
|
-
|
521
|
-
# Delegate the creation of the resulting SQL to the given dataset,
|
522
|
-
# since it may be database dependent.
|
523
|
-
def to_s(ds)
|
524
|
-
ds.column_all_sql(self)
|
525
|
-
end
|
526
|
-
end
|
527
|
-
|
528
|
-
# Represents an SQL function call.
|
529
|
-
class Function < GenericExpression
|
530
|
-
# The array of arguments to pass to the function (may be blank)
|
531
|
-
attr_reader :args
|
532
|
-
|
533
|
-
# The SQL function to call
|
534
|
-
attr_reader :f
|
535
|
-
|
536
|
-
# Set the attributes to the given arguments
|
537
|
-
def initialize(f, *args)
|
538
|
-
@f, @args = f, args
|
539
|
-
end
|
540
|
-
|
541
|
-
# Functions are considered equivalent if they
|
542
|
-
# have the same class, function, and arguments.
|
543
|
-
def ==(x)
|
544
|
-
x.class == self.class && @f == x.f && @args == x.args
|
545
|
-
end
|
546
|
-
|
547
|
-
# Delegate the creation of the resulting SQL to the given dataset,
|
548
|
-
# since it may be database dependent.
|
549
|
-
def to_s(ds)
|
550
|
-
ds.function_sql(self)
|
551
|
-
end
|
552
|
-
end
|
553
|
-
|
554
|
-
# Represents an identifier (column or table). Can be used
|
555
|
-
# to specify a Symbol with multiple underscores should not be
|
556
|
-
# split, or for creating an identifier without using a symbol.
|
557
|
-
class Identifier < GenericExpression
|
558
|
-
include QualifyingMethods
|
559
|
-
|
560
|
-
# The table and column to reference
|
561
|
-
attr_reader :value
|
562
|
-
|
563
|
-
# Set the value to the given argument
|
564
|
-
def initialize(value)
|
565
|
-
@value = value
|
566
|
-
end
|
567
|
-
|
568
|
-
# Delegate the creation of the resulting SQL to the given dataset,
|
569
|
-
# since it may be database dependent.
|
570
|
-
def to_s(ds)
|
571
|
-
ds.quote_identifier(@value)
|
572
|
-
end
|
573
|
-
end
|
574
|
-
|
575
|
-
# IrregularFunction is used for the SQL EXTRACT and CAST functions,
|
576
|
-
# which don't use regular function calling syntax. The IrregularFunction
|
577
|
-
# replaces the commas the regular function uses with a custom
|
578
|
-
# join string.
|
579
|
-
#
|
580
|
-
# This shouldn't be used directly, see CastMethods#cast and
|
581
|
-
# ComplexExpressionMethods#extract.
|
582
|
-
class IrregularFunction < Function
|
583
|
-
# The arguments to pass to the function (may be blank)
|
584
|
-
attr_reader :arg1, :arg2
|
585
|
-
|
586
|
-
# The SQL function to call
|
587
|
-
attr_reader :f
|
588
|
-
|
589
|
-
# The literal string to use in place of a comma to join arguments
|
590
|
-
attr_reader :joiner
|
591
|
-
|
592
|
-
# Set the attributes to the given arguments
|
593
|
-
def initialize(f, arg1, joiner, arg2)
|
594
|
-
@f, @arg1, @joiner, @arg2 = f, arg1, joiner, arg2
|
595
|
-
end
|
596
|
-
|
597
|
-
# Delegate the creation of the resulting SQL to the given dataset,
|
598
|
-
# since it may be database dependent.
|
599
|
-
def to_s(ds)
|
600
|
-
ds.irregular_function_sql(self)
|
601
|
-
end
|
602
|
-
end
|
603
|
-
|
604
|
-
# Represents an SQL JOIN clause, used for joining tables.
|
605
|
-
class JoinClause < SpecificExpression
|
606
|
-
# The type of join to do
|
607
|
-
attr_reader :join_type
|
608
|
-
|
609
|
-
# The actual table to join
|
610
|
-
attr_reader :table
|
611
|
-
|
612
|
-
# The table alias to use for the join, if any
|
613
|
-
attr_reader :table_alias
|
614
|
-
|
615
|
-
# Create an object with the given conditions and
|
616
|
-
# default value.
|
617
|
-
def initialize(join_type, table, table_alias = nil)
|
618
|
-
@join_type, @table, @table_alias = join_type, table, table_alias
|
619
|
-
end
|
620
|
-
|
621
|
-
# Delegate the creation of the resulting SQL to the given dataset,
|
622
|
-
# since it may be database dependent.
|
623
|
-
def to_s(ds)
|
624
|
-
ds.join_clause_sql(self)
|
625
|
-
end
|
626
|
-
end
|
627
|
-
|
628
|
-
# Represents an SQL JOIN table ON conditions clause.
|
629
|
-
class JoinOnClause < JoinClause
|
630
|
-
# The conditions for the join
|
631
|
-
attr_reader :on
|
632
|
-
|
633
|
-
# Create an object with the given conditions and
|
634
|
-
# default value.
|
635
|
-
def initialize(on, *args)
|
636
|
-
@on = on
|
637
|
-
super(*args)
|
638
|
-
end
|
639
|
-
|
640
|
-
# Delegate the creation of the resulting SQL to the given dataset,
|
641
|
-
# since it may be database dependent.
|
642
|
-
def to_s(ds)
|
643
|
-
ds.join_on_clause_sql(self)
|
644
|
-
end
|
645
|
-
end
|
646
|
-
|
647
|
-
# Represents an SQL JOIN table USING (columns) clause.
|
648
|
-
class JoinUsingClause < JoinClause
|
649
|
-
# The columns that appear both tables that should be equal
|
650
|
-
# for the conditions to match.
|
651
|
-
attr_reader :using
|
652
|
-
|
653
|
-
# Create an object with the given conditions and
|
654
|
-
# default value.
|
655
|
-
def initialize(using, *args)
|
656
|
-
@using = using
|
657
|
-
super(*args)
|
658
|
-
end
|
659
|
-
|
660
|
-
# Delegate the creation of the resulting SQL to the given dataset,
|
661
|
-
# since it may be database dependent.
|
662
|
-
def to_s(ds)
|
663
|
-
ds.join_using_clause_sql(self)
|
664
|
-
end
|
665
|
-
end
|
666
|
-
|
667
|
-
# Subclass of ComplexExpression where the expression results
|
668
|
-
# in a numeric value in SQL.
|
669
|
-
class NumericExpression < ComplexExpression
|
670
|
-
include BitwiseMethods
|
671
|
-
include NumericMethods
|
672
|
-
include InequalityMethods
|
673
|
-
include NoBooleanInputMethods
|
674
|
-
end
|
675
|
-
|
676
|
-
# Represents a column/expression to order the result set by.
|
677
|
-
class OrderedExpression < SpecificExpression
|
678
|
-
# The expression to order the result set by.
|
679
|
-
attr_reader :expression
|
680
|
-
|
681
|
-
# Whether the expression should order the result set in a descending manner
|
682
|
-
attr_reader :descending
|
683
|
-
|
684
|
-
# Set the expression and descending attributes to the given values.
|
685
|
-
def initialize(expression, descending = true)
|
686
|
-
@expression, @descending = expression, descending
|
687
|
-
end
|
688
|
-
|
689
|
-
# Delegate the creation of the resulting SQL to the given dataset,
|
690
|
-
# since it may be database dependent.
|
691
|
-
def to_s(ds)
|
692
|
-
ds.ordered_expression_sql(self)
|
693
|
-
end
|
694
|
-
end
|
695
|
-
|
696
|
-
# Represents a qualified (column with table) reference. Used when
|
697
|
-
# joining tables to disambiguate columns.
|
698
|
-
class QualifiedIdentifier < GenericExpression
|
699
|
-
# The table and column to reference
|
700
|
-
attr_reader :table, :column
|
701
|
-
|
702
|
-
# Set the attributes to the given arguments
|
703
|
-
def initialize(table, column)
|
704
|
-
@table, @column = table, column
|
705
|
-
end
|
706
|
-
|
707
|
-
# Delegate the creation of the resulting SQL to the given dataset,
|
708
|
-
# since it may be database dependent.
|
709
|
-
def to_s(ds)
|
710
|
-
ds.qualified_identifier_sql(self)
|
711
|
-
end
|
712
|
-
end
|
713
|
-
|
714
|
-
# Subclass of ComplexExpression where the expression results
|
715
|
-
# in a text/string/varchar value in SQL.
|
716
|
-
class StringExpression < ComplexExpression
|
717
|
-
include StringMethods
|
718
|
-
include StringConcatenationMethods
|
719
|
-
include InequalityMethods
|
720
|
-
include NoBooleanInputMethods
|
721
|
-
|
722
|
-
# Creates a SQL pattern match exprssion. left (l) is the SQL string we
|
723
|
-
# are matching against, and ces are the patterns we are matching.
|
724
|
-
# The match succeeds if any of the patterns match (SQL OR). Patterns
|
725
|
-
# can be given as strings or regular expressions. Strings will cause
|
726
|
-
# the SQL LIKE operator to be used, and should be supported by most
|
727
|
-
# databases. Regular expressions will probably only work on MySQL
|
728
|
-
# and PostgreSQL, and SQL regular expression syntax is not fully compatible
|
729
|
-
# with ruby regular expression syntax, so be careful if using regular
|
730
|
-
# expressions.
|
731
|
-
#
|
732
|
-
# The pattern match will be case insensitive if the last argument is a hash
|
733
|
-
# with a key of :case_insensitive that is not false or nil. Also,
|
734
|
-
# if a case insensitive regular expression is used (//i), that particular
|
735
|
-
# pattern which will always be case insensitive.
|
736
|
-
def self.like(l, *ces)
|
737
|
-
case_insensitive = ces.extract_options![:case_insensitive]
|
738
|
-
ces.collect! do |ce|
|
739
|
-
op, expr = Regexp === ce ? [ce.casefold? || case_insensitive ? :'~*' : :~, ce.source] : [case_insensitive ? :ILIKE : :LIKE, ce.to_s]
|
740
|
-
BooleanExpression.new(op, l, expr)
|
741
|
-
end
|
742
|
-
ces.length == 1 ? ces.at(0) : BooleanExpression.new(:OR, *ces)
|
743
|
-
end
|
744
|
-
end
|
745
|
-
|
746
|
-
# Represents an SQL array access, with multiple possible arguments.
|
747
|
-
class Subscript < GenericExpression
|
748
|
-
# The SQL array column
|
749
|
-
attr_reader :f
|
750
|
-
|
751
|
-
# The array of subscripts to use (should be an array of numbers)
|
752
|
-
attr_reader :sub
|
753
|
-
|
754
|
-
# Set the attributes to the given arguments
|
755
|
-
def initialize(f, sub)
|
756
|
-
@f, @sub = f, sub
|
757
|
-
end
|
758
|
-
|
759
|
-
# Create a new subscript appending the given subscript(s)
|
760
|
-
# the the current array of subscripts.
|
761
|
-
def |(sub)
|
762
|
-
Subscript.new(@f, @sub + Array(sub))
|
763
|
-
end
|
764
|
-
|
765
|
-
# Delegate the creation of the resulting SQL to the given dataset,
|
766
|
-
# since it may be database dependent.
|
767
|
-
def to_s(ds)
|
768
|
-
ds.subscript_sql(self)
|
769
|
-
end
|
770
|
-
end
|
771
|
-
|
772
|
-
# An instance of this class is yielded to the block supplied to filter.
|
773
|
-
# Useful if another library also defines the operator methods that
|
774
|
-
# Sequel defines for symbols.
|
775
|
-
#
|
776
|
-
# Examples:
|
777
|
-
#
|
778
|
-
# ds = DB[:t]
|
779
|
-
# ds.filter{|r| r.name < 2} # SELECT * FROM t WHERE (name < 2)
|
780
|
-
# ds.filter{|r| r.table__column + 1 < 2} # SELECT * FROM t WHERE ((table.column + 1) < 2)
|
781
|
-
# ds.filter{|r| r.is_active(1, 'arg2')} # SELECT * FROM t WHERE is_active(1, 'arg2')
|
782
|
-
class VirtualRow
|
783
|
-
(instance_methods - %w"__id__ __send__").each{|m| undef_method(m)}
|
784
|
-
|
785
|
-
# Can return Identifiers, QualifiedIdentifiers, or Functions:
|
786
|
-
#
|
787
|
-
# * Function - returned if any arguments are supplied, using the method name
|
788
|
-
# as the function name, and the arguments as the function arguments.
|
789
|
-
# * QualifiedIdentifier - returned if the method name contains __, with the
|
790
|
-
# table being the part before __, and the column being the part after.
|
791
|
-
# * Identifier - returned otherwise, using the method name.
|
792
|
-
def method_missing(m, *args)
|
793
|
-
if args.empty?
|
794
|
-
table, column = m.to_s.split('__', 2)
|
795
|
-
column ? QualifiedIdentifier.new(table, column) : Identifier.new(m)
|
796
|
-
else
|
797
|
-
Function.new(m, *args)
|
798
|
-
end
|
799
|
-
end
|
800
|
-
end
|
801
|
-
end
|
802
|
-
|
803
|
-
# LiteralString is used to represent literal SQL expressions. A
|
804
|
-
# LiteralString is copied verbatim into an SQL statement. Instances of
|
805
|
-
# LiteralString can be created by calling String#lit.
|
806
|
-
# LiteralStrings can use all of the SQL::ColumnMethods and the
|
807
|
-
# SQL::ComplexExpressionMethods.
|
808
|
-
class LiteralString < ::String
|
809
|
-
include SQL::OrderMethods
|
810
|
-
include SQL::ComplexExpressionMethods
|
811
|
-
end
|
812
|
-
end
|