sequel_core 1.0.7 → 1.0.8
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +8 -0
- data/Rakefile +1 -1
- data/lib/sequel_core/adapters/adapter_skeleton.rb +1 -1
- data/lib/sequel_core/adapters/mysql.rb +19 -41
- data/lib/sequel_core/adapters/odbc_mssql.rb +1 -1
- data/lib/sequel_core/adapters/postgres.rb +24 -56
- data/lib/sequel_core/database.rb +1 -1
- data/lib/sequel_core/dataset.rb +7 -6
- data/lib/sequel_core/dataset/convenience.rb +4 -4
- data/lib/sequel_core/dataset/sequelizer.rb +13 -3
- data/lib/sequel_core/dataset/sql.rb +20 -20
- data/spec/adapters/mysql_spec.rb +13 -1
- data/spec/dataset_spec.rb +33 -12
- data/spec/sequelizer_spec.rb +22 -0
- metadata +33 -33
data/CHANGELOG
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
=== 1.0.8 (2008-02-08)
|
2
|
+
|
3
|
+
* Added support for multiple choices in string matching expressions (#147).
|
4
|
+
|
5
|
+
* Renamed Dataset#clone_merge to Dataset#clone, works with or without options for merging (#148).
|
6
|
+
|
7
|
+
* Fixed MySQL::Database#<< method to always free the result in order to allow multiple calls in a row (#149). Same also for PostgreSQL adapter.
|
8
|
+
|
1
9
|
=== 1.0.7 (2008-02-05)
|
2
10
|
|
3
11
|
* Added support for conditional filters (using if else statements) inside block filters (thanks Kee).
|
data/Rakefile
CHANGED
@@ -9,7 +9,7 @@ include FileUtils
|
|
9
9
|
# Configuration
|
10
10
|
##############################################################################
|
11
11
|
NAME = "sequel_core"
|
12
|
-
VERS = "1.0.
|
12
|
+
VERS = "1.0.8"
|
13
13
|
CLEAN.include ["**/.*.sw?", "pkg/*", ".config", "doc/*", "coverage/*"]
|
14
14
|
RDOC_OPTS = [
|
15
15
|
"--quiet",
|
@@ -119,34 +119,22 @@ module Sequel
|
|
119
119
|
MySQL::Dataset.new(self, opts)
|
120
120
|
end
|
121
121
|
|
122
|
-
def execute(sql)
|
122
|
+
def execute(sql, &block)
|
123
123
|
@logger.info(sql) if @logger
|
124
124
|
@pool.hold do |conn|
|
125
125
|
conn.query(sql)
|
126
|
+
block[conn] if block
|
126
127
|
end
|
127
128
|
end
|
128
129
|
|
129
|
-
def execute_select(sql)
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
def execute_insert(sql)
|
138
|
-
@logger.info(sql) if @logger
|
139
|
-
@pool.hold do |conn|
|
140
|
-
conn.query(sql)
|
141
|
-
conn.insert_id
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
def execute_affected(sql)
|
146
|
-
@logger.info(sql) if @logger
|
147
|
-
@pool.hold do |conn|
|
148
|
-
conn.query(sql)
|
149
|
-
conn.affected_rows
|
130
|
+
def execute_select(sql, &block)
|
131
|
+
execute(sql) do |c|
|
132
|
+
r = c.use_result
|
133
|
+
begin
|
134
|
+
block[r]
|
135
|
+
ensure
|
136
|
+
r.free
|
137
|
+
end
|
150
138
|
end
|
151
139
|
end
|
152
140
|
|
@@ -327,39 +315,29 @@ module Sequel
|
|
327
315
|
end
|
328
316
|
|
329
317
|
def insert(*values)
|
330
|
-
@db.
|
318
|
+
@db.execute(insert_sql(*values)) {|c| c.insert_id}
|
331
319
|
end
|
332
320
|
|
333
321
|
def update(*args, &block)
|
334
|
-
@db.
|
322
|
+
@db.execute(update_sql(*args, &block)) {|c| c.affected_rows}
|
335
323
|
end
|
336
324
|
|
337
325
|
def delete(opts = nil)
|
338
|
-
@db.
|
326
|
+
@db.execute(delete_sql(opts)) {|c| c.affected_rows}
|
339
327
|
end
|
340
328
|
|
341
329
|
def fetch_rows(sql)
|
342
|
-
@db.
|
343
|
-
|
344
|
-
|
345
|
-
@columns = r.columns
|
346
|
-
r.each_hash {|row| yield row}
|
347
|
-
ensure
|
348
|
-
r.free
|
349
|
-
end
|
330
|
+
@db.execute_select(sql) do |r|
|
331
|
+
@columns = r.columns
|
332
|
+
r.each_hash {|row| yield row}
|
350
333
|
end
|
351
334
|
self
|
352
335
|
end
|
353
336
|
|
354
337
|
def array_tuples_fetch_rows(sql, &block)
|
355
|
-
@db.
|
356
|
-
|
357
|
-
|
358
|
-
@columns = r.columns
|
359
|
-
r.each_array(&block)
|
360
|
-
ensure
|
361
|
-
r.free
|
362
|
-
end
|
338
|
+
@db.execute_select(sql) do |r|
|
339
|
+
@columns = r.columns
|
340
|
+
r.each_array(&block)
|
363
341
|
end
|
364
342
|
self
|
365
343
|
end
|
@@ -47,17 +47,23 @@ class PGconn
|
|
47
47
|
alias_method :async_exec, :exec
|
48
48
|
end
|
49
49
|
|
50
|
-
def execute(sql)
|
50
|
+
def execute(sql, &block)
|
51
|
+
q = nil
|
51
52
|
begin
|
52
|
-
async_exec(sql)
|
53
|
+
q = async_exec(sql)
|
53
54
|
rescue PGError => e
|
54
55
|
unless connected?
|
55
56
|
reset
|
56
|
-
async_exec(sql)
|
57
|
+
q = async_exec(sql)
|
57
58
|
else
|
58
59
|
raise e
|
59
60
|
end
|
60
61
|
end
|
62
|
+
begin
|
63
|
+
block ? block[q] : q.cmdtuples
|
64
|
+
ensure
|
65
|
+
q.clear
|
66
|
+
end
|
61
67
|
end
|
62
68
|
|
63
69
|
attr_accessor :transaction_in_progress
|
@@ -218,22 +224,14 @@ module Sequel
|
|
218
224
|
filter("pg_class.relfilenode=pg_locks.relation")
|
219
225
|
end
|
220
226
|
|
221
|
-
def execute(sql)
|
227
|
+
def execute(sql, &block)
|
222
228
|
@logger.info(sql) if @logger
|
223
|
-
@pool.hold {|conn| conn.execute(sql)}
|
229
|
+
@pool.hold {|conn| conn.execute(sql, &block)}
|
224
230
|
rescue => e
|
225
231
|
@logger.error(e.message) if @logger
|
226
232
|
raise e
|
227
233
|
end
|
228
234
|
|
229
|
-
def execute_and_forget(sql)
|
230
|
-
@logger.info(sql) if @logger
|
231
|
-
@pool.hold {|conn| conn.execute(sql).clear}
|
232
|
-
rescue => e
|
233
|
-
@logger.error(e.message) if @logger
|
234
|
-
raise e
|
235
|
-
end
|
236
|
-
|
237
235
|
def primary_key_for_table(conn, table)
|
238
236
|
@primary_keys ||= {}
|
239
237
|
@primary_keys[table] ||= conn.primary_key(table)
|
@@ -268,7 +266,7 @@ module Sequel
|
|
268
266
|
def execute_insert(sql, table, values)
|
269
267
|
@logger.info(sql) if @logger
|
270
268
|
@pool.hold do |conn|
|
271
|
-
conn.execute(sql)
|
269
|
+
conn.execute(sql)
|
272
270
|
insert_result(conn, table, values)
|
273
271
|
end
|
274
272
|
rescue => e
|
@@ -276,10 +274,6 @@ module Sequel
|
|
276
274
|
raise e
|
277
275
|
end
|
278
276
|
|
279
|
-
def synchronize(&block)
|
280
|
-
@pool.hold(&block)
|
281
|
-
end
|
282
|
-
|
283
277
|
SQL_BEGIN = 'BEGIN'.freeze
|
284
278
|
SQL_COMMIT = 'COMMIT'.freeze
|
285
279
|
SQL_ROLLBACK = 'ROLLBACK'.freeze
|
@@ -363,11 +357,11 @@ module Sequel
|
|
363
357
|
end
|
364
358
|
|
365
359
|
def for_update
|
366
|
-
|
360
|
+
clone(:lock => :update)
|
367
361
|
end
|
368
362
|
|
369
363
|
def for_share
|
370
|
-
|
364
|
+
clone(:lock => :share)
|
371
365
|
end
|
372
366
|
|
373
367
|
EXPLAIN = 'EXPLAIN '.freeze
|
@@ -406,9 +400,9 @@ module Sequel
|
|
406
400
|
sql = LOCK % [@opts[:from], mode]
|
407
401
|
@db.synchronize do
|
408
402
|
if block # perform locking inside a transaction and yield to block
|
409
|
-
@db.transaction {@db.
|
403
|
+
@db.transaction {@db.execute(sql); yield}
|
410
404
|
else
|
411
|
-
@db.
|
405
|
+
@db.execute(sql) # lock without a transaction
|
412
406
|
self
|
413
407
|
end
|
414
408
|
end
|
@@ -420,38 +414,17 @@ module Sequel
|
|
420
414
|
end
|
421
415
|
|
422
416
|
def update(*args, &block)
|
423
|
-
@db.
|
424
|
-
result = @db.execute(update_sql(*args, &block))
|
425
|
-
begin
|
426
|
-
affected = result.cmdtuples
|
427
|
-
ensure
|
428
|
-
result.clear
|
429
|
-
end
|
430
|
-
affected
|
431
|
-
end
|
417
|
+
@db.execute(update_sql(*args, &block))
|
432
418
|
end
|
433
419
|
|
434
420
|
def delete(opts = nil)
|
435
|
-
@db.
|
436
|
-
result = @db.execute(delete_sql(opts))
|
437
|
-
begin
|
438
|
-
affected = result.cmdtuples
|
439
|
-
ensure
|
440
|
-
result.clear
|
441
|
-
end
|
442
|
-
affected
|
443
|
-
end
|
421
|
+
@db.execute(delete_sql(opts))
|
444
422
|
end
|
445
423
|
|
446
424
|
def fetch_rows(sql, &block)
|
447
|
-
@db.
|
448
|
-
|
449
|
-
|
450
|
-
conv = row_converter(result)
|
451
|
-
result.each {|r| yield conv[r]}
|
452
|
-
ensure
|
453
|
-
result.clear
|
454
|
-
end
|
425
|
+
@db.execute(sql) do |q|
|
426
|
+
conv = row_converter(q)
|
427
|
+
q.each {|r| yield conv[r]}
|
455
428
|
end
|
456
429
|
end
|
457
430
|
|
@@ -489,14 +462,9 @@ module Sequel
|
|
489
462
|
end
|
490
463
|
|
491
464
|
def array_tuples_fetch_rows(sql, &block)
|
492
|
-
@db.
|
493
|
-
|
494
|
-
|
495
|
-
conv = array_tuples_row_converter(result)
|
496
|
-
result.each {|r| yield conv[r]}
|
497
|
-
ensure
|
498
|
-
result.clear
|
499
|
-
end
|
465
|
+
@db.execute(sql) do |q|
|
466
|
+
conv = array_tuples_row_converter(q)
|
467
|
+
q.each {|r| yield conv[r]}
|
500
468
|
end
|
501
469
|
end
|
502
470
|
|
data/lib/sequel_core/database.rb
CHANGED
@@ -134,7 +134,7 @@ module Sequel
|
|
134
134
|
def [](*args)
|
135
135
|
(String === args.first) ? fetch(*args) : from(*args)
|
136
136
|
end
|
137
|
-
|
137
|
+
|
138
138
|
# Raises a Sequel::Error::NotImplemented. This method is overriden in descendants.
|
139
139
|
def execute(sql)
|
140
140
|
raise NotImplementedError, "#execute should be overriden by adapters"
|
data/lib/sequel_core/dataset.rb
CHANGED
@@ -91,12 +91,13 @@ module Sequel
|
|
91
91
|
@transform = nil
|
92
92
|
end
|
93
93
|
|
94
|
-
# Returns a new
|
95
|
-
def
|
96
|
-
|
97
|
-
|
98
|
-
|
94
|
+
# Returns a new clone of the dataset with with the given options merged.
|
95
|
+
def clone(opts = {})
|
96
|
+
c = super()
|
97
|
+
c.set_options @opts.merge(opts)
|
98
|
+
c
|
99
99
|
end
|
100
|
+
alias_method :clone_merge, :clone # should be deprecated in the next major release.
|
100
101
|
|
101
102
|
def set_options(opts) #:nodoc:
|
102
103
|
@opts = opts
|
@@ -178,7 +179,7 @@ module Sequel
|
|
178
179
|
# Returns a naked dataset clone - i.e. a dataset that returns records as
|
179
180
|
# hashes rather than model objects.
|
180
181
|
def naked
|
181
|
-
d =
|
182
|
+
d = clone(:naked => true, :models => nil, :polymorphic_key => nil)
|
182
183
|
d.set_model(nil)
|
183
184
|
d
|
184
185
|
end
|
@@ -74,7 +74,7 @@ module Sequel
|
|
74
74
|
if args == 1
|
75
75
|
single_record(opts)
|
76
76
|
else
|
77
|
-
|
77
|
+
clone(opts).all
|
78
78
|
end
|
79
79
|
else
|
80
80
|
filter(args).last(1)
|
@@ -247,7 +247,7 @@ module Sequel
|
|
247
247
|
def update(*args); raise Error, "#update cannot be invoked inside a query block."; end
|
248
248
|
def delete(*args); raise Error, "#delete cannot be invoked inside a query block."; end
|
249
249
|
|
250
|
-
def
|
250
|
+
def clone(opts)
|
251
251
|
@opts.merge!(opts)
|
252
252
|
end
|
253
253
|
end
|
@@ -262,10 +262,10 @@ module Sequel
|
|
262
262
|
# end
|
263
263
|
#
|
264
264
|
def query(&block)
|
265
|
-
copy =
|
265
|
+
copy = clone({})
|
266
266
|
copy.extend(QueryBlockCopy)
|
267
267
|
copy.instance_eval(&block)
|
268
|
-
|
268
|
+
clone(copy.opts)
|
269
269
|
end
|
270
270
|
|
271
271
|
MUTATION_RE = /^(.+)!$/.freeze
|
@@ -49,12 +49,22 @@ class Sequel::Dataset
|
|
49
49
|
when NilClass
|
50
50
|
"(#{literal(l)} IS NULL)"
|
51
51
|
when Regexp
|
52
|
-
|
52
|
+
collate_match_expr(l, r)
|
53
53
|
else
|
54
54
|
"(#{literal(l)} = #{literal(r)})"
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
58
|
+
# Formats a string matching expression with support for multiple choices.
|
59
|
+
# For more information see #match_expr.
|
60
|
+
def collate_match_expr(l, r)
|
61
|
+
if r.is_a?(Array)
|
62
|
+
"(#{r.map {|i| match_expr(l, i)}.join(' OR ')})"
|
63
|
+
else
|
64
|
+
match_expr(l, r)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
58
68
|
# Formats a string matching expression. The stock implementation supports
|
59
69
|
# matching against strings only using the LIKE operator. Specific adapters
|
60
70
|
# can override this method to provide support for regular expressions.
|
@@ -121,7 +131,7 @@ class Sequel::Dataset
|
|
121
131
|
when :=~
|
122
132
|
l = eval_expr(e[1], b, opts)
|
123
133
|
r = eval_expr(e[3][1], b, opts)
|
124
|
-
|
134
|
+
collate_match_expr(l, r)
|
125
135
|
when :+, :-, :*, :%, :/
|
126
136
|
l = eval_expr(e[1], b, opts)
|
127
137
|
r = eval_expr(e[3][1], b, opts)
|
@@ -156,7 +166,7 @@ class Sequel::Dataset
|
|
156
166
|
when :like, :like?
|
157
167
|
l = eval_expr(e[1], b, opts)
|
158
168
|
r = eval_expr(e[3][1], b, opts)
|
159
|
-
|
169
|
+
collate_match_expr(l, r)
|
160
170
|
else
|
161
171
|
if (op == :[]) && (e[1][0] == :lit) && (Symbol === e[1][1])
|
162
172
|
# SQL Functions, e.g.: :sum[:x]
|
@@ -152,7 +152,7 @@ module Sequel
|
|
152
152
|
|
153
153
|
# Returns a copy of the dataset with the source changed.
|
154
154
|
def from(*source)
|
155
|
-
|
155
|
+
clone(:from => source)
|
156
156
|
end
|
157
157
|
|
158
158
|
# Returns a dataset selecting from the current dataset.
|
@@ -161,7 +161,7 @@ module Sequel
|
|
161
161
|
# ds.sql #=> "SELECT * FROM items ORDER BY name"
|
162
162
|
# ds.from_self.sql #=> "SELECT * FROM (SELECT * FROM items ORDER BY name)"
|
163
163
|
def from_self
|
164
|
-
|
164
|
+
clone(:from => [self], :select => nil, :group => nil,
|
165
165
|
:sql => nil, :distinct => nil, :join => nil, :where => nil,
|
166
166
|
:order => nil, :having => nil, :limit => nil, :offset => nil,
|
167
167
|
:union => nil)
|
@@ -169,41 +169,41 @@ module Sequel
|
|
169
169
|
|
170
170
|
# Returns a copy of the dataset with the selected columns changed.
|
171
171
|
def select(*columns)
|
172
|
-
|
172
|
+
clone(:select => columns)
|
173
173
|
end
|
174
174
|
|
175
175
|
# Returns a copy of the dataset with additional selected columns.
|
176
176
|
def select_more(*columns)
|
177
177
|
if @opts[:select]
|
178
|
-
|
178
|
+
clone(:select => @opts[:select] + columns)
|
179
179
|
else
|
180
|
-
|
180
|
+
clone(:select => columns)
|
181
181
|
end
|
182
182
|
end
|
183
183
|
|
184
184
|
# Returns a copy of the dataset selecting the wildcard.
|
185
185
|
def select_all
|
186
|
-
|
186
|
+
clone(:select => nil)
|
187
187
|
end
|
188
188
|
|
189
189
|
# Returns a copy of the dataset with the distinct option.
|
190
190
|
def uniq(*args)
|
191
|
-
|
191
|
+
clone(:distinct => args)
|
192
192
|
end
|
193
193
|
alias_method :distinct, :uniq
|
194
194
|
|
195
195
|
# Returns a copy of the dataset with the order changed.
|
196
196
|
def order(*order)
|
197
|
-
|
197
|
+
clone(:order => order)
|
198
198
|
end
|
199
199
|
alias_method :order_by, :order
|
200
200
|
|
201
201
|
# Returns a copy of the dataset with the order changed.
|
202
202
|
def order_more(*order)
|
203
203
|
if @opts[:order]
|
204
|
-
|
204
|
+
clone(:order => @opts[:order] + order)
|
205
205
|
else
|
206
|
-
|
206
|
+
clone(:order => order)
|
207
207
|
end
|
208
208
|
end
|
209
209
|
|
@@ -233,7 +233,7 @@ module Sequel
|
|
233
233
|
# Returns a copy of the dataset with the results grouped by the value of
|
234
234
|
# the given columns
|
235
235
|
def group(*columns)
|
236
|
-
|
236
|
+
clone(:group => columns)
|
237
237
|
end
|
238
238
|
|
239
239
|
alias_method :group_by, :group
|
@@ -270,9 +270,9 @@ module Sequel
|
|
270
270
|
if !@opts[clause].nil? and @opts[clause].any?
|
271
271
|
l = expression_list(@opts[clause])
|
272
272
|
r = expression_list(block || cond, parenthesize)
|
273
|
-
|
273
|
+
clone(clause => "#{l} AND #{r}")
|
274
274
|
else
|
275
|
-
|
275
|
+
clone(:filter => cond, clause => expression_list(block || cond))
|
276
276
|
end
|
277
277
|
end
|
278
278
|
|
@@ -285,7 +285,7 @@ module Sequel
|
|
285
285
|
if @opts[clause]
|
286
286
|
l = expression_list(@opts[clause])
|
287
287
|
r = expression_list(block || cond, parenthesize)
|
288
|
-
|
288
|
+
clone(clause => "#{l} OR #{r}")
|
289
289
|
else
|
290
290
|
raise Error::NoExistingFilter, "No existing filter found."
|
291
291
|
end
|
@@ -317,7 +317,7 @@ module Sequel
|
|
317
317
|
else
|
318
318
|
cond = "(NOT #{expression_list(block || cond, true)})"
|
319
319
|
end
|
320
|
-
|
320
|
+
clone(clause => cond)
|
321
321
|
end
|
322
322
|
|
323
323
|
# Returns a copy of the dataset with the where conditions changed. Raises
|
@@ -340,19 +340,19 @@ module Sequel
|
|
340
340
|
# Adds a UNION clause using a second dataset object. If all is true the
|
341
341
|
# clause used is UNION ALL, which may return duplicate rows.
|
342
342
|
def union(dataset, all = false)
|
343
|
-
|
343
|
+
clone(:union => dataset, :union_all => all)
|
344
344
|
end
|
345
345
|
|
346
346
|
# Adds an INTERSECT clause using a second dataset object. If all is true
|
347
347
|
# the clause used is INTERSECT ALL, which may return duplicate rows.
|
348
348
|
def intersect(dataset, all = false)
|
349
|
-
|
349
|
+
clone(:intersect => dataset, :intersect_all => all)
|
350
350
|
end
|
351
351
|
|
352
352
|
# Adds an EXCEPT clause using a second dataset object. If all is true the
|
353
353
|
# clause used is EXCEPT ALL, which may return duplicate rows.
|
354
354
|
def except(dataset, all = false)
|
355
|
-
|
355
|
+
clone(:except => dataset, :except_all => all)
|
356
356
|
end
|
357
357
|
|
358
358
|
JOIN_TYPES = {
|
@@ -385,7 +385,7 @@ module Sequel
|
|
385
385
|
end
|
386
386
|
clause = join_expr(type, table, expr)
|
387
387
|
join = @opts[:join] ? @opts[:join] + clause : clause
|
388
|
-
|
388
|
+
clone(:join => join, :last_joined_table => table)
|
389
389
|
end
|
390
390
|
|
391
391
|
# Returns a LEFT OUTER joined dataset.
|
@@ -617,7 +617,7 @@ module Sequel
|
|
617
617
|
else
|
618
618
|
opts = {:limit => l}
|
619
619
|
end
|
620
|
-
|
620
|
+
clone(opts)
|
621
621
|
end
|
622
622
|
|
623
623
|
STOCK_COUNT_OPTS = {:select => ["COUNT(*)".lit], :order => nil}.freeze
|
data/spec/adapters/mysql_spec.rb
CHANGED
@@ -362,6 +362,17 @@ context "A MySQL database" do
|
|
362
362
|
"CREATE TABLE items (`p_id` integer NOT NULL, FOREIGN KEY (`p_id`) REFERENCES users(`id`) ON DELETE CASCADE)"
|
363
363
|
]
|
364
364
|
end
|
365
|
+
|
366
|
+
specify "should accept repeated raw sql statements using Database#<<" do
|
367
|
+
@db << 'DELETE FROM items'
|
368
|
+
@db[:items].count.should == 0
|
369
|
+
|
370
|
+
@db << "INSERT INTO items (name, value) VALUES ('tutu', 1234)"
|
371
|
+
@db[:items].first.should == {:name => 'tutu', :value => 1234}
|
372
|
+
|
373
|
+
@db << 'DELETE FROM items'
|
374
|
+
@db[:items].first.should == nil
|
375
|
+
end
|
365
376
|
end
|
366
377
|
|
367
378
|
context "A MySQL database" do
|
@@ -401,4 +412,5 @@ context "A grouped MySQL dataset" do
|
|
401
412
|
ds = MYSQL_DB[:test2].select(:name).where(:name => '11').group(:name)
|
402
413
|
ds.count.should == 1
|
403
414
|
end
|
404
|
-
end
|
415
|
+
end
|
416
|
+
|
data/spec/dataset_spec.rb
CHANGED
@@ -18,15 +18,15 @@ context "Dataset" do
|
|
18
18
|
d.opts.should == {}
|
19
19
|
end
|
20
20
|
|
21
|
-
specify "should provide
|
22
|
-
d1 = @dataset.
|
21
|
+
specify "should provide clone for chainability." do
|
22
|
+
d1 = @dataset.clone(:from => :test)
|
23
23
|
d1.class.should == @dataset.class
|
24
24
|
d1.should_not == @dataset
|
25
25
|
d1.db.should be(@dataset.db)
|
26
26
|
d1.opts[:from].should == :test
|
27
27
|
@dataset.opts[:from].should be_nil
|
28
28
|
|
29
|
-
d2 = d1.
|
29
|
+
d2 = d1.clone(:order => :name)
|
30
30
|
d2.class.should == @dataset.class
|
31
31
|
d2.should_not == d1
|
32
32
|
d2.should_not == @dataset
|
@@ -48,30 +48,48 @@ context "Dataset" do
|
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
|
-
context "Dataset#
|
51
|
+
context "Dataset#clone" do
|
52
52
|
setup do
|
53
53
|
@dataset = Sequel::Dataset.new(nil).from(:items)
|
54
54
|
end
|
55
55
|
|
56
|
+
specify "should create an exact copy of the dataset" do
|
57
|
+
@c = Class.new
|
58
|
+
@dataset.set_model(@c)
|
59
|
+
@clone = @dataset.clone
|
60
|
+
|
61
|
+
@clone.should_not === @dataset
|
62
|
+
@clone.class.should == @dataset.class
|
63
|
+
@clone.model_classes.should == @dataset.model_classes
|
64
|
+
end
|
65
|
+
|
66
|
+
specify "should deep-copy the dataset opts" do
|
67
|
+
@clone = @dataset.clone
|
68
|
+
|
69
|
+
@clone.opts.should_not eql(@dataset.opts)
|
70
|
+
@dataset.filter!(:a => 'b')
|
71
|
+
@clone.opts[:filter].should be_nil
|
72
|
+
end
|
73
|
+
|
56
74
|
specify "should return a clone self" do
|
57
|
-
clone = @dataset.
|
75
|
+
clone = @dataset.clone({})
|
58
76
|
clone.class.should == @dataset.class
|
59
77
|
clone.db.should == @dataset.db
|
60
78
|
clone.opts.should == @dataset.opts
|
61
79
|
end
|
62
80
|
|
63
81
|
specify "should merge the specified options" do
|
64
|
-
clone = @dataset.
|
82
|
+
clone = @dataset.clone(1 => 2)
|
65
83
|
clone.opts.should == {1 => 2, :from => [:items]}
|
66
84
|
end
|
67
85
|
|
68
86
|
specify "should overwrite existing options" do
|
69
|
-
clone = @dataset.
|
87
|
+
clone = @dataset.clone(:from => [:other])
|
70
88
|
clone.opts.should == {:from => [:other]}
|
71
89
|
end
|
72
90
|
|
73
91
|
specify "should create a clone with a deep copy of options" do
|
74
|
-
clone = @dataset.
|
92
|
+
clone = @dataset.clone(:from => [:other])
|
75
93
|
@dataset.opts[:from].should == [:items]
|
76
94
|
clone.opts[:from].should == [:other]
|
77
95
|
end
|
@@ -81,7 +99,7 @@ context "Dataset#clone_merge" do
|
|
81
99
|
def __xyz__; "xyz"; end
|
82
100
|
end
|
83
101
|
@dataset.extend(m)
|
84
|
-
@dataset.
|
102
|
+
@dataset.clone({}).should respond_to(:__xyz__)
|
85
103
|
end
|
86
104
|
end
|
87
105
|
|
@@ -355,6 +373,9 @@ context "Dataset#where" do
|
|
355
373
|
|
356
374
|
@dataset.filter {:c.like? 'ABC%'}.sql.should ==
|
357
375
|
"SELECT * FROM test WHERE (c LIKE 'ABC%')"
|
376
|
+
|
377
|
+
@dataset.filter {:c.like? ['ABC%', '%XYZ']}.sql.should ==
|
378
|
+
"SELECT * FROM test WHERE ((c LIKE 'ABC%') OR (c LIKE '%XYZ'))"
|
358
379
|
end
|
359
380
|
|
360
381
|
specify "should raise if receiving a single boolean value" do
|
@@ -1379,7 +1400,7 @@ context "Dataset#last" do
|
|
1379
1400
|
end
|
1380
1401
|
|
1381
1402
|
def single_record(opts = nil)
|
1382
|
-
@@last_dataset =
|
1403
|
+
@@last_dataset = clone(opts) if opts
|
1383
1404
|
{:a => 1, :b => 2}
|
1384
1405
|
end
|
1385
1406
|
|
@@ -1477,7 +1498,7 @@ context "Dataset#[]" do
|
|
1477
1498
|
end
|
1478
1499
|
|
1479
1500
|
def single_record(opts = nil)
|
1480
|
-
@@last_dataset = opts ?
|
1501
|
+
@@last_dataset = opts ? clone(opts) : self
|
1481
1502
|
{1 => 2, 3 => 4}
|
1482
1503
|
end
|
1483
1504
|
end
|
@@ -1941,7 +1962,7 @@ context "A paginated dataset" do
|
|
1941
1962
|
end
|
1942
1963
|
|
1943
1964
|
specify "should work with fixed sql" do
|
1944
|
-
ds = @d.
|
1965
|
+
ds = @d.clone(:sql => 'select * from blah')
|
1945
1966
|
ds.meta_def(:count) {150}
|
1946
1967
|
ds.paginate(2, 50).sql.should == 'SELECT * FROM (select * from blah) t1 LIMIT 50 OFFSET 50'
|
1947
1968
|
end
|
data/spec/sequelizer_spec.rb
CHANGED
@@ -196,6 +196,11 @@ context "Proc#to_sql" do
|
|
196
196
|
proc {:x.like? '%abc'}.sql.should == "(x LIKE '%abc')"
|
197
197
|
end
|
198
198
|
|
199
|
+
specify "should support like? pattern with multiple choices" do
|
200
|
+
proc {:x.like? ['%abc', '%def', '%ghi']}.sql.should == \
|
201
|
+
"((x LIKE '%abc') OR (x LIKE '%def') OR (x LIKE '%ghi'))"
|
202
|
+
end
|
203
|
+
|
199
204
|
specify "should support =~ operator" do
|
200
205
|
# stock SQL version does not know about regexps
|
201
206
|
proc {:x =~ '123'}.sql.should == "(x LIKE '123')"
|
@@ -203,6 +208,15 @@ context "Proc#to_sql" do
|
|
203
208
|
proc {:x =~ /^123/}.sql.should == "(x ~ '^123')"
|
204
209
|
end
|
205
210
|
|
211
|
+
specify "should support =~ operator with multiple choices" do
|
212
|
+
# stock SQL version does not know about regexps
|
213
|
+
proc {:x =~ ['123', '456', '789']}.sql.should == "((x LIKE '123') OR (x LIKE '456') OR (x LIKE '789'))"
|
214
|
+
|
215
|
+
proc {:x =~ [/^123/, /^456/, /^789/]}.sql.should == "((x ~ '^123') OR (x ~ '^456') OR (x ~ '^789'))"
|
216
|
+
|
217
|
+
proc {:x =~ [/^123/, '456%', /^789/]}.sql.should == "((x ~ '^123') OR (x LIKE '456%') OR (x ~ '^789'))"
|
218
|
+
end
|
219
|
+
|
206
220
|
specify "should raise on =~ operator for unsupported types" do
|
207
221
|
proc {proc {:x =~ 123}.sql}.should raise_error(Sequel::Error)
|
208
222
|
end
|
@@ -211,10 +225,18 @@ context "Proc#to_sql" do
|
|
211
225
|
proc {:x != 100}.sql.should == "(NOT (x = 100))"
|
212
226
|
end
|
213
227
|
|
228
|
+
specify "should support != operator with multiple choices" do
|
229
|
+
proc {:x != [100, 200, 300]}.sql.should == "(NOT (x IN (100, 200, 300)))"
|
230
|
+
end
|
231
|
+
|
214
232
|
specify "should support !~ operator" do
|
215
233
|
proc {:x !~ '123'}.sql.should == "(NOT (x LIKE '123'))"
|
216
234
|
end
|
217
235
|
|
236
|
+
specify "should support !~ operator with multiple choices" do
|
237
|
+
proc {:x !~ ['123', '456']}.sql.should == "(NOT ((x LIKE '123') OR (x LIKE '456')))"
|
238
|
+
end
|
239
|
+
|
218
240
|
specify "should support ! operator" do
|
219
241
|
proc {!:x}.sql.should == "(x = 'f')"
|
220
242
|
proc {!(:x > 100)}.sql.should == "(NOT (x > 100))"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sequel_core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sharon Rosner
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-02-
|
12
|
+
date: 2008-02-09 00:00:00 +02:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -73,59 +73,59 @@ files:
|
|
73
73
|
- Rakefile
|
74
74
|
- bin/sequel
|
75
75
|
- spec/adapters
|
76
|
+
- spec/adapters/informix_spec.rb
|
76
77
|
- spec/adapters/mysql_spec.rb
|
77
78
|
- spec/adapters/oracle_spec.rb
|
78
79
|
- spec/adapters/postgres_spec.rb
|
79
|
-
- spec/adapters/informix_spec.rb
|
80
80
|
- spec/adapters/sqlite_spec.rb
|
81
|
-
- spec/database_spec.rb
|
82
|
-
- spec/schema_generator_spec.rb
|
83
|
-
- spec/core_sql_spec.rb
|
84
|
-
- spec/core_ext_spec.rb
|
85
81
|
- spec/array_keys_spec.rb
|
86
|
-
- spec/
|
87
|
-
- spec/
|
88
|
-
- spec/
|
82
|
+
- spec/core_ext_spec.rb
|
83
|
+
- spec/core_sql_spec.rb
|
84
|
+
- spec/database_spec.rb
|
89
85
|
- spec/dataset_spec.rb
|
90
|
-
- spec/sequelizer_spec.rb
|
91
86
|
- spec/migration_spec.rb
|
92
87
|
- spec/pretty_table_spec.rb
|
88
|
+
- spec/rcov.opts
|
89
|
+
- spec/schema_generator_spec.rb
|
93
90
|
- spec/schema_spec.rb
|
91
|
+
- spec/sequelizer_spec.rb
|
94
92
|
- spec/spec.opts
|
95
|
-
-
|
93
|
+
- spec/spec_helper.rb
|
94
|
+
- spec/worker_spec.rb
|
96
95
|
- lib/sequel_core
|
97
|
-
- lib/sequel_core/schema
|
98
|
-
- lib/sequel_core/schema/schema_sql.rb
|
99
|
-
- lib/sequel_core/schema/schema_generator.rb
|
100
96
|
- lib/sequel_core/adapters
|
97
|
+
- lib/sequel_core/adapters/adapter_skeleton.rb
|
98
|
+
- lib/sequel_core/adapters/ado.rb
|
99
|
+
- lib/sequel_core/adapters/db2.rb
|
101
100
|
- lib/sequel_core/adapters/dbi.rb
|
102
|
-
- lib/sequel_core/adapters/
|
101
|
+
- lib/sequel_core/adapters/informix.rb
|
103
102
|
- lib/sequel_core/adapters/jdbc.rb
|
104
|
-
- lib/sequel_core/adapters/ado.rb
|
105
|
-
- lib/sequel_core/adapters/adapter_skeleton.rb
|
106
103
|
- lib/sequel_core/adapters/mysql.rb
|
107
|
-
- lib/sequel_core/adapters/oracle.rb
|
108
|
-
- lib/sequel_core/adapters/postgres.rb
|
109
|
-
- lib/sequel_core/adapters/odbc_mssql.rb
|
110
|
-
- lib/sequel_core/adapters/db2.rb
|
111
104
|
- lib/sequel_core/adapters/odbc.rb
|
112
|
-
- lib/sequel_core/adapters/
|
105
|
+
- lib/sequel_core/adapters/odbc_mssql.rb
|
113
106
|
- lib/sequel_core/adapters/openbase.rb
|
107
|
+
- lib/sequel_core/adapters/oracle.rb
|
108
|
+
- lib/sequel_core/adapters/postgres.rb
|
109
|
+
- lib/sequel_core/adapters/sqlite.rb
|
110
|
+
- lib/sequel_core/array_keys.rb
|
111
|
+
- lib/sequel_core/core_ext.rb
|
112
|
+
- lib/sequel_core/core_sql.rb
|
113
|
+
- lib/sequel_core/database.rb
|
114
114
|
- lib/sequel_core/dataset
|
115
|
-
- lib/sequel_core/dataset/sql.rb
|
116
|
-
- lib/sequel_core/dataset/sequelizer.rb
|
117
115
|
- lib/sequel_core/dataset/convenience.rb
|
118
|
-
- lib/sequel_core/
|
119
|
-
- lib/sequel_core/
|
120
|
-
- lib/sequel_core/model.rb
|
121
|
-
- lib/sequel_core/exceptions.rb
|
122
|
-
- lib/sequel_core/database.rb
|
116
|
+
- lib/sequel_core/dataset/sequelizer.rb
|
117
|
+
- lib/sequel_core/dataset/sql.rb
|
123
118
|
- lib/sequel_core/dataset.rb
|
124
|
-
- lib/sequel_core/
|
125
|
-
- lib/sequel_core/core_ext.rb
|
119
|
+
- lib/sequel_core/exceptions.rb
|
126
120
|
- lib/sequel_core/migration.rb
|
121
|
+
- lib/sequel_core/model.rb
|
122
|
+
- lib/sequel_core/pretty_table.rb
|
123
|
+
- lib/sequel_core/schema
|
124
|
+
- lib/sequel_core/schema/schema_generator.rb
|
125
|
+
- lib/sequel_core/schema/schema_sql.rb
|
126
|
+
- lib/sequel_core/schema.rb
|
127
127
|
- lib/sequel_core/worker.rb
|
128
|
-
- lib/sequel_core
|
128
|
+
- lib/sequel_core.rb
|
129
129
|
- CHANGELOG
|
130
130
|
has_rdoc: true
|
131
131
|
homepage: http://sequel.rubyforge.org
|