sequel 0.2.1 → 0.2.1.1

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,21 @@
1
+ === 0.2.1.1 (2007-10-07)
2
+
3
+ * Added Date literalization to sqlite adapter (#60).
4
+
5
+ * Changed Model.serialize to allow calling it after the class is defined (#59).
6
+
7
+ * Fixed after_create hooks to allow calling save inside the hook (#58).
8
+
9
+ * Fixed MySQL quoting of sql functions (#57).
10
+
11
+ * Implemented rollback! global method for cancelling transactions in progress.
12
+
13
+ * Fixed =~ operator in Sequelizer.
14
+
15
+ * Fixed ODBC::Dataset#fetch_rows (thanks Dusty).
16
+
17
+ * Renamed Model.recreate_table to create_table!. recreate_table is deprecated and will issue a warning (#56).
18
+
1
19
  === 0.2.1 (2007-09-24)
2
20
 
3
21
  * Added default implementation of Model.primary_key_hash.
data/Rakefile CHANGED
@@ -6,7 +6,7 @@ require 'fileutils'
6
6
  include FileUtils
7
7
 
8
8
  NAME = "sequel"
9
- VERS = "0.2.1"
9
+ VERS = "0.2.1.1"
10
10
  CLEAN.include ['**/.*.sw?', 'pkg/*', '.config', 'doc/*', 'coverage/*']
11
11
  RDOC_OPTS = ['--quiet', '--title', "Sequel: Concise ORM for Ruby",
12
12
  "--opname", "index.html",
@@ -161,7 +161,7 @@ module Sequel
161
161
  result
162
162
  rescue => e
163
163
  conn.execute(SQL_ROLLBACK)
164
- raise e
164
+ raise e unless SequelRollbackError === e
165
165
  ensure
166
166
  @transactions.delete(Thread.current)
167
167
  end
@@ -236,7 +236,7 @@ class Sequel::Dataset
236
236
  "(#{e[1..-1].map {|i| pt_expr(i, b)}.join(" AND ")})"
237
237
  when :or # x || y
238
238
  "(#{pt_expr(e[1], b)} OR #{pt_expr(e[2], b)})"
239
- when :call, :vcall, :iter # method calls, blocks
239
+ when :call, :vcall, :iter, :match3 # method calls, blocks
240
240
  eval_expr(e, b)
241
241
  else # literals
242
242
  if e == [:lvar, :block]
@@ -1,2 +1,11 @@
1
1
  class SequelError < StandardError
2
+ end
3
+
4
+ class SequelRollbackError < StandardError
5
+ end
6
+
7
+ class Object
8
+ def rollback!
9
+ raise SequelRollbackError
10
+ end
2
11
  end
@@ -70,6 +70,7 @@ module Sequel
70
70
  m[c] = filters
71
71
  m
72
72
  end
73
+ @dataset.transform(@transform) if @dataset
73
74
  end
74
75
  end
75
76
 
@@ -89,6 +89,7 @@ module Sequel
89
89
  @this = nil # remove memoized this dataset
90
90
  refresh
91
91
  end
92
+ @new = false
92
93
  run_hooks(:after_create)
93
94
  else
94
95
  run_hooks(:before_update)
@@ -96,7 +97,6 @@ module Sequel
96
97
  run_hooks(:after_update)
97
98
  end
98
99
  run_hooks(:after_save)
99
- @new = false
100
100
  self
101
101
  end
102
102
 
@@ -28,9 +28,15 @@ module Sequel
28
28
  db.execute db.drop_table_sql(table_name)
29
29
  end
30
30
 
31
- def self.recreate_table
31
+ def self.create_table!
32
32
  drop_table if table_exists?
33
33
  create_table
34
+
35
+ end
36
+
37
+ def self.recreate_table
38
+ warn "Model.recreate_table is deprecated. Please use Model.create_table! instead."
39
+ create_table!
34
40
  end
35
41
  end
36
42
  end
@@ -133,7 +133,7 @@ module Sequel
133
133
  result
134
134
  rescue => e
135
135
  conn.query(SQL_ROLLBACK)
136
- raise e
136
+ raise e unless SequelRollbackError === e
137
137
  ensure
138
138
  @transactions.delete(Thread.current)
139
139
  end
@@ -144,10 +144,10 @@ module Sequel
144
144
  class Dataset < Sequel::Dataset
145
145
  UNQUOTABLE_FIELD_RE = /^(`(.+)`)|\*$/.freeze
146
146
  def quote_field(f)
147
- f =~ UNQUOTABLE_FIELD_RE ? f : "`#{f}`"
147
+ (f.nil? || f.empty? || f =~ UNQUOTABLE_FIELD_RE) ? f : "`#{f}`"
148
148
  end
149
149
 
150
- FIELD_EXPR_RE = /^([^\(]+\()?([^\.]+\.)?([^\s\)]+)(\))?(\sAS\s(.+))?$/i.freeze
150
+ FIELD_EXPR_RE = /^([^\(]+\()?([^\.]+\.)?([^\s\)]+)?(\))?(\sAS\s(.+))?$/i.freeze
151
151
  FIELD_ORDER_RE = /^(.*) (DESC|ASC)$/i.freeze
152
152
  def quoted_field_name(name)
153
153
  case name
@@ -46,7 +46,7 @@ module Sequel
46
46
 
47
47
  def fetch_rows(sql, &block)
48
48
  @db.synchronize do
49
- s = @db.execute select_sql(sql)
49
+ s = @db.execute sql
50
50
  begin
51
51
  @columns = s.columns(true).map {|c| c.name.to_sym}
52
52
  rows = s.fetch_all
@@ -260,7 +260,7 @@ module Sequel
260
260
  rescue => e
261
261
  @logger.info(SQL_ROLLBACK) if @logger
262
262
  conn.async_exec(SQL_ROLLBACK) rescue nil
263
- raise e
263
+ raise e unless SequelRollbackError === e
264
264
  ensure
265
265
  conn.transaction_in_progress = nil
266
266
  end
@@ -99,6 +99,7 @@ module Sequel
99
99
  def literal(v)
100
100
  case v
101
101
  when Time: literal(v.iso8601)
102
+ when Date: literal(v.to_s)
102
103
  else
103
104
  super
104
105
  end
@@ -79,6 +79,9 @@ context "A MySQL dataset" do
79
79
 
80
80
  @d.select(:value.MAX).sql.should == \
81
81
  'SELECT max(`value`) FROM items'
82
+
83
+ @d.select(:NOW[]).sql.should == \
84
+ 'SELECT NOW() FROM items'
82
85
 
83
86
  @d.select(:items__value.MAX).sql.should == \
84
87
  'SELECT max(items.`value`) FROM items'
@@ -289,6 +289,16 @@ context "Database#transaction" do
289
289
  proc {@db.transaction {raise RuntimeError}}.should raise_error(RuntimeError)
290
290
  end
291
291
 
292
+ specify "should issue ROLLBACK if rollback! is called in the transaction" do
293
+ @db.transaction do
294
+ @db.drop_table(:a)
295
+ rollback!
296
+ @db.drop_table(:b)
297
+ end
298
+
299
+ @db.sql.should == ['BEGIN', 'DROP TABLE a;', 'ROLLBACK']
300
+ end
301
+
292
302
  specify "should be re-entrant" do
293
303
  stop = false
294
304
  cc = nil
@@ -252,6 +252,38 @@ context "Model#serialize" do
252
252
  ]
253
253
  end
254
254
 
255
+
256
+ specify "should support calling after the class is defined" do
257
+ @c = Class.new(Sequel::Model(:items)) do
258
+ no_primary_key
259
+ end
260
+
261
+ @c.serialize :def
262
+
263
+ @c.create(:def => 1)
264
+ @c.create(:def => "hello")
265
+
266
+ MODEL_DB.sqls.should == [ \
267
+ "INSERT INTO items (def) VALUES ('--- 1\n');", \
268
+ "INSERT INTO items (def) VALUES ('--- hello\n');", \
269
+ ]
270
+ end
271
+
272
+ specify "should support using the Marshal format" do
273
+ @c = Class.new(Sequel::Model(:items)) do
274
+ no_primary_key
275
+ serialize :abc, :format => :marshal
276
+ end
277
+
278
+ @c.create(:abc => 1)
279
+ @c.create(:abc => "hello")
280
+
281
+ MODEL_DB.sqls.should == [ \
282
+ "INSERT INTO items (abc) VALUES ('\004\bi\006');", \
283
+ "INSERT INTO items (abc) VALUES ('\004\b\"\nhello');", \
284
+ ]
285
+ end
286
+
255
287
  specify "should translate values to and from YAML using accessor methods" do
256
288
  @c = Class.new(Sequel::Model(:items)) do
257
289
  serialize :abc, :def
@@ -338,4 +370,71 @@ context "Model attribute accessors" do
338
370
  proc {o.x = 3}.should_not raise_error
339
371
  proc {o.yy = 4}.should raise_error
340
372
  end
373
+ end
374
+
375
+ context "Model#new?" do
376
+ setup do
377
+ MODEL_DB.reset
378
+
379
+ @c = Class.new(Sequel::Model(:items)) do
380
+ def columns
381
+ [:id, :x, :y]
382
+ end
383
+ end
384
+ end
385
+
386
+ specify "should be true for a new instance" do
387
+ n = @c.new(:x => 1)
388
+ n.should be_new
389
+ end
390
+
391
+ specify "should be false after saving" do
392
+ n = @c.new(:x => 1)
393
+ n.save
394
+ n.should_not be_new
395
+ end
396
+ end
397
+
398
+ context "Model.after_create" do
399
+ setup do
400
+ MODEL_DB.reset
401
+
402
+ @c = Class.new(Sequel::Model(:items)) do
403
+ def columns
404
+ [:id, :x, :y]
405
+ end
406
+ end
407
+
408
+ ds = @c.dataset
409
+ def ds.insert(*args)
410
+ super(*args)
411
+ 1
412
+ end
413
+ end
414
+
415
+ specify "should be called after creation" do
416
+ s = []
417
+
418
+ @c.after_create do
419
+ s = MODEL_DB.sqls.dup
420
+ end
421
+
422
+ n = @c.create(:x => 1)
423
+ MODEL_DB.sqls.should == ['INSERT INTO items (x) VALUES (1);']
424
+ s.should == ['INSERT INTO items (x) VALUES (1);']
425
+ end
426
+
427
+ specify "should allow calling save in the hook" do
428
+ @c.after_create do
429
+ values.delete(:x)
430
+ self.id = 2
431
+ save
432
+ end
433
+
434
+ n = @c.create(:id => 1)
435
+ MODEL_DB.sqls.should == ['INSERT INTO items (id) VALUES (1);', 'UPDATE items SET id = 2 WHERE (id = 1)']
436
+ end
437
+ end
438
+
439
+ context "Model.serialize" do
341
440
  end
@@ -9,7 +9,18 @@ context "Proc#to_sql" do
9
9
  DS.proc_to_sql(self)
10
10
  end
11
11
  end
12
-
12
+
13
+ def DS.match_expr(l, r)
14
+ case r
15
+ when String:
16
+ "(#{literal(l)} LIKE #{literal(r)})"
17
+ when Regexp:
18
+ "(#{literal(l)} ~ #{literal(r.source)})"
19
+ else
20
+ raise SequelError, "Unsupported match pattern class (#{r.class})."
21
+ end
22
+ end
23
+
13
24
  specify "should support <sym> <op> <lit>" do
14
25
  proc {:x > 100}.to_sql.should == '(x > 100)'
15
26
  proc {:x < 100}.to_sql.should == '(x < 100)'
@@ -79,11 +90,11 @@ context "Proc#to_sql" do
79
90
  specify "should support =~ operator" do
80
91
  # stock SQL version does not know about regexps
81
92
  proc {:x =~ '123'}.to_sql.should == "(x LIKE '123')"
93
+
94
+ proc {:x =~ /^123/}.to_sql.should == "(x ~ '^123')"
82
95
  end
83
96
 
84
97
  specify "should raise on =~ operator for unsupported types" do
85
- # stock SQL version does not know about regexps
86
- proc {proc {:x =~ /123/}.to_sql}.should raise_error(SequelError)
87
98
  proc {proc {:x =~ 123}.to_sql}.should raise_error(SequelError)
88
99
  end
89
100
 
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4
3
3
  specification_version: 1
4
4
  name: sequel
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.2.1
7
- date: 2007-09-24 00:00:00 +02:00
6
+ version: 0.2.1.1
7
+ date: 2007-10-07 00:00:00 +02:00
8
8
  summary: Lightweight ORM library for Ruby
9
9
  require_paths:
10
10
  - lib