sequel 3.28.0 → 3.29.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +119 -3
- data/Rakefile +5 -3
- data/bin/sequel +1 -5
- data/doc/model_hooks.rdoc +9 -1
- data/doc/opening_databases.rdoc +49 -40
- data/doc/prepared_statements.rdoc +27 -6
- data/doc/release_notes/3.28.0.txt +2 -2
- data/doc/release_notes/3.29.0.txt +459 -0
- data/doc/sharding.rdoc +7 -1
- data/doc/testing.rdoc +18 -9
- data/doc/transactions.rdoc +41 -1
- data/lib/sequel/adapters/ado.rb +28 -17
- data/lib/sequel/adapters/ado/mssql.rb +18 -6
- data/lib/sequel/adapters/amalgalite.rb +11 -7
- data/lib/sequel/adapters/db2.rb +122 -70
- data/lib/sequel/adapters/dbi.rb +15 -15
- data/lib/sequel/adapters/do.rb +5 -36
- data/lib/sequel/adapters/do/mysql.rb +0 -5
- data/lib/sequel/adapters/do/postgres.rb +0 -5
- data/lib/sequel/adapters/do/sqlite.rb +0 -5
- data/lib/sequel/adapters/firebird.rb +3 -6
- data/lib/sequel/adapters/ibmdb.rb +24 -16
- data/lib/sequel/adapters/informix.rb +2 -4
- data/lib/sequel/adapters/jdbc.rb +47 -11
- data/lib/sequel/adapters/jdbc/as400.rb +5 -24
- data/lib/sequel/adapters/jdbc/db2.rb +0 -5
- data/lib/sequel/adapters/jdbc/derby.rb +217 -0
- data/lib/sequel/adapters/jdbc/firebird.rb +0 -5
- data/lib/sequel/adapters/jdbc/h2.rb +10 -12
- data/lib/sequel/adapters/jdbc/hsqldb.rb +166 -0
- data/lib/sequel/adapters/jdbc/informix.rb +0 -5
- data/lib/sequel/adapters/jdbc/jtds.rb +0 -5
- data/lib/sequel/adapters/jdbc/mysql.rb +0 -10
- data/lib/sequel/adapters/jdbc/oracle.rb +70 -3
- data/lib/sequel/adapters/jdbc/postgresql.rb +0 -11
- data/lib/sequel/adapters/jdbc/sqlite.rb +0 -5
- data/lib/sequel/adapters/jdbc/sqlserver.rb +0 -5
- data/lib/sequel/adapters/jdbc/transactions.rb +56 -7
- data/lib/sequel/adapters/mock.rb +315 -0
- data/lib/sequel/adapters/mysql.rb +64 -51
- data/lib/sequel/adapters/mysql2.rb +15 -9
- data/lib/sequel/adapters/odbc.rb +13 -6
- data/lib/sequel/adapters/odbc/db2.rb +0 -4
- data/lib/sequel/adapters/odbc/mssql.rb +0 -5
- data/lib/sequel/adapters/openbase.rb +2 -4
- data/lib/sequel/adapters/oracle.rb +333 -51
- data/lib/sequel/adapters/postgres.rb +80 -27
- data/lib/sequel/adapters/shared/access.rb +0 -6
- data/lib/sequel/adapters/shared/db2.rb +13 -15
- data/lib/sequel/adapters/shared/firebird.rb +6 -6
- data/lib/sequel/adapters/shared/mssql.rb +23 -18
- data/lib/sequel/adapters/shared/mysql.rb +6 -6
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +6 -0
- data/lib/sequel/adapters/shared/oracle.rb +185 -30
- data/lib/sequel/adapters/shared/postgres.rb +35 -18
- data/lib/sequel/adapters/shared/progress.rb +0 -6
- data/lib/sequel/adapters/shared/sqlite.rb +116 -37
- data/lib/sequel/adapters/sqlite.rb +16 -8
- data/lib/sequel/adapters/swift.rb +5 -5
- data/lib/sequel/adapters/swift/mysql.rb +0 -5
- data/lib/sequel/adapters/swift/postgres.rb +0 -5
- data/lib/sequel/adapters/swift/sqlite.rb +6 -4
- data/lib/sequel/adapters/tinytds.rb +13 -10
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +8 -0
- data/lib/sequel/core.rb +40 -0
- data/lib/sequel/database/connecting.rb +1 -2
- data/lib/sequel/database/dataset.rb +3 -3
- data/lib/sequel/database/dataset_defaults.rb +58 -0
- data/lib/sequel/database/misc.rb +62 -2
- data/lib/sequel/database/query.rb +113 -49
- data/lib/sequel/database/schema_methods.rb +7 -2
- data/lib/sequel/dataset/actions.rb +37 -19
- data/lib/sequel/dataset/features.rb +24 -0
- data/lib/sequel/dataset/graph.rb +7 -6
- data/lib/sequel/dataset/misc.rb +11 -3
- data/lib/sequel/dataset/mutation.rb +2 -3
- data/lib/sequel/dataset/prepared_statements.rb +6 -4
- data/lib/sequel/dataset/query.rb +46 -15
- data/lib/sequel/dataset/sql.rb +28 -4
- data/lib/sequel/extensions/named_timezones.rb +5 -0
- data/lib/sequel/extensions/thread_local_timezones.rb +1 -1
- data/lib/sequel/model.rb +2 -1
- data/lib/sequel/model/associations.rb +115 -33
- data/lib/sequel/model/base.rb +91 -31
- data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
- data/lib/sequel/plugins/dataset_associations.rb +100 -0
- data/lib/sequel/plugins/force_encoding.rb +6 -6
- data/lib/sequel/plugins/identity_map.rb +1 -1
- data/lib/sequel/plugins/many_through_many.rb +6 -10
- data/lib/sequel/plugins/prepared_statements.rb +12 -1
- data/lib/sequel/plugins/prepared_statements_associations.rb +1 -1
- data/lib/sequel/plugins/rcte_tree.rb +29 -15
- data/lib/sequel/plugins/serialization.rb +6 -1
- data/lib/sequel/plugins/sharding.rb +0 -5
- data/lib/sequel/plugins/single_table_inheritance.rb +1 -1
- data/lib/sequel/plugins/typecast_on_load.rb +9 -12
- data/lib/sequel/plugins/update_primary_key.rb +1 -1
- data/lib/sequel/timezones.rb +42 -42
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mssql_spec.rb +29 -29
- data/spec/adapters/mysql_spec.rb +86 -104
- data/spec/adapters/oracle_spec.rb +48 -76
- data/spec/adapters/postgres_spec.rb +98 -33
- data/spec/adapters/spec_helper.rb +0 -5
- data/spec/adapters/sqlite_spec.rb +24 -21
- data/spec/core/connection_pool_spec.rb +9 -15
- data/spec/core/core_sql_spec.rb +20 -31
- data/spec/core/database_spec.rb +491 -227
- data/spec/core/dataset_spec.rb +638 -1051
- data/spec/core/expression_filters_spec.rb +0 -1
- data/spec/core/mock_adapter_spec.rb +378 -0
- data/spec/core/object_graph_spec.rb +48 -114
- data/spec/core/schema_generator_spec.rb +3 -3
- data/spec/core/schema_spec.rb +51 -114
- data/spec/core/spec_helper.rb +3 -90
- data/spec/extensions/class_table_inheritance_spec.rb +1 -1
- data/spec/extensions/dataset_associations_spec.rb +199 -0
- data/spec/extensions/instance_hooks_spec.rb +71 -0
- data/spec/extensions/named_timezones_spec.rb +22 -2
- data/spec/extensions/nested_attributes_spec.rb +3 -0
- data/spec/extensions/schema_spec.rb +1 -1
- data/spec/extensions/serialization_modification_detection_spec.rb +1 -0
- data/spec/extensions/serialization_spec.rb +5 -8
- data/spec/extensions/spec_helper.rb +4 -0
- data/spec/extensions/thread_local_timezones_spec.rb +22 -2
- data/spec/extensions/typecast_on_load_spec.rb +1 -6
- data/spec/integration/associations_test.rb +123 -12
- data/spec/integration/dataset_test.rb +140 -47
- data/spec/integration/eager_loader_test.rb +19 -21
- data/spec/integration/model_test.rb +80 -1
- data/spec/integration/plugin_test.rb +179 -128
- data/spec/integration/prepared_statement_test.rb +92 -91
- data/spec/integration/schema_test.rb +42 -23
- data/spec/integration/spec_helper.rb +25 -31
- data/spec/integration/timezone_test.rb +38 -12
- data/spec/integration/transaction_test.rb +161 -34
- data/spec/integration/type_test.rb +3 -3
- data/spec/model/association_reflection_spec.rb +83 -7
- data/spec/model/associations_spec.rb +393 -676
- data/spec/model/base_spec.rb +186 -116
- data/spec/model/dataset_methods_spec.rb +7 -27
- data/spec/model/eager_loading_spec.rb +343 -867
- data/spec/model/hooks_spec.rb +160 -79
- data/spec/model/model_spec.rb +118 -165
- data/spec/model/plugins_spec.rb +7 -13
- data/spec/model/record_spec.rb +138 -207
- data/spec/model/spec_helper.rb +10 -73
- metadata +14 -8
data/spec/model/plugins_spec.rb
CHANGED
@@ -125,24 +125,21 @@ describe Sequel::Model, ".plugin" do
|
|
125
125
|
def self.configure(model, *args, &block)
|
126
126
|
@args << :configure
|
127
127
|
end
|
128
|
-
|
128
|
+
self::InstanceMethods = Module.new do
|
129
129
|
def self.included(model)
|
130
130
|
model.plugins.last.args << :im
|
131
131
|
end
|
132
132
|
end
|
133
|
-
|
133
|
+
self::ClassMethods = Module.new do
|
134
134
|
def self.extended(model)
|
135
135
|
model.plugins.last.args << :cm
|
136
136
|
end
|
137
137
|
end
|
138
|
-
|
138
|
+
self::DatasetMethods = Module.new do
|
139
139
|
def self.extended(dataset)
|
140
140
|
dataset.model.plugins.last.args << :dm
|
141
141
|
end
|
142
142
|
end
|
143
|
-
const_set(:InstanceMethods, im)
|
144
|
-
const_set(:ClassMethods, cm)
|
145
|
-
const_set(:DatasetMethods, dm)
|
146
143
|
end
|
147
144
|
|
148
145
|
b = lambda{44}
|
@@ -192,11 +189,10 @@ describe Sequel::Model, ".plugin" do
|
|
192
189
|
|
193
190
|
it "should define class methods for all public instance methods in DatasetMethod" do
|
194
191
|
m = Module.new do
|
195
|
-
|
192
|
+
self::DatasetMethods = Module.new do
|
196
193
|
def a; 1; end
|
197
194
|
def b; 2; end
|
198
195
|
end
|
199
|
-
const_set(:DatasetMethods, dm)
|
200
196
|
end
|
201
197
|
@c.plugin m
|
202
198
|
@c.dataset.a.should == 1
|
@@ -205,14 +201,13 @@ describe Sequel::Model, ".plugin" do
|
|
205
201
|
@c.b.should == 2
|
206
202
|
end
|
207
203
|
|
208
|
-
it "should define class methods for
|
204
|
+
it "should not define class methods for private instance methods in DatasetMethod" do
|
209
205
|
m = Module.new do
|
210
|
-
|
206
|
+
self::DatasetMethods = Module.new do
|
211
207
|
def b; 2; end
|
212
208
|
private
|
213
209
|
def a; 1; end
|
214
210
|
end
|
215
|
-
const_set(:DatasetMethods, dm)
|
216
211
|
end
|
217
212
|
@c.plugin m
|
218
213
|
@c.dataset.b.should == 2
|
@@ -225,11 +220,10 @@ describe Sequel::Model, ".plugin" do
|
|
225
220
|
|
226
221
|
it "should not raise an error if the DatasetMethod module has no public instance methods" do
|
227
222
|
m = Module.new do
|
228
|
-
|
223
|
+
self::DatasetMethods = Module.new do
|
229
224
|
private
|
230
225
|
def a; 1; end
|
231
226
|
end
|
232
|
-
const_set(:DatasetMethods, dm)
|
233
227
|
end
|
234
228
|
lambda{@c.plugin m}.should_not raise_error
|
235
229
|
end
|
data/spec/model/record_spec.rb
CHANGED
@@ -1,36 +1,23 @@
|
|
1
1
|
require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
2
2
|
|
3
3
|
describe "Model#save server use" do
|
4
|
-
|
5
|
-
|
6
|
-
@c = Class.new(Sequel::Model(:items))
|
7
|
-
|
8
|
-
|
9
|
-
@
|
10
|
-
db2 = @db2 = MockDatabase.new
|
11
|
-
@c.class_eval do
|
12
|
-
define_method(:after_save) do
|
13
|
-
model.db = db2
|
14
|
-
ds = model.dataset
|
15
|
-
def ds.fetch_rows(sql)
|
16
|
-
yield @db.execute(sql, @opts[:server])
|
17
|
-
end
|
18
|
-
@this = nil
|
19
|
-
end
|
20
|
-
end
|
4
|
+
before do
|
5
|
+
@db = Sequel.mock(:autoid=>proc{|sql| 10}, :fetch=>{:x=>1, :id=>10}, :servers=>{:blah=>{}, :read_only=>{}})
|
6
|
+
@c = Class.new(Sequel::Model(@db[:items]))
|
7
|
+
@c.columns :id, :x, :y
|
8
|
+
@c.dataset.columns(:id, :x, :y)
|
9
|
+
@db.sqls
|
21
10
|
end
|
22
11
|
|
23
12
|
it "should use the :default server if the model doesn't have one already specified" do
|
24
|
-
@c.
|
25
|
-
@
|
26
|
-
@c.new(:x=>1).save
|
13
|
+
@c.new(:x=>1).save.should == @c.load(:x=>1, :id=>10)
|
14
|
+
@db.sqls.should == ["INSERT INTO items (x) VALUES (1)", 'SELECT * FROM items WHERE (id = 10) LIMIT 1']
|
27
15
|
end
|
28
16
|
|
29
17
|
it "should use the model's server if the model has one already specified" do
|
30
18
|
@c.dataset = @c.dataset.server(:blah)
|
31
|
-
@c.
|
32
|
-
@
|
33
|
-
@c.new(:x=>1).save
|
19
|
+
@c.new(:x=>1).save.should == @c.load(:x=>1, :id=>10)
|
20
|
+
@db.sqls.should == ["INSERT INTO items (x) VALUES (1) -- blah", 'SELECT * FROM items WHERE (id = 10) LIMIT 1 -- blah']
|
34
21
|
end
|
35
22
|
end
|
36
23
|
|
@@ -39,29 +26,28 @@ describe "Model#save" do
|
|
39
26
|
@c = Class.new(Sequel::Model(:items)) do
|
40
27
|
columns :id, :x, :y
|
41
28
|
end
|
42
|
-
@c.dataset.
|
29
|
+
@c.dataset.autoid = 13
|
43
30
|
MODEL_DB.reset
|
44
31
|
end
|
45
32
|
|
46
33
|
it "should insert a record for a new model instance" do
|
47
34
|
o = @c.new(:x => 1)
|
48
35
|
o.save
|
49
|
-
MODEL_DB.sqls.should == ["INSERT INTO items (x) VALUES (1)",
|
50
|
-
"SELECT * FROM items WHERE (id = 1) LIMIT 1"]
|
36
|
+
MODEL_DB.sqls.should == ["INSERT INTO items (x) VALUES (1)", "SELECT * FROM items WHERE (id = 13) LIMIT 1"]
|
51
37
|
end
|
52
38
|
|
53
39
|
it "should use dataset's insert_select method if present" do
|
54
40
|
ds = @c.dataset = @c.dataset.clone
|
41
|
+
ds._fetch = {:y=>2}
|
55
42
|
def ds.supports_insert_select?() true end
|
56
43
|
def ds.insert_select(hash)
|
57
|
-
execute("INSERT INTO items (y) VALUES (2)")
|
58
|
-
{:y=>2}
|
44
|
+
execute("INSERT INTO items (y) VALUES (2) RETURNING *"){|r| return r}
|
59
45
|
end
|
60
46
|
o = @c.new(:x => 1)
|
61
47
|
o.save
|
62
48
|
|
63
49
|
o.values.should == {:y=>2}
|
64
|
-
MODEL_DB.sqls.should == ["INSERT INTO items (y) VALUES (2)"]
|
50
|
+
MODEL_DB.sqls.should == ["INSERT INTO items (y) VALUES (2) RETURNING *"]
|
65
51
|
end
|
66
52
|
|
67
53
|
it "should not use dataset's insert_select method if specific columns are selected" do
|
@@ -71,7 +57,6 @@ describe "Model#save" do
|
|
71
57
|
end
|
72
58
|
|
73
59
|
it "should use value returned by insert as the primary key and refresh the object" do
|
74
|
-
@c.dataset.meta_def(:insert){|h| super(h); 13}
|
75
60
|
o = @c.new(:x => 11)
|
76
61
|
o.save
|
77
62
|
MODEL_DB.sqls.should == ["INSERT INTO items (x) VALUES (11)",
|
@@ -79,14 +64,12 @@ describe "Model#save" do
|
|
79
64
|
end
|
80
65
|
|
81
66
|
it "should allow you to skip refreshing by overridding _save_refresh" do
|
82
|
-
@c.dataset.meta_def(:insert){|h| super(h); 13}
|
83
67
|
@c.send(:define_method, :_save_refresh){}
|
84
68
|
@c.create(:x => 11)
|
85
69
|
MODEL_DB.sqls.should == ["INSERT INTO items (x) VALUES (11)"]
|
86
70
|
end
|
87
71
|
|
88
72
|
it "should work correctly for inserting a record without a primary key" do
|
89
|
-
@c.dataset.meta_def(:insert){|h| super(h); 13}
|
90
73
|
@c.no_primary_key
|
91
74
|
o = @c.new(:x => 11)
|
92
75
|
o.save
|
@@ -94,15 +77,15 @@ describe "Model#save" do
|
|
94
77
|
end
|
95
78
|
|
96
79
|
it "should set the autoincrementing_primary_key value to the value returned by insert" do
|
97
|
-
@c.dataset.meta_def(:insert){|h| super(h); 13}
|
98
80
|
@c.unrestrict_primary_key
|
99
81
|
@c.set_primary_key [:x, :y]
|
100
82
|
o = @c.new(:x => 11)
|
101
83
|
o.meta_def(:autoincrementing_primary_key){:y}
|
102
84
|
o.save
|
103
|
-
MODEL_DB.sqls
|
104
|
-
|
105
|
-
|
85
|
+
sqls = MODEL_DB.sqls
|
86
|
+
sqls.length.should == 2
|
87
|
+
sqls.first.should == "INSERT INTO items (x) VALUES (11)"
|
88
|
+
sqls.last.should =~ %r{SELECT \* FROM items WHERE \(\([xy] = 1[13]\) AND \([xy] = 1[13]\)\) LIMIT 1}
|
106
89
|
end
|
107
90
|
|
108
91
|
it "should update a record for an existing model instance" do
|
@@ -113,17 +96,18 @@ describe "Model#save" do
|
|
113
96
|
|
114
97
|
it "should raise a NoExistingObject exception if the dataset update call doesn't return 1, unless require_modification is false" do
|
115
98
|
o = @c.load(:id => 3, :x => 1)
|
116
|
-
o.this
|
99
|
+
t = o.this
|
100
|
+
t.numrows = 0
|
117
101
|
proc{o.save}.should raise_error(Sequel::NoExistingObject)
|
118
|
-
|
102
|
+
t.numrows = 2
|
119
103
|
proc{o.save}.should raise_error(Sequel::NoExistingObject)
|
120
|
-
|
104
|
+
t.numrows = 1
|
121
105
|
proc{o.save}.should_not raise_error
|
122
106
|
|
123
107
|
o.require_modification = false
|
124
|
-
|
108
|
+
t.numrows = 0
|
125
109
|
proc{o.save}.should_not raise_error
|
126
|
-
|
110
|
+
t.numrows = 2
|
127
111
|
proc{o.save}.should_not raise_error
|
128
112
|
end
|
129
113
|
|
@@ -192,22 +176,18 @@ describe "Model#save" do
|
|
192
176
|
@c.use_transactions = true
|
193
177
|
@c.load(:id => 3, :x => 1, :y => nil).save(:y)
|
194
178
|
MODEL_DB.sqls.should == ["BEGIN", "UPDATE items SET y = NULL WHERE (id = 3)", "COMMIT"]
|
195
|
-
MODEL_DB.reset
|
196
179
|
@c.use_transactions = false
|
197
180
|
@c.load(:id => 3, :x => 1, :y => nil).save(:y)
|
198
181
|
MODEL_DB.sqls.should == ["UPDATE items SET y = NULL WHERE (id = 3)"]
|
199
|
-
MODEL_DB.reset
|
200
182
|
end
|
201
183
|
|
202
184
|
it "should inherit Model's use_transactions setting" do
|
203
185
|
@c.use_transactions = true
|
204
186
|
Class.new(@c).load(:id => 3, :x => 1, :y => nil).save(:y)
|
205
187
|
MODEL_DB.sqls.should == ["BEGIN", "UPDATE items SET y = NULL WHERE (id = 3)", "COMMIT"]
|
206
|
-
MODEL_DB.reset
|
207
188
|
@c.use_transactions = false
|
208
189
|
Class.new(@c).load(:id => 3, :x => 1, :y => nil).save(:y)
|
209
190
|
MODEL_DB.sqls.should == ["UPDATE items SET y = NULL WHERE (id = 3)"]
|
210
|
-
MODEL_DB.reset
|
211
191
|
end
|
212
192
|
|
213
193
|
it "should use object's use_transactions setting" do
|
@@ -216,13 +196,11 @@ describe "Model#save" do
|
|
216
196
|
@c.use_transactions = true
|
217
197
|
o.save(:y)
|
218
198
|
MODEL_DB.sqls.should == ["UPDATE items SET y = NULL WHERE (id = 3)"]
|
219
|
-
MODEL_DB.reset
|
220
199
|
o = @c.load(:id => 3, :x => 1, :y => nil)
|
221
200
|
o.use_transactions = true
|
222
201
|
@c.use_transactions = false
|
223
202
|
o.save(:y)
|
224
203
|
MODEL_DB.sqls.should == ["BEGIN", "UPDATE items SET y = NULL WHERE (id = 3)", "COMMIT"]
|
225
|
-
MODEL_DB.reset
|
226
204
|
end
|
227
205
|
|
228
206
|
it "should use :transaction option if given" do
|
@@ -230,12 +208,10 @@ describe "Model#save" do
|
|
230
208
|
o.use_transactions = true
|
231
209
|
o.save(:y, :transaction=>false)
|
232
210
|
MODEL_DB.sqls.should == ["UPDATE items SET y = NULL WHERE (id = 3)"]
|
233
|
-
MODEL_DB.reset
|
234
211
|
o = @c.load(:id => 3, :x => 1, :y => nil)
|
235
212
|
o.use_transactions = false
|
236
213
|
o.save(:y, :transaction=>true)
|
237
214
|
MODEL_DB.sqls.should == ["BEGIN", "UPDATE items SET y = NULL WHERE (id = 3)", "COMMIT"]
|
238
|
-
MODEL_DB.reset
|
239
215
|
end
|
240
216
|
|
241
217
|
it "should rollback if before_save returns false and raise_on_save_failure = true" do
|
@@ -247,7 +223,6 @@ describe "Model#save" do
|
|
247
223
|
end
|
248
224
|
proc { o.save(:y) }.should raise_error(Sequel::BeforeHookFailed)
|
249
225
|
MODEL_DB.sqls.should == ["BEGIN", "ROLLBACK"]
|
250
|
-
MODEL_DB.reset
|
251
226
|
end
|
252
227
|
|
253
228
|
it "should rollback if before_save returns false and :raise_on_failure option is true" do
|
@@ -259,7 +234,6 @@ describe "Model#save" do
|
|
259
234
|
end
|
260
235
|
proc { o.save(:y, :raise_on_failure => true) }.should raise_error(Sequel::BeforeHookFailed)
|
261
236
|
MODEL_DB.sqls.should == ["BEGIN", "ROLLBACK"]
|
262
|
-
MODEL_DB.reset
|
263
237
|
end
|
264
238
|
|
265
239
|
it "should not rollback outer transactions if before_save returns false and raise_on_save_failure = false" do
|
@@ -274,7 +248,6 @@ describe "Model#save" do
|
|
274
248
|
MODEL_DB.run "BLAH"
|
275
249
|
end
|
276
250
|
MODEL_DB.sqls.should == ["BEGIN", "BLAH", "COMMIT"]
|
277
|
-
MODEL_DB.reset
|
278
251
|
end
|
279
252
|
|
280
253
|
it "should rollback if before_save returns false and raise_on_save_failure = false" do
|
@@ -286,7 +259,6 @@ describe "Model#save" do
|
|
286
259
|
end
|
287
260
|
o.save(:y).should == nil
|
288
261
|
MODEL_DB.sqls.should == ["BEGIN", "ROLLBACK"]
|
289
|
-
MODEL_DB.reset
|
290
262
|
end
|
291
263
|
|
292
264
|
it "should not rollback if before_save throws Rollback and use_transactions = false" do
|
@@ -297,7 +269,6 @@ describe "Model#save" do
|
|
297
269
|
end
|
298
270
|
proc { o.save(:y) }.should raise_error(Sequel::Rollback)
|
299
271
|
MODEL_DB.sqls.should == []
|
300
|
-
MODEL_DB.reset
|
301
272
|
end
|
302
273
|
end
|
303
274
|
|
@@ -306,7 +277,6 @@ describe "Model#marshallable" do
|
|
306
277
|
class ::Album < Sequel::Model
|
307
278
|
columns :id, :x
|
308
279
|
end
|
309
|
-
Album.dataset.meta_def(:insert){|h| super(h); 1}
|
310
280
|
end
|
311
281
|
after do
|
312
282
|
Object.send(:remove_const, :Album)
|
@@ -388,7 +358,6 @@ describe "Model#modified[!?]" do
|
|
388
358
|
end
|
389
359
|
|
390
360
|
describe "Model#save_changes" do
|
391
|
-
|
392
361
|
before do
|
393
362
|
@c = Class.new(Sequel::Model(:items)) do
|
394
363
|
unrestrict_primary_key
|
@@ -433,15 +402,14 @@ describe "Model#save_changes" do
|
|
433
402
|
MODEL_DB.sqls.should == ["UPDATE items SET x = 2 WHERE (id = 3)"]
|
434
403
|
o.save_changes
|
435
404
|
o.save_changes
|
436
|
-
MODEL_DB.sqls.should == [
|
437
|
-
MODEL_DB.reset
|
405
|
+
MODEL_DB.sqls.should == []
|
438
406
|
|
439
407
|
o.y = 4
|
440
408
|
o.save_changes
|
441
409
|
MODEL_DB.sqls.should == ["UPDATE items SET y = 4 WHERE (id = 3)"]
|
442
410
|
o.save_changes
|
443
411
|
o.save_changes
|
444
|
-
MODEL_DB.sqls.should == [
|
412
|
+
MODEL_DB.sqls.should == []
|
445
413
|
end
|
446
414
|
|
447
415
|
it "should not consider columns changed if the values did not change" do
|
@@ -453,7 +421,6 @@ describe "Model#save_changes" do
|
|
453
421
|
o.x = 3
|
454
422
|
o.save_changes
|
455
423
|
MODEL_DB.sqls.should == ["UPDATE items SET x = 3 WHERE (id = 3)"]
|
456
|
-
MODEL_DB.reset
|
457
424
|
|
458
425
|
o[:y] = nil
|
459
426
|
o.save_changes
|
@@ -479,13 +446,11 @@ describe "Model#save_changes" do
|
|
479
446
|
o.x = 2
|
480
447
|
o.save_changes
|
481
448
|
MODEL_DB.sqls.should == ["UPDATE items SET x = 3 WHERE (id = 3)"]
|
482
|
-
MODEL_DB.reset
|
483
449
|
o.save_changes
|
484
450
|
MODEL_DB.sqls.should == []
|
485
451
|
o.x = 4
|
486
452
|
o.save_changes
|
487
453
|
MODEL_DB.sqls.should == ["UPDATE items SET x = 5 WHERE (id = 3)"]
|
488
|
-
MODEL_DB.reset
|
489
454
|
end
|
490
455
|
|
491
456
|
it "should update columns changed in a before_save hook" do
|
@@ -496,25 +461,21 @@ describe "Model#save_changes" do
|
|
496
461
|
o.x = 2
|
497
462
|
o.save_changes
|
498
463
|
MODEL_DB.sqls.should == ["UPDATE items SET x = 3 WHERE (id = 3)"]
|
499
|
-
MODEL_DB.reset
|
500
464
|
o.save_changes
|
501
465
|
MODEL_DB.sqls.should == []
|
502
466
|
o.x = 4
|
503
467
|
o.save_changes
|
504
468
|
MODEL_DB.sqls.should == ["UPDATE items SET x = 5 WHERE (id = 3)"]
|
505
|
-
MODEL_DB.reset
|
506
469
|
end
|
507
470
|
end
|
508
471
|
|
509
472
|
describe "Model#new?" do
|
510
|
-
|
511
|
-
before(:each) do
|
512
|
-
MODEL_DB.reset
|
513
|
-
|
473
|
+
before do
|
514
474
|
@c = Class.new(Sequel::Model(:items)) do
|
515
475
|
unrestrict_primary_key
|
516
476
|
columns :x
|
517
477
|
end
|
478
|
+
MODEL_DB.reset
|
518
479
|
end
|
519
480
|
|
520
481
|
it "should be true for a new instance" do
|
@@ -530,74 +491,65 @@ describe "Model#new?" do
|
|
530
491
|
end
|
531
492
|
|
532
493
|
describe Sequel::Model, "w/ primary key" do
|
533
|
-
|
534
494
|
it "should default to ':id'" do
|
535
495
|
model_a = Class.new Sequel::Model
|
536
|
-
model_a.primary_key.should
|
496
|
+
model_a.primary_key.should == :id
|
537
497
|
end
|
538
498
|
|
539
499
|
it "should be changed through 'set_primary_key'" do
|
540
|
-
model_a = Class.new(Sequel::Model)
|
541
|
-
model_a.primary_key.should
|
500
|
+
model_a = Class.new(Sequel::Model){ set_primary_key :a }
|
501
|
+
model_a.primary_key.should == :a
|
542
502
|
end
|
543
503
|
|
544
504
|
it "should support multi argument composite keys" do
|
545
|
-
model_a = Class.new(Sequel::Model)
|
546
|
-
model_a.primary_key.should
|
505
|
+
model_a = Class.new(Sequel::Model){ set_primary_key :a, :b }
|
506
|
+
model_a.primary_key.should == [:a, :b]
|
547
507
|
end
|
548
508
|
|
549
509
|
it "should accept single argument composite keys" do
|
550
|
-
model_a = Class.new(Sequel::Model)
|
551
|
-
model_a.primary_key.should
|
510
|
+
model_a = Class.new(Sequel::Model){ set_primary_key [:a, :b] }
|
511
|
+
model_a.primary_key.should == [:a, :b]
|
552
512
|
end
|
553
|
-
|
554
513
|
end
|
555
514
|
|
556
515
|
describe Sequel::Model, "w/o primary key" do
|
557
516
|
it "should return nil for primary key" do
|
558
|
-
Class.new(Sequel::Model)
|
517
|
+
Class.new(Sequel::Model){no_primary_key}.primary_key.should be_nil
|
559
518
|
end
|
560
519
|
|
561
520
|
it "should raise a Sequel::Error on 'this'" do
|
562
|
-
instance = Class.new(Sequel::Model)
|
563
|
-
proc
|
521
|
+
instance = Class.new(Sequel::Model){no_primary_key}.new
|
522
|
+
proc{instance.this}.should raise_error(Sequel::Error)
|
564
523
|
end
|
565
524
|
end
|
566
525
|
|
567
526
|
describe Sequel::Model, "with this" do
|
568
|
-
|
569
|
-
|
527
|
+
before do
|
528
|
+
@example = Class.new(Sequel::Model(:examples))
|
529
|
+
@example.columns :id, :a, :x, :y
|
530
|
+
end
|
570
531
|
|
571
532
|
it "should return a dataset identifying the record" do
|
572
|
-
instance = @example.load
|
573
|
-
instance.this.sql.should
|
533
|
+
instance = @example.load(:id => 3)
|
534
|
+
instance.this.sql.should == "SELECT * FROM examples WHERE (id = 3) LIMIT 1"
|
574
535
|
end
|
575
536
|
|
576
537
|
it "should support arbitary primary keys" do
|
577
538
|
@example.set_primary_key :a
|
578
539
|
|
579
|
-
instance = @example.load
|
580
|
-
instance.this.sql.should
|
540
|
+
instance = @example.load(:a => 3)
|
541
|
+
instance.this.sql.should == "SELECT * FROM examples WHERE (a = 3) LIMIT 1"
|
581
542
|
end
|
582
543
|
|
583
544
|
it "should support composite primary keys" do
|
584
545
|
@example.set_primary_key :x, :y
|
585
|
-
instance = @example.load
|
586
|
-
|
587
|
-
parts = [
|
588
|
-
'SELECT * FROM examples WHERE %s LIMIT 1',
|
589
|
-
'((x = 4) AND (y = 5))',
|
590
|
-
'((y = 5) AND (x = 4))'
|
591
|
-
].map { |expr| Regexp.escape expr }
|
592
|
-
regexp = Regexp.new parts.first % "(?:#{parts[1]}|#{parts[2]})"
|
593
|
-
|
594
|
-
instance.this.sql.should match(regexp)
|
546
|
+
instance = @example.load(:x => 4, :y => 5)
|
547
|
+
instance.this.sql.should =~ /SELECT \* FROM examples WHERE \(\([xy] = [45]\) AND \([xy] = [45]\)\) LIMIT 1/
|
595
548
|
end
|
596
|
-
|
597
549
|
end
|
598
550
|
|
599
551
|
describe "Model#pk" do
|
600
|
-
before
|
552
|
+
before do
|
601
553
|
@m = Class.new(Sequel::Model)
|
602
554
|
@m.columns :id, :x, :y
|
603
555
|
end
|
@@ -631,7 +583,7 @@ describe "Model#pk" do
|
|
631
583
|
end
|
632
584
|
|
633
585
|
describe "Model#pk_or_nil" do
|
634
|
-
before
|
586
|
+
before do
|
635
587
|
@m = Class.new(Sequel::Model)
|
636
588
|
@m.columns :id, :x, :y
|
637
589
|
end
|
@@ -665,7 +617,7 @@ describe "Model#pk_or_nil" do
|
|
665
617
|
end
|
666
618
|
|
667
619
|
describe "Model#pk_hash" do
|
668
|
-
before
|
620
|
+
before do
|
669
621
|
@m = Class.new(Sequel::Model)
|
670
622
|
@m.columns :id, :x, :y
|
671
623
|
end
|
@@ -700,16 +652,14 @@ end
|
|
700
652
|
|
701
653
|
describe Sequel::Model, "#set" do
|
702
654
|
before do
|
703
|
-
MODEL_DB.reset
|
704
|
-
|
705
655
|
@c = Class.new(Sequel::Model(:items)) do
|
706
656
|
set_primary_key :id
|
707
657
|
columns :x, :y, :id
|
708
658
|
end
|
709
659
|
@c.strict_param_setting = false
|
710
|
-
@c.instance_variable_set(:@columns, true)
|
711
660
|
@o1 = @c.new
|
712
661
|
@o2 = @c.load(:id => 5)
|
662
|
+
MODEL_DB.reset
|
713
663
|
end
|
714
664
|
|
715
665
|
it "should filter the given params using the model columns" do
|
@@ -833,47 +783,44 @@ end
|
|
833
783
|
|
834
784
|
describe Sequel::Model, "#update" do
|
835
785
|
before do
|
836
|
-
MODEL_DB.reset
|
837
|
-
|
838
786
|
@c = Class.new(Sequel::Model(:items)) do
|
839
787
|
set_primary_key :id
|
840
788
|
columns :x, :y, :id
|
841
789
|
end
|
842
790
|
@c.strict_param_setting = false
|
843
|
-
@c.instance_variable_set(:@columns, true)
|
844
791
|
@o1 = @c.new
|
845
792
|
@o2 = @c.load(:id => 5)
|
793
|
+
MODEL_DB.reset
|
846
794
|
end
|
847
795
|
|
848
796
|
it "should filter the given params using the model columns" do
|
849
797
|
@o1.update(:x => 1, :z => 2)
|
850
|
-
MODEL_DB.sqls.
|
798
|
+
MODEL_DB.sqls.should == ["INSERT INTO items (x) VALUES (1)", "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
|
851
799
|
|
852
800
|
MODEL_DB.reset
|
853
801
|
@o2.update(:y => 1, :abc => 2)
|
854
|
-
MODEL_DB.sqls.
|
802
|
+
MODEL_DB.sqls.should == ["UPDATE items SET y = 1 WHERE (id = 5)"]
|
855
803
|
end
|
856
804
|
|
857
805
|
it "should support virtual attributes" do
|
858
806
|
@c.send(:define_method, :blah=){|v| self.x = v}
|
859
807
|
@o1.update(:blah => 333)
|
860
|
-
MODEL_DB.sqls.
|
808
|
+
MODEL_DB.sqls.should == ["INSERT INTO items (x) VALUES (333)", "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
|
861
809
|
end
|
862
810
|
|
863
811
|
it "should not modify the primary key" do
|
864
812
|
@o1.update(:x => 1, :id => 2)
|
865
|
-
MODEL_DB.sqls.
|
813
|
+
MODEL_DB.sqls.should == ["INSERT INTO items (x) VALUES (1)", "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
|
866
814
|
MODEL_DB.reset
|
867
815
|
@o2.update('y'=> 1, 'id'=> 2)
|
868
816
|
@o2.values.should == {:y => 1, :id=> 5}
|
869
|
-
MODEL_DB.sqls.
|
817
|
+
MODEL_DB.sqls.should == ["UPDATE items SET y = 1 WHERE (id = 5)"]
|
870
818
|
end
|
871
819
|
end
|
872
820
|
|
873
821
|
describe Sequel::Model, "#set_fields" do
|
874
822
|
before do
|
875
|
-
@c = Class.new(Sequel::Model(:items))
|
876
|
-
@c.class_eval do
|
823
|
+
@c = Class.new(Sequel::Model(:items)) do
|
877
824
|
set_primary_key :id
|
878
825
|
columns :x, :y, :z, :id
|
879
826
|
end
|
@@ -893,11 +840,9 @@ end
|
|
893
840
|
|
894
841
|
describe Sequel::Model, "#update_fields" do
|
895
842
|
before do
|
896
|
-
@c = Class.new(Sequel::Model(:items))
|
897
|
-
@c.class_eval do
|
843
|
+
@c = Class.new(Sequel::Model(:items)) do
|
898
844
|
set_primary_key :id
|
899
845
|
columns :x, :y, :z, :id
|
900
|
-
def _refresh(ds); end
|
901
846
|
end
|
902
847
|
@c.strict_param_setting = true
|
903
848
|
@o1 = @c.load(:id=>1)
|
@@ -907,21 +852,18 @@ describe Sequel::Model, "#update_fields" do
|
|
907
852
|
it "should set only the given fields, and then save the changes to the record" do
|
908
853
|
@o1.update_fields({:x => 1, :y => 2, :z=>3, :id=>4}, [:x, :y])
|
909
854
|
@o1.values.should == {:x => 1, :y => 2, :id=>1}
|
910
|
-
|
911
|
-
|
912
|
-
|
855
|
+
sqls = MODEL_DB.sqls
|
856
|
+
sqls.pop.should =~ /UPDATE items SET [xy] = [12], [xy] = [12] WHERE \(id = 1\)/
|
857
|
+
sqls.should == []
|
913
858
|
|
914
859
|
@o1.update_fields({:x => 1, :y => 5, :z=>6, :id=>7}, [:x, :y])
|
915
860
|
@o1.values.should == {:x => 1, :y => 5, :id=>1}
|
916
861
|
MODEL_DB.sqls.should == ["UPDATE items SET y = 5 WHERE (id = 1)"]
|
917
|
-
MODEL_DB.reset
|
918
862
|
end
|
919
863
|
end
|
920
864
|
|
921
865
|
describe Sequel::Model, "#(set|update)_(all|except|only)" do
|
922
866
|
before do
|
923
|
-
MODEL_DB.reset
|
924
|
-
|
925
867
|
@c = Class.new(Sequel::Model(:items)) do
|
926
868
|
set_primary_key :id
|
927
869
|
columns :x, :y, :z, :id
|
@@ -929,8 +871,8 @@ describe Sequel::Model, "#(set|update)_(all|except|only)" do
|
|
929
871
|
set_restricted_columns :y
|
930
872
|
end
|
931
873
|
@c.strict_param_setting = false
|
932
|
-
@c.instance_variable_set(:@columns, true)
|
933
874
|
@o1 = @c.new
|
875
|
+
MODEL_DB.reset
|
934
876
|
end
|
935
877
|
|
936
878
|
it "should raise errors if not all hash fields can be set and strict_param_setting is true" do
|
@@ -974,40 +916,34 @@ describe Sequel::Model, "#(set|update)_(all|except|only)" do
|
|
974
916
|
|
975
917
|
it "#update_all should update all attributes" do
|
976
918
|
@c.new.update_all(:x => 1, :id=>4)
|
977
|
-
MODEL_DB.sqls.
|
978
|
-
MODEL_DB.reset
|
919
|
+
MODEL_DB.sqls.should == ["INSERT INTO items (x) VALUES (1)", "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
|
979
920
|
@c.new.update_all(:y => 1, :id=>4)
|
980
|
-
MODEL_DB.sqls.
|
981
|
-
MODEL_DB.reset
|
921
|
+
MODEL_DB.sqls.should == ["INSERT INTO items (y) VALUES (1)", "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
|
982
922
|
@c.new.update_all(:z => 1, :id=>4)
|
983
|
-
MODEL_DB.sqls.
|
923
|
+
MODEL_DB.sqls.should == ["INSERT INTO items (z) VALUES (1)", "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
|
984
924
|
end
|
985
925
|
|
986
926
|
it "#update_only should only update given attributes" do
|
987
927
|
@o1.update_only({:x => 1, :y => 2, :z=>3, :id=>4}, [:x])
|
988
|
-
MODEL_DB.sqls.
|
989
|
-
MODEL_DB.reset
|
928
|
+
MODEL_DB.sqls.should == ["INSERT INTO items (x) VALUES (1)", "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
|
990
929
|
@c.new.update_only({:x => 1, :y => 2, :z=>3, :id=>4}, :x)
|
991
|
-
MODEL_DB.sqls.
|
930
|
+
MODEL_DB.sqls.should == ["INSERT INTO items (x) VALUES (1)", "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
|
992
931
|
end
|
993
932
|
|
994
933
|
it "#update_except should not update given attributes" do
|
995
934
|
@o1.update_except({:x => 1, :y => 2, :z=>3, :id=>4}, [:y, :z])
|
996
|
-
MODEL_DB.sqls.
|
997
|
-
MODEL_DB.reset
|
935
|
+
MODEL_DB.sqls.should == ["INSERT INTO items (x) VALUES (1)", "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
|
998
936
|
@c.new.update_except({:x => 1, :y => 2, :z=>3, :id=>4}, :y, :z)
|
999
|
-
MODEL_DB.sqls.
|
937
|
+
MODEL_DB.sqls.should == ["INSERT INTO items (x) VALUES (1)", "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
|
1000
938
|
end
|
1001
939
|
end
|
1002
940
|
|
1003
941
|
describe Sequel::Model, "#destroy" do
|
1004
942
|
before do
|
1005
|
-
MODEL_DB.reset
|
1006
943
|
@model = Class.new(Sequel::Model(:items))
|
1007
944
|
@model.columns :id
|
1008
|
-
@model.dataset.meta_def(:delete){MODEL_DB.execute delete_sql;1}
|
1009
|
-
|
1010
945
|
@instance = @model.load(:id => 1234)
|
946
|
+
MODEL_DB.reset
|
1011
947
|
end
|
1012
948
|
|
1013
949
|
it "should return self" do
|
@@ -1032,49 +968,40 @@ describe Sequel::Model, "#destroy" do
|
|
1032
968
|
|
1033
969
|
it "should run within a transaction if use_transactions is true" do
|
1034
970
|
@instance.use_transactions = true
|
1035
|
-
@model.db.should_receive(:transaction)
|
1036
971
|
@instance.destroy
|
972
|
+
MODEL_DB.sqls.should == ["BEGIN", "DELETE FROM items WHERE (id = 1234)", "COMMIT"]
|
1037
973
|
end
|
1038
974
|
|
1039
975
|
it "should not run within a transaction if use_transactions is false" do
|
1040
976
|
@instance.use_transactions = false
|
1041
|
-
@model.db.should_not_receive(:transaction)
|
1042
977
|
@instance.destroy
|
978
|
+
MODEL_DB.sqls.should == ["DELETE FROM items WHERE (id = 1234)"]
|
1043
979
|
end
|
1044
980
|
|
1045
981
|
it "should run within a transaction if :transaction option is true" do
|
1046
982
|
@instance.use_transactions = false
|
1047
|
-
@model.db.should_receive(:transaction)
|
1048
983
|
@instance.destroy(:transaction => true)
|
984
|
+
MODEL_DB.sqls.should == ["BEGIN", "DELETE FROM items WHERE (id = 1234)", "COMMIT"]
|
1049
985
|
end
|
1050
986
|
|
1051
987
|
it "should not run within a transaction if :transaction option is false" do
|
1052
988
|
@instance.use_transactions = true
|
1053
|
-
@model.db.should_not_receive(:transaction)
|
1054
989
|
@instance.destroy(:transaction => false)
|
990
|
+
MODEL_DB.sqls.should == ["DELETE FROM items WHERE (id = 1234)"]
|
1055
991
|
end
|
1056
992
|
|
1057
993
|
it "should run before_destroy and after_destroy hooks" do
|
1058
994
|
@model.send(:define_method, :before_destroy){MODEL_DB.execute('before blah')}
|
1059
995
|
@model.send(:define_method, :after_destroy){MODEL_DB.execute('after blah')}
|
1060
996
|
@instance.destroy
|
1061
|
-
|
1062
|
-
MODEL_DB.sqls.should == [
|
1063
|
-
"before blah",
|
1064
|
-
"DELETE FROM items WHERE (id = 1234)",
|
1065
|
-
"after blah"
|
1066
|
-
]
|
997
|
+
MODEL_DB.sqls.should == ["before blah", "DELETE FROM items WHERE (id = 1234)", "after blah"]
|
1067
998
|
end
|
1068
999
|
end
|
1069
1000
|
|
1070
1001
|
describe Sequel::Model, "#exists?" do
|
1071
|
-
before
|
1002
|
+
before do
|
1072
1003
|
@model = Class.new(Sequel::Model(:items))
|
1073
|
-
@
|
1074
|
-
def @ds.fetch_rows(sql)
|
1075
|
-
db.execute(sql)
|
1076
|
-
yield(:x=>1) if sql =~ /id = 1/
|
1077
|
-
end
|
1004
|
+
@model.dataset._fetch = proc{|sql| {:x=>1} if sql =~ /id = 1/}
|
1078
1005
|
MODEL_DB.reset
|
1079
1006
|
end
|
1080
1007
|
|
@@ -1103,7 +1030,7 @@ describe Sequel::Model, "#each" do
|
|
1103
1030
|
|
1104
1031
|
specify "should iterate over the values" do
|
1105
1032
|
h = {}
|
1106
|
-
@m.each
|
1033
|
+
@m.each{|k, v| h[k] = v}
|
1107
1034
|
h.should == {:a => 1, :b => 2, :id => 4444}
|
1108
1035
|
end
|
1109
1036
|
end
|
@@ -1116,11 +1043,8 @@ describe Sequel::Model, "#keys" do
|
|
1116
1043
|
end
|
1117
1044
|
|
1118
1045
|
specify "should return the value keys" do
|
1119
|
-
@m.keys.
|
1120
|
-
@
|
1121
|
-
|
1122
|
-
@m = @model.new()
|
1123
|
-
@m.keys.should == []
|
1046
|
+
@m.keys.sort_by{|k| k.to_s}.should == [:a, :b, :id]
|
1047
|
+
@model.new.keys.should == []
|
1124
1048
|
end
|
1125
1049
|
end
|
1126
1050
|
|
@@ -1335,8 +1259,7 @@ describe Sequel::Model, "#initialize_set" do
|
|
1335
1259
|
end
|
1336
1260
|
|
1337
1261
|
describe Sequel::Model, ".create" do
|
1338
|
-
|
1339
|
-
before(:each) do
|
1262
|
+
before do
|
1340
1263
|
MODEL_DB.reset
|
1341
1264
|
@c = Class.new(Sequel::Model(:items)) do
|
1342
1265
|
unrestrict_primary_key
|
@@ -1347,13 +1270,13 @@ describe Sequel::Model, ".create" do
|
|
1347
1270
|
it "should be able to create rows in the associated table" do
|
1348
1271
|
o = @c.create(:x => 1)
|
1349
1272
|
o.class.should == @c
|
1350
|
-
MODEL_DB.sqls.should == ['INSERT INTO items (x) VALUES (1)',
|
1273
|
+
MODEL_DB.sqls.should == ['INSERT INTO items (x) VALUES (1)', "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
|
1351
1274
|
end
|
1352
1275
|
|
1353
1276
|
it "should be able to create rows without any values specified" do
|
1354
1277
|
o = @c.create
|
1355
1278
|
o.class.should == @c
|
1356
|
-
MODEL_DB.sqls.should == ["INSERT INTO items DEFAULT VALUES", "SELECT * FROM items WHERE (id
|
1279
|
+
MODEL_DB.sqls.should == ["INSERT INTO items DEFAULT VALUES", "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
|
1357
1280
|
end
|
1358
1281
|
|
1359
1282
|
it "should accept a block and run it" do
|
@@ -1363,7 +1286,7 @@ describe Sequel::Model, ".create" do
|
|
1363
1286
|
o1.should === o
|
1364
1287
|
o3.should === o
|
1365
1288
|
o2.should == :blah
|
1366
|
-
MODEL_DB.sqls.should == ["INSERT INTO items (x) VALUES (333)", "SELECT * FROM items WHERE (id
|
1289
|
+
MODEL_DB.sqls.should == ["INSERT INTO items (x) VALUES (333)", "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
|
1367
1290
|
end
|
1368
1291
|
|
1369
1292
|
it "should create a row for a model with custom primary key" do
|
@@ -1376,32 +1299,35 @@ end
|
|
1376
1299
|
|
1377
1300
|
describe Sequel::Model, "#refresh" do
|
1378
1301
|
before do
|
1379
|
-
MODEL_DB.reset
|
1380
1302
|
@c = Class.new(Sequel::Model(:items)) do
|
1381
1303
|
unrestrict_primary_key
|
1382
1304
|
columns :id, :x
|
1383
1305
|
end
|
1306
|
+
MODEL_DB.reset
|
1384
1307
|
end
|
1385
1308
|
|
1386
1309
|
specify "should reload the instance values from the database" do
|
1387
1310
|
@m = @c.new(:id => 555)
|
1388
1311
|
@m[:x] = 'blah'
|
1389
|
-
@
|
1312
|
+
@c.dataset._fetch = {:x => 'kaboom', :id => 555}
|
1390
1313
|
@m.refresh
|
1391
1314
|
@m[:x].should == 'kaboom'
|
1315
|
+
MODEL_DB.sqls.should == ["SELECT * FROM items WHERE (id = 555) LIMIT 1"]
|
1392
1316
|
end
|
1393
1317
|
|
1394
1318
|
specify "should raise if the instance is not found" do
|
1395
1319
|
@m = @c.new(:id => 555)
|
1396
|
-
@
|
1320
|
+
@c.dataset._fetch = []
|
1397
1321
|
proc {@m.refresh}.should raise_error(Sequel::Error)
|
1322
|
+
MODEL_DB.sqls.should == ["SELECT * FROM items WHERE (id = 555) LIMIT 1"]
|
1398
1323
|
end
|
1399
1324
|
|
1400
1325
|
specify "should be aliased by #reload" do
|
1401
1326
|
@m = @c.new(:id => 555)
|
1402
|
-
@
|
1327
|
+
@c.dataset._fetch = {:x => 'kaboom', :id => 555}
|
1403
1328
|
@m.reload
|
1404
1329
|
@m[:x].should == 'kaboom'
|
1330
|
+
MODEL_DB.sqls.should == ["SELECT * FROM items WHERE (id = 555) LIMIT 1"]
|
1405
1331
|
end
|
1406
1332
|
|
1407
1333
|
specify "should remove cached associations" do
|
@@ -1415,10 +1341,11 @@ end
|
|
1415
1341
|
|
1416
1342
|
describe Sequel::Model, "typecasting" do
|
1417
1343
|
before do
|
1418
|
-
MODEL_DB.reset
|
1419
1344
|
@c = Class.new(Sequel::Model(:items)) do
|
1420
1345
|
columns :x
|
1421
1346
|
end
|
1347
|
+
@c.db_schema = {:x=>{:type=>:integer}}
|
1348
|
+
MODEL_DB.reset
|
1422
1349
|
end
|
1423
1350
|
|
1424
1351
|
after do
|
@@ -1427,14 +1354,13 @@ describe Sequel::Model, "typecasting" do
|
|
1427
1354
|
|
1428
1355
|
specify "should not convert if typecasting is turned off" do
|
1429
1356
|
@c.typecast_on_assignment = false
|
1430
|
-
@c.instance_variable_set(:@db_schema, {:x=>{:type=>:integer}})
|
1431
1357
|
m = @c.new
|
1432
1358
|
m.x = '1'
|
1433
1359
|
m.x.should == '1'
|
1434
1360
|
end
|
1435
1361
|
|
1436
1362
|
specify "should convert to integer for an integer field" do
|
1437
|
-
@c.
|
1363
|
+
@c.db_schema = {:x=>{:type=>:integer}}
|
1438
1364
|
m = @c.new
|
1439
1365
|
m.x = '1'
|
1440
1366
|
m.x.should == 1
|
@@ -1446,13 +1372,13 @@ describe Sequel::Model, "typecasting" do
|
|
1446
1372
|
|
1447
1373
|
specify "should typecast '' to nil unless type is string or blob" do
|
1448
1374
|
[:integer, :float, :decimal, :boolean, :date, :time, :datetime].each do |x|
|
1449
|
-
@c.
|
1375
|
+
@c.db_schema = {:x=>{:type=>x}}
|
1450
1376
|
m = @c.new
|
1451
1377
|
m.x = ''
|
1452
1378
|
m.x.should == nil
|
1453
1379
|
end
|
1454
1380
|
[:string, :blob].each do |x|
|
1455
|
-
@c.
|
1381
|
+
@c.db_schema = {:x=>{:type=>x}}
|
1456
1382
|
m = @c.new
|
1457
1383
|
m.x = ''
|
1458
1384
|
m.x.should == ''
|
@@ -1460,7 +1386,6 @@ describe Sequel::Model, "typecasting" do
|
|
1460
1386
|
end
|
1461
1387
|
|
1462
1388
|
specify "should not typecast '' to nil if typecast_empty_string_to_nil is false" do
|
1463
|
-
@c.instance_variable_set(:@db_schema, {:x=>{:type=>:integer}})
|
1464
1389
|
m = @c.new
|
1465
1390
|
m.typecast_empty_string_to_nil = false
|
1466
1391
|
proc{m.x = ''}.should raise_error
|
@@ -1469,21 +1394,21 @@ describe Sequel::Model, "typecasting" do
|
|
1469
1394
|
end
|
1470
1395
|
|
1471
1396
|
specify "should not typecast nil if NULLs are allowed" do
|
1472
|
-
@c.
|
1397
|
+
@c.db_schema[:x][:allow_null] = true
|
1473
1398
|
m = @c.new
|
1474
1399
|
m.x = nil
|
1475
1400
|
m.x.should == nil
|
1476
1401
|
end
|
1477
1402
|
|
1478
1403
|
specify "should raise an error if attempting to typecast nil and NULLs are not allowed" do
|
1479
|
-
@c.
|
1404
|
+
@c.db_schema[:x][:allow_null] = false
|
1480
1405
|
proc{@c.new.x = nil}.should raise_error(Sequel::Error)
|
1481
1406
|
proc{@c.new.x = ''}.should raise_error(Sequel::Error)
|
1482
1407
|
end
|
1483
1408
|
|
1484
1409
|
specify "should not raise an error if NULLs are not allowed and typecasting is turned off" do
|
1485
1410
|
@c.typecast_on_assignment = false
|
1486
|
-
@c.
|
1411
|
+
@c.db_schema[:x][:allow_null] = false
|
1487
1412
|
m = @c.new
|
1488
1413
|
m.x = nil
|
1489
1414
|
m.x.should == nil
|
@@ -1492,7 +1417,6 @@ describe Sequel::Model, "typecasting" do
|
|
1492
1417
|
specify "should not raise when typecasting nil to NOT NULL column but raise_on_typecast_failure is off" do
|
1493
1418
|
@c.raise_on_typecast_failure = false
|
1494
1419
|
@c.typecast_on_assignment = true
|
1495
|
-
@c.instance_variable_set(:@db_schema, {:x=>{:type=>:integer,:allow_null=>false}})
|
1496
1420
|
m = @c.new
|
1497
1421
|
m.x = ''
|
1498
1422
|
m.x.should == nil
|
@@ -1501,20 +1425,18 @@ describe Sequel::Model, "typecasting" do
|
|
1501
1425
|
end
|
1502
1426
|
|
1503
1427
|
specify "should raise an error if invalid data is used in an integer field" do
|
1504
|
-
@c.instance_variable_set(:@db_schema, {:x=>{:type=>:integer}})
|
1505
1428
|
proc{@c.new.x = 'a'}.should raise_error(Sequel::InvalidValue)
|
1506
1429
|
end
|
1507
1430
|
|
1508
1431
|
specify "should assign value if raise_on_typecast_failure is off and assigning invalid integer" do
|
1509
1432
|
@c.raise_on_typecast_failure = false
|
1510
|
-
@c.instance_variable_set(:@db_schema, {:x=>{:type=>:integer}})
|
1511
1433
|
model = @c.new
|
1512
1434
|
model.x = '1d'
|
1513
1435
|
model.x.should == '1d'
|
1514
1436
|
end
|
1515
1437
|
|
1516
1438
|
specify "should convert to float for a float field" do
|
1517
|
-
@c.
|
1439
|
+
@c.db_schema = {:x=>{:type=>:float}}
|
1518
1440
|
m = @c.new
|
1519
1441
|
m.x = '1.3'
|
1520
1442
|
m.x.should == 1.3
|
@@ -1525,20 +1447,20 @@ describe Sequel::Model, "typecasting" do
|
|
1525
1447
|
end
|
1526
1448
|
|
1527
1449
|
specify "should raise an error if invalid data is used in an float field" do
|
1528
|
-
@c.
|
1450
|
+
@c.db_schema = {:x=>{:type=>:float}}
|
1529
1451
|
proc{@c.new.x = 'a'}.should raise_error(Sequel::InvalidValue)
|
1530
1452
|
end
|
1531
1453
|
|
1532
1454
|
specify "should assign value if raise_on_typecast_failure is off and assigning invalid float" do
|
1533
1455
|
@c.raise_on_typecast_failure = false
|
1534
|
-
@c.
|
1456
|
+
@c.db_schema = {:x=>{:type=>:float}}
|
1535
1457
|
model = @c.new
|
1536
1458
|
model.x = '1d'
|
1537
1459
|
model.x.should == '1d'
|
1538
1460
|
end
|
1539
1461
|
|
1540
1462
|
specify "should convert to BigDecimal for a decimal field" do
|
1541
|
-
@c.
|
1463
|
+
@c.db_schema = {:x=>{:type=>:decimal}}
|
1542
1464
|
m = @c.new
|
1543
1465
|
bd = BigDecimal.new('1.0')
|
1544
1466
|
m.x = '1.0'
|
@@ -1552,13 +1474,13 @@ describe Sequel::Model, "typecasting" do
|
|
1552
1474
|
end
|
1553
1475
|
|
1554
1476
|
specify "should raise an error if invalid data is used in an decimal field" do
|
1555
|
-
@c.
|
1477
|
+
@c.db_schema = {:x=>{:type=>:decimal}}
|
1556
1478
|
proc{@c.new.x = Date.today}.should raise_error(Sequel::InvalidValue)
|
1557
1479
|
end
|
1558
1480
|
|
1559
1481
|
specify "should assign value if raise_on_typecast_failure is off and assigning invalid decimal" do
|
1560
1482
|
@c.raise_on_typecast_failure = false
|
1561
|
-
@c.
|
1483
|
+
@c.db_schema = {:x=>{:type=>:decimal}}
|
1562
1484
|
model = @c.new
|
1563
1485
|
time = Time.now
|
1564
1486
|
model.x = time
|
@@ -1566,7 +1488,7 @@ describe Sequel::Model, "typecasting" do
|
|
1566
1488
|
end
|
1567
1489
|
|
1568
1490
|
specify "should convert to string for a string field" do
|
1569
|
-
@c.
|
1491
|
+
@c.db_schema = {:x=>{:type=>:string}}
|
1570
1492
|
m = @c.new
|
1571
1493
|
m.x = '1.3'
|
1572
1494
|
m.x.should == '1.3'
|
@@ -1577,7 +1499,7 @@ describe Sequel::Model, "typecasting" do
|
|
1577
1499
|
end
|
1578
1500
|
|
1579
1501
|
specify "should convert to boolean for a boolean field" do
|
1580
|
-
@c.
|
1502
|
+
@c.db_schema = {:x=>{:type=>:boolean}}
|
1581
1503
|
m = @c.new
|
1582
1504
|
m.x = '1.3'
|
1583
1505
|
m.x.should == true
|
@@ -1589,6 +1511,10 @@ describe Sequel::Model, "typecasting" do
|
|
1589
1511
|
m.x.should == true
|
1590
1512
|
m.x = 'T'
|
1591
1513
|
m.x.should == true
|
1514
|
+
m.x = 'y'
|
1515
|
+
m.x.should == true
|
1516
|
+
m.x = 'Y'
|
1517
|
+
m.x.should == true
|
1592
1518
|
m.x = true
|
1593
1519
|
m.x.should == true
|
1594
1520
|
m.x = nil
|
@@ -1605,6 +1531,14 @@ describe Sequel::Model, "typecasting" do
|
|
1605
1531
|
m.x.should == false
|
1606
1532
|
m.x = 'FALSE'
|
1607
1533
|
m.x.should == false
|
1534
|
+
m.x = 'n'
|
1535
|
+
m.x.should == false
|
1536
|
+
m.x = 'N'
|
1537
|
+
m.x.should == false
|
1538
|
+
m.x = 'no'
|
1539
|
+
m.x.should == false
|
1540
|
+
m.x = 'NO'
|
1541
|
+
m.x.should == false
|
1608
1542
|
m.x = '0'
|
1609
1543
|
m.x.should == false
|
1610
1544
|
m.x = 0
|
@@ -1614,7 +1548,7 @@ describe Sequel::Model, "typecasting" do
|
|
1614
1548
|
end
|
1615
1549
|
|
1616
1550
|
specify "should convert to date for a date field" do
|
1617
|
-
@c.
|
1551
|
+
@c.db_schema = {:x=>{:type=>:date}}
|
1618
1552
|
m = @c.new
|
1619
1553
|
y = Date.new(2007,10,21)
|
1620
1554
|
m.x = '2007-10-21'
|
@@ -1628,7 +1562,7 @@ describe Sequel::Model, "typecasting" do
|
|
1628
1562
|
end
|
1629
1563
|
|
1630
1564
|
specify "should accept a hash with symbol or string keys for a date field" do
|
1631
|
-
@c.
|
1565
|
+
@c.db_schema = {:x=>{:type=>:date}}
|
1632
1566
|
m = @c.new
|
1633
1567
|
y = Date.new(2007,10,21)
|
1634
1568
|
m.x = {:year=>2007, :month=>10, :day=>21}
|
@@ -1638,32 +1572,33 @@ describe Sequel::Model, "typecasting" do
|
|
1638
1572
|
end
|
1639
1573
|
|
1640
1574
|
specify "should raise an error if invalid data is used in a date field" do
|
1641
|
-
@c.
|
1575
|
+
@c.db_schema = {:x=>{:type=>:date}}
|
1642
1576
|
proc{@c.new.x = 'a'}.should raise_error(Sequel::InvalidValue)
|
1643
1577
|
proc{@c.new.x = 100}.should raise_error(Sequel::InvalidValue)
|
1644
1578
|
end
|
1645
1579
|
|
1646
1580
|
specify "should assign value if raise_on_typecast_failure is off and assigning invalid date" do
|
1647
1581
|
@c.raise_on_typecast_failure = false
|
1648
|
-
@c.
|
1582
|
+
@c.db_schema = {:x=>{:type=>:date}}
|
1649
1583
|
model = @c.new
|
1650
1584
|
model.x = 4
|
1651
1585
|
model.x.should == 4
|
1652
1586
|
end
|
1653
1587
|
|
1654
|
-
specify "should convert to
|
1655
|
-
@c.
|
1588
|
+
specify "should convert to Sequel::SQLTime for a time field" do
|
1589
|
+
@c.db_schema = {:x=>{:type=>:time}}
|
1656
1590
|
m = @c.new
|
1657
1591
|
x = '10:20:30'
|
1658
|
-
y =
|
1592
|
+
y = Sequel::SQLTime.parse(x)
|
1659
1593
|
m.x = x
|
1660
1594
|
m.x.should == y
|
1661
1595
|
m.x = y
|
1662
1596
|
m.x.should == y
|
1597
|
+
m.x.should be_a_kind_of(Sequel::SQLTime)
|
1663
1598
|
end
|
1664
1599
|
|
1665
1600
|
specify "should accept a hash with symbol or string keys for a time field" do
|
1666
|
-
@c.
|
1601
|
+
@c.db_schema = {:x=>{:type=>:time}}
|
1667
1602
|
m = @c.new
|
1668
1603
|
y = Time.parse('10:20:30')
|
1669
1604
|
m.x = {:hour=>10, :minute=>20, :second=>30}
|
@@ -1673,7 +1608,7 @@ describe Sequel::Model, "typecasting" do
|
|
1673
1608
|
end
|
1674
1609
|
|
1675
1610
|
specify "should raise an error if invalid data is used in a time field" do
|
1676
|
-
@c.
|
1611
|
+
@c.db_schema = {:x=>{:type=>:time}}
|
1677
1612
|
proc{@c.new.x = '0000'}.should raise_error
|
1678
1613
|
proc{@c.new.x = Date.parse('2008-10-21')}.should raise_error(Sequel::InvalidValue)
|
1679
1614
|
proc{@c.new.x = DateTime.parse('2008-10-21')}.should raise_error(Sequel::InvalidValue)
|
@@ -1681,14 +1616,14 @@ describe Sequel::Model, "typecasting" do
|
|
1681
1616
|
|
1682
1617
|
specify "should assign value if raise_on_typecast_failure is off and assigning invalid time" do
|
1683
1618
|
@c.raise_on_typecast_failure = false
|
1684
|
-
@c.
|
1619
|
+
@c.db_schema = {:x=>{:type=>:time}}
|
1685
1620
|
model = @c.new
|
1686
1621
|
model.x = '0000'
|
1687
1622
|
model.x.should == '0000'
|
1688
1623
|
end
|
1689
1624
|
|
1690
1625
|
specify "should convert to the Sequel.datetime_class for a datetime field" do
|
1691
|
-
@c.
|
1626
|
+
@c.db_schema = {:x=>{:type=>:datetime}}
|
1692
1627
|
m = @c.new
|
1693
1628
|
x = '2007-10-21T10:20:30-07:00'
|
1694
1629
|
y = Time.parse(x)
|
@@ -1713,7 +1648,7 @@ describe Sequel::Model, "typecasting" do
|
|
1713
1648
|
end
|
1714
1649
|
|
1715
1650
|
specify "should accept a hash with symbol or string keys for a datetime field" do
|
1716
|
-
@c.
|
1651
|
+
@c.db_schema = {:x=>{:type=>:datetime}}
|
1717
1652
|
m = @c.new
|
1718
1653
|
y = Time.parse('2007-10-21 10:20:30')
|
1719
1654
|
m.x = {:year=>2007, :month=>10, :day=>21, :hour=>10, :minute=>20, :second=>30}
|
@@ -1729,7 +1664,7 @@ describe Sequel::Model, "typecasting" do
|
|
1729
1664
|
end
|
1730
1665
|
|
1731
1666
|
specify "should raise an error if invalid data is used in a datetime field" do
|
1732
|
-
@c.
|
1667
|
+
@c.db_schema = {:x=>{:type=>:datetime}}
|
1733
1668
|
proc{@c.new.x = '0000'}.should raise_error(Sequel::InvalidValue)
|
1734
1669
|
Sequel.datetime_class = DateTime
|
1735
1670
|
proc{@c.new.x = '0000'}.should raise_error(Sequel::InvalidValue)
|
@@ -1738,7 +1673,7 @@ describe Sequel::Model, "typecasting" do
|
|
1738
1673
|
|
1739
1674
|
specify "should assign value if raise_on_typecast_failure is off and assigning invalid datetime" do
|
1740
1675
|
@c.raise_on_typecast_failure = false
|
1741
|
-
@c.
|
1676
|
+
@c.db_schema = {:x=>{:type=>:datetime}}
|
1742
1677
|
model = @c.new
|
1743
1678
|
model.x = '0000'
|
1744
1679
|
model.x.should == '0000'
|
@@ -1756,11 +1691,7 @@ describe "Model#lock!" do
|
|
1756
1691
|
@c = Class.new(Sequel::Model(:items)) do
|
1757
1692
|
columns :id
|
1758
1693
|
end
|
1759
|
-
|
1760
|
-
def ds.fetch_rows(sql)
|
1761
|
-
db.execute(sql)
|
1762
|
-
yield({:id=>1})
|
1763
|
-
end
|
1694
|
+
@c.dataset._fetch = {:id=>1}
|
1764
1695
|
MODEL_DB.reset
|
1765
1696
|
end
|
1766
1697
|
|