sequel 3.21.0 → 3.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +413 -3
- data/README.rdoc +20 -6
- data/Rakefile +23 -16
- data/bin/sequel +1 -5
- data/doc/association_basics.rdoc +210 -43
- data/doc/dataset_basics.rdoc +4 -4
- data/doc/mass_assignment.rdoc +54 -0
- data/doc/migration.rdoc +15 -538
- data/doc/model_hooks.rdoc +72 -27
- data/doc/opening_databases.rdoc +86 -50
- data/doc/prepared_statements.rdoc +40 -13
- data/doc/reflection.rdoc +8 -2
- data/doc/release_notes/3.22.0.txt +39 -0
- data/doc/release_notes/3.23.0.txt +172 -0
- data/doc/release_notes/3.24.0.txt +420 -0
- data/doc/release_notes/3.25.0.txt +88 -0
- data/doc/release_notes/3.26.0.txt +88 -0
- data/doc/release_notes/3.27.0.txt +82 -0
- data/doc/release_notes/3.28.0.txt +304 -0
- data/doc/release_notes/3.29.0.txt +459 -0
- data/doc/schema_modification.rdoc +547 -0
- data/doc/sharding.rdoc +7 -1
- data/doc/testing.rdoc +115 -0
- data/doc/transactions.rdoc +137 -0
- data/doc/virtual_rows.rdoc +2 -2
- data/lib/sequel/adapters/ado/mssql.rb +18 -6
- data/lib/sequel/adapters/ado.rb +40 -18
- data/lib/sequel/adapters/amalgalite.rb +15 -7
- data/lib/sequel/adapters/db2.rb +175 -86
- data/lib/sequel/adapters/dbi.rb +15 -15
- 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/do.rb +17 -36
- data/lib/sequel/adapters/firebird.rb +27 -208
- data/lib/sequel/adapters/ibmdb.rb +448 -0
- data/lib/sequel/adapters/informix.rb +6 -23
- data/lib/sequel/adapters/jdbc/as400.rb +5 -31
- data/lib/sequel/adapters/jdbc/db2.rb +44 -0
- data/lib/sequel/adapters/jdbc/derby.rb +217 -0
- data/lib/sequel/adapters/jdbc/firebird.rb +29 -0
- data/lib/sequel/adapters/jdbc/h2.rb +26 -17
- data/lib/sequel/adapters/jdbc/hsqldb.rb +166 -0
- data/lib/sequel/adapters/jdbc/informix.rb +26 -0
- data/lib/sequel/adapters/jdbc/jtds.rb +29 -0
- data/lib/sequel/adapters/jdbc/mssql.rb +0 -32
- data/lib/sequel/adapters/jdbc/mysql.rb +9 -10
- data/lib/sequel/adapters/jdbc/oracle.rb +67 -25
- data/lib/sequel/adapters/jdbc/postgresql.rb +6 -11
- data/lib/sequel/adapters/jdbc/sqlite.rb +0 -5
- data/lib/sequel/adapters/jdbc/sqlserver.rb +41 -0
- data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
- data/lib/sequel/adapters/jdbc.rb +107 -38
- data/lib/sequel/adapters/mock.rb +315 -0
- data/lib/sequel/adapters/mysql.rb +78 -182
- data/lib/sequel/adapters/mysql2.rb +24 -23
- data/lib/sequel/adapters/odbc/db2.rb +17 -0
- data/lib/sequel/adapters/odbc/mssql.rb +0 -5
- data/lib/sequel/adapters/odbc.rb +28 -9
- data/lib/sequel/adapters/openbase.rb +2 -4
- data/lib/sequel/adapters/oracle.rb +349 -51
- data/lib/sequel/adapters/postgres.rb +169 -21
- data/lib/sequel/adapters/shared/access.rb +21 -6
- data/lib/sequel/adapters/shared/db2.rb +288 -0
- data/lib/sequel/adapters/shared/firebird.rb +214 -0
- data/lib/sequel/adapters/shared/informix.rb +45 -0
- data/lib/sequel/adapters/shared/mssql.rb +108 -65
- data/lib/sequel/adapters/shared/mysql.rb +56 -13
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +149 -0
- data/lib/sequel/adapters/shared/oracle.rb +185 -34
- data/lib/sequel/adapters/shared/postgres.rb +107 -58
- data/lib/sequel/adapters/shared/progress.rb +0 -6
- data/lib/sequel/adapters/shared/sqlite.rb +168 -41
- data/lib/sequel/adapters/sqlite.rb +27 -18
- data/lib/sequel/adapters/swift/mysql.rb +9 -5
- data/lib/sequel/adapters/swift/postgres.rb +0 -5
- data/lib/sequel/adapters/swift/sqlite.rb +6 -4
- data/lib/sequel/adapters/swift.rb +5 -5
- data/lib/sequel/adapters/tinytds.rb +152 -17
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +63 -0
- data/lib/sequel/ast_transformer.rb +190 -0
- data/lib/sequel/connection_pool/threaded.rb +3 -2
- data/lib/sequel/connection_pool.rb +1 -1
- data/lib/sequel/core.rb +46 -5
- data/lib/sequel/database/connecting.rb +5 -6
- data/lib/sequel/database/dataset.rb +4 -4
- data/lib/sequel/database/dataset_defaults.rb +59 -1
- data/lib/sequel/database/logging.rb +1 -1
- data/lib/sequel/database/misc.rb +100 -19
- data/lib/sequel/database/query.rb +153 -58
- data/lib/sequel/database/schema_generator.rb +8 -5
- data/lib/sequel/database/schema_methods.rb +59 -29
- data/lib/sequel/dataset/actions.rb +194 -57
- data/lib/sequel/dataset/features.rb +81 -8
- data/lib/sequel/dataset/graph.rb +8 -7
- data/lib/sequel/dataset/misc.rb +50 -23
- data/lib/sequel/dataset/mutation.rb +5 -6
- data/lib/sequel/dataset/prepared_statements.rb +32 -15
- data/lib/sequel/dataset/query.rb +223 -42
- data/lib/sequel/dataset/sql.rb +58 -61
- data/lib/sequel/dataset.rb +8 -0
- data/lib/sequel/exceptions.rb +4 -0
- data/lib/sequel/extensions/columns_introspection.rb +61 -0
- data/lib/sequel/extensions/migration.rb +6 -4
- data/lib/sequel/extensions/named_timezones.rb +5 -0
- data/lib/sequel/extensions/thread_local_timezones.rb +1 -1
- data/lib/sequel/extensions/to_dot.rb +95 -83
- data/lib/sequel/model/associations.rb +997 -331
- data/lib/sequel/model/base.rb +386 -129
- data/lib/sequel/model/errors.rb +1 -1
- data/lib/sequel/model/exceptions.rb +5 -1
- data/lib/sequel/model.rb +15 -8
- data/lib/sequel/plugins/association_pks.rb +22 -4
- data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
- data/lib/sequel/plugins/dataset_associations.rb +100 -0
- data/lib/sequel/plugins/defaults_setter.rb +58 -0
- data/lib/sequel/plugins/force_encoding.rb +6 -6
- data/lib/sequel/plugins/identity_map.rb +114 -7
- data/lib/sequel/plugins/many_through_many.rb +65 -7
- data/lib/sequel/plugins/prepared_statements.rb +151 -0
- data/lib/sequel/plugins/prepared_statements_associations.rb +84 -0
- data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
- data/lib/sequel/plugins/rcte_tree.rb +29 -15
- data/lib/sequel/plugins/serialization.rb +6 -1
- data/lib/sequel/plugins/serialization_modification_detection.rb +51 -0
- data/lib/sequel/plugins/sharding.rb +12 -25
- data/lib/sequel/plugins/single_table_inheritance.rb +3 -1
- data/lib/sequel/plugins/typecast_on_load.rb +9 -12
- data/lib/sequel/plugins/update_primary_key.rb +2 -2
- data/lib/sequel/plugins/xml_serializer.rb +3 -3
- data/lib/sequel/sql.rb +107 -51
- data/lib/sequel/timezones.rb +44 -35
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +146 -0
- data/spec/adapters/mssql_spec.rb +65 -29
- data/spec/adapters/mysql_spec.rb +122 -123
- data/spec/adapters/oracle_spec.rb +48 -76
- data/spec/adapters/postgres_spec.rb +213 -61
- data/spec/adapters/spec_helper.rb +6 -5
- data/spec/adapters/sqlite_spec.rb +35 -21
- data/spec/core/connection_pool_spec.rb +71 -92
- data/spec/core/core_sql_spec.rb +20 -31
- data/spec/core/database_spec.rb +729 -508
- data/spec/core/dataset_spec.rb +980 -1044
- data/spec/core/expression_filters_spec.rb +159 -42
- 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 +298 -38
- data/spec/core/spec_helper.rb +6 -48
- data/spec/extensions/association_pks_spec.rb +38 -0
- data/spec/extensions/class_table_inheritance_spec.rb +1 -1
- data/spec/extensions/columns_introspection_spec.rb +91 -0
- data/spec/extensions/dataset_associations_spec.rb +199 -0
- data/spec/extensions/defaults_setter_spec.rb +64 -0
- data/spec/extensions/identity_map_spec.rb +162 -0
- data/spec/extensions/instance_hooks_spec.rb +71 -0
- data/spec/extensions/many_through_many_spec.rb +195 -20
- data/spec/extensions/migration_spec.rb +17 -17
- data/spec/extensions/named_timezones_spec.rb +22 -2
- data/spec/extensions/nested_attributes_spec.rb +4 -0
- data/spec/extensions/prepared_statements_associations_spec.rb +126 -0
- data/spec/extensions/prepared_statements_safe_spec.rb +79 -0
- data/spec/extensions/prepared_statements_spec.rb +72 -0
- data/spec/extensions/prepared_statements_with_pk_spec.rb +38 -0
- data/spec/extensions/schema_dumper_spec.rb +2 -2
- data/spec/extensions/schema_spec.rb +13 -21
- data/spec/extensions/serialization_modification_detection_spec.rb +37 -0
- data/spec/extensions/serialization_spec.rb +5 -8
- data/spec/extensions/single_table_inheritance_spec.rb +11 -0
- data/spec/extensions/spec_helper.rb +7 -1
- data/spec/extensions/thread_local_timezones_spec.rb +22 -2
- data/spec/extensions/to_dot_spec.rb +3 -5
- data/spec/extensions/typecast_on_load_spec.rb +1 -6
- data/spec/extensions/xml_serializer_spec.rb +16 -4
- data/spec/integration/associations_test.rb +522 -21
- data/spec/integration/database_test.rb +4 -2
- data/spec/integration/dataset_test.rb +375 -62
- data/spec/integration/eager_loader_test.rb +19 -21
- data/spec/integration/model_test.rb +80 -1
- data/spec/integration/plugin_test.rb +304 -116
- data/spec/integration/prepared_statement_test.rb +200 -120
- data/spec/integration/schema_test.rb +161 -30
- data/spec/integration/spec_helper.rb +39 -30
- data/spec/integration/timezone_test.rb +38 -12
- data/spec/integration/transaction_test.rb +172 -5
- data/spec/integration/type_test.rb +17 -3
- data/spec/model/association_reflection_spec.rb +174 -7
- data/spec/model/associations_spec.rb +849 -661
- data/spec/model/base_spec.rb +255 -95
- data/spec/model/dataset_methods_spec.rb +7 -27
- data/spec/model/eager_loading_spec.rb +640 -676
- data/spec/model/hooks_spec.rb +309 -67
- data/spec/model/model_spec.rb +207 -167
- data/spec/model/plugins_spec.rb +24 -13
- data/spec/model/record_spec.rb +321 -218
- data/spec/model/spec_helper.rb +13 -71
- data/spec/model/validations_spec.rb +11 -0
- metadata +95 -38
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,32 +26,37 @@ 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}
|
|
42
|
+
def ds.supports_insert_select?() true end
|
|
55
43
|
def ds.insert_select(hash)
|
|
56
|
-
execute("INSERT INTO items (y) VALUES (2)")
|
|
57
|
-
{:y=>2}
|
|
44
|
+
execute("INSERT INTO items (y) VALUES (2) RETURNING *"){|r| return r}
|
|
58
45
|
end
|
|
59
46
|
o = @c.new(:x => 1)
|
|
60
47
|
o.save
|
|
61
48
|
|
|
62
49
|
o.values.should == {:y=>2}
|
|
63
|
-
MODEL_DB.sqls.should == ["INSERT INTO items (y) VALUES (2)"]
|
|
50
|
+
MODEL_DB.sqls.should == ["INSERT INTO items (y) VALUES (2) RETURNING *"]
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it "should not use dataset's insert_select method if specific columns are selected" do
|
|
54
|
+
ds = @c.dataset = @c.dataset.select(:y)
|
|
55
|
+
ds.should_not_receive(:insert_select)
|
|
56
|
+
@c.new(:x => 1).save
|
|
64
57
|
end
|
|
65
58
|
|
|
66
59
|
it "should use value returned by insert as the primary key and refresh the object" do
|
|
67
|
-
@c.dataset.meta_def(:insert){|h| super(h); 13}
|
|
68
60
|
o = @c.new(:x => 11)
|
|
69
61
|
o.save
|
|
70
62
|
MODEL_DB.sqls.should == ["INSERT INTO items (x) VALUES (11)",
|
|
@@ -72,14 +64,12 @@ describe "Model#save" do
|
|
|
72
64
|
end
|
|
73
65
|
|
|
74
66
|
it "should allow you to skip refreshing by overridding _save_refresh" do
|
|
75
|
-
@c.dataset.meta_def(:insert){|h| super(h); 13}
|
|
76
67
|
@c.send(:define_method, :_save_refresh){}
|
|
77
68
|
@c.create(:x => 11)
|
|
78
69
|
MODEL_DB.sqls.should == ["INSERT INTO items (x) VALUES (11)"]
|
|
79
70
|
end
|
|
80
71
|
|
|
81
72
|
it "should work correctly for inserting a record without a primary key" do
|
|
82
|
-
@c.dataset.meta_def(:insert){|h| super(h); 13}
|
|
83
73
|
@c.no_primary_key
|
|
84
74
|
o = @c.new(:x => 11)
|
|
85
75
|
o.save
|
|
@@ -87,15 +77,15 @@ describe "Model#save" do
|
|
|
87
77
|
end
|
|
88
78
|
|
|
89
79
|
it "should set the autoincrementing_primary_key value to the value returned by insert" do
|
|
90
|
-
@c.dataset.meta_def(:insert){|h| super(h); 13}
|
|
91
80
|
@c.unrestrict_primary_key
|
|
92
81
|
@c.set_primary_key [:x, :y]
|
|
93
82
|
o = @c.new(:x => 11)
|
|
94
83
|
o.meta_def(:autoincrementing_primary_key){:y}
|
|
95
84
|
o.save
|
|
96
|
-
MODEL_DB.sqls
|
|
97
|
-
|
|
98
|
-
|
|
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}
|
|
99
89
|
end
|
|
100
90
|
|
|
101
91
|
it "should update a record for an existing model instance" do
|
|
@@ -106,17 +96,18 @@ describe "Model#save" do
|
|
|
106
96
|
|
|
107
97
|
it "should raise a NoExistingObject exception if the dataset update call doesn't return 1, unless require_modification is false" do
|
|
108
98
|
o = @c.load(:id => 3, :x => 1)
|
|
109
|
-
o.this
|
|
99
|
+
t = o.this
|
|
100
|
+
t.numrows = 0
|
|
110
101
|
proc{o.save}.should raise_error(Sequel::NoExistingObject)
|
|
111
|
-
|
|
102
|
+
t.numrows = 2
|
|
112
103
|
proc{o.save}.should raise_error(Sequel::NoExistingObject)
|
|
113
|
-
|
|
104
|
+
t.numrows = 1
|
|
114
105
|
proc{o.save}.should_not raise_error
|
|
115
106
|
|
|
116
107
|
o.require_modification = false
|
|
117
|
-
|
|
108
|
+
t.numrows = 0
|
|
118
109
|
proc{o.save}.should_not raise_error
|
|
119
|
-
|
|
110
|
+
t.numrows = 2
|
|
120
111
|
proc{o.save}.should_not raise_error
|
|
121
112
|
end
|
|
122
113
|
|
|
@@ -185,22 +176,18 @@ describe "Model#save" do
|
|
|
185
176
|
@c.use_transactions = true
|
|
186
177
|
@c.load(:id => 3, :x => 1, :y => nil).save(:y)
|
|
187
178
|
MODEL_DB.sqls.should == ["BEGIN", "UPDATE items SET y = NULL WHERE (id = 3)", "COMMIT"]
|
|
188
|
-
MODEL_DB.reset
|
|
189
179
|
@c.use_transactions = false
|
|
190
180
|
@c.load(:id => 3, :x => 1, :y => nil).save(:y)
|
|
191
181
|
MODEL_DB.sqls.should == ["UPDATE items SET y = NULL WHERE (id = 3)"]
|
|
192
|
-
MODEL_DB.reset
|
|
193
182
|
end
|
|
194
183
|
|
|
195
184
|
it "should inherit Model's use_transactions setting" do
|
|
196
185
|
@c.use_transactions = true
|
|
197
186
|
Class.new(@c).load(:id => 3, :x => 1, :y => nil).save(:y)
|
|
198
187
|
MODEL_DB.sqls.should == ["BEGIN", "UPDATE items SET y = NULL WHERE (id = 3)", "COMMIT"]
|
|
199
|
-
MODEL_DB.reset
|
|
200
188
|
@c.use_transactions = false
|
|
201
189
|
Class.new(@c).load(:id => 3, :x => 1, :y => nil).save(:y)
|
|
202
190
|
MODEL_DB.sqls.should == ["UPDATE items SET y = NULL WHERE (id = 3)"]
|
|
203
|
-
MODEL_DB.reset
|
|
204
191
|
end
|
|
205
192
|
|
|
206
193
|
it "should use object's use_transactions setting" do
|
|
@@ -209,13 +196,11 @@ describe "Model#save" do
|
|
|
209
196
|
@c.use_transactions = true
|
|
210
197
|
o.save(:y)
|
|
211
198
|
MODEL_DB.sqls.should == ["UPDATE items SET y = NULL WHERE (id = 3)"]
|
|
212
|
-
MODEL_DB.reset
|
|
213
199
|
o = @c.load(:id => 3, :x => 1, :y => nil)
|
|
214
200
|
o.use_transactions = true
|
|
215
201
|
@c.use_transactions = false
|
|
216
202
|
o.save(:y)
|
|
217
203
|
MODEL_DB.sqls.should == ["BEGIN", "UPDATE items SET y = NULL WHERE (id = 3)", "COMMIT"]
|
|
218
|
-
MODEL_DB.reset
|
|
219
204
|
end
|
|
220
205
|
|
|
221
206
|
it "should use :transaction option if given" do
|
|
@@ -223,12 +208,10 @@ describe "Model#save" do
|
|
|
223
208
|
o.use_transactions = true
|
|
224
209
|
o.save(:y, :transaction=>false)
|
|
225
210
|
MODEL_DB.sqls.should == ["UPDATE items SET y = NULL WHERE (id = 3)"]
|
|
226
|
-
MODEL_DB.reset
|
|
227
211
|
o = @c.load(:id => 3, :x => 1, :y => nil)
|
|
228
212
|
o.use_transactions = false
|
|
229
213
|
o.save(:y, :transaction=>true)
|
|
230
214
|
MODEL_DB.sqls.should == ["BEGIN", "UPDATE items SET y = NULL WHERE (id = 3)", "COMMIT"]
|
|
231
|
-
MODEL_DB.reset
|
|
232
215
|
end
|
|
233
216
|
|
|
234
217
|
it "should rollback if before_save returns false and raise_on_save_failure = true" do
|
|
@@ -240,7 +223,6 @@ describe "Model#save" do
|
|
|
240
223
|
end
|
|
241
224
|
proc { o.save(:y) }.should raise_error(Sequel::BeforeHookFailed)
|
|
242
225
|
MODEL_DB.sqls.should == ["BEGIN", "ROLLBACK"]
|
|
243
|
-
MODEL_DB.reset
|
|
244
226
|
end
|
|
245
227
|
|
|
246
228
|
it "should rollback if before_save returns false and :raise_on_failure option is true" do
|
|
@@ -252,7 +234,6 @@ describe "Model#save" do
|
|
|
252
234
|
end
|
|
253
235
|
proc { o.save(:y, :raise_on_failure => true) }.should raise_error(Sequel::BeforeHookFailed)
|
|
254
236
|
MODEL_DB.sqls.should == ["BEGIN", "ROLLBACK"]
|
|
255
|
-
MODEL_DB.reset
|
|
256
237
|
end
|
|
257
238
|
|
|
258
239
|
it "should not rollback outer transactions if before_save returns false and raise_on_save_failure = false" do
|
|
@@ -267,7 +248,6 @@ describe "Model#save" do
|
|
|
267
248
|
MODEL_DB.run "BLAH"
|
|
268
249
|
end
|
|
269
250
|
MODEL_DB.sqls.should == ["BEGIN", "BLAH", "COMMIT"]
|
|
270
|
-
MODEL_DB.reset
|
|
271
251
|
end
|
|
272
252
|
|
|
273
253
|
it "should rollback if before_save returns false and raise_on_save_failure = false" do
|
|
@@ -279,7 +259,6 @@ describe "Model#save" do
|
|
|
279
259
|
end
|
|
280
260
|
o.save(:y).should == nil
|
|
281
261
|
MODEL_DB.sqls.should == ["BEGIN", "ROLLBACK"]
|
|
282
|
-
MODEL_DB.reset
|
|
283
262
|
end
|
|
284
263
|
|
|
285
264
|
it "should not rollback if before_save throws Rollback and use_transactions = false" do
|
|
@@ -290,7 +269,6 @@ describe "Model#save" do
|
|
|
290
269
|
end
|
|
291
270
|
proc { o.save(:y) }.should raise_error(Sequel::Rollback)
|
|
292
271
|
MODEL_DB.sqls.should == []
|
|
293
|
-
MODEL_DB.reset
|
|
294
272
|
end
|
|
295
273
|
end
|
|
296
274
|
|
|
@@ -299,7 +277,6 @@ describe "Model#marshallable" do
|
|
|
299
277
|
class ::Album < Sequel::Model
|
|
300
278
|
columns :id, :x
|
|
301
279
|
end
|
|
302
|
-
Album.dataset.meta_def(:insert){|h| super(h); 1}
|
|
303
280
|
end
|
|
304
281
|
after do
|
|
305
282
|
Object.send(:remove_const, :Album)
|
|
@@ -381,7 +358,6 @@ describe "Model#modified[!?]" do
|
|
|
381
358
|
end
|
|
382
359
|
|
|
383
360
|
describe "Model#save_changes" do
|
|
384
|
-
|
|
385
361
|
before do
|
|
386
362
|
@c = Class.new(Sequel::Model(:items)) do
|
|
387
363
|
unrestrict_primary_key
|
|
@@ -426,15 +402,14 @@ describe "Model#save_changes" do
|
|
|
426
402
|
MODEL_DB.sqls.should == ["UPDATE items SET x = 2 WHERE (id = 3)"]
|
|
427
403
|
o.save_changes
|
|
428
404
|
o.save_changes
|
|
429
|
-
MODEL_DB.sqls.should == [
|
|
430
|
-
MODEL_DB.reset
|
|
405
|
+
MODEL_DB.sqls.should == []
|
|
431
406
|
|
|
432
407
|
o.y = 4
|
|
433
408
|
o.save_changes
|
|
434
409
|
MODEL_DB.sqls.should == ["UPDATE items SET y = 4 WHERE (id = 3)"]
|
|
435
410
|
o.save_changes
|
|
436
411
|
o.save_changes
|
|
437
|
-
MODEL_DB.sqls.should == [
|
|
412
|
+
MODEL_DB.sqls.should == []
|
|
438
413
|
end
|
|
439
414
|
|
|
440
415
|
it "should not consider columns changed if the values did not change" do
|
|
@@ -446,7 +421,6 @@ describe "Model#save_changes" do
|
|
|
446
421
|
o.x = 3
|
|
447
422
|
o.save_changes
|
|
448
423
|
MODEL_DB.sqls.should == ["UPDATE items SET x = 3 WHERE (id = 3)"]
|
|
449
|
-
MODEL_DB.reset
|
|
450
424
|
|
|
451
425
|
o[:y] = nil
|
|
452
426
|
o.save_changes
|
|
@@ -472,13 +446,11 @@ describe "Model#save_changes" do
|
|
|
472
446
|
o.x = 2
|
|
473
447
|
o.save_changes
|
|
474
448
|
MODEL_DB.sqls.should == ["UPDATE items SET x = 3 WHERE (id = 3)"]
|
|
475
|
-
MODEL_DB.reset
|
|
476
449
|
o.save_changes
|
|
477
450
|
MODEL_DB.sqls.should == []
|
|
478
451
|
o.x = 4
|
|
479
452
|
o.save_changes
|
|
480
453
|
MODEL_DB.sqls.should == ["UPDATE items SET x = 5 WHERE (id = 3)"]
|
|
481
|
-
MODEL_DB.reset
|
|
482
454
|
end
|
|
483
455
|
|
|
484
456
|
it "should update columns changed in a before_save hook" do
|
|
@@ -489,25 +461,21 @@ describe "Model#save_changes" do
|
|
|
489
461
|
o.x = 2
|
|
490
462
|
o.save_changes
|
|
491
463
|
MODEL_DB.sqls.should == ["UPDATE items SET x = 3 WHERE (id = 3)"]
|
|
492
|
-
MODEL_DB.reset
|
|
493
464
|
o.save_changes
|
|
494
465
|
MODEL_DB.sqls.should == []
|
|
495
466
|
o.x = 4
|
|
496
467
|
o.save_changes
|
|
497
468
|
MODEL_DB.sqls.should == ["UPDATE items SET x = 5 WHERE (id = 3)"]
|
|
498
|
-
MODEL_DB.reset
|
|
499
469
|
end
|
|
500
470
|
end
|
|
501
471
|
|
|
502
472
|
describe "Model#new?" do
|
|
503
|
-
|
|
504
|
-
before(:each) do
|
|
505
|
-
MODEL_DB.reset
|
|
506
|
-
|
|
473
|
+
before do
|
|
507
474
|
@c = Class.new(Sequel::Model(:items)) do
|
|
508
475
|
unrestrict_primary_key
|
|
509
476
|
columns :x
|
|
510
477
|
end
|
|
478
|
+
MODEL_DB.reset
|
|
511
479
|
end
|
|
512
480
|
|
|
513
481
|
it "should be true for a new instance" do
|
|
@@ -523,74 +491,65 @@ describe "Model#new?" do
|
|
|
523
491
|
end
|
|
524
492
|
|
|
525
493
|
describe Sequel::Model, "w/ primary key" do
|
|
526
|
-
|
|
527
494
|
it "should default to ':id'" do
|
|
528
495
|
model_a = Class.new Sequel::Model
|
|
529
|
-
model_a.primary_key.should
|
|
496
|
+
model_a.primary_key.should == :id
|
|
530
497
|
end
|
|
531
498
|
|
|
532
499
|
it "should be changed through 'set_primary_key'" do
|
|
533
|
-
model_a = Class.new(Sequel::Model)
|
|
534
|
-
model_a.primary_key.should
|
|
500
|
+
model_a = Class.new(Sequel::Model){ set_primary_key :a }
|
|
501
|
+
model_a.primary_key.should == :a
|
|
535
502
|
end
|
|
536
503
|
|
|
537
504
|
it "should support multi argument composite keys" do
|
|
538
|
-
model_a = Class.new(Sequel::Model)
|
|
539
|
-
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]
|
|
540
507
|
end
|
|
541
508
|
|
|
542
509
|
it "should accept single argument composite keys" do
|
|
543
|
-
model_a = Class.new(Sequel::Model)
|
|
544
|
-
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]
|
|
545
512
|
end
|
|
546
|
-
|
|
547
513
|
end
|
|
548
514
|
|
|
549
515
|
describe Sequel::Model, "w/o primary key" do
|
|
550
516
|
it "should return nil for primary key" do
|
|
551
|
-
Class.new(Sequel::Model)
|
|
517
|
+
Class.new(Sequel::Model){no_primary_key}.primary_key.should be_nil
|
|
552
518
|
end
|
|
553
519
|
|
|
554
520
|
it "should raise a Sequel::Error on 'this'" do
|
|
555
|
-
instance = Class.new(Sequel::Model)
|
|
556
|
-
proc
|
|
521
|
+
instance = Class.new(Sequel::Model){no_primary_key}.new
|
|
522
|
+
proc{instance.this}.should raise_error(Sequel::Error)
|
|
557
523
|
end
|
|
558
524
|
end
|
|
559
525
|
|
|
560
526
|
describe Sequel::Model, "with this" do
|
|
561
|
-
|
|
562
|
-
|
|
527
|
+
before do
|
|
528
|
+
@example = Class.new(Sequel::Model(:examples))
|
|
529
|
+
@example.columns :id, :a, :x, :y
|
|
530
|
+
end
|
|
563
531
|
|
|
564
532
|
it "should return a dataset identifying the record" do
|
|
565
|
-
instance = @example.load
|
|
566
|
-
instance.this.sql.should
|
|
533
|
+
instance = @example.load(:id => 3)
|
|
534
|
+
instance.this.sql.should == "SELECT * FROM examples WHERE (id = 3) LIMIT 1"
|
|
567
535
|
end
|
|
568
536
|
|
|
569
537
|
it "should support arbitary primary keys" do
|
|
570
538
|
@example.set_primary_key :a
|
|
571
539
|
|
|
572
|
-
instance = @example.load
|
|
573
|
-
instance.this.sql.should
|
|
540
|
+
instance = @example.load(:a => 3)
|
|
541
|
+
instance.this.sql.should == "SELECT * FROM examples WHERE (a = 3) LIMIT 1"
|
|
574
542
|
end
|
|
575
543
|
|
|
576
544
|
it "should support composite primary keys" do
|
|
577
545
|
@example.set_primary_key :x, :y
|
|
578
|
-
instance = @example.load
|
|
579
|
-
|
|
580
|
-
parts = [
|
|
581
|
-
'SELECT * FROM examples WHERE %s LIMIT 1',
|
|
582
|
-
'((x = 4) AND (y = 5))',
|
|
583
|
-
'((y = 5) AND (x = 4))'
|
|
584
|
-
].map { |expr| Regexp.escape expr }
|
|
585
|
-
regexp = Regexp.new parts.first % "(?:#{parts[1]}|#{parts[2]})"
|
|
586
|
-
|
|
587
|
-
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/
|
|
588
548
|
end
|
|
589
|
-
|
|
590
549
|
end
|
|
591
550
|
|
|
592
551
|
describe "Model#pk" do
|
|
593
|
-
before
|
|
552
|
+
before do
|
|
594
553
|
@m = Class.new(Sequel::Model)
|
|
595
554
|
@m.columns :id, :x, :y
|
|
596
555
|
end
|
|
@@ -623,8 +582,42 @@ describe "Model#pk" do
|
|
|
623
582
|
end
|
|
624
583
|
end
|
|
625
584
|
|
|
585
|
+
describe "Model#pk_or_nil" do
|
|
586
|
+
before do
|
|
587
|
+
@m = Class.new(Sequel::Model)
|
|
588
|
+
@m.columns :id, :x, :y
|
|
589
|
+
end
|
|
590
|
+
|
|
591
|
+
it "should be default return the value of the :id column" do
|
|
592
|
+
m = @m.load(:id => 111, :x => 2, :y => 3)
|
|
593
|
+
m.pk_or_nil.should == 111
|
|
594
|
+
end
|
|
595
|
+
|
|
596
|
+
it "should be return the primary key value for custom primary key" do
|
|
597
|
+
@m.set_primary_key :x
|
|
598
|
+
m = @m.load(:id => 111, :x => 2, :y => 3)
|
|
599
|
+
m.pk_or_nil.should == 2
|
|
600
|
+
end
|
|
601
|
+
|
|
602
|
+
it "should be return the primary key value for composite primary key" do
|
|
603
|
+
@m.set_primary_key [:y, :x]
|
|
604
|
+
m = @m.load(:id => 111, :x => 2, :y => 3)
|
|
605
|
+
m.pk_or_nil.should == [3, 2]
|
|
606
|
+
end
|
|
607
|
+
|
|
608
|
+
it "should raise if no primary key" do
|
|
609
|
+
@m.set_primary_key nil
|
|
610
|
+
m = @m.new(:id => 111, :x => 2, :y => 3)
|
|
611
|
+
m.pk_or_nil.should be_nil
|
|
612
|
+
|
|
613
|
+
@m.no_primary_key
|
|
614
|
+
m = @m.new(:id => 111, :x => 2, :y => 3)
|
|
615
|
+
m.pk_or_nil.should be_nil
|
|
616
|
+
end
|
|
617
|
+
end
|
|
618
|
+
|
|
626
619
|
describe "Model#pk_hash" do
|
|
627
|
-
before
|
|
620
|
+
before do
|
|
628
621
|
@m = Class.new(Sequel::Model)
|
|
629
622
|
@m.columns :id, :x, :y
|
|
630
623
|
end
|
|
@@ -659,16 +652,14 @@ end
|
|
|
659
652
|
|
|
660
653
|
describe Sequel::Model, "#set" do
|
|
661
654
|
before do
|
|
662
|
-
MODEL_DB.reset
|
|
663
|
-
|
|
664
655
|
@c = Class.new(Sequel::Model(:items)) do
|
|
665
656
|
set_primary_key :id
|
|
666
657
|
columns :x, :y, :id
|
|
667
658
|
end
|
|
668
659
|
@c.strict_param_setting = false
|
|
669
|
-
@c.instance_variable_set(:@columns, true)
|
|
670
660
|
@o1 = @c.new
|
|
671
661
|
@o2 = @c.load(:id => 5)
|
|
662
|
+
MODEL_DB.reset
|
|
672
663
|
end
|
|
673
664
|
|
|
674
665
|
it "should filter the given params using the model columns" do
|
|
@@ -716,6 +707,29 @@ describe Sequel::Model, "#set" do
|
|
|
716
707
|
MODEL_DB.sqls.should == []
|
|
717
708
|
end
|
|
718
709
|
|
|
710
|
+
it "should raise error if strict_param_setting is true and method does not exist" do
|
|
711
|
+
@o1.strict_param_setting = true
|
|
712
|
+
proc{@o1.set('foo' => 1)}.should raise_error(Sequel::Error)
|
|
713
|
+
end
|
|
714
|
+
|
|
715
|
+
it "should raise error if strict_param_setting is true and column is a primary key" do
|
|
716
|
+
@o1.strict_param_setting = true
|
|
717
|
+
proc{@o1.set('id' => 1)}.should raise_error(Sequel::Error)
|
|
718
|
+
end
|
|
719
|
+
|
|
720
|
+
it "should raise error if strict_param_setting is true and column is restricted" do
|
|
721
|
+
@o1.strict_param_setting = true
|
|
722
|
+
@c.set_restricted_columns :x
|
|
723
|
+
proc{@o1.set('x' => 1)}.should raise_error(Sequel::Error)
|
|
724
|
+
end
|
|
725
|
+
|
|
726
|
+
it "should not create a symbol if strict_param_setting is true and string is given" do
|
|
727
|
+
@o1.strict_param_setting = true
|
|
728
|
+
l = Symbol.all_symbols.length
|
|
729
|
+
proc{@o1.set('sadojafdso' => 1)}.should raise_error(Sequel::Error)
|
|
730
|
+
Symbol.all_symbols.length.should == l
|
|
731
|
+
end
|
|
732
|
+
|
|
719
733
|
it "#set should correctly handle cases where an instance method is added to the class" do
|
|
720
734
|
@o1.set(:x => 1)
|
|
721
735
|
@o1.values.should == {:x => 1}
|
|
@@ -739,51 +753,74 @@ describe Sequel::Model, "#set" do
|
|
|
739
753
|
@o1.set(:x => 2, :z => 3)
|
|
740
754
|
@o1.values.should == {:x => 2, :z=>3}
|
|
741
755
|
end
|
|
756
|
+
|
|
757
|
+
it "#set should correctly handle cases where a module with a setter method is included in the class" do
|
|
758
|
+
@o1.set(:x => 1)
|
|
759
|
+
@o1.values.should == {:x => 1}
|
|
760
|
+
|
|
761
|
+
@c.send(:include, Module.new do
|
|
762
|
+
def z=(v)
|
|
763
|
+
self[:z] = v
|
|
764
|
+
end
|
|
765
|
+
end)
|
|
766
|
+
@o1.set(:x => 2, :z => 3)
|
|
767
|
+
@o1.values.should == {:x => 2, :z=>3}
|
|
768
|
+
end
|
|
769
|
+
|
|
770
|
+
it "#set should correctly handle cases where the object extends a module with a setter method " do
|
|
771
|
+
@o1.set(:x => 1)
|
|
772
|
+
@o1.values.should == {:x => 1}
|
|
773
|
+
|
|
774
|
+
@o1.extend(Module.new do
|
|
775
|
+
def z=(v)
|
|
776
|
+
self[:z] = v
|
|
777
|
+
end
|
|
778
|
+
end)
|
|
779
|
+
@o1.set(:x => 2, :z => 3)
|
|
780
|
+
@o1.values.should == {:x => 2, :z=>3}
|
|
781
|
+
end
|
|
742
782
|
end
|
|
743
783
|
|
|
744
784
|
describe Sequel::Model, "#update" do
|
|
745
785
|
before do
|
|
746
|
-
MODEL_DB.reset
|
|
747
|
-
|
|
748
786
|
@c = Class.new(Sequel::Model(:items)) do
|
|
749
787
|
set_primary_key :id
|
|
750
788
|
columns :x, :y, :id
|
|
751
789
|
end
|
|
752
790
|
@c.strict_param_setting = false
|
|
753
|
-
@c.instance_variable_set(:@columns, true)
|
|
754
791
|
@o1 = @c.new
|
|
755
792
|
@o2 = @c.load(:id => 5)
|
|
793
|
+
MODEL_DB.reset
|
|
756
794
|
end
|
|
757
795
|
|
|
758
796
|
it "should filter the given params using the model columns" do
|
|
759
797
|
@o1.update(:x => 1, :z => 2)
|
|
760
|
-
MODEL_DB.sqls.
|
|
798
|
+
MODEL_DB.sqls.should == ["INSERT INTO items (x) VALUES (1)", "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
|
|
761
799
|
|
|
762
800
|
MODEL_DB.reset
|
|
763
801
|
@o2.update(:y => 1, :abc => 2)
|
|
764
|
-
MODEL_DB.sqls.
|
|
802
|
+
MODEL_DB.sqls.should == ["UPDATE items SET y = 1 WHERE (id = 5)"]
|
|
765
803
|
end
|
|
766
804
|
|
|
767
805
|
it "should support virtual attributes" do
|
|
768
806
|
@c.send(:define_method, :blah=){|v| self.x = v}
|
|
769
807
|
@o1.update(:blah => 333)
|
|
770
|
-
MODEL_DB.sqls.
|
|
808
|
+
MODEL_DB.sqls.should == ["INSERT INTO items (x) VALUES (333)", "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
|
|
771
809
|
end
|
|
772
810
|
|
|
773
811
|
it "should not modify the primary key" do
|
|
774
812
|
@o1.update(:x => 1, :id => 2)
|
|
775
|
-
MODEL_DB.sqls.
|
|
813
|
+
MODEL_DB.sqls.should == ["INSERT INTO items (x) VALUES (1)", "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
|
|
776
814
|
MODEL_DB.reset
|
|
777
815
|
@o2.update('y'=> 1, 'id'=> 2)
|
|
778
816
|
@o2.values.should == {:y => 1, :id=> 5}
|
|
779
|
-
MODEL_DB.sqls.
|
|
817
|
+
MODEL_DB.sqls.should == ["UPDATE items SET y = 1 WHERE (id = 5)"]
|
|
780
818
|
end
|
|
781
819
|
end
|
|
782
820
|
|
|
783
821
|
describe Sequel::Model, "#set_fields" do
|
|
784
822
|
before do
|
|
785
|
-
@c = Class.new(Sequel::Model(:items))
|
|
786
|
-
@c.class_eval do
|
|
823
|
+
@c = Class.new(Sequel::Model(:items)) do
|
|
787
824
|
set_primary_key :id
|
|
788
825
|
columns :x, :y, :z, :id
|
|
789
826
|
end
|
|
@@ -803,11 +840,9 @@ end
|
|
|
803
840
|
|
|
804
841
|
describe Sequel::Model, "#update_fields" do
|
|
805
842
|
before do
|
|
806
|
-
@c = Class.new(Sequel::Model(:items))
|
|
807
|
-
@c.class_eval do
|
|
843
|
+
@c = Class.new(Sequel::Model(:items)) do
|
|
808
844
|
set_primary_key :id
|
|
809
845
|
columns :x, :y, :z, :id
|
|
810
|
-
def _refresh(ds); end
|
|
811
846
|
end
|
|
812
847
|
@c.strict_param_setting = true
|
|
813
848
|
@o1 = @c.load(:id=>1)
|
|
@@ -817,21 +852,18 @@ describe Sequel::Model, "#update_fields" do
|
|
|
817
852
|
it "should set only the given fields, and then save the changes to the record" do
|
|
818
853
|
@o1.update_fields({:x => 1, :y => 2, :z=>3, :id=>4}, [:x, :y])
|
|
819
854
|
@o1.values.should == {:x => 1, :y => 2, :id=>1}
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
855
|
+
sqls = MODEL_DB.sqls
|
|
856
|
+
sqls.pop.should =~ /UPDATE items SET [xy] = [12], [xy] = [12] WHERE \(id = 1\)/
|
|
857
|
+
sqls.should == []
|
|
823
858
|
|
|
824
859
|
@o1.update_fields({:x => 1, :y => 5, :z=>6, :id=>7}, [:x, :y])
|
|
825
860
|
@o1.values.should == {:x => 1, :y => 5, :id=>1}
|
|
826
861
|
MODEL_DB.sqls.should == ["UPDATE items SET y = 5 WHERE (id = 1)"]
|
|
827
|
-
MODEL_DB.reset
|
|
828
862
|
end
|
|
829
863
|
end
|
|
830
864
|
|
|
831
865
|
describe Sequel::Model, "#(set|update)_(all|except|only)" do
|
|
832
866
|
before do
|
|
833
|
-
MODEL_DB.reset
|
|
834
|
-
|
|
835
867
|
@c = Class.new(Sequel::Model(:items)) do
|
|
836
868
|
set_primary_key :id
|
|
837
869
|
columns :x, :y, :z, :id
|
|
@@ -839,8 +871,8 @@ describe Sequel::Model, "#(set|update)_(all|except|only)" do
|
|
|
839
871
|
set_restricted_columns :y
|
|
840
872
|
end
|
|
841
873
|
@c.strict_param_setting = false
|
|
842
|
-
@c.instance_variable_set(:@columns, true)
|
|
843
874
|
@o1 = @c.new
|
|
875
|
+
MODEL_DB.reset
|
|
844
876
|
end
|
|
845
877
|
|
|
846
878
|
it "should raise errors if not all hash fields can be set and strict_param_setting is true" do
|
|
@@ -884,40 +916,34 @@ describe Sequel::Model, "#(set|update)_(all|except|only)" do
|
|
|
884
916
|
|
|
885
917
|
it "#update_all should update all attributes" do
|
|
886
918
|
@c.new.update_all(:x => 1, :id=>4)
|
|
887
|
-
MODEL_DB.sqls.
|
|
888
|
-
MODEL_DB.reset
|
|
919
|
+
MODEL_DB.sqls.should == ["INSERT INTO items (x) VALUES (1)", "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
|
|
889
920
|
@c.new.update_all(:y => 1, :id=>4)
|
|
890
|
-
MODEL_DB.sqls.
|
|
891
|
-
MODEL_DB.reset
|
|
921
|
+
MODEL_DB.sqls.should == ["INSERT INTO items (y) VALUES (1)", "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
|
|
892
922
|
@c.new.update_all(:z => 1, :id=>4)
|
|
893
|
-
MODEL_DB.sqls.
|
|
923
|
+
MODEL_DB.sqls.should == ["INSERT INTO items (z) VALUES (1)", "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
|
|
894
924
|
end
|
|
895
925
|
|
|
896
926
|
it "#update_only should only update given attributes" do
|
|
897
927
|
@o1.update_only({:x => 1, :y => 2, :z=>3, :id=>4}, [:x])
|
|
898
|
-
MODEL_DB.sqls.
|
|
899
|
-
MODEL_DB.reset
|
|
928
|
+
MODEL_DB.sqls.should == ["INSERT INTO items (x) VALUES (1)", "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
|
|
900
929
|
@c.new.update_only({:x => 1, :y => 2, :z=>3, :id=>4}, :x)
|
|
901
|
-
MODEL_DB.sqls.
|
|
930
|
+
MODEL_DB.sqls.should == ["INSERT INTO items (x) VALUES (1)", "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
|
|
902
931
|
end
|
|
903
932
|
|
|
904
933
|
it "#update_except should not update given attributes" do
|
|
905
934
|
@o1.update_except({:x => 1, :y => 2, :z=>3, :id=>4}, [:y, :z])
|
|
906
|
-
MODEL_DB.sqls.
|
|
907
|
-
MODEL_DB.reset
|
|
935
|
+
MODEL_DB.sqls.should == ["INSERT INTO items (x) VALUES (1)", "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
|
|
908
936
|
@c.new.update_except({:x => 1, :y => 2, :z=>3, :id=>4}, :y, :z)
|
|
909
|
-
MODEL_DB.sqls.
|
|
937
|
+
MODEL_DB.sqls.should == ["INSERT INTO items (x) VALUES (1)", "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
|
|
910
938
|
end
|
|
911
939
|
end
|
|
912
940
|
|
|
913
941
|
describe Sequel::Model, "#destroy" do
|
|
914
942
|
before do
|
|
915
|
-
MODEL_DB.reset
|
|
916
943
|
@model = Class.new(Sequel::Model(:items))
|
|
917
944
|
@model.columns :id
|
|
918
|
-
@model.dataset.meta_def(:delete){MODEL_DB.execute delete_sql;1}
|
|
919
|
-
|
|
920
945
|
@instance = @model.load(:id => 1234)
|
|
946
|
+
MODEL_DB.reset
|
|
921
947
|
end
|
|
922
948
|
|
|
923
949
|
it "should return self" do
|
|
@@ -942,49 +968,40 @@ describe Sequel::Model, "#destroy" do
|
|
|
942
968
|
|
|
943
969
|
it "should run within a transaction if use_transactions is true" do
|
|
944
970
|
@instance.use_transactions = true
|
|
945
|
-
@model.db.should_receive(:transaction)
|
|
946
971
|
@instance.destroy
|
|
972
|
+
MODEL_DB.sqls.should == ["BEGIN", "DELETE FROM items WHERE (id = 1234)", "COMMIT"]
|
|
947
973
|
end
|
|
948
974
|
|
|
949
975
|
it "should not run within a transaction if use_transactions is false" do
|
|
950
976
|
@instance.use_transactions = false
|
|
951
|
-
@model.db.should_not_receive(:transaction)
|
|
952
977
|
@instance.destroy
|
|
978
|
+
MODEL_DB.sqls.should == ["DELETE FROM items WHERE (id = 1234)"]
|
|
953
979
|
end
|
|
954
980
|
|
|
955
981
|
it "should run within a transaction if :transaction option is true" do
|
|
956
982
|
@instance.use_transactions = false
|
|
957
|
-
@model.db.should_receive(:transaction)
|
|
958
983
|
@instance.destroy(:transaction => true)
|
|
984
|
+
MODEL_DB.sqls.should == ["BEGIN", "DELETE FROM items WHERE (id = 1234)", "COMMIT"]
|
|
959
985
|
end
|
|
960
986
|
|
|
961
987
|
it "should not run within a transaction if :transaction option is false" do
|
|
962
988
|
@instance.use_transactions = true
|
|
963
|
-
@model.db.should_not_receive(:transaction)
|
|
964
989
|
@instance.destroy(:transaction => false)
|
|
990
|
+
MODEL_DB.sqls.should == ["DELETE FROM items WHERE (id = 1234)"]
|
|
965
991
|
end
|
|
966
992
|
|
|
967
993
|
it "should run before_destroy and after_destroy hooks" do
|
|
968
994
|
@model.send(:define_method, :before_destroy){MODEL_DB.execute('before blah')}
|
|
969
995
|
@model.send(:define_method, :after_destroy){MODEL_DB.execute('after blah')}
|
|
970
996
|
@instance.destroy
|
|
971
|
-
|
|
972
|
-
MODEL_DB.sqls.should == [
|
|
973
|
-
"before blah",
|
|
974
|
-
"DELETE FROM items WHERE (id = 1234)",
|
|
975
|
-
"after blah"
|
|
976
|
-
]
|
|
997
|
+
MODEL_DB.sqls.should == ["before blah", "DELETE FROM items WHERE (id = 1234)", "after blah"]
|
|
977
998
|
end
|
|
978
999
|
end
|
|
979
1000
|
|
|
980
1001
|
describe Sequel::Model, "#exists?" do
|
|
981
|
-
before
|
|
1002
|
+
before do
|
|
982
1003
|
@model = Class.new(Sequel::Model(:items))
|
|
983
|
-
@
|
|
984
|
-
def @ds.fetch_rows(sql)
|
|
985
|
-
db.execute(sql)
|
|
986
|
-
yield(:x=>1) if sql =~ /id = 1/
|
|
987
|
-
end
|
|
1004
|
+
@model.dataset._fetch = proc{|sql| {:x=>1} if sql =~ /id = 1/}
|
|
988
1005
|
MODEL_DB.reset
|
|
989
1006
|
end
|
|
990
1007
|
|
|
@@ -997,6 +1014,11 @@ describe Sequel::Model, "#exists?" do
|
|
|
997
1014
|
@model.load(:id=>2).exists?.should be_false
|
|
998
1015
|
MODEL_DB.sqls.should == ['SELECT 1 FROM items WHERE (id = 2) LIMIT 1']
|
|
999
1016
|
end
|
|
1017
|
+
|
|
1018
|
+
it "should return false without issuing a query if the model object is new" do
|
|
1019
|
+
@model.new.exists?.should be_false
|
|
1020
|
+
MODEL_DB.sqls.should == []
|
|
1021
|
+
end
|
|
1000
1022
|
end
|
|
1001
1023
|
|
|
1002
1024
|
describe Sequel::Model, "#each" do
|
|
@@ -1008,7 +1030,7 @@ describe Sequel::Model, "#each" do
|
|
|
1008
1030
|
|
|
1009
1031
|
specify "should iterate over the values" do
|
|
1010
1032
|
h = {}
|
|
1011
|
-
@m.each
|
|
1033
|
+
@m.each{|k, v| h[k] = v}
|
|
1012
1034
|
h.should == {:a => 1, :b => 2, :id => 4444}
|
|
1013
1035
|
end
|
|
1014
1036
|
end
|
|
@@ -1021,11 +1043,8 @@ describe Sequel::Model, "#keys" do
|
|
|
1021
1043
|
end
|
|
1022
1044
|
|
|
1023
1045
|
specify "should return the value keys" do
|
|
1024
|
-
@m.keys.
|
|
1025
|
-
@
|
|
1026
|
-
|
|
1027
|
-
@m = @model.new()
|
|
1028
|
-
@m.keys.should == []
|
|
1046
|
+
@m.keys.sort_by{|k| k.to_s}.should == [:a, :b, :id]
|
|
1047
|
+
@model.new.keys.should == []
|
|
1029
1048
|
end
|
|
1030
1049
|
end
|
|
1031
1050
|
|
|
@@ -1094,13 +1113,10 @@ describe Sequel::Model, "#hash" do
|
|
|
1094
1113
|
y = Class.new(Sequel::Model)
|
|
1095
1114
|
y.columns :id, :x
|
|
1096
1115
|
a = z.load(:id => 1, :x => 3)
|
|
1097
|
-
b = z.load(:id => 1, :x => 4)
|
|
1098
|
-
c = z.load(:id => 2, :x => 3)
|
|
1099
|
-
d = y.load(:id => 1, :x => 3)
|
|
1100
1116
|
|
|
1101
|
-
a.hash.should ==
|
|
1102
|
-
a.hash.should_not ==
|
|
1103
|
-
a.hash.should_not ==
|
|
1117
|
+
a.hash.should == z.load(:id => 1, :x => 4).hash
|
|
1118
|
+
a.hash.should_not == z.load(:id => 2, :x => 3).hash
|
|
1119
|
+
a.hash.should_not == y.load(:id => 1, :x => 3).hash
|
|
1104
1120
|
end
|
|
1105
1121
|
|
|
1106
1122
|
specify "should be the same only for objects with the same class and values if the pk is nil" do
|
|
@@ -1109,14 +1125,71 @@ describe Sequel::Model, "#hash" do
|
|
|
1109
1125
|
y = Class.new(Sequel::Model)
|
|
1110
1126
|
y.columns :id, :x
|
|
1111
1127
|
a = z.new(:x => 3)
|
|
1112
|
-
b = z.new(:x => 4)
|
|
1113
|
-
c = z.new(:x => 3)
|
|
1114
|
-
d = y.new(:x => 3)
|
|
1115
1128
|
|
|
1116
|
-
a.hash.should_not ==
|
|
1117
|
-
a.hash.should ==
|
|
1118
|
-
a.hash.should_not ==
|
|
1129
|
+
a.hash.should_not == z.new(:x => 4).hash
|
|
1130
|
+
a.hash.should == z.new(:x => 3).hash
|
|
1131
|
+
a.hash.should_not == y.new(:x => 3).hash
|
|
1132
|
+
end
|
|
1133
|
+
|
|
1134
|
+
specify "should be the same only for objects with the same class and pk if pk is composite and all values are non-NULL" do
|
|
1135
|
+
z = Class.new(Sequel::Model)
|
|
1136
|
+
z.columns :id, :id2, :x
|
|
1137
|
+
z.set_primary_key(:id, :id2)
|
|
1138
|
+
y = Class.new(Sequel::Model)
|
|
1139
|
+
y.columns :id, :id2, :x
|
|
1140
|
+
y.set_primary_key(:id, :id2)
|
|
1141
|
+
a = z.load(:id => 1, :id2=>2, :x => 3)
|
|
1142
|
+
|
|
1143
|
+
a.hash.should == z.load(:id => 1, :id2=>2, :x => 4).hash
|
|
1144
|
+
a.hash.should_not == z.load(:id => 2, :id2=>1, :x => 3).hash
|
|
1145
|
+
a.hash.should_not == y.load(:id => 1, :id2=>1, :x => 3).hash
|
|
1119
1146
|
end
|
|
1147
|
+
|
|
1148
|
+
specify "should be the same only for objects with the same class and value if pk is composite and one values is NULL" do
|
|
1149
|
+
z = Class.new(Sequel::Model)
|
|
1150
|
+
z.columns :id, :id2, :x
|
|
1151
|
+
z.set_primary_key(:id, :id2)
|
|
1152
|
+
y = Class.new(Sequel::Model)
|
|
1153
|
+
y.columns :id, :id2, :x
|
|
1154
|
+
y.set_primary_key(:id, :id2)
|
|
1155
|
+
|
|
1156
|
+
a = z.load(:id => 1, :id2 => nil, :x => 3)
|
|
1157
|
+
a.hash.should == z.load(:id => 1, :id2=>nil, :x => 3).hash
|
|
1158
|
+
a.hash.should_not == z.load(:id => 1, :id2=>nil, :x => 4).hash
|
|
1159
|
+
a.hash.should_not == y.load(:id => 1, :id2=>nil, :x => 3).hash
|
|
1160
|
+
|
|
1161
|
+
a = z.load(:id =>nil, :id2 => nil, :x => 3)
|
|
1162
|
+
a.hash.should == z.load(:id => nil, :id2=>nil, :x => 3).hash
|
|
1163
|
+
a.hash.should_not == z.load(:id => nil, :id2=>nil, :x => 4).hash
|
|
1164
|
+
a.hash.should_not == y.load(:id => nil, :id2=>nil, :x => 3).hash
|
|
1165
|
+
|
|
1166
|
+
a = z.load(:id => 1, :x => 3)
|
|
1167
|
+
a.hash.should == z.load(:id => 1, :x => 3).hash
|
|
1168
|
+
a.hash.should_not == z.load(:id => 1, :id2=>nil, :x => 3).hash
|
|
1169
|
+
a.hash.should_not == z.load(:id => 1, :x => 4).hash
|
|
1170
|
+
a.hash.should_not == y.load(:id => 1, :x => 3).hash
|
|
1171
|
+
|
|
1172
|
+
a = z.load(:x => 3)
|
|
1173
|
+
a.hash.should == z.load(:x => 3).hash
|
|
1174
|
+
a.hash.should_not == z.load(:id => nil, :id2=>nil, :x => 3).hash
|
|
1175
|
+
a.hash.should_not == z.load(:x => 4).hash
|
|
1176
|
+
a.hash.should_not == y.load(:x => 3).hash
|
|
1177
|
+
end
|
|
1178
|
+
|
|
1179
|
+
specify "should be the same only for objects with the same class and values if the no primary key" do
|
|
1180
|
+
z = Class.new(Sequel::Model)
|
|
1181
|
+
z.columns :id, :x
|
|
1182
|
+
z.no_primary_key
|
|
1183
|
+
y = Class.new(Sequel::Model)
|
|
1184
|
+
y.columns :id, :x
|
|
1185
|
+
y.no_primary_key
|
|
1186
|
+
a = z.new(:x => 3)
|
|
1187
|
+
|
|
1188
|
+
a.hash.should_not == z.new(:x => 4).hash
|
|
1189
|
+
a.hash.should == z.new(:x => 3).hash
|
|
1190
|
+
a.hash.should_not == y.new(:x => 3).hash
|
|
1191
|
+
end
|
|
1192
|
+
|
|
1120
1193
|
end
|
|
1121
1194
|
|
|
1122
1195
|
describe Sequel::Model, "#initialize" do
|
|
@@ -1161,10 +1234,32 @@ describe Sequel::Model, "#initialize" do
|
|
|
1161
1234
|
m.values.should == {:x => 2}
|
|
1162
1235
|
end
|
|
1163
1236
|
end
|
|
1237
|
+
|
|
1238
|
+
describe Sequel::Model, "#initialize_set" do
|
|
1239
|
+
before do
|
|
1240
|
+
@c = Class.new(Sequel::Model){columns :id, :x, :y}
|
|
1241
|
+
end
|
|
1164
1242
|
|
|
1165
|
-
|
|
1243
|
+
specify "should be called by initialize to set the column values" do
|
|
1244
|
+
@c.send(:define_method, :initialize_set){|h| set(:y => 3)}
|
|
1245
|
+
@c.new(:x => 2).values.should == {:y => 3}
|
|
1246
|
+
end
|
|
1247
|
+
|
|
1248
|
+
specify "should be called with the hash given to initialize " do
|
|
1249
|
+
x = nil
|
|
1250
|
+
@c.send(:define_method, :initialize_set){|y| x = y}
|
|
1251
|
+
@c.new(:x => 2)
|
|
1252
|
+
x.should == {:x => 2}
|
|
1253
|
+
end
|
|
1254
|
+
|
|
1255
|
+
specify "should not cause columns modified by the method to be considered as changed" do
|
|
1256
|
+
@c.send(:define_method, :initialize_set){|h| set(:y => 3)}
|
|
1257
|
+
@c.new(:x => 2).changed_columns.should == []
|
|
1258
|
+
end
|
|
1259
|
+
end
|
|
1166
1260
|
|
|
1167
|
-
|
|
1261
|
+
describe Sequel::Model, ".create" do
|
|
1262
|
+
before do
|
|
1168
1263
|
MODEL_DB.reset
|
|
1169
1264
|
@c = Class.new(Sequel::Model(:items)) do
|
|
1170
1265
|
unrestrict_primary_key
|
|
@@ -1175,13 +1270,13 @@ describe Sequel::Model, ".create" do
|
|
|
1175
1270
|
it "should be able to create rows in the associated table" do
|
|
1176
1271
|
o = @c.create(:x => 1)
|
|
1177
1272
|
o.class.should == @c
|
|
1178
|
-
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"]
|
|
1179
1274
|
end
|
|
1180
1275
|
|
|
1181
1276
|
it "should be able to create rows without any values specified" do
|
|
1182
1277
|
o = @c.create
|
|
1183
1278
|
o.class.should == @c
|
|
1184
|
-
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"]
|
|
1185
1280
|
end
|
|
1186
1281
|
|
|
1187
1282
|
it "should accept a block and run it" do
|
|
@@ -1191,7 +1286,7 @@ describe Sequel::Model, ".create" do
|
|
|
1191
1286
|
o1.should === o
|
|
1192
1287
|
o3.should === o
|
|
1193
1288
|
o2.should == :blah
|
|
1194
|
-
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"]
|
|
1195
1290
|
end
|
|
1196
1291
|
|
|
1197
1292
|
it "should create a row for a model with custom primary key" do
|
|
@@ -1204,32 +1299,35 @@ end
|
|
|
1204
1299
|
|
|
1205
1300
|
describe Sequel::Model, "#refresh" do
|
|
1206
1301
|
before do
|
|
1207
|
-
MODEL_DB.reset
|
|
1208
1302
|
@c = Class.new(Sequel::Model(:items)) do
|
|
1209
1303
|
unrestrict_primary_key
|
|
1210
1304
|
columns :id, :x
|
|
1211
1305
|
end
|
|
1306
|
+
MODEL_DB.reset
|
|
1212
1307
|
end
|
|
1213
1308
|
|
|
1214
1309
|
specify "should reload the instance values from the database" do
|
|
1215
1310
|
@m = @c.new(:id => 555)
|
|
1216
1311
|
@m[:x] = 'blah'
|
|
1217
|
-
@
|
|
1312
|
+
@c.dataset._fetch = {:x => 'kaboom', :id => 555}
|
|
1218
1313
|
@m.refresh
|
|
1219
1314
|
@m[:x].should == 'kaboom'
|
|
1315
|
+
MODEL_DB.sqls.should == ["SELECT * FROM items WHERE (id = 555) LIMIT 1"]
|
|
1220
1316
|
end
|
|
1221
1317
|
|
|
1222
1318
|
specify "should raise if the instance is not found" do
|
|
1223
1319
|
@m = @c.new(:id => 555)
|
|
1224
|
-
@
|
|
1320
|
+
@c.dataset._fetch = []
|
|
1225
1321
|
proc {@m.refresh}.should raise_error(Sequel::Error)
|
|
1322
|
+
MODEL_DB.sqls.should == ["SELECT * FROM items WHERE (id = 555) LIMIT 1"]
|
|
1226
1323
|
end
|
|
1227
1324
|
|
|
1228
1325
|
specify "should be aliased by #reload" do
|
|
1229
1326
|
@m = @c.new(:id => 555)
|
|
1230
|
-
@
|
|
1327
|
+
@c.dataset._fetch = {:x => 'kaboom', :id => 555}
|
|
1231
1328
|
@m.reload
|
|
1232
1329
|
@m[:x].should == 'kaboom'
|
|
1330
|
+
MODEL_DB.sqls.should == ["SELECT * FROM items WHERE (id = 555) LIMIT 1"]
|
|
1233
1331
|
end
|
|
1234
1332
|
|
|
1235
1333
|
specify "should remove cached associations" do
|
|
@@ -1243,10 +1341,11 @@ end
|
|
|
1243
1341
|
|
|
1244
1342
|
describe Sequel::Model, "typecasting" do
|
|
1245
1343
|
before do
|
|
1246
|
-
MODEL_DB.reset
|
|
1247
1344
|
@c = Class.new(Sequel::Model(:items)) do
|
|
1248
1345
|
columns :x
|
|
1249
1346
|
end
|
|
1347
|
+
@c.db_schema = {:x=>{:type=>:integer}}
|
|
1348
|
+
MODEL_DB.reset
|
|
1250
1349
|
end
|
|
1251
1350
|
|
|
1252
1351
|
after do
|
|
@@ -1255,14 +1354,13 @@ describe Sequel::Model, "typecasting" do
|
|
|
1255
1354
|
|
|
1256
1355
|
specify "should not convert if typecasting is turned off" do
|
|
1257
1356
|
@c.typecast_on_assignment = false
|
|
1258
|
-
@c.instance_variable_set(:@db_schema, {:x=>{:type=>:integer}})
|
|
1259
1357
|
m = @c.new
|
|
1260
1358
|
m.x = '1'
|
|
1261
1359
|
m.x.should == '1'
|
|
1262
1360
|
end
|
|
1263
1361
|
|
|
1264
1362
|
specify "should convert to integer for an integer field" do
|
|
1265
|
-
@c.
|
|
1363
|
+
@c.db_schema = {:x=>{:type=>:integer}}
|
|
1266
1364
|
m = @c.new
|
|
1267
1365
|
m.x = '1'
|
|
1268
1366
|
m.x.should == 1
|
|
@@ -1274,13 +1372,13 @@ describe Sequel::Model, "typecasting" do
|
|
|
1274
1372
|
|
|
1275
1373
|
specify "should typecast '' to nil unless type is string or blob" do
|
|
1276
1374
|
[:integer, :float, :decimal, :boolean, :date, :time, :datetime].each do |x|
|
|
1277
|
-
@c.
|
|
1375
|
+
@c.db_schema = {:x=>{:type=>x}}
|
|
1278
1376
|
m = @c.new
|
|
1279
1377
|
m.x = ''
|
|
1280
1378
|
m.x.should == nil
|
|
1281
1379
|
end
|
|
1282
1380
|
[:string, :blob].each do |x|
|
|
1283
|
-
@c.
|
|
1381
|
+
@c.db_schema = {:x=>{:type=>x}}
|
|
1284
1382
|
m = @c.new
|
|
1285
1383
|
m.x = ''
|
|
1286
1384
|
m.x.should == ''
|
|
@@ -1288,7 +1386,6 @@ describe Sequel::Model, "typecasting" do
|
|
|
1288
1386
|
end
|
|
1289
1387
|
|
|
1290
1388
|
specify "should not typecast '' to nil if typecast_empty_string_to_nil is false" do
|
|
1291
|
-
@c.instance_variable_set(:@db_schema, {:x=>{:type=>:integer}})
|
|
1292
1389
|
m = @c.new
|
|
1293
1390
|
m.typecast_empty_string_to_nil = false
|
|
1294
1391
|
proc{m.x = ''}.should raise_error
|
|
@@ -1297,21 +1394,21 @@ describe Sequel::Model, "typecasting" do
|
|
|
1297
1394
|
end
|
|
1298
1395
|
|
|
1299
1396
|
specify "should not typecast nil if NULLs are allowed" do
|
|
1300
|
-
@c.
|
|
1397
|
+
@c.db_schema[:x][:allow_null] = true
|
|
1301
1398
|
m = @c.new
|
|
1302
1399
|
m.x = nil
|
|
1303
1400
|
m.x.should == nil
|
|
1304
1401
|
end
|
|
1305
1402
|
|
|
1306
1403
|
specify "should raise an error if attempting to typecast nil and NULLs are not allowed" do
|
|
1307
|
-
@c.
|
|
1404
|
+
@c.db_schema[:x][:allow_null] = false
|
|
1308
1405
|
proc{@c.new.x = nil}.should raise_error(Sequel::Error)
|
|
1309
1406
|
proc{@c.new.x = ''}.should raise_error(Sequel::Error)
|
|
1310
1407
|
end
|
|
1311
1408
|
|
|
1312
1409
|
specify "should not raise an error if NULLs are not allowed and typecasting is turned off" do
|
|
1313
1410
|
@c.typecast_on_assignment = false
|
|
1314
|
-
@c.
|
|
1411
|
+
@c.db_schema[:x][:allow_null] = false
|
|
1315
1412
|
m = @c.new
|
|
1316
1413
|
m.x = nil
|
|
1317
1414
|
m.x.should == nil
|
|
@@ -1320,7 +1417,6 @@ describe Sequel::Model, "typecasting" do
|
|
|
1320
1417
|
specify "should not raise when typecasting nil to NOT NULL column but raise_on_typecast_failure is off" do
|
|
1321
1418
|
@c.raise_on_typecast_failure = false
|
|
1322
1419
|
@c.typecast_on_assignment = true
|
|
1323
|
-
@c.instance_variable_set(:@db_schema, {:x=>{:type=>:integer,:allow_null=>false}})
|
|
1324
1420
|
m = @c.new
|
|
1325
1421
|
m.x = ''
|
|
1326
1422
|
m.x.should == nil
|
|
@@ -1329,20 +1425,18 @@ describe Sequel::Model, "typecasting" do
|
|
|
1329
1425
|
end
|
|
1330
1426
|
|
|
1331
1427
|
specify "should raise an error if invalid data is used in an integer field" do
|
|
1332
|
-
@c.instance_variable_set(:@db_schema, {:x=>{:type=>:integer}})
|
|
1333
1428
|
proc{@c.new.x = 'a'}.should raise_error(Sequel::InvalidValue)
|
|
1334
1429
|
end
|
|
1335
1430
|
|
|
1336
1431
|
specify "should assign value if raise_on_typecast_failure is off and assigning invalid integer" do
|
|
1337
1432
|
@c.raise_on_typecast_failure = false
|
|
1338
|
-
@c.instance_variable_set(:@db_schema, {:x=>{:type=>:integer}})
|
|
1339
1433
|
model = @c.new
|
|
1340
1434
|
model.x = '1d'
|
|
1341
1435
|
model.x.should == '1d'
|
|
1342
1436
|
end
|
|
1343
1437
|
|
|
1344
1438
|
specify "should convert to float for a float field" do
|
|
1345
|
-
@c.
|
|
1439
|
+
@c.db_schema = {:x=>{:type=>:float}}
|
|
1346
1440
|
m = @c.new
|
|
1347
1441
|
m.x = '1.3'
|
|
1348
1442
|
m.x.should == 1.3
|
|
@@ -1353,20 +1447,20 @@ describe Sequel::Model, "typecasting" do
|
|
|
1353
1447
|
end
|
|
1354
1448
|
|
|
1355
1449
|
specify "should raise an error if invalid data is used in an float field" do
|
|
1356
|
-
@c.
|
|
1450
|
+
@c.db_schema = {:x=>{:type=>:float}}
|
|
1357
1451
|
proc{@c.new.x = 'a'}.should raise_error(Sequel::InvalidValue)
|
|
1358
1452
|
end
|
|
1359
1453
|
|
|
1360
1454
|
specify "should assign value if raise_on_typecast_failure is off and assigning invalid float" do
|
|
1361
1455
|
@c.raise_on_typecast_failure = false
|
|
1362
|
-
@c.
|
|
1456
|
+
@c.db_schema = {:x=>{:type=>:float}}
|
|
1363
1457
|
model = @c.new
|
|
1364
1458
|
model.x = '1d'
|
|
1365
1459
|
model.x.should == '1d'
|
|
1366
1460
|
end
|
|
1367
1461
|
|
|
1368
1462
|
specify "should convert to BigDecimal for a decimal field" do
|
|
1369
|
-
@c.
|
|
1463
|
+
@c.db_schema = {:x=>{:type=>:decimal}}
|
|
1370
1464
|
m = @c.new
|
|
1371
1465
|
bd = BigDecimal.new('1.0')
|
|
1372
1466
|
m.x = '1.0'
|
|
@@ -1380,13 +1474,13 @@ describe Sequel::Model, "typecasting" do
|
|
|
1380
1474
|
end
|
|
1381
1475
|
|
|
1382
1476
|
specify "should raise an error if invalid data is used in an decimal field" do
|
|
1383
|
-
@c.
|
|
1477
|
+
@c.db_schema = {:x=>{:type=>:decimal}}
|
|
1384
1478
|
proc{@c.new.x = Date.today}.should raise_error(Sequel::InvalidValue)
|
|
1385
1479
|
end
|
|
1386
1480
|
|
|
1387
1481
|
specify "should assign value if raise_on_typecast_failure is off and assigning invalid decimal" do
|
|
1388
1482
|
@c.raise_on_typecast_failure = false
|
|
1389
|
-
@c.
|
|
1483
|
+
@c.db_schema = {:x=>{:type=>:decimal}}
|
|
1390
1484
|
model = @c.new
|
|
1391
1485
|
time = Time.now
|
|
1392
1486
|
model.x = time
|
|
@@ -1394,7 +1488,7 @@ describe Sequel::Model, "typecasting" do
|
|
|
1394
1488
|
end
|
|
1395
1489
|
|
|
1396
1490
|
specify "should convert to string for a string field" do
|
|
1397
|
-
@c.
|
|
1491
|
+
@c.db_schema = {:x=>{:type=>:string}}
|
|
1398
1492
|
m = @c.new
|
|
1399
1493
|
m.x = '1.3'
|
|
1400
1494
|
m.x.should == '1.3'
|
|
@@ -1405,7 +1499,7 @@ describe Sequel::Model, "typecasting" do
|
|
|
1405
1499
|
end
|
|
1406
1500
|
|
|
1407
1501
|
specify "should convert to boolean for a boolean field" do
|
|
1408
|
-
@c.
|
|
1502
|
+
@c.db_schema = {:x=>{:type=>:boolean}}
|
|
1409
1503
|
m = @c.new
|
|
1410
1504
|
m.x = '1.3'
|
|
1411
1505
|
m.x.should == true
|
|
@@ -1417,6 +1511,10 @@ describe Sequel::Model, "typecasting" do
|
|
|
1417
1511
|
m.x.should == true
|
|
1418
1512
|
m.x = 'T'
|
|
1419
1513
|
m.x.should == true
|
|
1514
|
+
m.x = 'y'
|
|
1515
|
+
m.x.should == true
|
|
1516
|
+
m.x = 'Y'
|
|
1517
|
+
m.x.should == true
|
|
1420
1518
|
m.x = true
|
|
1421
1519
|
m.x.should == true
|
|
1422
1520
|
m.x = nil
|
|
@@ -1433,6 +1531,14 @@ describe Sequel::Model, "typecasting" do
|
|
|
1433
1531
|
m.x.should == false
|
|
1434
1532
|
m.x = 'FALSE'
|
|
1435
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
|
|
1436
1542
|
m.x = '0'
|
|
1437
1543
|
m.x.should == false
|
|
1438
1544
|
m.x = 0
|
|
@@ -1442,7 +1548,7 @@ describe Sequel::Model, "typecasting" do
|
|
|
1442
1548
|
end
|
|
1443
1549
|
|
|
1444
1550
|
specify "should convert to date for a date field" do
|
|
1445
|
-
@c.
|
|
1551
|
+
@c.db_schema = {:x=>{:type=>:date}}
|
|
1446
1552
|
m = @c.new
|
|
1447
1553
|
y = Date.new(2007,10,21)
|
|
1448
1554
|
m.x = '2007-10-21'
|
|
@@ -1456,7 +1562,7 @@ describe Sequel::Model, "typecasting" do
|
|
|
1456
1562
|
end
|
|
1457
1563
|
|
|
1458
1564
|
specify "should accept a hash with symbol or string keys for a date field" do
|
|
1459
|
-
@c.
|
|
1565
|
+
@c.db_schema = {:x=>{:type=>:date}}
|
|
1460
1566
|
m = @c.new
|
|
1461
1567
|
y = Date.new(2007,10,21)
|
|
1462
1568
|
m.x = {:year=>2007, :month=>10, :day=>21}
|
|
@@ -1466,32 +1572,33 @@ describe Sequel::Model, "typecasting" do
|
|
|
1466
1572
|
end
|
|
1467
1573
|
|
|
1468
1574
|
specify "should raise an error if invalid data is used in a date field" do
|
|
1469
|
-
@c.
|
|
1575
|
+
@c.db_schema = {:x=>{:type=>:date}}
|
|
1470
1576
|
proc{@c.new.x = 'a'}.should raise_error(Sequel::InvalidValue)
|
|
1471
1577
|
proc{@c.new.x = 100}.should raise_error(Sequel::InvalidValue)
|
|
1472
1578
|
end
|
|
1473
1579
|
|
|
1474
1580
|
specify "should assign value if raise_on_typecast_failure is off and assigning invalid date" do
|
|
1475
1581
|
@c.raise_on_typecast_failure = false
|
|
1476
|
-
@c.
|
|
1582
|
+
@c.db_schema = {:x=>{:type=>:date}}
|
|
1477
1583
|
model = @c.new
|
|
1478
1584
|
model.x = 4
|
|
1479
1585
|
model.x.should == 4
|
|
1480
1586
|
end
|
|
1481
1587
|
|
|
1482
|
-
specify "should convert to
|
|
1483
|
-
@c.
|
|
1588
|
+
specify "should convert to Sequel::SQLTime for a time field" do
|
|
1589
|
+
@c.db_schema = {:x=>{:type=>:time}}
|
|
1484
1590
|
m = @c.new
|
|
1485
1591
|
x = '10:20:30'
|
|
1486
|
-
y =
|
|
1592
|
+
y = Sequel::SQLTime.parse(x)
|
|
1487
1593
|
m.x = x
|
|
1488
1594
|
m.x.should == y
|
|
1489
1595
|
m.x = y
|
|
1490
1596
|
m.x.should == y
|
|
1597
|
+
m.x.should be_a_kind_of(Sequel::SQLTime)
|
|
1491
1598
|
end
|
|
1492
1599
|
|
|
1493
1600
|
specify "should accept a hash with symbol or string keys for a time field" do
|
|
1494
|
-
@c.
|
|
1601
|
+
@c.db_schema = {:x=>{:type=>:time}}
|
|
1495
1602
|
m = @c.new
|
|
1496
1603
|
y = Time.parse('10:20:30')
|
|
1497
1604
|
m.x = {:hour=>10, :minute=>20, :second=>30}
|
|
@@ -1501,7 +1608,7 @@ describe Sequel::Model, "typecasting" do
|
|
|
1501
1608
|
end
|
|
1502
1609
|
|
|
1503
1610
|
specify "should raise an error if invalid data is used in a time field" do
|
|
1504
|
-
@c.
|
|
1611
|
+
@c.db_schema = {:x=>{:type=>:time}}
|
|
1505
1612
|
proc{@c.new.x = '0000'}.should raise_error
|
|
1506
1613
|
proc{@c.new.x = Date.parse('2008-10-21')}.should raise_error(Sequel::InvalidValue)
|
|
1507
1614
|
proc{@c.new.x = DateTime.parse('2008-10-21')}.should raise_error(Sequel::InvalidValue)
|
|
@@ -1509,14 +1616,14 @@ describe Sequel::Model, "typecasting" do
|
|
|
1509
1616
|
|
|
1510
1617
|
specify "should assign value if raise_on_typecast_failure is off and assigning invalid time" do
|
|
1511
1618
|
@c.raise_on_typecast_failure = false
|
|
1512
|
-
@c.
|
|
1619
|
+
@c.db_schema = {:x=>{:type=>:time}}
|
|
1513
1620
|
model = @c.new
|
|
1514
1621
|
model.x = '0000'
|
|
1515
1622
|
model.x.should == '0000'
|
|
1516
1623
|
end
|
|
1517
1624
|
|
|
1518
1625
|
specify "should convert to the Sequel.datetime_class for a datetime field" do
|
|
1519
|
-
@c.
|
|
1626
|
+
@c.db_schema = {:x=>{:type=>:datetime}}
|
|
1520
1627
|
m = @c.new
|
|
1521
1628
|
x = '2007-10-21T10:20:30-07:00'
|
|
1522
1629
|
y = Time.parse(x)
|
|
@@ -1541,7 +1648,7 @@ describe Sequel::Model, "typecasting" do
|
|
|
1541
1648
|
end
|
|
1542
1649
|
|
|
1543
1650
|
specify "should accept a hash with symbol or string keys for a datetime field" do
|
|
1544
|
-
@c.
|
|
1651
|
+
@c.db_schema = {:x=>{:type=>:datetime}}
|
|
1545
1652
|
m = @c.new
|
|
1546
1653
|
y = Time.parse('2007-10-21 10:20:30')
|
|
1547
1654
|
m.x = {:year=>2007, :month=>10, :day=>21, :hour=>10, :minute=>20, :second=>30}
|
|
@@ -1557,7 +1664,7 @@ describe Sequel::Model, "typecasting" do
|
|
|
1557
1664
|
end
|
|
1558
1665
|
|
|
1559
1666
|
specify "should raise an error if invalid data is used in a datetime field" do
|
|
1560
|
-
@c.
|
|
1667
|
+
@c.db_schema = {:x=>{:type=>:datetime}}
|
|
1561
1668
|
proc{@c.new.x = '0000'}.should raise_error(Sequel::InvalidValue)
|
|
1562
1669
|
Sequel.datetime_class = DateTime
|
|
1563
1670
|
proc{@c.new.x = '0000'}.should raise_error(Sequel::InvalidValue)
|
|
@@ -1566,7 +1673,7 @@ describe Sequel::Model, "typecasting" do
|
|
|
1566
1673
|
|
|
1567
1674
|
specify "should assign value if raise_on_typecast_failure is off and assigning invalid datetime" do
|
|
1568
1675
|
@c.raise_on_typecast_failure = false
|
|
1569
|
-
@c.
|
|
1676
|
+
@c.db_schema = {:x=>{:type=>:datetime}}
|
|
1570
1677
|
model = @c.new
|
|
1571
1678
|
model.x = '0000'
|
|
1572
1679
|
model.x.should == '0000'
|
|
@@ -1584,11 +1691,7 @@ describe "Model#lock!" do
|
|
|
1584
1691
|
@c = Class.new(Sequel::Model(:items)) do
|
|
1585
1692
|
columns :id
|
|
1586
1693
|
end
|
|
1587
|
-
|
|
1588
|
-
def ds.fetch_rows(sql)
|
|
1589
|
-
db.execute(sql)
|
|
1590
|
-
yield({:id=>1})
|
|
1591
|
-
end
|
|
1694
|
+
@c.dataset._fetch = {:id=>1}
|
|
1592
1695
|
MODEL_DB.reset
|
|
1593
1696
|
end
|
|
1594
1697
|
|