sequel 1.4.0 → 1.5.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.
@@ -23,7 +23,12 @@ describe Sequel::Model, "many_to_one" do
23
23
  MODEL_DB.reset
24
24
 
25
25
  @c2 = Class.new(Sequel::Model(:nodes)) do
26
- def columns; [:id, :parent_id]; end
26
+ columns :id, :parent_id, :par_parent_id, :blah
27
+ def self.create_new(values)
28
+ obj = self.new(values)
29
+ obj.instance_variable_set(:@new, false)
30
+ obj
31
+ end
27
32
  end
28
33
 
29
34
  @dataset = @c2.dataset
@@ -53,6 +58,21 @@ describe Sequel::Model, "many_to_one" do
53
58
  MODEL_DB.sqls.should == ["SELECT * FROM par_parents WHERE (id = 234) LIMIT 1"]
54
59
  end
55
60
 
61
+ it "should use class inside module if given as a string" do
62
+ module Par
63
+ class Parent < Sequel::Model
64
+ end
65
+ end
66
+
67
+ @c2.many_to_one :par_parent, :class=>"Par::Parent"
68
+
69
+ d = @c2.new(:id => 1, :par_parent_id => 234)
70
+ p = d.par_parent
71
+ p.class.should == Par::Parent
72
+
73
+ MODEL_DB.sqls.should == ["SELECT * FROM parents WHERE (id = 234) LIMIT 1"]
74
+ end
75
+
56
76
  it "should use explicit key if given" do
57
77
  @c2.many_to_one :parent, :class => @c2, :key => :blah
58
78
 
@@ -71,6 +91,21 @@ describe Sequel::Model, "many_to_one" do
71
91
  d.parent.should == nil
72
92
  end
73
93
 
94
+ it "should cache negative lookup" do
95
+ @c2.many_to_one :parent, :class => @c2
96
+ ds = @c2.dataset
97
+ def ds.fetch_rows(sql, &block)
98
+ MODEL_DB.sqls << sql
99
+ end
100
+
101
+ d = @c2.new(:id => 1, :parent_id=>555)
102
+ MODEL_DB.sqls.should == []
103
+ d.parent.should == nil
104
+ MODEL_DB.sqls.should == ['SELECT * FROM nodes WHERE (id = 555) LIMIT 1']
105
+ d.parent.should == nil
106
+ MODEL_DB.sqls.should == ['SELECT * FROM nodes WHERE (id = 555) LIMIT 1']
107
+ end
108
+
74
109
  it "should define a setter method" do
75
110
  @c2.many_to_one :parent, :class => @c2
76
111
 
@@ -89,7 +124,7 @@ describe Sequel::Model, "many_to_one" do
89
124
  it "should not persist changes until saved" do
90
125
  @c2.many_to_one :parent, :class => @c2
91
126
 
92
- d = @c2.create(:id => 1)
127
+ d = @c2.create_new(:id => 1)
93
128
  MODEL_DB.reset
94
129
  d.parent = @c2.new(:id => 345)
95
130
  MODEL_DB.sqls.should == []
@@ -100,10 +135,12 @@ describe Sequel::Model, "many_to_one" do
100
135
  it "should set cached instance variable when accessed" do
101
136
  @c2.many_to_one :parent, :class => @c2
102
137
 
103
- d = @c2.create(:id => 1)
138
+ d = @c2.create_new(:id => 1)
104
139
  MODEL_DB.reset
105
140
  d.parent_id = 234
106
- d.instance_variables.include?("@parent").should == false
141
+ d.instance_variable_get("@parent").should == nil
142
+ ds = @c2.dataset
143
+ def ds.fetch_rows(sql, &block); MODEL_DB.sqls << sql; yield({:id=>234}) end
107
144
  e = d.parent
108
145
  MODEL_DB.sqls.should == ["SELECT * FROM nodes WHERE (id = 234) LIMIT 1"]
109
146
  d.instance_variable_get("@parent").should == e
@@ -114,7 +151,7 @@ describe Sequel::Model, "many_to_one" do
114
151
 
