sequel_core 1.0.7 → 1.0.8
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/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
|