sequel 0.2.1 → 0.2.1.1

Sign up to get free protection for your applications and to get access to all the features.
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