115
152
  d = @c2.create(:id => 1)
116
153
  MODEL_DB.reset
117
- d.instance_variables.include?("@parent").should == false
154
+ d.instance_variable_get("@parent").should == nil
118
155
  d.parent = @c2.new(:id => 234)
119
156
  e = d.parent
120
157
  d.instance_variable_get("@parent").should == e
@@ -142,13 +179,64 @@ describe Sequel::Model, "many_to_one" do
142
179
  MODEL_DB.sqls.should == ["SELECT * FROM nodes WHERE (id = 234) LIMIT 1"]
143
180
  end
144
181
 
182
+ it "should have the setter add to the reciprocal one_to_many cached association list if it exists" do
183
+ @c2.many_to_one :parent, :class => @c2
184
+ @c2.one_to_many :children, :class => @c2, :key=>:parent_id
185
+ ds = @c2.dataset
186
+ def ds.fetch_rows(sql, &block)
187
+ MODEL_DB.sqls << sql
188
+ end
189
+
190
+ d = @c2.new(:id => 1)
191
+ e = @c2.new(:id => 2)
192
+ MODEL_DB.sqls.should == []
193
+ d.parent = e
194
+ e.children.should_not(include(d))
195
+ MODEL_DB.sqls.should == ['SELECT * FROM nodes WHERE (parent_id = 2)']
196
+
197
+ MODEL_DB.reset
198
+ d = @c2.new(:id => 1)
199
+ e = @c2.new(:id => 2)
200
+ e.children.should_not(include(d))
201
+ MODEL_DB.sqls.should == ['SELECT * FROM nodes WHERE (parent_id = 2)']
202
+ d.parent = e
203
+ e.children.should(include(d))
204
+ MODEL_DB.sqls.should == ['SELECT * FROM nodes WHERE (parent_id = 2)']
205
+ end
206
+
207
+ it "should have the setter remove the object from the previous associated object's reciprocal one_to_many cached association list if it exists" do
208
+ @c2.many_to_one :parent, :class => @c2
209
+ @c2.one_to_many :children, :class => @c2, :key=>:parent_id
210
+ ds = @c2.dataset
211
+ def ds.fetch_rows(sql, &block)
212
+ MODEL_DB.sqls << sql
213
+ end
214
+
215
+ d = @c2.new(:id => 1)
216
+ e = @c2.new(:id => 2)
217
+ f = @c2.new(:id => 3)
218
+ e.children.should_not(include(d))
219
+ f.children.should_not(include(d))
220
+ MODEL_DB.reset
221
+ d.parent = e
222
+ e.children.should(include(d))
223
+ d.parent = f
224
+ f.children.should(include(d))
225
+ e.children.should_not(include(d))
226
+ d.parent = nil
227
+ f.children.should_not(include(d))
228
+ MODEL_DB.sqls.should == []
229
+ end
230
+
145
231
  it "should have belongs_to alias" do
146
232
  @c2.belongs_to :parent, :class => @c2
147
233
 
148
- d = @c2.create(:id => 1)
234
+ d = @c2.create_new(:id => 1)
149
235
  MODEL_DB.reset
150
236
  d.parent_id = 234
151
- d.instance_variables.include?("@parent").should == false
237
+ d.instance_variable_get("@parent").should == nil
238
+ ds = @c2.dataset
239
+ def ds.fetch_rows(sql, &block); MODEL_DB.sqls << sql; yield({:id=>234}) end
152
240
  e = d.parent
153
241
  MODEL_DB.sqls.should == ["SELECT * FROM nodes WHERE (id = 234) LIMIT 1"]
154
242
  d.instance_variable_get("@parent").should == e
@@ -161,7 +249,7 @@ describe Sequel::Model, "one_to_many" do
161
249
  MODEL_DB.reset
162
250
 
163
251
  @c1 = Class.new(Sequel::Model(:attributes)) do
164
- def columns; [:id, :node_id]; end
252
+ columns :id, :node_id
165
253
  end
166
254
 
