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 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