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 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.7"
12
+ VERS = "1.0.8"
13
13
  CLEAN.include ["**/.*.sw?", "pkg/*", ".config", "doc/*", "coverage/*"]
14
14
  RDOC_OPTS = [
15
15
  "--quiet",
@@ -16,7 +16,7 @@ module Sequel
16
16
  def dataset(opts = nil)
17
17
  Adapter::Dataset.new(self, opts)
18
18
  end
19
-
19
+
20
20
  def execute(sql)
21
21
  @logger.info(sql) if @logger
22
22
  @pool.hold {|conn| conn.exec(sql)}
@@ -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
- @logger.info(sql) if @logger
131
- @pool.hold do |conn|
132
- conn.query(sql)
133
- conn.use_result
134
- end
135
- end
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.execute_insert(insert_sql(*values))
318
+ @db.execute(insert_sql(*values)) {|c| c.insert_id}
331
319
  end
332
320
 
333
321
  def update(*args, &block)
334
- @db.execute_affected(update_sql(*args, &block))
322
+ @db.execute(update_sql(*args, &block)) {|c| c.affected_rows}
335
323
  end
336
324
 
337
325
  def delete(opts = nil)
338
- @db.execute_affected(delete_sql(opts))
326
+ @db.execute(delete_sql(opts)) {|c| c.affected_rows}
339
327
  end
340
328
 
341
329
  def fetch_rows(sql)
342
- @db.synchronize do
343
- r = @db.execute_select(sql)
344
- begin
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.synchronize do
356
- r = @db.execute_select(sql)
357
- begin
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
@@ -16,7 +16,7 @@ module Sequel
16
16
  class Dataset < ODBC::Dataset
17
17
  # Allows you to do .nolock on a query
18
18
  def nolock
19
- clone_merge(:with => "(NOLOCK)")
19
+ clone(:with => "(NOLOCK)")
20
20
  end
21
21
 
22
22
  # Formats a SELECT statement using the given options and the dataset
@@ -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).clear
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
- clone_merge(:lock => :update)
360
+ clone(:lock => :update)
367
361
  end
368
362
 
369
363
  def for_share
370
- clone_merge(:lock => :share)
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.execute_and_forget(sql); yield}
403
+ @db.transaction {@db.execute(sql); yield}
410
404
  else
411
- @db.execute_and_forget(sql) # lock without a transaction
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.synchronize do
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.synchronize do
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.synchronize do
448
- result = @db.execute(sql)
449
- begin
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.synchronize do
493
- result = @db.execute(sql)
494
- begin
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
 
@@ -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"
@@ -91,12 +91,13 @@ module Sequel
91
91
  @transform = nil
92
92
  end
93
93
 
94
- # Returns a new instance of the dataset with with the give options merged.
95
- def clone_merge(opts)
96
- new_dataset = clone
97
- new_dataset.set_options(@opts.merge(opts))
98
- new_dataset
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 = clone_merge(:naked => true, :models => nil, :polymorphic_key => nil)
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
- clone_merge(opts).all
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 clone_merge(opts)
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 = clone_merge({})
265
+ copy = clone({})
266
266
  copy.extend(QueryBlockCopy)
267
267
  copy.instance_eval(&block)
268
- clone_merge(copy.opts)
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
- match_expr(l, r)
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
- match_expr(l, r)
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
- match_expr(l, r)
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
- clone_merge(:from => source)
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
- clone_merge(:from => [self], :select => nil, :group => nil,
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
- clone_merge(:select => columns)
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
- clone_merge(:select => @opts[:select] + columns)
178
+ clone(:select => @opts[:select] + columns)
179
179
  else
180
- clone_merge(:select => columns)
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
- clone_merge(:select => nil)
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
- clone_merge(:distinct => args)
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
- clone_merge(:order => order)
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
- clone_merge(:order => @opts[:order] + order)
204
+ clone(:order => @opts[:order] + order)
205
205
  else
206
- clone_merge(:order => order)
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
- clone_merge(:group => columns)
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
- clone_merge(clause => "#{l} AND #{r}")
273
+ clone(clause => "#{l} AND #{r}")
274
274
  else
275
- clone_merge(:filter => cond, clause => expression_list(block || cond))
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
- clone_merge(clause => "#{l} OR #{r}")
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
- clone_merge(clause => cond)
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
- clone_merge(:union => dataset, :union_all => all)
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
- clone_merge(:intersect => dataset, :intersect_all => all)
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
- clone_merge(:except => dataset, :except_all => all)
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
- clone_merge(:join => join, :last_joined_table => table)
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
- clone_merge(opts)
620
+ clone(opts)
621
621
  end
622
622
 
623
623
  STOCK_COUNT_OPTS = {:select => ["COUNT(*)".lit], :order => nil}.freeze
@@ -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
+
@@ -18,15 +18,15 @@ context "Dataset" do
18
18
  d.opts.should == {}
19
19
  end
20
20
 
21
- specify "should provide clone_merge for chainability." do
22
- d1 = @dataset.clone_merge(:from => :test)
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.clone_merge(:order => :name)
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#clone_merge" do
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.clone_merge({})
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.clone_merge(1 => 2)
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.clone_merge(:from => [:other])
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.clone_merge(:from => [:other])
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.clone_merge({}).should respond_to(:__xyz__)
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 = clone_merge(opts) if opts
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 ? clone_merge(opts) : self
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.clone_merge(:sql => 'select * from blah')
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
@@ -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.7
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-05 00:00:00 +02:00
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/worker_spec.rb
87
- - spec/spec_helper.rb
88
- - spec/rcov.opts
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
- - lib/sequel_core.rb
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/sqlite.rb
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/informix.rb
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/pretty_table.rb
119
- - lib/sequel_core/schema.rb
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/core_sql.rb
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/array_keys.rb
128
+ - lib/sequel_core.rb
129
129
  - CHANGELOG
130
130
  has_rdoc: true
131
131
  homepage: http://sequel.rubyforge.org