167
255
  @c2 = Class.new(Sequel::Model(:nodes)) do
@@ -169,6 +257,7 @@ describe Sequel::Model, "one_to_many" do
169
257
 
170
258
  def self.name; 'Node'; end
171
259
  def self.to_s; 'Node'; end
260
+ columns :id
172
261
  end
173
262
  @dataset = @c2.dataset
174
263
 
@@ -209,6 +298,21 @@ describe Sequel::Model, "one_to_many" do
209
298
  v.model_classes.should == {nil => HistoricalValue}
210
299
  end
211
300
 
301
+ it "should use class inside a module if given as a string" do
302
+ module Historical
303
+ class Value < Sequel::Model
304
+ end
305
+ end
306
+
307
+ @c2.one_to_many :historical_values, :class=>'Historical::Value'
308
+
309
+ n = @c2.new(:id => 1234)
310
+ v = n.historical_values_dataset
311
+ v.should be_a_kind_of(Sequel::Dataset)
312
+ v.sql.should == 'SELECT * FROM values WHERE (node_id = 1234)'
313
+ v.model_classes.should == {nil => Historical::Value}
314
+ end
315
+
212
316
  it "should use explicit key if given" do
213
317
  @c2.one_to_many :attributes, :class => @c1, :key => :nodeid
214
318
 
@@ -340,6 +444,16 @@ describe Sequel::Model, "one_to_many" do
340
444
  a.should == [att]
341
445
  end
342
446
 
447
+ it "should set object to item's reciprocal cached association variable when calling add_" do
448
+ @c2.one_to_many :attributes, :class => @c1
449
+ @c1.many_to_one :node, :class => @c2
450
+
451
+ n = @c2.new(:id => 1234)
452
+ att = @c1.new(:id => 345)
453
+ n.add_attribute(att)
454
+ att.node.should == n
455
+ end
456
+
343
457
  it "should remove item from cached instance variable if it exists when calling remove_" do
344
458
  @c2.one_to_many :attributes, :class => @c1
345
459
 
@@ -352,6 +466,18 @@ describe Sequel::Model, "one_to_many" do
352
466
  a.should == []
353
467
  end
354
468
 
469
+ it "should remove item's reciprocal cached association variable when calling remove_" do
470
+ @c2.one_to_many :attributes, :class => @c1
471
+ @c1.many_to_one :node, :class => @c2
472
+
473
+ n = @c2.new(:id => 1234)
474
+ att = @c1.new(:id => 345)
475
+ att.instance_variable_set(:@node, n)
476
+ att.node.should == n
477
+ n.remove_attribute(att)
478
+ att.node.should == nil
479
+ end
480
+
355
481
  it "should have has_many alias" do
356
482
  @c2.has_many :attributes, :class => @c1
357
483
 
@@ -405,6 +531,7 @@ describe Sequel::Model, "many_to_many" do
405
531
  @c1 = Class.new(Sequel::Model(:attributes)) do
406
532
  def self.name; 'Attribute'; end
407
533
  def self.to_s; 'Attribute'; end
534
+ columns :id
408
535
  end
409
536
 
410
537
  @c2 = Class.new(Sequel::Model(:nodes)) do
@@ -412,6 +539,7 @@ describe Sequel::Model, "many_to_many" do
412
539
 
413
540
  def self.name; 'Node'; end
414
541
  def self.to_s; 'Node'; end
542
+ columns :id
415
543
  end
416
544
  @dataset = @c2.dataset
417
545
 
@@ -450,6 +578,22 @@ describe Sequel::Model, "many_to_many" do
450
578
  ].should(include(a.sql))
451
579
  end
452
580
 
