sequel 0.2.1.1 → 0.3.0
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 +76 -0
- data/Rakefile +1 -1
- data/lib/sequel.rb +1 -1
- data/lib/sequel/ado.rb +17 -0
- data/lib/sequel/array_keys.rb +233 -0
- data/lib/sequel/connection_pool.rb +14 -0
- data/lib/sequel/core_ext.rb +3 -3
- data/lib/sequel/database.rb +25 -7
- data/lib/sequel/dataset.rb +46 -15
- data/lib/sequel/dataset/convenience.rb +27 -2
- data/lib/sequel/dataset/sequelizer.rb +2 -2
- data/lib/sequel/dataset/sql.rb +49 -18
- data/lib/sequel/dbi.rb +17 -0
- data/lib/sequel/model.rb +276 -82
- data/lib/sequel/model/base.rb +41 -30
- data/lib/sequel/model/caching.rb +42 -0
- data/lib/sequel/model/hooks.rb +113 -27
- data/lib/sequel/model/record.rb +78 -21
- data/lib/sequel/model/relations.rb +5 -0
- data/lib/sequel/model/schema.rb +11 -1
- data/lib/sequel/mysql.rb +61 -17
- data/lib/sequel/odbc.rb +42 -1
- data/lib/sequel/postgres.rb +45 -0
- data/lib/sequel/pretty_table.rb +14 -11
- data/lib/sequel/schema/schema_generator.rb +9 -3
- data/lib/sequel/sqlite.rb +33 -1
- data/spec/adapters/mysql_spec.rb +69 -15
- data/spec/adapters/postgres_spec.rb +66 -12
- data/spec/adapters/sqlite_spec.rb +113 -1
- data/spec/array_keys_spec.rb +544 -0
- data/spec/connection_pool_spec.rb +83 -0
- data/spec/database_spec.rb +81 -2
- data/spec/dataset_spec.rb +227 -9
- data/spec/model_spec.rb +392 -68
- data/spec/schema_spec.rb +7 -0
- metadata +5 -2
data/spec/model_spec.rb
CHANGED
@@ -2,90 +2,154 @@ require File.join(File.dirname(__FILE__), 'spec_helper')
|
|
2
2
|
|
3
3
|
Sequel::Model.db = MODEL_DB = MockDatabase.new
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
5
|
+
describe Sequel::Model do
|
6
|
+
|
7
|
+
it "should have class method aliased as model" do
|
8
|
+
Sequel::Model.instance_methods.should include('model')
|
9
|
+
|
10
|
+
model_a = Class.new Sequel::Model
|
11
|
+
model_a.new.model.should be(model_a)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should be associated with a dataset" do
|
15
|
+
model_a = Class.new(Sequel::Model) { set_dataset MODEL_DB[:as] }
|
10
16
|
|
11
|
-
|
12
|
-
|
17
|
+
model_a.dataset.should be_a_kind_of(MockDataset)
|
18
|
+
model_a.dataset.opts[:from].should == [:as]
|
13
19
|
|
14
|
-
|
15
|
-
set_dataset MODEL_DB[:zzz]
|
16
|
-
end
|
20
|
+
model_b = Class.new(Sequel::Model) { set_dataset MODEL_DB[:bs] }
|
17
21
|
|
18
|
-
|
19
|
-
|
20
|
-
|
22
|
+
model_b.dataset.should be_a_kind_of(MockDataset)
|
23
|
+
model_b.dataset.opts[:from].should == [:bs]
|
24
|
+
|
25
|
+
model_a.dataset.opts[:from].should == [:as]
|
21
26
|
end
|
27
|
+
|
22
28
|
end
|
23
29
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
@m.primary_key.should == :id
|
30
|
+
describe Sequel::Model, 'w/ primary key' do
|
31
|
+
|
32
|
+
it "should default to ':id'" do
|
33
|
+
model_a = Class.new Sequel::Model
|
34
|
+
model_a.primary_key.should be_equal(:id)
|
30
35
|
end
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
end
|
36
|
-
|
37
|
-
@m.primary_key.should == :xxx
|
36
|
+
|
37
|
+
it "should be changed through 'set_primary_key'" do
|
38
|
+
model_a = Class.new(Sequel::Model) { set_primary_key :a }
|
39
|
+
model_a.primary_key.should be_equal(:a)
|
38
40
|
end
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
41
|
+
|
42
|
+
it "should support multi argument composite keys" do
|
43
|
+
model_a = Class.new(Sequel::Model) { set_primary_key :a, :b }
|
44
|
+
model_a.primary_key.should be_eql([:a, :b])
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should accept single argument composite keys" do
|
48
|
+
model_a = Class.new(Sequel::Model) { set_primary_key [:a, :b] }
|
49
|
+
model_a.primary_key.should be_eql([:a, :b])
|
45
50
|
end
|
51
|
+
|
46
52
|
end
|
47
53
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
end
|
54
|
+
describe Sequel::Model, 'w/o primary key' do
|
55
|
+
|
56
|
+
it "should return nil for primary key" do
|
57
|
+
Class.new(Sequel::Model) { no_primary_key }.primary_key.should be_nil
|
53
58
|
end
|
54
|
-
|
55
|
-
|
56
|
-
|
59
|
+
|
60
|
+
it "should raise a SequelError on 'this'" do
|
61
|
+
instance = Class.new(Sequel::Model) { no_primary_key }.new
|
62
|
+
proc { instance.this }.should raise_error(SequelError)
|
57
63
|
end
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
describe Sequel::Model, 'with this' do
|
68
|
+
|
69
|
+
before { @example = Class.new Sequel::Model(:examples) }
|
70
|
+
|
71
|
+
it "should return a dataset identifying the record" do
|
72
|
+
instance = @example.new :id => 3
|
73
|
+
instance.this.sql.should be_eql("SELECT * FROM examples WHERE (id = 3) LIMIT 1")
|
62
74
|
end
|
75
|
+
|
76
|
+
it "should support arbitary primary keys" do
|
77
|
+
@example.set_primary_key :a
|
78
|
+
|
79
|
+
instance = @example.new :a => 3
|
80
|
+
instance.this.sql.should be_eql("SELECT * FROM examples WHERE (a = 3) LIMIT 1")
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should support composite primary keys" do
|
84
|
+
@example.set_primary_key :x, :y
|
85
|
+
instance = @example.new :x => 4, :y => 5
|
86
|
+
|
87
|
+
parts = ['SELECT * FROM examples WHERE %s LIMIT 1',
|
88
|
+
'(x = 4) AND (y = 5)', '(y = 5) AND (x = 4)'
|
89
|
+
].map { |expr| Regexp.escape expr }
|
90
|
+
regexp = Regexp.new parts.first % "(?:#{parts[1]}|#{parts[2]})"
|
91
|
+
|
92
|
+
instance.this.sql.should match(regexp)
|
93
|
+
end
|
94
|
+
|
63
95
|
end
|
64
96
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
97
|
+
describe Sequel::Model, 'with hooks' do
|
98
|
+
|
99
|
+
before do
|
100
|
+
MODEL_DB.reset
|
101
|
+
Sequel::Model.hooks.clear
|
102
|
+
|
103
|
+
@hooks = %w{
|
104
|
+
before_save before_create before_update before_destroy
|
105
|
+
after_save after_create after_update after_destroy
|
106
|
+
}.select { |hook| !hook.empty? }
|
69
107
|
end
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
108
|
+
|
109
|
+
it "should have hooks for everything" do
|
110
|
+
Sequel::Model.methods.should include('hooks')
|
111
|
+
Sequel::Model.methods.should include(*@hooks)
|
112
|
+
@hooks.each do |hook|
|
113
|
+
Sequel::Model.hooks[hook.to_sym].should be_an_instance_of(Array)
|
114
|
+
end
|
74
115
|
end
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
116
|
+
it "should be inherited" do
|
117
|
+
pending 'soon'
|
118
|
+
|
119
|
+
@hooks.each do |hook|
|
120
|
+
Sequel::Model.send(hook.to_sym) { nil }
|
121
|
+
end
|
122
|
+
|
123
|
+
model = Class.new Sequel::Model(:models)
|
124
|
+
model.hooks.should == Sequel::Model.hooks
|
81
125
|
end
|
82
|
-
|
83
|
-
specify "should support composite primary keys" do
|
84
|
-
@m.set_primary_key [:x, :y]
|
85
|
-
o = @m.new(:x => 4, :y => 5)
|
86
126
|
|
87
|
-
|
127
|
+
it "should run hooks" do
|
128
|
+
pending 'soon'
|
129
|
+
|
130
|
+
test = mock 'Test'
|
131
|
+
test.should_receive(:run).exactly(@hooks.length)
|
132
|
+
|
133
|
+
@hooks.each do |hook|
|
134
|
+
Sequel::Model.send(hook.to_sym) { test.run }
|
135
|
+
end
|
136
|
+
|
137
|
+
model = Class.new Sequel::Model(:models)
|
138
|
+
model.hooks.should == Sequel::Model.hooks
|
139
|
+
|
140
|
+
model_instance = model.new
|
141
|
+
@hooks.each { |hook| model_instance.run_hooks(hook) }
|
142
|
+
end
|
143
|
+
it "should run hooks around save and create" do
|
144
|
+
pending 'test execution'
|
145
|
+
end
|
146
|
+
it "should run hooks around save and update" do
|
147
|
+
pending 'test execution'
|
88
148
|
end
|
149
|
+
it "should run hooks around delete" do
|
150
|
+
pending 'test execution'
|
151
|
+
end
|
152
|
+
|
89
153
|
end
|
90
154
|
|
91
155
|
context "A new model instance" do
|
@@ -214,7 +278,7 @@ context "A model class without a primary key" do
|
|
214
278
|
i = nil
|
215
279
|
proc {i = @c.create(:x => 1)}.should_not raise_error
|
216
280
|
i.class.should be(@c)
|
217
|
-
i.values.should == {:x => 1}
|
281
|
+
i.values.to_hash.should == {:x => 1}
|
218
282
|
|
219
283
|
MODEL_DB.sqls.should == ['INSERT INTO items (x) VALUES (1);']
|
220
284
|
end
|
@@ -325,6 +389,7 @@ context "Model#serialize" do
|
|
325
389
|
o.set(:abc => 23)
|
326
390
|
ds.sqls.should == "UPDATE items SET abc = '#{23.to_yaml}' WHERE (id = 1)"
|
327
391
|
|
392
|
+
ds.raw = {:id => 1, :abc => "--- 1\n", :def => "--- hello\n"}
|
328
393
|
o = @c.create(:abc => [1, 2, 3])
|
329
394
|
ds.sqls.should == "INSERT INTO items (abc) VALUES ('#{[1, 2, 3].to_yaml}');"
|
330
395
|
end
|
@@ -377,9 +442,6 @@ context "Model#new?" do
|
|
377
442
|
MODEL_DB.reset
|
378
443
|
|
379
444
|
@c = Class.new(Sequel::Model(:items)) do
|
380
|
-
def columns
|
381
|
-
[:id, :x, :y]
|
382
|
-
end
|
383
445
|
end
|
384
446
|
end
|
385
447
|
|
@@ -436,5 +498,267 @@ context "Model.after_create" do
|
|
436
498
|
end
|
437
499
|
end
|
438
500
|
|
439
|
-
context "Model.
|
501
|
+
context "Model.subset" do
|
502
|
+
setup do
|
503
|
+
MODEL_DB.reset
|
504
|
+
|
505
|
+
@c = Class.new(Sequel::Model(:items)) do
|
506
|
+
def columns
|
507
|
+
[:id, :x, :y]
|
508
|
+
end
|
509
|
+
end
|
510
|
+
end
|
511
|
+
|
512
|
+
specify "should create a filter on the underlying dataset" do
|
513
|
+
proc {@c.new_only}.should raise_error(NoMethodError)
|
514
|
+
|
515
|
+
@c.subset(:new_only) {:age == 'new'}
|
516
|
+
|
517
|
+
@c.new_only.sql.should == "SELECT * FROM items WHERE (age = 'new')"
|
518
|
+
@c.dataset.new_only.sql.should == "SELECT * FROM items WHERE (age = 'new')"
|
519
|
+
|
520
|
+
@c.subset(:pricey) {:price > 100}
|
521
|
+
|
522
|
+
@c.pricey.sql.should == "SELECT * FROM items WHERE (price > 100)"
|
523
|
+
@c.dataset.pricey.sql.should == "SELECT * FROM items WHERE (price > 100)"
|
524
|
+
|
525
|
+
# check if subsets are composable
|
526
|
+
@c.pricey.new_only.sql.should == "SELECT * FROM items WHERE (price > 100) AND (age = 'new')"
|
527
|
+
@c.new_only.pricey.sql.should == "SELECT * FROM items WHERE (age = 'new') AND (price > 100)"
|
528
|
+
end
|
529
|
+
end
|
530
|
+
|
531
|
+
context "Model.find" do
|
532
|
+
setup do
|
533
|
+
MODEL_DB.reset
|
534
|
+
|
535
|
+
@c = Class.new(Sequel::Model(:items)) do
|
536
|
+
def self.columns
|
537
|
+
[:name, :id]
|
538
|
+
end
|
539
|
+
end
|
540
|
+
|
541
|
+
$cache_dataset_row = {:name => 'sharon', :id => 1}
|
542
|
+
@dataset = @c.dataset
|
543
|
+
$sqls = []
|
544
|
+
@dataset.extend(Module.new {
|
545
|
+
def fetch_rows(sql)
|
546
|
+
$sqls << sql
|
547
|
+
yield $cache_dataset_row
|
548
|
+
end
|
549
|
+
})
|
550
|
+
end
|
551
|
+
|
552
|
+
specify "should return the first record matching the given filter" do
|
553
|
+
@c.find(:name => 'sharon').should be_a_kind_of(@c)
|
554
|
+
$sqls.last.should == "SELECT * FROM items WHERE (name = 'sharon') LIMIT 1"
|
555
|
+
|
556
|
+
@c.find {"name LIKE 'abc%'".lit}.should be_a_kind_of(@c)
|
557
|
+
$sqls.last.should == "SELECT * FROM items WHERE name LIKE 'abc%' LIMIT 1"
|
558
|
+
end
|
559
|
+
|
560
|
+
specify "should accept filter blocks" do
|
561
|
+
@c.find {:id == 1}.should be_a_kind_of(@c)
|
562
|
+
$sqls.last.should == "SELECT * FROM items WHERE (id = 1) LIMIT 1"
|
563
|
+
|
564
|
+
@c.find {:x > 1 && :y < 2}.should be_a_kind_of(@c)
|
565
|
+
$sqls.last.should == "SELECT * FROM items WHERE ((x > 1) AND (y < 2)) LIMIT 1"
|
566
|
+
end
|
567
|
+
end
|
568
|
+
|
569
|
+
context "Model.[]" do
|
570
|
+
setup do
|
571
|
+
MODEL_DB.reset
|
572
|
+
|
573
|
+
@c = Class.new(Sequel::Model(:items)) do
|
574
|
+
def self.columns
|
575
|
+
[:name, :id]
|
576
|
+
end
|
577
|
+
end
|
578
|
+
|
579
|
+
$cache_dataset_row = {:name => 'sharon', :id => 1}
|
580
|
+
@dataset = @c.dataset
|
581
|
+
$sqls = []
|
582
|
+
@dataset.extend(Module.new {
|
583
|
+
def fetch_rows(sql)
|
584
|
+
$sqls << sql
|
585
|
+
yield $cache_dataset_row
|
586
|
+
end
|
587
|
+
})
|
588
|
+
end
|
589
|
+
|
590
|
+
specify "should return the first record for the given pk" do
|
591
|
+
@c[1].should be_a_kind_of(@c)
|
592
|
+
$sqls.last.should == "SELECT * FROM items WHERE (id = 1) LIMIT 1"
|
593
|
+
@c[9999].should be_a_kind_of(@c)
|
594
|
+
$sqls.last.should == "SELECT * FROM items WHERE (id = 9999) LIMIT 1"
|
595
|
+
end
|
596
|
+
|
597
|
+
specify "should work correctly for custom primary key" do
|
598
|
+
@c.set_primary_key :name
|
599
|
+
@c['sharon'].should be_a_kind_of(@c)
|
600
|
+
$sqls.last.should == "SELECT * FROM items WHERE (name = 'sharon') LIMIT 1"
|
601
|
+
end
|
602
|
+
|
603
|
+
specify "should work correctly for composite primary key" do
|
604
|
+
@c.set_primary_key [:node_id, :kind]
|
605
|
+
@c[3921, 201].should be_a_kind_of(@c)
|
606
|
+
$sqls.last.should =~ \
|
607
|
+
/^SELECT \* FROM items WHERE (\(node_id = 3921\) AND \(kind = 201\))|(\(kind = 201\) AND \(node_id = 3921\)) LIMIT 1$/
|
608
|
+
end
|
609
|
+
|
610
|
+
specify "should act as shortcut to find if a hash is given" do
|
611
|
+
@c[:id => 1].should be_a_kind_of(@c)
|
612
|
+
$sqls.last.should == "SELECT * FROM items WHERE (id = 1) LIMIT 1"
|
613
|
+
|
614
|
+
@c[:name => ['abc', 'def']].should be_a_kind_of(@c)
|
615
|
+
$sqls.last.should == "SELECT * FROM items WHERE (name IN ('abc', 'def')) LIMIT 1"
|
616
|
+
end
|
617
|
+
end
|
618
|
+
|
619
|
+
context "A cached model" do
|
620
|
+
setup do
|
621
|
+
MODEL_DB.reset
|
622
|
+
|
623
|
+
@cache_class = Class.new(Hash) do
|
624
|
+
attr_accessor :ttl
|
625
|
+
def set(k, v, ttl); self[k] = v; @ttl = ttl; end
|
626
|
+
def get(k); self[k]; end
|
627
|
+
end
|
628
|
+
cache = @cache_class.new
|
629
|
+
@cache = cache
|
630
|
+
|
631
|
+
@c = Class.new(Sequel::Model(:items)) do
|
632
|
+
set_cache cache
|
633
|
+
|
634
|
+
def self.columns
|
635
|
+
[:name, :id]
|
636
|
+
end
|
637
|
+
end
|
638
|
+
|
639
|
+
$cache_dataset_row = {:name => 'sharon', :id => 1}
|
640
|
+
@dataset = @c.dataset
|
641
|
+
$sqls = []
|
642
|
+
@dataset.extend(Module.new {
|
643
|
+
def fetch_rows(sql)
|
644
|
+
$sqls << sql
|
645
|
+
yield $cache_dataset_row
|
646
|
+
end
|
647
|
+
|
648
|
+
def update(values)
|
649
|
+
$sqls << update_sql(values)
|
650
|
+
$cache_dataset_row.merge!(values)
|
651
|
+
end
|
652
|
+
|
653
|
+
def delete
|
654
|
+
$sqls << delete_sql
|
655
|
+
end
|
656
|
+
})
|
657
|
+
end
|
658
|
+
|
659
|
+
specify "should set the model's cache store" do
|
660
|
+
@c.cache_store.should be(@cache)
|
661
|
+
end
|
662
|
+
|
663
|
+
specify "should have a default ttl of 3600" do
|
664
|
+
@c.cache_ttl.should == 3600
|
665
|
+
end
|
666
|
+
|
667
|
+
specify "should take a ttl option" do
|
668
|
+
@c.set_cache @cache, :ttl => 1234
|
669
|
+
@c.cache_ttl.should == 1234
|
670
|
+
end
|
671
|
+
|
672
|
+
specify "should offer a set_cache_ttl method for setting the ttl" do
|
673
|
+
@c.cache_ttl.should == 3600
|
674
|
+
@c.set_cache_ttl 1234
|
675
|
+
@c.cache_ttl.should == 1234
|
676
|
+
end
|
677
|
+
|
678
|
+
specify "should generate a cache key appropriate to the class" do
|
679
|
+
m = @c.new
|
680
|
+
m.values[:id] = 1
|
681
|
+
m.cache_key.should == "#{m.class}:1"
|
682
|
+
|
683
|
+
# custom primary key
|
684
|
+
@c.set_primary_key :ttt
|
685
|
+
m = @c.new
|
686
|
+
m.values[:ttt] = 333
|
687
|
+
m.cache_key.should == "#{m.class}:333"
|
688
|
+
|
689
|
+
# composite primary key
|
690
|
+
@c.set_primary_key [:a, :b, :c]
|
691
|
+
m = @c.new
|
692
|
+
m.values[:a] = 123
|
693
|
+
m.values[:c] = 456
|
694
|
+
m.values[:b] = 789
|
695
|
+
m.cache_key.should == "#{m.class}:123,789,456"
|
696
|
+
end
|
697
|
+
|
698
|
+
specify "should raise error if attempting to generate cache_key and primary key value is null" do
|
699
|
+
m = @c.new
|
700
|
+
proc {m.cache_key}.should raise_error(SequelError)
|
701
|
+
|
702
|
+
m.values[:id] = 1
|
703
|
+
proc {m.cache_key}.should_not raise_error(SequelError)
|
704
|
+
end
|
705
|
+
|
706
|
+
specify "should set the cache when reading from the database" do
|
707
|
+
$sqls.should == []
|
708
|
+
@cache.should be_empty
|
709
|
+
|
710
|
+
m = @c[1]
|
711
|
+
$sqls.should == ['SELECT * FROM items WHERE (id = 1) LIMIT 1']
|
712
|
+
m.values.should == $cache_dataset_row
|
713
|
+
@cache[m.cache_key].should == m
|
714
|
+
|
715
|
+
# read from cache
|
716
|
+
m2 = @c[1]
|
717
|
+
$sqls.should == ['SELECT * FROM items WHERE (id = 1) LIMIT 1']
|
718
|
+
m2.should == m
|
719
|
+
m2.values.should == $cache_dataset_row
|
720
|
+
end
|
721
|
+
|
722
|
+
specify "should delete the cache when writing to the database" do
|
723
|
+
# fill the cache
|
724
|
+
m = @c[1]
|
725
|
+
@cache[m.cache_key].should == m
|
726
|
+
|
727
|
+
m.set(:name => 'tutu')
|
728
|
+
@cache.has_key?(m.cache_key).should be_false
|
729
|
+
$sqls.last.should == "UPDATE items SET name = 'tutu' WHERE (id = 1)"
|
730
|
+
|
731
|
+
m = @c[1]
|
732
|
+
@cache[m.cache_key].should == m
|
733
|
+
m.name = 'hey'
|
734
|
+
m.save
|
735
|
+
@cache.has_key?(m.cache_key).should be_false
|
736
|
+
$sqls.last.should == "UPDATE items SET name = 'hey', id = 1 WHERE (id = 1)"
|
737
|
+
end
|
738
|
+
|
739
|
+
specify "should delete the cache when deleting the record" do
|
740
|
+
# fill the cache
|
741
|
+
m = @c[1]
|
742
|
+
@cache[m.cache_key].should == m
|
743
|
+
|
744
|
+
m.delete
|
745
|
+
@cache.has_key?(m.cache_key).should be_false
|
746
|
+
$sqls.last.should == "DELETE FROM items WHERE (id = 1)"
|
747
|
+
end
|
748
|
+
|
749
|
+
specify "should support #[] as a shortcut to #find with hash" do
|
750
|
+
m = @c[:id => 3]
|
751
|
+
@cache[m.cache_key].should be_nil
|
752
|
+
$sqls.last.should == "SELECT * FROM items WHERE (id = 3) LIMIT 1"
|
753
|
+
|
754
|
+
m = @c[1]
|
755
|
+
@cache[m.cache_key].should == m
|
756
|
+
$sqls.should == ["SELECT * FROM items WHERE (id = 3) LIMIT 1", \
|
757
|
+
"SELECT * FROM items WHERE (id = 1) LIMIT 1"]
|
758
|
+
|
759
|
+
@c[:id => 4]
|
760
|
+
$sqls.should == ["SELECT * FROM items WHERE (id = 3) LIMIT 1", \
|
761
|
+
"SELECT * FROM items WHERE (id = 1) LIMIT 1", \
|
762
|
+
"SELECT * FROM items WHERE (id = 4) LIMIT 1"]
|
763
|
+
end
|
440
764
|
end
|