sequel_model 0.5.0.2 → 3.8.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.
- metadata +22 -69
- data/CHANGELOG +0 -111
- data/COPYING +0 -18
- data/README +0 -251
- data/Rakefile +0 -152
- data/lib/sequel_model.rb +0 -323
- data/lib/sequel_model/associations.rb +0 -325
- data/lib/sequel_model/base.rb +0 -119
- data/lib/sequel_model/caching.rb +0 -42
- data/lib/sequel_model/hooks.rb +0 -55
- data/lib/sequel_model/plugins.rb +0 -47
- data/lib/sequel_model/pretty_table.rb +0 -73
- data/lib/sequel_model/record.rb +0 -330
- data/lib/sequel_model/schema.rb +0 -48
- data/lib/sequel_model/validations.rb +0 -15
- data/spec/associations_spec.rb +0 -627
- data/spec/base_spec.rb +0 -239
- data/spec/caching_spec.rb +0 -150
- data/spec/deprecated_relations_spec.rb +0 -153
- data/spec/hooks_spec.rb +0 -269
- data/spec/model_spec.rb +0 -543
- data/spec/plugins_spec.rb +0 -74
- data/spec/rcov.opts +0 -4
- data/spec/record_spec.rb +0 -575
- data/spec/schema_spec.rb +0 -69
- data/spec/spec.opts +0 -5
- data/spec/spec_helper.rb +0 -43
- data/spec/validations_spec.rb +0 -246
data/spec/hooks_spec.rb
DELETED
@@ -1,269 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), "spec_helper")
|
2
|
-
|
3
|
-
describe "Model hooks" do
|
4
|
-
before do
|
5
|
-
MODEL_DB.reset
|
6
|
-
|
7
|
-
@hooks = [
|
8
|
-
:after_initialize,
|
9
|
-
:before_create,
|
10
|
-
:after_create,
|
11
|
-
:before_update,
|
12
|
-
:after_update,
|
13
|
-
:before_save,
|
14
|
-
:after_save,
|
15
|
-
:before_destroy,
|
16
|
-
:after_destroy
|
17
|
-
]
|
18
|
-
|
19
|
-
# @hooks.each {|h| Sequel::Model.class_def(h) {}}
|
20
|
-
end
|
21
|
-
|
22
|
-
specify "should be definable using def <hook name>" do
|
23
|
-
c = Class.new(Sequel::Model) do
|
24
|
-
def before_save
|
25
|
-
"hi there"
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
c.new.before_save.should == 'hi there'
|
30
|
-
end
|
31
|
-
|
32
|
-
specify "should be definable using a block" do
|
33
|
-
$adds = []
|
34
|
-
c = Class.new(Sequel::Model) do
|
35
|
-
before_save {$adds << 'hi'}
|
36
|
-
end
|
37
|
-
|
38
|
-
c.new.before_save
|
39
|
-
$adds.should == ['hi']
|
40
|
-
end
|
41
|
-
|
42
|
-
specify "should be definable using a method name" do
|
43
|
-
$adds = []
|
44
|
-
c = Class.new(Sequel::Model) do
|
45
|
-
def bye; $adds << 'bye'; end
|
46
|
-
before_save :bye
|
47
|
-
end
|
48
|
-
|
49
|
-
c.new.before_save
|
50
|
-
$adds.should == ['bye']
|
51
|
-
end
|
52
|
-
|
53
|
-
specify "should be additive" do
|
54
|
-
$adds = []
|
55
|
-
c = Class.new(Sequel::Model) do
|
56
|
-
before_save {$adds << 'hyiyie'}
|
57
|
-
before_save {$adds << 'byiyie'}
|
58
|
-
end
|
59
|
-
|
60
|
-
c.new.before_save
|
61
|
-
$adds.should == ['hyiyie', 'byiyie']
|
62
|
-
end
|
63
|
-
|
64
|
-
specify "should be inheritable" do
|
65
|
-
# pending
|
66
|
-
|
67
|
-
$adds = []
|
68
|
-
a = Class.new(Sequel::Model) do
|
69
|
-
before_save {$adds << '123'}
|
70
|
-
end
|
71
|
-
|
72
|
-
b = Class.new(a) do
|
73
|
-
before_save {$adds << '456'}
|
74
|
-
before_save {$adds << '789'}
|
75
|
-
end
|
76
|
-
|
77
|
-
b.new.before_save
|
78
|
-
$adds.should == ['123', '456', '789']
|
79
|
-
end
|
80
|
-
|
81
|
-
specify "should be overridable in descendant classes" do
|
82
|
-
$adds = []
|
83
|
-
a = Class.new(Sequel::Model) do
|
84
|
-
before_save {$adds << '123'}
|
85
|
-
end
|
86
|
-
|
87
|
-
b = Class.new(a) do
|
88
|
-
def before_save; $adds << '456'; end
|
89
|
-
end
|
90
|
-
|
91
|
-
a.new.before_save
|
92
|
-
$adds.should == ['123']
|
93
|
-
$adds = []
|
94
|
-
b.new.before_save
|
95
|
-
$adds.should == ['456']
|
96
|
-
end
|
97
|
-
|
98
|
-
specify "should stop processing if a hook returns false" do
|
99
|
-
$flag = true
|
100
|
-
$adds = []
|
101
|
-
|
102
|
-
a = Class.new(Sequel::Model) do
|
103
|
-
before_save {$adds << 'blah'; $flag}
|
104
|
-
before_save {$adds << 'cruel'}
|
105
|
-
end
|
106
|
-
|
107
|
-
a.new.before_save
|
108
|
-
$adds.should == ['blah', 'cruel']
|
109
|
-
|
110
|
-
# chain should not break on nil
|
111
|
-
$adds = []
|
112
|
-
$flag = nil
|
113
|
-
a.new.before_save
|
114
|
-
$adds.should == ['blah', 'cruel']
|
115
|
-
|
116
|
-
$adds = []
|
117
|
-
$flag = false
|
118
|
-
a.new.before_save
|
119
|
-
$adds.should == ['blah']
|
120
|
-
|
121
|
-
b = Class.new(a) do
|
122
|
-
before_save {$adds << 'mau'}
|
123
|
-
end
|
124
|
-
|
125
|
-
$adds = []
|
126
|
-
b.new.before_save
|
127
|
-
$adds.should == ['blah']
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
describe "Model#after_initialize" do
|
132
|
-
specify "should be called after initialization" do
|
133
|
-
$values1 = nil
|
134
|
-
|
135
|
-
a = Class.new(Sequel::Model) do
|
136
|
-
after_initialize do
|
137
|
-
$values1 = @values.clone
|
138
|
-
raise Sequel::Error if @values[:blow]
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
a.new(:x => 1, :y => 2)
|
143
|
-
$values1.should == {:x => 1, :y => 2}
|
144
|
-
|
145
|
-
proc {a.new(:blow => true)}.should raise_error(Sequel::Error)
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
describe "Model#before_create && Model#after_create" do
|
150
|
-
setup do
|
151
|
-
MODEL_DB.reset
|
152
|
-
|
153
|
-
@c = Class.new(Sequel::Model(:items)) do
|
154
|
-
no_primary_key
|
155
|
-
|
156
|
-
before_create {MODEL_DB << "BLAH before"}
|
157
|
-
after_create {MODEL_DB << "BLAH after"}
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
|
-
specify "should be called around new record creation" do
|
162
|
-
@c.create(:x => 2)
|
163
|
-
MODEL_DB.sqls.should == [
|
164
|
-
'BLAH before',
|
165
|
-
'INSERT INTO items (x) VALUES (2)',
|
166
|
-
'BLAH after'
|
167
|
-
]
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
describe "Model#before_update && Model#after_update" do
|
172
|
-
setup do
|
173
|
-
MODEL_DB.reset
|
174
|
-
|
175
|
-
@c = Class.new(Sequel::Model(:items)) do
|
176
|
-
before_update {MODEL_DB << "BLAH before"}
|
177
|
-
after_update {MODEL_DB << "BLAH after"}
|
178
|
-
end
|
179
|
-
end
|
180
|
-
|
181
|
-
specify "should be called around record update" do
|
182
|
-
m = @c.load(:id => 2233)
|
183
|
-
m.save
|
184
|
-
MODEL_DB.sqls.should == [
|
185
|
-
'BLAH before',
|
186
|
-
'UPDATE items SET id = 2233 WHERE (id = 2233)',
|
187
|
-
'BLAH after'
|
188
|
-
]
|
189
|
-
end
|
190
|
-
end
|
191
|
-
|
192
|
-
describe "Model#before_save && Model#after_save" do
|
193
|
-
setup do
|
194
|
-
MODEL_DB.reset
|
195
|
-
|
196
|
-
@c = Class.new(Sequel::Model(:items)) do
|
197
|
-
before_save {MODEL_DB << "BLAH before"}
|
198
|
-
after_save {MODEL_DB << "BLAH after"}
|
199
|
-
end
|
200
|
-
end
|
201
|
-
|
202
|
-
specify "should be called around record update" do
|
203
|
-
m = @c.load(:id => 2233)
|
204
|
-
m.save
|
205
|
-
MODEL_DB.sqls.should == [
|
206
|
-
'BLAH before',
|
207
|
-
'UPDATE items SET id = 2233 WHERE (id = 2233)',
|
208
|
-
'BLAH after'
|
209
|
-
]
|
210
|
-
end
|
211
|
-
|
212
|
-
specify "should be called around record creation" do
|
213
|
-
@c.no_primary_key
|
214
|
-
@c.create(:x => 2)
|
215
|
-
MODEL_DB.sqls.should == [
|
216
|
-
'BLAH before',
|
217
|
-
'INSERT INTO items (x) VALUES (2)',
|
218
|
-
'BLAH after'
|
219
|
-
]
|
220
|
-
end
|
221
|
-
end
|
222
|
-
|
223
|
-
describe "Model#before_destroy && Model#after_destroy" do
|
224
|
-
setup do
|
225
|
-
MODEL_DB.reset
|
226
|
-
|
227
|
-
@c = Class.new(Sequel::Model(:items)) do
|
228
|
-
before_destroy {MODEL_DB << "BLAH before"}
|
229
|
-
after_destroy {MODEL_DB << "BLAH after"}
|
230
|
-
|
231
|
-
def delete
|
232
|
-
MODEL_DB << "DELETE BLAH"
|
233
|
-
end
|
234
|
-
end
|
235
|
-
end
|
236
|
-
|
237
|
-
specify "should be called around record update" do
|
238
|
-
m = @c.new(:id => 2233)
|
239
|
-
m.destroy
|
240
|
-
MODEL_DB.sqls.should == [
|
241
|
-
'BLAH before',
|
242
|
-
'DELETE BLAH',
|
243
|
-
'BLAH after'
|
244
|
-
]
|
245
|
-
end
|
246
|
-
end
|
247
|
-
|
248
|
-
describe "Model#has_hooks?" do
|
249
|
-
setup do
|
250
|
-
@c = Class.new(Sequel::Model)
|
251
|
-
end
|
252
|
-
|
253
|
-
specify "should return false if no hooks are defined" do
|
254
|
-
@c.has_hooks?(:before_save).should be_false
|
255
|
-
end
|
256
|
-
|
257
|
-
specify "should return true if hooks are defined" do
|
258
|
-
@c.before_save {'blah'}
|
259
|
-
@c.has_hooks?(:before_save).should be_true
|
260
|
-
end
|
261
|
-
|
262
|
-
specify "should return true if hooks are inherited" do
|
263
|
-
@d = Class.new(@c)
|
264
|
-
@d.has_hooks?(:before_save).should be_false
|
265
|
-
|
266
|
-
@c.before_save :blah
|
267
|
-
@d.has_hooks?(:before_save).should be_true
|
268
|
-
end
|
269
|
-
end
|
data/spec/model_spec.rb
DELETED
@@ -1,543 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), "spec_helper")
|
2
|
-
|
3
|
-
describe Sequel::Model do
|
4
|
-
it "should have class method aliased as model" do
|
5
|
-
Sequel::Model.instance_methods.should include("model")
|
6
|
-
|
7
|
-
model_a = Class.new Sequel::Model
|
8
|
-
model_a.new.model.should be(model_a)
|
9
|
-
end
|
10
|
-
|
11
|
-
it "should be associated with a dataset" do
|
12
|
-
model_a = Class.new(Sequel::Model) { set_dataset MODEL_DB[:as] }
|
13
|
-
|
14
|
-
model_a.dataset.should be_a_kind_of(MockDataset)
|
15
|
-
model_a.dataset.opts[:from].should == [:as]
|
16
|
-
|
17
|
-
model_b = Class.new(Sequel::Model) { set_dataset MODEL_DB[:bs] }
|
18
|
-
|
19
|
-
model_b.dataset.should be_a_kind_of(MockDataset)
|
20
|
-
model_b.dataset.opts[:from].should == [:bs]
|
21
|
-
|
22
|
-
model_a.dataset.opts[:from].should == [:as]
|
23
|
-
end
|
24
|
-
|
25
|
-
end
|
26
|
-
|
27
|
-
describe Sequel::Model, "dataset & schema" do
|
28
|
-
|
29
|
-
before do
|
30
|
-
@model = Class.new(Sequel::Model(:items))
|
31
|
-
end
|
32
|
-
|
33
|
-
it "creates dynamic model subclass with set table name" do
|
34
|
-
@model.table_name.should == :items
|
35
|
-
end
|
36
|
-
|
37
|
-
it "defaults to primary key of id" do
|
38
|
-
@model.primary_key.should == :id
|
39
|
-
end
|
40
|
-
|
41
|
-
it "allow primary key change" do
|
42
|
-
@model.set_primary_key :ssn
|
43
|
-
@model.primary_key.should == :ssn
|
44
|
-
end
|
45
|
-
|
46
|
-
it "allows dataset change" do
|
47
|
-
@model.set_dataset(MODEL_DB[:foo])
|
48
|
-
@model.table_name.should == :foo
|
49
|
-
end
|
50
|
-
|
51
|
-
it "sets schema with implicit table name" do
|
52
|
-
@model.set_schema do
|
53
|
-
primary_key :ssn, :string
|
54
|
-
end
|
55
|
-
@model.primary_key.should == :ssn
|
56
|
-
@model.table_name.should == :items
|
57
|
-
end
|
58
|
-
|
59
|
-
it "sets schema with explicit table name" do
|
60
|
-
@model.set_schema :foo do
|
61
|
-
primary_key :id
|
62
|
-
end
|
63
|
-
@model.primary_key.should == :id
|
64
|
-
@model.table_name.should == :foo
|
65
|
-
end
|
66
|
-
|
67
|
-
it "puts the lotion in the basket or it gets the hose again" do
|
68
|
-
# just kidding!
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
describe Sequel::Model, "constructor" do
|
73
|
-
|
74
|
-
before(:each) do
|
75
|
-
@m = Class.new(Sequel::Model)
|
76
|
-
end
|
77
|
-
|
78
|
-
it "should accept a hash" do
|
79
|
-
m = @m.new(:a => 1, :b => 2)
|
80
|
-
m.values.should == {:a => 1, :b => 2}
|
81
|
-
m.should be_new
|
82
|
-
end
|
83
|
-
|
84
|
-
it "should accept a block and yield itself to the block" do
|
85
|
-
block_called = false
|
86
|
-
m = @m.new {|i| block_called = true; i.should be_a_kind_of(@m); i.values[:a] = 1}
|
87
|
-
|
88
|
-
block_called.should be_true
|
89
|
-
m.values[:a].should == 1
|
90
|
-
end
|
91
|
-
|
92
|
-
end
|
93
|
-
|
94
|
-
describe Sequel::Model, "new" do
|
95
|
-
|
96
|
-
before(:each) do
|
97
|
-
@m = Class.new(Sequel::Model) do
|
98
|
-
set_dataset MODEL_DB[:items]
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
it "should be marked as new?" do
|
103
|
-
o = @m.new
|
104
|
-
o.should be_new
|
105
|
-
o.should be_new_record
|
106
|
-
end
|
107
|
-
|
108
|
-
it "should not be marked as new? once it is saved" do
|
109
|
-
o = @m.new(:x => 1)
|
110
|
-
o.should be_new
|
111
|
-
o.save
|
112
|
-
o.should_not be_new
|
113
|
-
o.should_not be_new_record
|
114
|
-
end
|
115
|
-
|
116
|
-
it "should use the last inserted id as primary key if not in values" do
|
117
|
-
d = @m.dataset
|
118
|
-
def d.insert(*args)
|
119
|
-
super
|
120
|
-
1234
|
121
|
-
end
|
122
|
-
|
123
|
-
def d.first
|
124
|
-
{:x => 1, :id => 1234}
|
125
|
-
end
|
126
|
-
|
127
|
-
o = @m.new(:x => 1)
|
128
|
-
o.save
|
129
|
-
o.id.should == 1234
|
130
|
-
|
131
|
-
o = @m.load(:x => 1, :id => 333)
|
132
|
-
o.save
|
133
|
-
o.id.should == 333
|
134
|
-
end
|
135
|
-
|
136
|
-
end
|
137
|
-
|
138
|
-
describe Sequel::Model, ".subset" do
|
139
|
-
|
140
|
-
before(:each) do
|
141
|
-
MODEL_DB.reset
|
142
|
-
|
143
|
-
@c = Class.new(Sequel::Model(:items))
|
144
|
-
end
|
145
|
-
|
146
|
-
it "should create a filter on the underlying dataset" do
|
147
|
-
proc {@c.new_only}.should raise_error(NoMethodError)
|
148
|
-
|
149
|
-
@c.subset(:new_only) {:age == 'new'}
|
150
|
-
|
151
|
-
@c.new_only.sql.should == "SELECT * FROM items WHERE (age = 'new')"
|
152
|
-
@c.dataset.new_only.sql.should == "SELECT * FROM items WHERE (age = 'new')"
|
153
|
-
|
154
|
-
@c.subset(:pricey) {:price > 100}
|
155
|
-
|
156
|
-
@c.pricey.sql.should == "SELECT * FROM items WHERE (price > 100)"
|
157
|
-
@c.dataset.pricey.sql.should == "SELECT * FROM items WHERE (price > 100)"
|
158
|
-
|
159
|
-
# check if subsets are composable
|
160
|
-
@c.pricey.new_only.sql.should == "SELECT * FROM items WHERE (price > 100) AND (age = 'new')"
|
161
|
-
@c.new_only.pricey.sql.should == "SELECT * FROM items WHERE (age = 'new') AND (price > 100)"
|
162
|
-
end
|
163
|
-
|
164
|
-
end
|
165
|
-
|
166
|
-
describe Sequel::Model, ".find" do
|
167
|
-
|
168
|
-
before(:each) do
|
169
|
-
MODEL_DB.reset
|
170
|
-
|
171
|
-
@c = Class.new(Sequel::Model(:items))
|
172
|
-
|
173
|
-
$cache_dataset_row = {:name => 'sharon', :id => 1}
|
174
|
-
@dataset = @c.dataset
|
175
|
-
$sqls = []
|
176
|
-
@dataset.extend(Module.new {
|
177
|
-
def fetch_rows(sql)
|
178
|
-
$sqls << sql
|
179
|
-
yield $cache_dataset_row
|
180
|
-
end
|
181
|
-
})
|
182
|
-
end
|
183
|
-
|
184
|
-
it "should return the first record matching the given filter" do
|
185
|
-
@c.find(:name => 'sharon').should be_a_kind_of(@c)
|
186
|
-
$sqls.last.should == "SELECT * FROM items WHERE (name = 'sharon') LIMIT 1"
|
187
|
-
|
188
|
-
@c.find {"name LIKE 'abc%'".lit}.should be_a_kind_of(@c)
|
189
|
-
$sqls.last.should == "SELECT * FROM items WHERE name LIKE 'abc%' LIMIT 1"
|
190
|
-
end
|
191
|
-
|
192
|
-
it "should accept filter blocks" do
|
193
|
-
@c.find {:id == 1}.should be_a_kind_of(@c)
|
194
|
-
$sqls.last.should == "SELECT * FROM items WHERE (id = 1) LIMIT 1"
|
195
|
-
|
196
|
-
@c.find {:x > 1 && :y < 2}.should be_a_kind_of(@c)
|
197
|
-
$sqls.last.should == "SELECT * FROM items WHERE ((x > 1) AND (y < 2)) LIMIT 1"
|
198
|
-
end
|
199
|
-
|
200
|
-
end
|
201
|
-
|
202
|
-
describe Sequel::Model, ".fetch" do
|
203
|
-
|
204
|
-
before(:each) do
|
205
|
-
MODEL_DB.reset
|
206
|
-
@c = Class.new(Sequel::Model(:items))
|
207
|
-
end
|
208
|
-
|
209
|
-
it "should return instances of Model" do
|
210
|
-
@c.fetch("SELECT * FROM items").first.should be_a_kind_of(@c)
|
211
|
-
end
|
212
|
-
|
213
|
-
it "should return true for .empty? and not raise an error on empty selection" do
|
214
|
-
rows = @c.fetch("SELECT * FROM items WHERE FALSE")
|
215
|
-
@c.class_def(:fetch_rows) {|sql| yield({:count => 0})}
|
216
|
-
proc {rows.empty?}.should_not raise_error
|
217
|
-
end
|
218
|
-
|
219
|
-
end
|
220
|
-
|
221
|
-
describe Sequel::Model, "magic methods" do
|
222
|
-
|
223
|
-
before(:each) do
|
224
|
-
@c = Class.new(Sequel::Dataset) do
|
225
|
-
@@sqls = []
|
226
|
-
|
227
|
-
def self.sqls; @@sqls; end
|
228
|
-
|
229
|
-
def fetch_rows(sql)
|
230
|
-
@@sqls << sql
|
231
|
-
yield({:id => 123, :name => 'hey'})
|
232
|
-
end
|
233
|
-
end
|
234
|
-
|
235
|
-
@m = Class.new(Sequel::Model(@c.new(nil).from(:items)))
|
236
|
-
end
|
237
|
-
|
238
|
-
it "should support order_by_xxx" do
|
239
|
-
@m.order_by_name.should be_a_kind_of(@c)
|
240
|
-
@m.order_by_name.sql.should == "SELECT * FROM items ORDER BY name"
|
241
|
-
end
|
242
|
-
|
243
|
-
it "should support group_by_xxx" do
|
244
|
-
@m.group_by_name.should be_a_kind_of(@c)
|
245
|
-
@m.group_by_name.sql.should == "SELECT * FROM items GROUP BY name"
|
246
|
-
end
|
247
|
-
|
248
|
-
it "should support count_by_xxx" do
|
249
|
-
@m.count_by_name.should be_a_kind_of(@c)
|
250
|
-
@m.count_by_name.sql.should == "SELECT name, count(*) AS count FROM items GROUP BY name ORDER BY count"
|
251
|
-
end
|
252
|
-
|
253
|
-
it "should support filter_by_xxx" do
|
254
|
-
@m.filter_by_name('sharon').should be_a_kind_of(@c)
|
255
|
-
@m.filter_by_name('sharon').sql.should == "SELECT * FROM items WHERE (name = 'sharon')"
|
256
|
-
end
|
257
|
-
|
258
|
-
it "should support all_by_xxx" do
|
259
|
-
all = @m.all_by_name('sharon')
|
260
|
-
all.class.should == Array
|
261
|
-
all.size.should == 1
|
262
|
-
all.first.should be_a_kind_of(@m)
|
263
|
-
all.first.values.should == {:id => 123, :name => 'hey'}
|
264
|
-
@c.sqls.should == ["SELECT * FROM items WHERE (name = 'sharon')"]
|
265
|
-
end
|
266
|
-
|
267
|
-
it "should support find_by_xxx" do
|
268
|
-
@m.find_by_name('sharon').should be_a_kind_of(@m)
|
269
|
-
@m.find_by_name('sharon').values.should == {:id => 123, :name => 'hey'}
|
270
|
-
@c.sqls.should == ["SELECT * FROM items WHERE (name = 'sharon') LIMIT 1"] * 2
|
271
|
-
end
|
272
|
-
|
273
|
-
it "should support first_by_xxx" do
|
274
|
-
@m.first_by_name('sharon').should be_a_kind_of(@m)
|
275
|
-
@m.first_by_name('sharon').values.should == {:id => 123, :name => 'hey'}
|
276
|
-
@c.sqls.should == ["SELECT * FROM items ORDER BY name LIMIT 1"] * 2
|
277
|
-
end
|
278
|
-
|
279
|
-
it "should support last_by_xxx" do
|
280
|
-
@m.last_by_name('sharon').should be_a_kind_of(@m)
|
281
|
-
@m.last_by_name('sharon').values.should == {:id => 123, :name => 'hey'}
|
282
|
-
@c.sqls.should == ["SELECT * FROM items ORDER BY name DESC LIMIT 1"] * 2
|
283
|
-
end
|
284
|
-
|
285
|
-
end
|
286
|
-
|
287
|
-
describe Sequel::Model, ".find_or_create" do
|
288
|
-
|
289
|
-
before(:each) do
|
290
|
-
MODEL_DB.reset
|
291
|
-
@c = Class.new(Sequel::Model(:items)) do
|
292
|
-
no_primary_key
|
293
|
-
end
|
294
|
-
end
|
295
|
-
|
296
|
-
it "should find the record" do
|
297
|
-
@c.find_or_create(:x => 1)
|
298
|
-
MODEL_DB.sqls.should == ["SELECT * FROM items WHERE (x = 1) LIMIT 1"]
|
299
|
-
|
300
|
-
MODEL_DB.reset
|
301
|
-
end
|
302
|
-
|
303
|
-
it "should create the record if not found" do
|
304
|
-
@c.meta_def(:find) do |*args|
|
305
|
-
dataset.filter(*args).first
|
306
|
-
nil
|
307
|
-
end
|
308
|
-
|
309
|
-
@c.find_or_create(:x => 1)
|
310
|
-
MODEL_DB.sqls.should == [
|
311
|
-
"SELECT * FROM items WHERE (x = 1) LIMIT 1",
|
312
|
-
"INSERT INTO items (x) VALUES (1)"
|
313
|
-
]
|
314
|
-
end
|
315
|
-
end
|
316
|
-
|
317
|
-
describe Sequel::Model, ".delete_all" do
|
318
|
-
|
319
|
-
before(:each) do
|
320
|
-
MODEL_DB.reset
|
321
|
-
@c = Class.new(Sequel::Model(:items)) do
|
322
|
-
no_primary_key
|
323
|
-
end
|
324
|
-
|
325
|
-
@c.dataset.meta_def(:delete) {MODEL_DB << delete_sql}
|
326
|
-
end
|
327
|
-
|
328
|
-
it "should delete all records in the dataset" do
|
329
|
-
@c.delete_all
|
330
|
-
MODEL_DB.sqls.should == ["DELETE FROM items"]
|
331
|
-
end
|
332
|
-
|
333
|
-
end
|
334
|
-
|
335
|
-
describe Sequel::Model, ".destroy_all" do
|
336
|
-
|
337
|
-
before(:each) do
|
338
|
-
MODEL_DB.reset
|
339
|
-
@c = Class.new(Sequel::Model(:items)) do
|
340
|
-
no_primary_key
|
341
|
-
end
|
342
|
-
|
343
|
-
@c.dataset.meta_def(:delete) {MODEL_DB << delete_sql}
|
344
|
-
end
|
345
|
-
|
346
|
-
it "should delete all records in the dataset" do
|
347
|
-
@c.dataset.meta_def(:destroy) {MODEL_DB << "DESTROY this stuff"}
|
348
|
-
@c.destroy_all
|
349
|
-
MODEL_DB.sqls.should == ["DESTROY this stuff"]
|
350
|
-
end
|
351
|
-
|
352
|
-
it "should call dataset.destroy" do
|
353
|
-
@c.dataset.should_receive(:destroy).and_return(true)
|
354
|
-
@c.destroy_all
|
355
|
-
end
|
356
|
-
end
|
357
|
-
|
358
|
-
describe Sequel::Model, ".join" do
|
359
|
-
|
360
|
-
before(:each) do
|
361
|
-
MODEL_DB.reset
|
362
|
-
@c = Class.new(Sequel::Model(:items)) do
|
363
|
-
no_primary_key
|
364
|
-
end
|
365
|
-
end
|
366
|
-
|
367
|
-
it "should format proper SQL" do
|
368
|
-
@c.join(:atts, :item_id => :id).sql.should == \
|
369
|
-
"SELECT items.* FROM items INNER JOIN atts ON (atts.item_id = items.id)"
|
370
|
-
end
|
371
|
-
|
372
|
-
end
|
373
|
-
|
374
|
-
describe Sequel::Model, ".all" do
|
375
|
-
|
376
|
-
before(:each) do
|
377
|
-
MODEL_DB.reset
|
378
|
-
@c = Class.new(Sequel::Model(:items)) do
|
379
|
-
no_primary_key
|
380
|
-
end
|
381
|
-
|
382
|
-
@c.dataset.meta_def(:all) {1234}
|
383
|
-
end
|
384
|
-
|
385
|
-
it "should return all records in the dataset" do
|
386
|
-
@c.all.should == 1234
|
387
|
-
end
|
388
|
-
|
389
|
-
end
|
390
|
-
|
391
|
-
class DummyModelBased < Sequel::Model(:blog)
|
392
|
-
end
|
393
|
-
|
394
|
-
describe Sequel::Model, "(:tablename)" do
|
395
|
-
|
396
|
-
it "should allow reopening of descendant classes" do
|
397
|
-
proc do
|
398
|
-
eval "class DummyModelBased < Sequel::Model(:blog); end"
|
399
|
-
end.should_not raise_error
|
400
|
-
end
|
401
|
-
|
402
|
-
end
|
403
|
-
|
404
|
-
describe Sequel::Model, "A model class without a primary key" do
|
405
|
-
|
406
|
-
before(:each) do
|
407
|
-
MODEL_DB.reset
|
408
|
-
@c = Class.new(Sequel::Model(:items)) do
|
409
|
-
no_primary_key
|
410
|
-
end
|
411
|
-
end
|
412
|
-
|
413
|
-
it "should be able to insert records without selecting them back" do
|
414
|
-
i = nil
|
415
|
-
proc {i = @c.create(:x => 1)}.should_not raise_error
|
416
|
-
i.class.should be(@c)
|
417
|
-
i.values.to_hash.should == {:x => 1}
|
418
|
-
|
419
|
-
MODEL_DB.sqls.should == ['INSERT INTO items (x) VALUES (1)']
|
420
|
-
end
|
421
|
-
|
422
|
-
it "should raise when deleting" do
|
423
|
-
o = @c.new
|
424
|
-
proc {o.delete}.should raise_error
|
425
|
-
end
|
426
|
-
|
427
|
-
it "should insert a record when saving" do
|
428
|
-
o = @c.new(:x => 2)
|
429
|
-
o.should be_new
|
430
|
-
o.save
|
431
|
-
MODEL_DB.sqls.should == ['INSERT INTO items (x) VALUES (2)']
|
432
|
-
end
|
433
|
-
|
434
|
-
end
|
435
|
-
|
436
|
-
describe Sequel::Model, "attribute accessors" do
|
437
|
-
|
438
|
-
before(:each) do
|
439
|
-
MODEL_DB.reset
|
440
|
-
|
441
|
-
@c = Class.new(Sequel::Model(:items)) do
|
442
|
-
end
|
443
|
-
|
444
|
-
@c.dataset.meta_def(:columns) {[:id, :x, :y]}
|
445
|
-
end
|
446
|
-
|
447
|
-
it "should be created dynamically" do
|
448
|
-
o = @c.new
|
449
|
-
|
450
|
-
o.should_not be_respond_to(:x)
|
451
|
-
o.x.should be_nil
|
452
|
-
o.should be_respond_to(:x)
|
453
|
-
|
454
|
-
o.should_not be_respond_to(:x=)
|
455
|
-
o.x = 34
|
456
|
-
o.x.should == 34
|
457
|
-
o.should be_respond_to(:x=)
|
458
|
-
end
|
459
|
-
|
460
|
-
it "should raise for a column that doesn't exist in the dataset" do
|
461
|
-
o = @c.new
|
462
|
-
|
463
|
-
proc {o.x}.should_not raise_error
|
464
|
-
proc {o.xx}.should raise_error(Sequel::Error)
|
465
|
-
|
466
|
-
proc {o.x = 3}.should_not raise_error
|
467
|
-
proc {o.yy = 4}.should raise_error(Sequel::Error)
|
468
|
-
|
469
|
-
proc {o.yy?}.should raise_error(NoMethodError)
|
470
|
-
end
|
471
|
-
|
472
|
-
it "should not raise for a column not in the dataset, but for which there's a value" do
|
473
|
-
o = @c.new
|
474
|
-
|
475
|
-
proc {o.xx}.should raise_error(Sequel::Error)
|
476
|
-
proc {o.yy}.should raise_error(Sequel::Error)
|
477
|
-
|
478
|
-
o.values[:xx] = 123
|
479
|
-
o.values[:yy] = nil
|
480
|
-
|
481
|
-
proc {o.xx; o.yy}.should_not raise_error(Sequel::Error)
|
482
|
-
|
483
|
-
o.xx.should == 123
|
484
|
-
o.yy.should == nil
|
485
|
-
|
486
|
-
proc {o.xx = 3}.should_not raise_error(Sequel::Error)
|
487
|
-
end
|
488
|
-
end
|
489
|
-
|
490
|
-
describe Sequel::Model, ".[]" do
|
491
|
-
|
492
|
-
before(:each) do
|
493
|
-
MODEL_DB.reset
|
494
|
-
|
495
|
-
@c = Class.new(Sequel::Model(:items))
|
496
|
-
|
497
|
-
$cache_dataset_row = {:name => 'sharon', :id => 1}
|
498
|
-
@dataset = @c.dataset
|
499
|
-
$sqls = []
|
500
|
-
@dataset.extend(Module.new {
|
501
|
-
def fetch_rows(sql)
|
502
|
-
$sqls << sql
|
503
|
-
yield $cache_dataset_row
|
504
|
-
end
|
505
|
-
})
|
506
|
-
end
|
507
|
-
|
508
|
-
it "should return the first record for the given pk" do
|
509
|
-
@c[1].should be_a_kind_of(@c)
|
510
|
-
$sqls.last.should == "SELECT * FROM items WHERE (id = 1) LIMIT 1"
|
511
|
-
@c[9999].should be_a_kind_of(@c)
|
512
|
-
$sqls.last.should == "SELECT * FROM items WHERE (id = 9999) LIMIT 1"
|
513
|
-
end
|
514
|
-
|
515
|
-
it "should raise for boolean argument (mistaken comparison)" do
|
516
|
-
# This in order to prevent stuff like Model[:a == 'b']
|
517
|
-
proc {@c[:a == 1]}.should raise_error(Sequel::Error)
|
518
|
-
proc {@c[:a != 1]}.should raise_error(Sequel::Error)
|
519
|
-
end
|
520
|
-
|
521
|
-
it "should work correctly for custom primary key" do
|
522
|
-
@c.set_primary_key :name
|
523
|
-
@c['sharon'].should be_a_kind_of(@c)
|
524
|
-
$sqls.last.should == "SELECT * FROM items WHERE (name = 'sharon') LIMIT 1"
|
525
|
-
end
|
526
|
-
|
527
|
-
it "should work correctly for composite primary key" do
|
528
|
-
@c.set_primary_key [:node_id, :kind]
|
529
|
-
@c[3921, 201].should be_a_kind_of(@c)
|
530
|
-
$sqls.last.should =~ \
|
531
|
-
/^SELECT \* FROM items WHERE (\(node_id = 3921\) AND \(kind = 201\))|(\(kind = 201\) AND \(node_id = 3921\)) LIMIT 1$/
|
532
|
-
end
|
533
|
-
end
|
534
|
-
|
535
|
-
context "Model#inspect" do
|
536
|
-
setup do
|
537
|
-
@o = Sequel::Model.load(:x => 333)
|
538
|
-
end
|
539
|
-
|
540
|
-
specify "should include the class name and the values" do
|
541
|
-
@o.inspect.should == '#<Sequel::Model @values={:x=>333}>'
|
542
|
-
end
|
543
|
-
end
|