581
+ it "should use class inside module if given as a string" do
582
+ module Historical
583
+ class Tag < Sequel::Model
584
+ end
585
+ end
586
+
587
+ @c2.many_to_many :tags, :class=>'::Historical::Tag'
588
+
589
+ n = @c2.new(:id => 1234)
590
+ a = n.tags_dataset
591
+ a.should be_a_kind_of(Sequel::Dataset)
592
+ ['SELECT tags.* FROM tags INNER JOIN nodes_tags ON (nodes_tags.tag_id = tags.id) AND (nodes_tags.node_id = 1234)',
593
+ 'SELECT tags.* FROM tags INNER JOIN nodes_tags ON (nodes_tags.node_id = 1234) AND (nodes_tags.tag_id = tags.id)'
594
+ ].should(include(a.sql))
595
+ end
596
+
453
597
  it "should use explicit key values and join table if given" do
454
598
  @c2.many_to_many :attributes, :class => @c1, :left_key => :nodeid, :right_key => :attributeid, :join_table => :attribute2node
455
599
 
@@ -495,7 +639,7 @@ describe Sequel::Model, "many_to_many" do
495
639
  end
496
640
 
497
641
  it "should support an array for the select option" do
498
- @c2.many_to_many :attributes, :class => @c1, :select => [:attributes.all, :attribute_nodes__blah2]
642
+ @c2.many_to_many :attributes, :class => @c1, :select => [:attributes.*, :attribute_nodes__blah2]
499
643
 
500
644
  n = @c2.new(:id => 1234)
501
645
  a = n.attributes_dataset
@@ -616,6 +760,17 @@ describe Sequel::Model, "many_to_many" do
616
760
  a.should == [att]
617
761
  end
618
762
 
763
+ it "should add item to reciprocal cached instance variable if it exists when calling add_" do
764
+ @c2.many_to_many :attributes, :class => @c1
765
+ @c1.many_to_many :nodes, :class => @c2
766
+
767
+ n = @c2.new(:id => 1234)
768
+ att = @c1.new(:id => 345)
769
+ att.instance_variable_set(:@nodes, [])
770
+ n.add_attribute(att)
771
+ att.nodes.should == [n]
772
+ end
773
+
619
774
  it "should remove item from cached instance variable if it exists when calling remove_" do
620
775
  @c2.many_to_many :attributes, :class => @c1
621
776
 
@@ -628,6 +783,17 @@ describe Sequel::Model, "many_to_many" do
628
783
  a.should == []
629
784
  end
630
785
 
786
+ it "should remove item from reciprocal cached instance variable if it exists when calling remove_" do
787
+ @c2.many_to_many :attributes, :class => @c1
788
+ @c1.many_to_many :nodes, :class => @c2
789
+
790
+ n = @c2.new(:id => 1234)
791
+ att = @c1.new(:id => 345)
792
+ att.instance_variable_set(:@nodes, [n])
793
+ n.remove_attribute(att)
794
+ att.nodes.should == []
795
+ end
796
+
631
797
  it "should have has_and_belongs_to_many alias" do
632
798
  @c2.has_and_belongs_to_many :attributes, :class => @c1
633
799
 
data/spec/base_spec.rb CHANGED
@@ -6,9 +6,7 @@ describe "Model attribute setters" do
6
6
  MODEL_DB.reset
7
7
 
8
8
  @c = Class.new(Sequel::Model(:items)) do
9
- def columns
10
- [:id, :x, :y]
11
- end
9
+ columns :id, :x, :y
12
10
  end
13
11
  end
14
12
 
@@ -43,6 +41,7 @@ describe "Model#serialize" do
43
41
  @c = Class.new(Sequel::Model(:items)) do
44
42
  no_primary_key
45
43
  serialize :abc
44
+ columns :abc
46
45
  end
47
46
 
48
47
  @c.create(:abc => 1)
@@ -57,6 +56,7 @@ describe "Model#serialize" do
57
56
  it "should support calling after the class is defined" do
58
57
  @c = Class.new(Sequel::Model(:items)) do
59
58
  no_primary_key
59
+ columns :def
60
60
  end
61
61
 
62
62
  @c.serialize :def
@@ -74,6 +74,7 @@ describe "Model#serialize" do
74
74
  @c = Class.new(Sequel::Model(:items)) do
75
75
  no_primary_key
76
76
  serialize :abc, :format => :marshal
77
+ columns :abc
77
78
  end
78
79
 
79
80
  @c.create(:abc => 1)
@@ -88,6 +89,7 @@ describe "Model#serialize" do
88
89
  it "should translate values to and from YAML using accessor methods" do
89
90
  @c = Class.new(Sequel::Model(:items)) do
90
91
  serialize :abc, :def
92
+ columns :abc, :def
91
93
  end
92
94
 
93
95
  ds = @c.dataset
@@ -124,7 +126,7 @@ describe "Model#serialize" do
124
126
  o.abc.should == 1
125
127
  o.def.should == "hello"
126
128
 
127
- o.set(:abc => 23)
129
+ o.update_values(:abc => 23)
128
130
  ds.sqls.should == "UPDATE items SET abc = '#{23.to_yaml}' WHERE (id = 1)"
129
131
 
130
132
  ds.raw = {:id => 1, :abc => "--- 1\n", :def => "--- hello\n"}
@@ -134,21 +136,8 @@ describe "Model#serialize" do
134
136
 
135
137
  end
136
138
 
137
- describe Sequel::Model, "super_dataset" do
138
- setup do
139
- MODEL_DB.reset
140
- class SubClass < Sequel::Model(:items) ; end
141
- end
142
-
143
- it "should call the superclass's dataset" do
144
- SubClass.should_receive(:superclass).exactly(3).times.and_return(Sequel::Model(:items))
145
- Sequel::Model(:items).should_receive(:dataset)
146
- SubClass.super_dataset
147
- end
148
- end
149
-
150
139
  describe Sequel::Model, "dataset" do
151
- setup do
140
+ before do
152
141
  @a = Class.new(Sequel::Model(:items))
153
142
  @b = Class.new(Sequel::Model)
154
143
 
@@ -193,6 +182,36 @@ describe Sequel::Model, "dataset" do
193
182
  end
194
183
  end
195
184
 
185
+ describe Sequel::Model, "def_dataset_method" do
186
+ setup do
187
+ @c = Class.new(Sequel::Model(:items)) do
188
+ @dataset = Object.new
189
+ end
190
+ end
191
+
192
+ it "should add a method to the dataset and model if called with a block argument" do
193
+ @c.instance_eval do
194
+ def_dataset_method(:return_3){3}
195
+ end
196
+ @c.return_3.should == 3
197
+ @c.dataset.return_3.should == 3
198
+ end
199
+
200
+ it "should add all passed methods to the model if called without a block argument" do
201
+ @c.instance_eval do
202
+ def_dataset_method(:return_3, :return_4)
203
+ end
204
+ proc{@c.return_3}.should raise_error(NoMethodError)
205
+ proc{@c.return_4}.should raise_error(NoMethodError)
206
+ @c.dataset.instance_eval do
207
+ def return_3; 3; end
208
+ def return_4; 4; end
209
+ end
210
+ @c.return_3.should == 3
211
+ @c.return_4.should == 4
212
+ end
213
+ end
214
+
196
215
  describe "A model class with implicit table name" do
197
216
  setup do
198
217
  class Donkey < Sequel::Model
data/spec/caching_spec.rb CHANGED
@@ -16,9 +16,7 @@ describe Sequel::Model, "caching" do
16
16
  @c = Class.new(Sequel::Model(:items)) do
17
17
  set_cache cache
18
18
 
19
- def self.columns
20
- [:name, :id]
21
- end
19
+ columns :name, :id
22
20
  end
23
21
 
24
22
  $cache_dataset_row = {:name => 'sharon', :id => 1}
@@ -88,6 +86,11 @@ describe Sequel::Model, "caching" do
88
86
  proc {m.cache_key}.should_not raise_error(Sequel::Error)
89
87
  end
90
88
 
89
+ it "should not raise error if trying to save a new record" do
90
+ proc {@c.new(:name=>'blah').save}.should_not raise_error
91
+ proc {@c.create(:name=>'blah')}.should_not raise_error
92
+ end
93
+
91
94
  it "should set the cache when reading from the database" do
92
95
  $sqls.should == []
93
96
  @cache.should be_empty
@@ -109,7 +112,7 @@ describe Sequel::Model, "caching" do
109
112
  m = @c[1]
110
113
  @cache[m.cache_key].should == m
111
114
 
112
- m.set(:name => 'tutu')
115
+ m.update_values(:name => 'tutu')
113
116
  @cache.has_key?(m.cache_key).should be_false
114
117
  $sqls.last.should == "UPDATE items SET name = 'tutu' WHERE (id = 1)"
115
118
 
@@ -9,7 +9,7 @@ describe Sequel::Model, "one_to_one" do
9
9
  end
10
10
 
11
11
  @c2 = Class.new(Sequel::Model(:nodes)) do
12
- def columns; [:id, :parent_id]; end
12
+ columns :id, :parent_id, :blah
13
13
  end
14
14
 
15
15
  @dataset = @c2.dataset
@@ -44,28 +44,6 @@ describe Sequel::Model, "one_to_one" do
44
44
  MODEL_DB.sqls.should == ["SELECT * FROM nodes WHERE (id = 567) LIMIT 1"]
45
45
  end
46
46
 
47
- # the new implementation doesn't support plain datasets as associations
48
- # it "should support plain dataset in the from option" do
49
- # @c2.one_to_one :parent, :from => MODEL_DB[:xyz]
50
- #
51
- # d = @c2.new(:id => 1, :parent_id => 789)
52
- # p = d.parent
53
- # p.class.should == Hash
54
- #
55
- # MODEL_DB.sqls.should == ["SELECT * FROM xyz WHERE (id = 789) LIMIT 1"]
56
- # end
57
-
58
- # the new implementation doesn't support plain datasets as associations
59
- # it "should support table name in the from option" do
60
- # @c2.one_to_one :parent, :from => :abc
61
- #
62
- # d = @c2.new(:id => 1, :parent_id => 789)
63
- # p = d.parent
64
- # p.class.should == Hash
65
- #
66
- # MODEL_DB.sqls.should == ["SELECT * FROM abc WHERE (id = 789) LIMIT 1"]
67
- # end
68
-
69
47
  it "should return nil if key value is nil" do
70
48
  @c2.one_to_one :parent, :from => @c2
71
49
 
@@ -104,6 +82,7 @@ describe Sequel::Model, "one_to_many" do
104
82
  end
105
83
 
106
84
  @c2 = Class.new(Sequel::Model(:nodes)) do
85
+ columns :id
107
86
  end
108
87
  end
109
88
 
@@ -116,32 +95,13 @@ describe Sequel::Model, "one_to_many" do
116
95
  a.sql.should == 'SELECT * FROM attributes WHERE (node_id = 1234)'
117
96
  end
118
97
 
119
- # the new implementation doesn't support plain datasets as associations
120
- # it "should support plain dataset in the from option" do
121
- # @c2.one_to_many :attributes, :from => MODEL_DB[:xyz], :key => :node_id
122
- #
123
- # n = @c2.new(:id => 1234)
124
- # a = n.attributes
125
- # a.should be_a_kind_of(Sequel::Dataset)
126
- # a.sql.should == 'SELECT * FROM xyz WHERE (node_id = 1234)'
127
- # end
128
-
129
- # the new implementation doesn't support plain datasets as associations
130
- # it "should support table name in the from option" do
131
- # @c2.one_to_many :attributes, :from => :abc, :key => :node_id
132
- #
133
- # n = @c2.new(:id => 1234)
134
- # a = n.attributes
135
- # a.should be_a_kind_of(Sequel::Dataset)
136
- # a.sql.should == 'SELECT * FROM abc WHERE (node_id = 1234)'
137
- # end
138
-
139
98
  it "should support implicit key names" do
140
99
  $c1 = @c1
141
100
 
142
101
  module Music
143
102
  class BlueNote < Sequel::Model
144
103
  one_to_many :attributes, :from => $c1
104
+ columns :id
145
105
  end
146
106
  end
147
107