sequel 3.21.0 → 3.32.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 +539 -3
- data/MIT-LICENSE +1 -1
- data/README.rdoc +20 -6
- data/Rakefile +37 -19
- data/bin/sequel +1 -5
- data/doc/advanced_associations.rdoc +17 -0
- data/doc/association_basics.rdoc +293 -43
- data/doc/dataset_basics.rdoc +4 -4
- data/doc/dataset_filtering.rdoc +8 -0
- 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 +89 -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/release_notes/3.30.0.txt +135 -0
- data/doc/release_notes/3.31.0.txt +146 -0
- data/doc/release_notes/3.32.0.txt +202 -0
- data/doc/schema_modification.rdoc +547 -0
- data/doc/sharding.rdoc +7 -1
- data/doc/testing.rdoc +129 -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 +17 -9
- data/lib/sequel/adapters/db2.rb +175 -86
- data/lib/sequel/adapters/dbi.rb +15 -15
- data/lib/sequel/adapters/do/mysql.rb +5 -7
- 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 +16 -34
- data/lib/sequel/adapters/jdbc/db2.rb +52 -0
- data/lib/sequel/adapters/jdbc/derby.rb +260 -0
- data/lib/sequel/adapters/jdbc/firebird.rb +29 -0
- data/lib/sequel/adapters/jdbc/h2.rb +66 -30
- data/lib/sequel/adapters/jdbc/hsqldb.rb +177 -0
- data/lib/sequel/adapters/jdbc/informix.rb +26 -0
- data/lib/sequel/adapters/jdbc/jtds.rb +34 -0
- data/lib/sequel/adapters/jdbc/mssql.rb +3 -33
- data/lib/sequel/adapters/jdbc/mysql.rb +11 -11
- data/lib/sequel/adapters/jdbc/oracle.rb +88 -25
- data/lib/sequel/adapters/jdbc/postgresql.rb +9 -13
- data/lib/sequel/adapters/jdbc/sqlite.rb +2 -6
- data/lib/sequel/adapters/jdbc/sqlserver.rb +71 -0
- data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
- data/lib/sequel/adapters/jdbc.rb +231 -78
- data/lib/sequel/adapters/mock.rb +339 -0
- data/lib/sequel/adapters/mysql.rb +85 -184
- data/lib/sequel/adapters/mysql2.rb +26 -25
- data/lib/sequel/adapters/odbc/db2.rb +17 -0
- data/lib/sequel/adapters/odbc/mssql.rb +1 -6
- data/lib/sequel/adapters/odbc.rb +28 -9
- data/lib/sequel/adapters/openbase.rb +3 -5
- data/lib/sequel/adapters/oracle.rb +355 -53
- data/lib/sequel/adapters/postgres.rb +194 -33
- data/lib/sequel/adapters/shared/access.rb +32 -9
- data/lib/sequel/adapters/shared/db2.rb +328 -0
- data/lib/sequel/adapters/shared/firebird.rb +221 -0
- data/lib/sequel/adapters/shared/informix.rb +53 -0
- data/lib/sequel/adapters/shared/mssql.rb +278 -107
- data/lib/sequel/adapters/shared/mysql.rb +203 -65
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +149 -0
- data/lib/sequel/adapters/shared/oracle.rb +237 -46
- data/lib/sequel/adapters/shared/postgres.rb +214 -82
- data/lib/sequel/adapters/shared/progress.rb +5 -8
- data/lib/sequel/adapters/shared/sqlite.rb +200 -50
- data/lib/sequel/adapters/sqlite.rb +29 -21
- data/lib/sequel/adapters/swift/mysql.rb +12 -7
- data/lib/sequel/adapters/swift/postgres.rb +0 -5
- data/lib/sequel/adapters/swift/sqlite.rb +8 -6
- data/lib/sequel/adapters/swift.rb +5 -5
- data/lib/sequel/adapters/tinytds.rb +160 -19
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +66 -0
- data/lib/sequel/adapters/utils/stored_procedures.rb +1 -11
- 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 +68 -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 +104 -19
- data/lib/sequel/database/query.rb +163 -59
- data/lib/sequel/database/schema_generator.rb +17 -7
- data/lib/sequel/database/schema_methods.rb +59 -29
- data/lib/sequel/dataset/actions.rb +240 -76
- data/lib/sequel/dataset/features.rb +91 -8
- data/lib/sequel/dataset/graph.rb +38 -11
- data/lib/sequel/dataset/misc.rb +50 -23
- data/lib/sequel/dataset/mutation.rb +12 -7
- data/lib/sequel/dataset/prepared_statements.rb +59 -27
- data/lib/sequel/dataset/query.rb +236 -43
- data/lib/sequel/dataset/sql.rb +676 -267
- 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/query.rb +1 -1
- 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 +1081 -344
- data/lib/sequel/model/base.rb +420 -133
- data/lib/sequel/model/errors.rb +1 -1
- data/lib/sequel/model/exceptions.rb +5 -1
- data/lib/sequel/model.rb +20 -10
- data/lib/sequel/plugins/active_model.rb +13 -1
- data/lib/sequel/plugins/association_pks.rb +22 -4
- data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
- data/lib/sequel/plugins/composition.rb +43 -10
- 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 +68 -7
- data/lib/sequel/plugins/nested_attributes.rb +65 -10
- 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 +98 -49
- data/lib/sequel/plugins/serialization_modification_detection.rb +63 -0
- data/lib/sequel/plugins/sharding.rb +21 -54
- 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 +109 -52
- data/lib/sequel/timezones.rb +57 -38
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +146 -0
- data/spec/adapters/mssql_spec.rb +135 -30
- data/spec/adapters/mysql_spec.rb +244 -212
- data/spec/adapters/oracle_spec.rb +67 -77
- data/spec/adapters/postgres_spec.rb +267 -78
- 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 +21 -30
- data/spec/core/database_spec.rb +789 -512
- data/spec/core/dataset_spec.rb +1176 -1061
- data/spec/core/expression_filters_spec.rb +159 -42
- data/spec/core/mock_adapter_spec.rb +419 -0
- data/spec/core/object_graph_spec.rb +86 -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/active_model_spec.rb +13 -0
- data/spec/extensions/association_autoreloading_spec.rb +1 -10
- data/spec/extensions/association_dependencies_spec.rb +2 -12
- data/spec/extensions/association_pks_spec.rb +66 -32
- data/spec/extensions/caching_spec.rb +23 -50
- data/spec/extensions/class_table_inheritance_spec.rb +31 -83
- data/spec/extensions/columns_introspection_spec.rb +91 -0
- data/spec/extensions/composition_spec.rb +18 -13
- data/spec/extensions/dataset_associations_spec.rb +199 -0
- data/spec/extensions/defaults_setter_spec.rb +64 -0
- data/spec/extensions/hook_class_methods_spec.rb +65 -91
- data/spec/extensions/identity_map_spec.rb +114 -22
- data/spec/extensions/instance_filters_spec.rb +11 -21
- data/spec/extensions/instance_hooks_spec.rb +53 -0
- data/spec/extensions/json_serializer_spec.rb +4 -5
- data/spec/extensions/lazy_attributes_spec.rb +16 -20
- data/spec/extensions/list_spec.rb +17 -39
- data/spec/extensions/many_through_many_spec.rb +283 -250
- data/spec/extensions/migration_spec.rb +35 -32
- data/spec/extensions/named_timezones_spec.rb +23 -3
- data/spec/extensions/nested_attributes_spec.rb +97 -88
- data/spec/extensions/optimistic_locking_spec.rb +9 -20
- data/spec/extensions/prepared_statements_associations_spec.rb +111 -0
- data/spec/extensions/prepared_statements_safe_spec.rb +61 -0
- data/spec/extensions/prepared_statements_spec.rb +53 -0
- data/spec/extensions/prepared_statements_with_pk_spec.rb +31 -0
- data/spec/extensions/pretty_table_spec.rb +1 -6
- data/spec/extensions/query_spec.rb +6 -0
- data/spec/extensions/rcte_tree_spec.rb +41 -43
- data/spec/extensions/schema_dumper_spec.rb +5 -8
- data/spec/extensions/schema_spec.rb +13 -21
- data/spec/extensions/serialization_modification_detection_spec.rb +72 -0
- data/spec/extensions/serialization_spec.rb +81 -43
- data/spec/extensions/sharding_spec.rb +66 -140
- data/spec/extensions/single_table_inheritance_spec.rb +18 -29
- data/spec/extensions/spec_helper.rb +13 -61
- data/spec/extensions/sql_expr_spec.rb +20 -60
- data/spec/extensions/tactical_eager_loading_spec.rb +9 -19
- data/spec/extensions/thread_local_timezones_spec.rb +22 -2
- data/spec/extensions/timestamps_spec.rb +6 -6
- data/spec/extensions/to_dot_spec.rb +4 -7
- data/spec/extensions/touch_spec.rb +13 -14
- data/spec/extensions/tree_spec.rb +11 -26
- data/spec/extensions/typecast_on_load_spec.rb +1 -6
- data/spec/extensions/update_primary_key_spec.rb +30 -24
- data/spec/extensions/validation_class_methods_spec.rb +30 -51
- data/spec/extensions/validation_helpers_spec.rb +16 -35
- data/spec/extensions/xml_serializer_spec.rb +16 -4
- data/spec/integration/associations_test.rb +661 -21
- data/spec/integration/database_test.rb +4 -2
- data/spec/integration/dataset_test.rb +500 -67
- data/spec/integration/eager_loader_test.rb +19 -21
- data/spec/integration/model_test.rb +80 -1
- data/spec/integration/plugin_test.rb +367 -119
- data/spec/integration/prepared_statement_test.rb +222 -125
- data/spec/integration/schema_test.rb +217 -39
- data/spec/integration/spec_helper.rb +39 -30
- data/spec/integration/timezone_test.rb +38 -12
- data/spec/integration/transaction_test.rb +182 -5
- data/spec/integration/type_test.rb +17 -3
- data/spec/model/association_reflection_spec.rb +201 -7
- data/spec/model/associations_spec.rb +955 -662
- data/spec/model/base_spec.rb +275 -95
- data/spec/model/dataset_methods_spec.rb +7 -27
- data/spec/model/eager_loading_spec.rb +677 -676
- data/spec/model/hooks_spec.rb +349 -67
- data/spec/model/model_spec.rb +222 -168
- data/spec/model/plugins_spec.rb +24 -13
- data/spec/model/record_spec.rb +381 -218
- data/spec/model/spec_helper.rb +13 -71
- data/spec/model/validations_spec.rb +11 -0
- metadata +117 -73
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,66 @@ 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
|
-
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
it "should support a :server option to set the server/shard to use" do
|
|
275
|
+
db = Sequel.mock(:fetch=>{:id=>13, :x=>1}, :autoid=>proc{13}, :numrows=>1, :servers=>{:s1=>{}})
|
|
276
|
+
c = Class.new(Sequel::Model(db[:items]))
|
|
277
|
+
c.columns :id, :x
|
|
278
|
+
db.sqls
|
|
279
|
+
o = c.new(:x => 1)
|
|
280
|
+
o.save(:server=>:s1)
|
|
281
|
+
db.sqls.should == ["INSERT INTO items (x) VALUES (1) -- s1", "SELECT * FROM items WHERE (id = 13) LIMIT 1 -- s1"]
|
|
282
|
+
o.save(:server=>:s1, :transaction=>true)
|
|
283
|
+
db.sqls.should == ["BEGIN -- s1", "UPDATE items SET x = 1 WHERE (id = 13) -- s1", 'COMMIT -- s1']
|
|
284
|
+
end
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
describe "Model#set_server" do
|
|
288
|
+
before do
|
|
289
|
+
@db = Sequel.mock(:fetch=>{:id=>13, :x=>1}, :autoid=>proc{13}, :numrows=>1, :servers=>{:s1=>{}})
|
|
290
|
+
@c = Class.new(Sequel::Model(@db[:items])) do
|
|
291
|
+
columns :id, :x
|
|
292
|
+
end
|
|
293
|
+
@db.sqls
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
it "should set the server to use when inserting" do
|
|
297
|
+
@c.new(:x => 1).set_server(:s1).save
|
|
298
|
+
@db.sqls.should == ["INSERT INTO items (x) VALUES (1) -- s1", "SELECT * FROM items WHERE (id = 13) LIMIT 1 -- s1"]
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
it "should set the server to use when updating" do
|
|
302
|
+
@c.load(:id=>13, :x => 1).set_server(:s1).save
|
|
303
|
+
@db.sqls.should == ["UPDATE items SET x = 1 WHERE (id = 13) -- s1"]
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
it "should set the server to use for transactions when saving" do
|
|
307
|
+
@c.load(:id=>13, :x => 1).set_server(:s1).save(:transaction=>true)
|
|
308
|
+
@db.sqls.should == ["BEGIN -- s1", "UPDATE items SET x = 1 WHERE (id = 13) -- s1", 'COMMIT -- s1']
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
it "should set the server to use when deleting" do
|
|
312
|
+
@c.load(:id=>13).set_server(:s1).delete
|
|
313
|
+
@db.sqls.should == ["DELETE FROM items WHERE (id = 13) -- s1"]
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
it "should set the server to use for transactions when destroying" do
|
|
317
|
+
o = @c.load(:id=>13).set_server(:s1)
|
|
318
|
+
o.use_transactions = true
|
|
319
|
+
o.destroy
|
|
320
|
+
@db.sqls.should == ["BEGIN -- s1", "DELETE FROM items WHERE (id = 13) -- s1", 'COMMIT -- s1']
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
it "should set the server on this if this is already loaded" do
|
|
324
|
+
o = @c.load(:id=>13, :x => 1)
|
|
325
|
+
o.this
|
|
326
|
+
o.set_server(:s1)
|
|
327
|
+
o.this.opts[:server].should == :s1
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
it "should set the server on this if this is not already loaded" do
|
|
331
|
+
@c.load(:id=>13, :x => 1).set_server(:s1).this.opts[:server].should == :s1
|
|
294
332
|
end
|
|
295
333
|
end
|
|
296
334
|
|
|
@@ -299,7 +337,6 @@ describe "Model#marshallable" do
|
|
|
299
337
|
class ::Album < Sequel::Model
|
|
300
338
|
columns :id, :x
|
|
301
339
|
end
|
|
302
|
-
Album.dataset.meta_def(:insert){|h| super(h); 1}
|
|
303
340
|
end
|
|
304
341
|
after do
|
|
305
342
|
Object.send(:remove_const, :Album)
|
|
@@ -381,7 +418,6 @@ describe "Model#modified[!?]" do
|
|
|
381
418
|
end
|
|
382
419
|
|
|
383
420
|
describe "Model#save_changes" do
|
|
384
|
-
|
|
385
421
|
before do
|
|
386
422
|
@c = Class.new(Sequel::Model(:items)) do
|
|
387
423
|
unrestrict_primary_key
|
|
@@ -426,15 +462,14 @@ describe "Model#save_changes" do
|
|
|
426
462
|
MODEL_DB.sqls.should == ["UPDATE items SET x = 2 WHERE (id = 3)"]
|
|
427
463
|
o.save_changes
|
|
428
464
|
o.save_changes
|
|
429
|
-
MODEL_DB.sqls.should == [
|
|
430
|
-
MODEL_DB.reset
|
|
465
|
+
MODEL_DB.sqls.should == []
|
|
431
466
|
|
|
432
467
|
o.y = 4
|
|
433
468
|
o.save_changes
|
|
434
469
|
MODEL_DB.sqls.should == ["UPDATE items SET y = 4 WHERE (id = 3)"]
|
|
435
470
|
o.save_changes
|
|
436
471
|
o.save_changes
|
|
437
|
-
MODEL_DB.sqls.should == [
|
|
472
|
+
MODEL_DB.sqls.should == []
|
|
438
473
|
end
|
|
439
474
|
|
|
440
475
|
it "should not consider columns changed if the values did not change" do
|
|
@@ -446,7 +481,6 @@ describe "Model#save_changes" do
|
|
|
446
481
|
o.x = 3
|
|
447
482
|
o.save_changes
|
|
448
483
|
MODEL_DB.sqls.should == ["UPDATE items SET x = 3 WHERE (id = 3)"]
|
|
449
|
-
MODEL_DB.reset
|
|
450
484
|
|
|
451
485
|
o[:y] = nil
|
|
452
486
|
o.save_changes
|
|
@@ -472,13 +506,11 @@ describe "Model#save_changes" do
|
|
|
472
506
|
o.x = 2
|
|
473
507
|
o.save_changes
|
|
474
508
|
MODEL_DB.sqls.should == ["UPDATE items SET x = 3 WHERE (id = 3)"]
|
|
475
|
-
MODEL_DB.reset
|
|
476
509
|
o.save_changes
|
|
477
510
|
MODEL_DB.sqls.should == []
|
|
478
511
|
o.x = 4
|
|
479
512
|
o.save_changes
|
|
480
513
|
MODEL_DB.sqls.should == ["UPDATE items SET x = 5 WHERE (id = 3)"]
|
|
481
|
-
MODEL_DB.reset
|
|
482
514
|
end
|
|
483
515
|
|
|
484
516
|
it "should update columns changed in a before_save hook" do
|
|
@@ -489,25 +521,21 @@ describe "Model#save_changes" do
|
|
|
489
521
|
o.x = 2
|
|
490
522
|
o.save_changes
|
|
491
523
|
MODEL_DB.sqls.should == ["UPDATE items SET x = 3 WHERE (id = 3)"]
|
|
492
|
-
MODEL_DB.reset
|
|
493
524
|
o.save_changes
|
|
494
525
|
MODEL_DB.sqls.should == []
|
|
495
526
|
o.x = 4
|
|
496
527
|
o.save_changes
|
|
497
528
|
MODEL_DB.sqls.should == ["UPDATE items SET x = 5 WHERE (id = 3)"]
|
|
498
|
-
MODEL_DB.reset
|
|
499
529
|
end
|
|
500
530
|
end
|
|
501
531
|
|
|
502
532
|
describe "Model#new?" do
|
|
503
|
-
|
|
504
|
-
before(:each) do
|
|
505
|
-
MODEL_DB.reset
|
|
506
|
-
|
|
533
|
+
before do
|
|
507
534
|
@c = Class.new(Sequel::Model(:items)) do
|
|
508
535
|
unrestrict_primary_key
|
|
509
536
|
columns :x
|
|
510
537
|
end
|
|
538
|
+
MODEL_DB.reset
|
|
511
539
|
end
|
|
512
540
|
|
|
513
541
|
it "should be true for a new instance" do
|
|
@@ -523,74 +551,65 @@ describe "Model#new?" do
|
|
|
523
551
|
end
|
|
524
552
|
|
|
525
553
|
describe Sequel::Model, "w/ primary key" do
|
|
526
|
-
|
|
527
554
|
it "should default to ':id'" do
|
|
528
555
|
model_a = Class.new Sequel::Model
|
|
529
|
-
model_a.primary_key.should
|
|
556
|
+
model_a.primary_key.should == :id
|
|
530
557
|
end
|
|
531
558
|
|
|
532
559
|
it "should be changed through 'set_primary_key'" do
|
|
533
|
-
model_a = Class.new(Sequel::Model)
|
|
534
|
-
model_a.primary_key.should
|
|
560
|
+
model_a = Class.new(Sequel::Model){ set_primary_key :a }
|
|
561
|
+
model_a.primary_key.should == :a
|
|
535
562
|
end
|
|
536
563
|
|
|
537
564
|
it "should support multi argument composite keys" do
|
|
538
|
-
model_a = Class.new(Sequel::Model)
|
|
539
|
-
model_a.primary_key.should
|
|
565
|
+
model_a = Class.new(Sequel::Model){ set_primary_key :a, :b }
|
|
566
|
+
model_a.primary_key.should == [:a, :b]
|
|
540
567
|
end
|
|
541
568
|
|
|
542
569
|
it "should accept single argument composite keys" do
|
|
543
|
-
model_a = Class.new(Sequel::Model)
|
|
544
|
-
model_a.primary_key.should
|
|
570
|
+
model_a = Class.new(Sequel::Model){ set_primary_key [:a, :b] }
|
|
571
|
+
model_a.primary_key.should == [:a, :b]
|
|
545
572
|
end
|
|
546
|
-
|
|
547
573
|
end
|
|
548
574
|
|
|
549
575
|
describe Sequel::Model, "w/o primary key" do
|
|
550
576
|
it "should return nil for primary key" do
|
|
551
|
-
Class.new(Sequel::Model)
|
|
577
|
+
Class.new(Sequel::Model){no_primary_key}.primary_key.should be_nil
|
|
552
578
|
end
|
|
553
579
|
|
|
554
580
|
it "should raise a Sequel::Error on 'this'" do
|
|
555
|
-
instance = Class.new(Sequel::Model)
|
|
556
|
-
proc
|
|
581
|
+
instance = Class.new(Sequel::Model){no_primary_key}.new
|
|
582
|
+
proc{instance.this}.should raise_error(Sequel::Error)
|
|
557
583
|
end
|
|
558
584
|
end
|
|
559
585
|
|
|
560
586
|
describe Sequel::Model, "with this" do
|
|
561
|
-
|
|
562
|
-
|
|
587
|
+
before do
|
|
588
|
+
@example = Class.new(Sequel::Model(:examples))
|
|
589
|
+
@example.columns :id, :a, :x, :y
|
|
590
|
+
end
|
|
563
591
|
|
|
564
592
|
it "should return a dataset identifying the record" do
|
|
565
|
-
instance = @example.load
|
|
566
|
-
instance.this.sql.should
|
|
593
|
+
instance = @example.load(:id => 3)
|
|
594
|
+
instance.this.sql.should == "SELECT * FROM examples WHERE (id = 3) LIMIT 1"
|
|
567
595
|
end
|
|
568
596
|
|
|
569
597
|
it "should support arbitary primary keys" do
|
|
570
598
|
@example.set_primary_key :a
|
|
571
599
|
|
|
572
|
-
instance = @example.load
|
|
573
|
-
instance.this.sql.should
|
|
600
|
+
instance = @example.load(:a => 3)
|
|
601
|
+
instance.this.sql.should == "SELECT * FROM examples WHERE (a = 3) LIMIT 1"
|
|
574
602
|
end
|
|
575
603
|
|
|
576
604
|
it "should support composite primary keys" do
|
|
577
605
|
@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)
|
|
606
|
+
instance = @example.load(:x => 4, :y => 5)
|
|
607
|
+
instance.this.sql.should =~ /SELECT \* FROM examples WHERE \(\([xy] = [45]\) AND \([xy] = [45]\)\) LIMIT 1/
|
|
588
608
|
end
|
|
589
|
-
|
|
590
609
|
end
|
|
591
610
|
|
|
592
611
|
describe "Model#pk" do
|
|
593
|
-
before
|
|
612
|
+
before do
|
|
594
613
|
@m = Class.new(Sequel::Model)
|
|
595
614
|
@m.columns :id, :x, :y
|
|
596
615
|
end
|
|
@@ -623,8 +642,42 @@ describe "Model#pk" do
|
|
|
623
642
|
end
|
|
624
643
|
end
|
|
625
644
|
|
|
645
|
+
describe "Model#pk_or_nil" do
|
|
646
|
+
before do
|
|
647
|
+
@m = Class.new(Sequel::Model)
|
|
648
|
+
@m.columns :id, :x, :y
|
|
649
|
+
end
|
|
650
|
+
|
|
651
|
+
it "should be default return the value of the :id column" do
|
|
652
|
+
m = @m.load(:id => 111, :x => 2, :y => 3)
|
|
653
|
+
m.pk_or_nil.should == 111
|
|
654
|
+
end
|
|
655
|
+
|
|
656
|
+
it "should be return the primary key value for custom primary key" do
|
|
657
|
+
@m.set_primary_key :x
|
|
658
|
+
m = @m.load(:id => 111, :x => 2, :y => 3)
|
|
659
|
+
m.pk_or_nil.should == 2
|
|
660
|
+
end
|
|
661
|
+
|
|
662
|
+
it "should be return the primary key value for composite primary key" do
|
|
663
|
+
@m.set_primary_key [:y, :x]
|
|
664
|
+
m = @m.load(:id => 111, :x => 2, :y => 3)
|
|
665
|
+
m.pk_or_nil.should == [3, 2]
|
|
666
|
+
end
|
|
667
|
+
|
|
668
|
+
it "should raise if no primary key" do
|
|
669
|
+
@m.set_primary_key nil
|
|
670
|
+
m = @m.new(:id => 111, :x => 2, :y => 3)
|
|
671
|
+
m.pk_or_nil.should be_nil
|
|
672
|
+
|
|
673
|
+
@m.no_primary_key
|
|
674
|
+
m = @m.new(:id => 111, :x => 2, :y => 3)
|
|
675
|
+
m.pk_or_nil.should be_nil
|
|
676
|
+
end
|
|
677
|
+
end
|
|
678
|
+
|
|
626
679
|
describe "Model#pk_hash" do
|
|
627
|
-
before
|
|
680
|
+
before do
|
|
628
681
|
@m = Class.new(Sequel::Model)
|
|
629
682
|
@m.columns :id, :x, :y
|
|
630
683
|
end
|
|
@@ -659,16 +712,14 @@ end
|
|
|
659
712
|
|
|
660
713
|
describe Sequel::Model, "#set" do
|
|
661
714
|
before do
|
|
662
|
-
MODEL_DB.reset
|
|
663
|
-
|
|
664
715
|
@c = Class.new(Sequel::Model(:items)) do
|
|
665
716
|
set_primary_key :id
|
|
666
717
|
columns :x, :y, :id
|
|
667
718
|
end
|
|
668
719
|
@c.strict_param_setting = false
|
|
669
|
-
@c.instance_variable_set(:@columns, true)
|
|
670
720
|
@o1 = @c.new
|
|
671
721
|
@o2 = @c.load(:id => 5)
|
|
722
|
+
MODEL_DB.reset
|
|
672
723
|
end
|
|
673
724
|
|
|
674
725
|
it "should filter the given params using the model columns" do
|
|
@@ -716,6 +767,29 @@ describe Sequel::Model, "#set" do
|
|
|
716
767
|
MODEL_DB.sqls.should == []
|
|
717
768
|
end
|
|
718
769
|
|
|
770
|
+
it "should raise error if strict_param_setting is true and method does not exist" do
|
|
771
|
+
@o1.strict_param_setting = true
|
|
772
|
+
proc{@o1.set('foo' => 1)}.should raise_error(Sequel::Error)
|
|
773
|
+
end
|
|
774
|
+
|
|
775
|
+
it "should raise error if strict_param_setting is true and column is a primary key" do
|
|
776
|
+
@o1.strict_param_setting = true
|
|
777
|
+
proc{@o1.set('id' => 1)}.should raise_error(Sequel::Error)
|
|
778
|
+
end
|
|
779
|
+
|
|
780
|
+
it "should raise error if strict_param_setting is true and column is restricted" do
|
|
781
|
+
@o1.strict_param_setting = true
|
|
782
|
+
@c.set_restricted_columns :x
|
|
783
|
+
proc{@o1.set('x' => 1)}.should raise_error(Sequel::Error)
|
|
784
|
+
end
|
|
785
|
+
|
|
786
|
+
it "should not create a symbol if strict_param_setting is true and string is given" do
|
|
787
|
+
@o1.strict_param_setting = true
|
|
788
|
+
l = Symbol.all_symbols.length
|
|
789
|
+
proc{@o1.set('sadojafdso' => 1)}.should raise_error(Sequel::Error)
|
|
790
|
+
Symbol.all_symbols.length.should == l
|
|
791
|
+
end
|
|
792
|
+
|
|
719
793
|
it "#set should correctly handle cases where an instance method is added to the class" do
|
|
720
794
|
@o1.set(:x => 1)
|
|
721
795
|
@o1.values.should == {:x => 1}
|
|
@@ -739,51 +813,74 @@ describe Sequel::Model, "#set" do
|
|
|
739
813
|
@o1.set(:x => 2, :z => 3)
|
|
740
814
|
@o1.values.should == {:x => 2, :z=>3}
|
|
741
815
|
end
|
|
816
|
+
|
|
817
|
+
it "#set should correctly handle cases where a module with a setter method is included in the class" do
|
|
818
|
+
@o1.set(:x => 1)
|
|
819
|
+
@o1.values.should == {:x => 1}
|
|
820
|
+
|
|
821
|
+
@c.send(:include, Module.new do
|
|
822
|
+
def z=(v)
|
|
823
|
+
self[:z] = v
|
|
824
|
+
end
|
|
825
|
+
end)
|
|
826
|
+
@o1.set(:x => 2, :z => 3)
|
|
827
|
+
@o1.values.should == {:x => 2, :z=>3}
|
|
828
|
+
end
|
|
829
|
+
|
|
830
|
+
it "#set should correctly handle cases where the object extends a module with a setter method " do
|
|
831
|
+
@o1.set(:x => 1)
|
|
832
|
+
@o1.values.should == {:x => 1}
|
|
833
|
+
|
|
834
|
+
@o1.extend(Module.new do
|
|
835
|
+
def z=(v)
|
|
836
|
+
self[:z] = v
|
|
837
|
+
end
|
|
838
|
+
end)
|
|
839
|
+
@o1.set(:x => 2, :z => 3)
|
|
840
|
+
@o1.values.should == {:x => 2, :z=>3}
|
|
841
|
+
end
|
|
742
842
|
end
|
|
743
843
|
|
|
744
844
|
describe Sequel::Model, "#update" do
|
|
745
845
|
before do
|
|
746
|
-
MODEL_DB.reset
|
|
747
|
-
|
|
748
846
|
@c = Class.new(Sequel::Model(:items)) do
|
|
749
847
|
set_primary_key :id
|
|
750
848
|
columns :x, :y, :id
|
|
751
849
|
end
|
|
752
850
|
@c.strict_param_setting = false
|
|
753
|
-
@c.instance_variable_set(:@columns, true)
|
|
754
851
|
@o1 = @c.new
|
|
755
852
|
@o2 = @c.load(:id => 5)
|
|
853
|
+
MODEL_DB.reset
|
|
756
854
|
end
|
|
757
855
|
|
|
758
856
|
it "should filter the given params using the model columns" do
|
|
759
857
|
@o1.update(:x => 1, :z => 2)
|
|
760
|
-
MODEL_DB.sqls.
|
|
858
|
+
MODEL_DB.sqls.should == ["INSERT INTO items (x) VALUES (1)", "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
|
|
761
859
|
|
|
762
860
|
MODEL_DB.reset
|
|
763
861
|
@o2.update(:y => 1, :abc => 2)
|
|
764
|
-
MODEL_DB.sqls.
|
|
862
|
+
MODEL_DB.sqls.should == ["UPDATE items SET y = 1 WHERE (id = 5)"]
|
|
765
863
|
end
|
|
766
864
|
|
|
767
865
|
it "should support virtual attributes" do
|
|
768
866
|
@c.send(:define_method, :blah=){|v| self.x = v}
|
|
769
867
|
@o1.update(:blah => 333)
|
|
770
|
-
MODEL_DB.sqls.
|
|
868
|
+
MODEL_DB.sqls.should == ["INSERT INTO items (x) VALUES (333)", "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
|
|
771
869
|
end
|
|
772
870
|
|
|
773
871
|
it "should not modify the primary key" do
|
|
774
872
|
@o1.update(:x => 1, :id => 2)
|
|
775
|
-
MODEL_DB.sqls.
|
|
873
|
+
MODEL_DB.sqls.should == ["INSERT INTO items (x) VALUES (1)", "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
|
|
776
874
|
MODEL_DB.reset
|
|
777
875
|
@o2.update('y'=> 1, 'id'=> 2)
|
|
778
876
|
@o2.values.should == {:y => 1, :id=> 5}
|
|
779
|
-
MODEL_DB.sqls.
|
|
877
|
+
MODEL_DB.sqls.should == ["UPDATE items SET y = 1 WHERE (id = 5)"]
|
|
780
878
|
end
|
|
781
879
|
end
|
|
782
880
|
|
|
783
881
|
describe Sequel::Model, "#set_fields" do
|
|
784
882
|
before do
|
|
785
|
-
@c = Class.new(Sequel::Model(:items))
|
|
786
|
-
@c.class_eval do
|
|
883
|
+
@c = Class.new(Sequel::Model(:items)) do
|
|
787
884
|
set_primary_key :id
|
|
788
885
|
columns :x, :y, :z, :id
|
|
789
886
|
end
|
|
@@ -803,11 +900,9 @@ end
|
|
|
803
900
|
|
|
804
901
|
describe Sequel::Model, "#update_fields" do
|
|
805
902
|
before do
|
|
806
|
-
@c = Class.new(Sequel::Model(:items))
|
|
807
|
-
@c.class_eval do
|
|
903
|
+
@c = Class.new(Sequel::Model(:items)) do
|
|
808
904
|
set_primary_key :id
|
|
809
905
|
columns :x, :y, :z, :id
|
|
810
|
-
def _refresh(ds); end
|
|
811
906
|
end
|
|
812
907
|
@c.strict_param_setting = true
|
|
813
908
|
@o1 = @c.load(:id=>1)
|
|
@@ -817,21 +912,18 @@ describe Sequel::Model, "#update_fields" do
|
|
|
817
912
|
it "should set only the given fields, and then save the changes to the record" do
|
|
818
913
|
@o1.update_fields({:x => 1, :y => 2, :z=>3, :id=>4}, [:x, :y])
|
|
819
914
|
@o1.values.should == {:x => 1, :y => 2, :id=>1}
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
915
|
+
sqls = MODEL_DB.sqls
|
|
916
|
+
sqls.pop.should =~ /UPDATE items SET [xy] = [12], [xy] = [12] WHERE \(id = 1\)/
|
|
917
|
+
sqls.should == []
|
|
823
918
|
|
|
824
919
|
@o1.update_fields({:x => 1, :y => 5, :z=>6, :id=>7}, [:x, :y])
|
|
825
920
|
@o1.values.should == {:x => 1, :y => 5, :id=>1}
|
|
826
921
|
MODEL_DB.sqls.should == ["UPDATE items SET y = 5 WHERE (id = 1)"]
|
|
827
|
-
MODEL_DB.reset
|
|
828
922
|
end
|
|
829
923
|
end
|
|
830
924
|
|
|
831
925
|
describe Sequel::Model, "#(set|update)_(all|except|only)" do
|
|
832
926
|
before do
|
|
833
|
-
MODEL_DB.reset
|
|
834
|
-
|
|
835
927
|
@c = Class.new(Sequel::Model(:items)) do
|
|
836
928
|
set_primary_key :id
|
|
837
929
|
columns :x, :y, :z, :id
|
|
@@ -839,8 +931,8 @@ describe Sequel::Model, "#(set|update)_(all|except|only)" do
|
|
|
839
931
|
set_restricted_columns :y
|
|
840
932
|
end
|
|
841
933
|
@c.strict_param_setting = false
|
|
842
|
-
@c.instance_variable_set(:@columns, true)
|
|
843
934
|
@o1 = @c.new
|
|
935
|
+
MODEL_DB.reset
|
|
844
936
|
end
|
|
845
937
|
|
|
846
938
|
it "should raise errors if not all hash fields can be set and strict_param_setting is true" do
|
|
@@ -884,40 +976,34 @@ describe Sequel::Model, "#(set|update)_(all|except|only)" do
|
|
|
884
976
|
|
|
885
977
|
it "#update_all should update all attributes" do
|
|
886
978
|
@c.new.update_all(:x => 1, :id=>4)
|
|
887
|
-
MODEL_DB.sqls.
|
|
888
|
-
MODEL_DB.reset
|
|
979
|
+
MODEL_DB.sqls.should == ["INSERT INTO items (x) VALUES (1)", "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
|
|
889
980
|
@c.new.update_all(:y => 1, :id=>4)
|
|
890
|
-
MODEL_DB.sqls.
|
|
891
|
-
MODEL_DB.reset
|
|
981
|
+
MODEL_DB.sqls.should == ["INSERT INTO items (y) VALUES (1)", "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
|
|
892
982
|
@c.new.update_all(:z => 1, :id=>4)
|
|
893
|
-
MODEL_DB.sqls.
|
|
983
|
+
MODEL_DB.sqls.should == ["INSERT INTO items (z) VALUES (1)", "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
|
|
894
984
|
end
|
|
895
985
|
|
|
896
986
|
it "#update_only should only update given attributes" do
|
|
897
987
|
@o1.update_only({:x => 1, :y => 2, :z=>3, :id=>4}, [:x])
|
|
898
|
-
MODEL_DB.sqls.
|
|
899
|
-
MODEL_DB.reset
|
|
988
|
+
MODEL_DB.sqls.should == ["INSERT INTO items (x) VALUES (1)", "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
|
|
900
989
|
@c.new.update_only({:x => 1, :y => 2, :z=>3, :id=>4}, :x)
|
|
901
|
-
MODEL_DB.sqls.
|
|
990
|
+
MODEL_DB.sqls.should == ["INSERT INTO items (x) VALUES (1)", "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
|
|
902
991
|
end
|
|
903
992
|
|
|
904
993
|
it "#update_except should not update given attributes" do
|
|
905
994
|
@o1.update_except({:x => 1, :y => 2, :z=>3, :id=>4}, [:y, :z])
|
|
906
|
-
MODEL_DB.sqls.
|
|
907
|
-
MODEL_DB.reset
|
|
995
|
+
MODEL_DB.sqls.should == ["INSERT INTO items (x) VALUES (1)", "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
|
|
908
996
|
@c.new.update_except({:x => 1, :y => 2, :z=>3, :id=>4}, :y, :z)
|
|
909
|
-
MODEL_DB.sqls.
|
|
997
|
+
MODEL_DB.sqls.should == ["INSERT INTO items (x) VALUES (1)", "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
|
|
910
998
|
end
|
|
911
999
|
end
|
|
912
1000
|
|
|
913
1001
|
describe Sequel::Model, "#destroy" do
|
|
914
1002
|
before do
|
|
915
|
-
MODEL_DB.reset
|
|
916
1003
|
@model = Class.new(Sequel::Model(:items))
|
|
917
1004
|
@model.columns :id
|
|
918
|
-
@model.dataset.meta_def(:delete){MODEL_DB.execute delete_sql;1}
|
|
919
|
-
|
|
920
1005
|
@instance = @model.load(:id => 1234)
|
|
1006
|
+
MODEL_DB.reset
|
|
921
1007
|
end
|
|
922
1008
|
|
|
923
1009
|
it "should return self" do
|
|
@@ -942,49 +1028,40 @@ describe Sequel::Model, "#destroy" do
|
|
|
942
1028
|
|
|
943
1029
|
it "should run within a transaction if use_transactions is true" do
|
|
944
1030
|
@instance.use_transactions = true
|
|
945
|
-
@model.db.should_receive(:transaction)
|
|
946
1031
|
@instance.destroy
|
|
1032
|
+
MODEL_DB.sqls.should == ["BEGIN", "DELETE FROM items WHERE (id = 1234)", "COMMIT"]
|
|
947
1033
|
end
|
|
948
1034
|
|
|
949
1035
|
it "should not run within a transaction if use_transactions is false" do
|
|
950
1036
|
@instance.use_transactions = false
|
|
951
|
-
@model.db.should_not_receive(:transaction)
|
|
952
1037
|
@instance.destroy
|
|
1038
|
+
MODEL_DB.sqls.should == ["DELETE FROM items WHERE (id = 1234)"]
|
|
953
1039
|
end
|
|
954
1040
|
|
|
955
1041
|
it "should run within a transaction if :transaction option is true" do
|
|
956
1042
|
@instance.use_transactions = false
|
|
957
|
-
@model.db.should_receive(:transaction)
|
|
958
1043
|
@instance.destroy(:transaction => true)
|
|
1044
|
+
MODEL_DB.sqls.should == ["BEGIN", "DELETE FROM items WHERE (id = 1234)", "COMMIT"]
|
|
959
1045
|
end
|
|
960
1046
|
|
|
961
1047
|
it "should not run within a transaction if :transaction option is false" do
|
|
962
1048
|
@instance.use_transactions = true
|
|
963
|
-
@model.db.should_not_receive(:transaction)
|
|
964
1049
|
@instance.destroy(:transaction => false)
|
|
1050
|
+
MODEL_DB.sqls.should == ["DELETE FROM items WHERE (id = 1234)"]
|
|
965
1051
|
end
|
|
966
1052
|
|
|
967
1053
|
it "should run before_destroy and after_destroy hooks" do
|
|
968
1054
|
@model.send(:define_method, :before_destroy){MODEL_DB.execute('before blah')}
|
|
969
1055
|
@model.send(:define_method, :after_destroy){MODEL_DB.execute('after blah')}
|
|
970
1056
|
@instance.destroy
|
|
971
|
-
|
|
972
|
-
MODEL_DB.sqls.should == [
|
|
973
|
-
"before blah",
|
|
974
|
-
"DELETE FROM items WHERE (id = 1234)",
|
|
975
|
-
"after blah"
|
|
976
|
-
]
|
|
1057
|
+
MODEL_DB.sqls.should == ["before blah", "DELETE FROM items WHERE (id = 1234)", "after blah"]
|
|
977
1058
|
end
|
|
978
1059
|
end
|
|
979
1060
|
|
|
980
1061
|
describe Sequel::Model, "#exists?" do
|
|
981
|
-
before
|
|
1062
|
+
before do
|
|
982
1063
|
@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
|
|
1064
|
+
@model.dataset._fetch = proc{|sql| {:x=>1} if sql =~ /id = 1/}
|
|
988
1065
|
MODEL_DB.reset
|
|
989
1066
|
end
|
|
990
1067
|
|
|
@@ -997,6 +1074,11 @@ describe Sequel::Model, "#exists?" do
|
|
|
997
1074
|
@model.load(:id=>2).exists?.should be_false
|
|
998
1075
|
MODEL_DB.sqls.should == ['SELECT 1 FROM items WHERE (id = 2) LIMIT 1']
|
|
999
1076
|
end
|
|
1077
|
+
|
|
1078
|
+
it "should return false without issuing a query if the model object is new" do
|
|
1079
|
+
@model.new.exists?.should be_false
|
|
1080
|
+
MODEL_DB.sqls.should == []
|
|
1081
|
+
end
|
|
1000
1082
|
end
|
|
1001
1083
|
|
|
1002
1084
|
describe Sequel::Model, "#each" do
|
|
@@ -1008,7 +1090,7 @@ describe Sequel::Model, "#each" do
|
|
|
1008
1090
|
|
|
1009
1091
|
specify "should iterate over the values" do
|
|
1010
1092
|
h = {}
|
|
1011
|
-
@m.each
|
|
1093
|
+
@m.each{|k, v| h[k] = v}
|
|
1012
1094
|
h.should == {:a => 1, :b => 2, :id => 4444}
|
|
1013
1095
|
end
|
|
1014
1096
|
end
|
|
@@ -1021,11 +1103,8 @@ describe Sequel::Model, "#keys" do
|
|
|
1021
1103
|
end
|
|
1022
1104
|
|
|
1023
1105
|
specify "should return the value keys" do
|
|
1024
|
-
@m.keys.
|
|
1025
|
-
@
|
|
1026
|
-
|
|
1027
|
-
@m = @model.new()
|
|
1028
|
-
@m.keys.should == []
|
|
1106
|
+
@m.keys.sort_by{|k| k.to_s}.should == [:a, :b, :id]
|
|
1107
|
+
@model.new.keys.should == []
|
|
1029
1108
|
end
|
|
1030
1109
|
end
|
|
1031
1110
|
|
|
@@ -1094,13 +1173,10 @@ describe Sequel::Model, "#hash" do
|
|
|
1094
1173
|
y = Class.new(Sequel::Model)
|
|
1095
1174
|
y.columns :id, :x
|
|
1096
1175
|
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
1176
|
|
|
1101
|
-
a.hash.should ==
|
|
1102
|
-
a.hash.should_not ==
|
|
1103
|
-
a.hash.should_not ==
|
|
1177
|
+
a.hash.should == z.load(:id => 1, :x => 4).hash
|
|
1178
|
+
a.hash.should_not == z.load(:id => 2, :x => 3).hash
|
|
1179
|
+
a.hash.should_not == y.load(:id => 1, :x => 3).hash
|
|
1104
1180
|
end
|
|
1105
1181
|
|
|
1106
1182
|
specify "should be the same only for objects with the same class and values if the pk is nil" do
|
|
@@ -1109,14 +1185,71 @@ describe Sequel::Model, "#hash" do
|
|
|
1109
1185
|
y = Class.new(Sequel::Model)
|
|
1110
1186
|
y.columns :id, :x
|
|
1111
1187
|
a = z.new(:x => 3)
|
|
1112
|
-
b = z.new(:x => 4)
|
|
1113
|
-
c = z.new(:x => 3)
|
|
1114
|
-
d = y.new(:x => 3)
|
|
1115
1188
|
|
|
1116
|
-
a.hash.should_not ==
|
|
1117
|
-
a.hash.should ==
|
|
1118
|
-
a.hash.should_not ==
|
|
1189
|
+
a.hash.should_not == z.new(:x => 4).hash
|
|
1190
|
+
a.hash.should == z.new(:x => 3).hash
|
|
1191
|
+
a.hash.should_not == y.new(:x => 3).hash
|
|
1192
|
+
end
|
|
1193
|
+
|
|
1194
|
+
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
|
|
1195
|
+
z = Class.new(Sequel::Model)
|
|
1196
|
+
z.columns :id, :id2, :x
|
|
1197
|
+
z.set_primary_key(:id, :id2)
|
|
1198
|
+
y = Class.new(Sequel::Model)
|
|
1199
|
+
y.columns :id, :id2, :x
|
|
1200
|
+
y.set_primary_key(:id, :id2)
|
|
1201
|
+
a = z.load(:id => 1, :id2=>2, :x => 3)
|
|
1202
|
+
|
|
1203
|
+
a.hash.should == z.load(:id => 1, :id2=>2, :x => 4).hash
|
|
1204
|
+
a.hash.should_not == z.load(:id => 2, :id2=>1, :x => 3).hash
|
|
1205
|
+
a.hash.should_not == y.load(:id => 1, :id2=>1, :x => 3).hash
|
|
1206
|
+
end
|
|
1207
|
+
|
|
1208
|
+
specify "should be the same only for objects with the same class and value if pk is composite and one values is NULL" do
|
|
1209
|
+
z = Class.new(Sequel::Model)
|
|
1210
|
+
z.columns :id, :id2, :x
|
|
1211
|
+
z.set_primary_key(:id, :id2)
|
|
1212
|
+
y = Class.new(Sequel::Model)
|
|
1213
|
+
y.columns :id, :id2, :x
|
|
1214
|
+
y.set_primary_key(:id, :id2)
|
|
1215
|
+
|
|
1216
|
+
a = z.load(:id => 1, :id2 => nil, :x => 3)
|
|
1217
|
+
a.hash.should == z.load(:id => 1, :id2=>nil, :x => 3).hash
|
|
1218
|
+
a.hash.should_not == z.load(:id => 1, :id2=>nil, :x => 4).hash
|
|
1219
|
+
a.hash.should_not == y.load(:id => 1, :id2=>nil, :x => 3).hash
|
|
1220
|
+
|
|
1221
|
+
a = z.load(:id =>nil, :id2 => nil, :x => 3)
|
|
1222
|
+
a.hash.should == z.load(:id => nil, :id2=>nil, :x => 3).hash
|
|
1223
|
+
a.hash.should_not == z.load(:id => nil, :id2=>nil, :x => 4).hash
|
|
1224
|
+
a.hash.should_not == y.load(:id => nil, :id2=>nil, :x => 3).hash
|
|
1225
|
+
|
|
1226
|
+
a = z.load(:id => 1, :x => 3)
|
|
1227
|
+
a.hash.should == z.load(:id => 1, :x => 3).hash
|
|
1228
|
+
a.hash.should_not == z.load(:id => 1, :id2=>nil, :x => 3).hash
|
|
1229
|
+
a.hash.should_not == z.load(:id => 1, :x => 4).hash
|
|
1230
|
+
a.hash.should_not == y.load(:id => 1, :x => 3).hash
|
|
1231
|
+
|
|
1232
|
+
a = z.load(:x => 3)
|
|
1233
|
+
a.hash.should == z.load(:x => 3).hash
|
|
1234
|
+
a.hash.should_not == z.load(:id => nil, :id2=>nil, :x => 3).hash
|
|
1235
|
+
a.hash.should_not == z.load(:x => 4).hash
|
|
1236
|
+
a.hash.should_not == y.load(:x => 3).hash
|
|
1237
|
+
end
|
|
1238
|
+
|
|
1239
|
+
specify "should be the same only for objects with the same class and values if the no primary key" do
|
|
1240
|
+
z = Class.new(Sequel::Model)
|
|
1241
|
+
z.columns :id, :x
|
|
1242
|
+
z.no_primary_key
|
|
1243
|
+
y = Class.new(Sequel::Model)
|
|
1244
|
+
y.columns :id, :x
|
|
1245
|
+
y.no_primary_key
|
|
1246
|
+
a = z.new(:x => 3)
|
|
1247
|
+
|
|
1248
|
+
a.hash.should_not == z.new(:x => 4).hash
|
|
1249
|
+
a.hash.should == z.new(:x => 3).hash
|
|
1250
|
+
a.hash.should_not == y.new(:x => 3).hash
|
|
1119
1251
|
end
|
|
1252
|
+
|
|
1120
1253
|
end
|
|
1121
1254
|
|
|
1122
1255
|
describe Sequel::Model, "#initialize" do
|
|
@@ -1161,10 +1294,32 @@ describe Sequel::Model, "#initialize" do
|
|
|
1161
1294
|
m.values.should == {:x => 2}
|
|
1162
1295
|
end
|
|
1163
1296
|
end
|
|
1297
|
+
|
|
1298
|
+
describe Sequel::Model, "#initialize_set" do
|
|
1299
|
+
before do
|
|
1300
|
+
@c = Class.new(Sequel::Model){columns :id, :x, :y}
|
|
1301
|
+
end
|
|
1164
1302
|
|
|
1165
|
-
|
|
1303
|
+
specify "should be called by initialize to set the column values" do
|
|
1304
|
+
@c.send(:define_method, :initialize_set){|h| set(:y => 3)}
|
|
1305
|
+
@c.new(:x => 2).values.should == {:y => 3}
|
|
1306
|
+
end
|
|
1307
|
+
|
|
1308
|
+
specify "should be called with the hash given to initialize " do
|
|
1309
|
+
x = nil
|
|
1310
|
+
@c.send(:define_method, :initialize_set){|y| x = y}
|
|
1311
|
+
@c.new(:x => 2)
|
|
1312
|
+
x.should == {:x => 2}
|
|
1313
|
+
end
|
|
1166
1314
|
|
|
1167
|
-
|
|
1315
|
+
specify "should not cause columns modified by the method to be considered as changed" do
|
|
1316
|
+
@c.send(:define_method, :initialize_set){|h| set(:y => 3)}
|
|
1317
|
+
@c.new(:x => 2).changed_columns.should == []
|
|
1318
|
+
end
|
|
1319
|
+
end
|
|
1320
|
+
|
|
1321
|
+
describe Sequel::Model, ".create" do
|
|
1322
|
+
before do
|
|
1168
1323
|
MODEL_DB.reset
|
|
1169
1324
|
@c = Class.new(Sequel::Model(:items)) do
|
|
1170
1325
|
unrestrict_primary_key
|
|
@@ -1175,13 +1330,13 @@ describe Sequel::Model, ".create" do
|
|
|
1175
1330
|
it "should be able to create rows in the associated table" do
|
|
1176
1331
|
o = @c.create(:x => 1)
|
|
1177
1332
|
o.class.should == @c
|
|
1178
|
-
MODEL_DB.sqls.should == ['INSERT INTO items (x) VALUES (1)',
|
|
1333
|
+
MODEL_DB.sqls.should == ['INSERT INTO items (x) VALUES (1)', "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
|
|
1179
1334
|
end
|
|
1180
1335
|
|
|
1181
1336
|
it "should be able to create rows without any values specified" do
|
|
1182
1337
|
o = @c.create
|
|
1183
1338
|
o.class.should == @c
|
|
1184
|
-
MODEL_DB.sqls.should == ["INSERT INTO items DEFAULT VALUES", "SELECT * FROM items WHERE (id
|
|
1339
|
+
MODEL_DB.sqls.should == ["INSERT INTO items DEFAULT VALUES", "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
|
|
1185
1340
|
end
|
|
1186
1341
|
|
|
1187
1342
|
it "should accept a block and run it" do
|
|
@@ -1191,7 +1346,7 @@ describe Sequel::Model, ".create" do
|
|
|
1191
1346
|
o1.should === o
|
|
1192
1347
|
o3.should === o
|
|
1193
1348
|
o2.should == :blah
|
|
1194
|
-
MODEL_DB.sqls.should == ["INSERT INTO items (x) VALUES (333)", "SELECT * FROM items WHERE (id
|
|
1349
|
+
MODEL_DB.sqls.should == ["INSERT INTO items (x) VALUES (333)", "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
|
|
1195
1350
|
end
|
|
1196
1351
|
|
|
1197
1352
|
it "should create a row for a model with custom primary key" do
|
|
@@ -1204,32 +1359,35 @@ end
|
|
|
1204
1359
|
|
|
1205
1360
|
describe Sequel::Model, "#refresh" do
|
|
1206
1361
|
before do
|
|
1207
|
-
MODEL_DB.reset
|
|
1208
1362
|
@c = Class.new(Sequel::Model(:items)) do
|
|
1209
1363
|
unrestrict_primary_key
|
|
1210
1364
|
columns :id, :x
|
|
1211
1365
|
end
|
|
1366
|
+
MODEL_DB.reset
|
|
1212
1367
|
end
|
|
1213
1368
|
|
|
1214
1369
|
specify "should reload the instance values from the database" do
|
|
1215
1370
|
@m = @c.new(:id => 555)
|
|
1216
1371
|
@m[:x] = 'blah'
|
|
1217
|
-
@
|
|
1372
|
+
@c.dataset._fetch = {:x => 'kaboom', :id => 555}
|
|
1218
1373
|
@m.refresh
|
|
1219
1374
|
@m[:x].should == 'kaboom'
|
|
1375
|
+
MODEL_DB.sqls.should == ["SELECT * FROM items WHERE (id = 555) LIMIT 1"]
|
|
1220
1376
|
end
|
|
1221
1377
|
|
|
1222
1378
|
specify "should raise if the instance is not found" do
|
|
1223
1379
|
@m = @c.new(:id => 555)
|
|
1224
|
-
@
|
|
1380
|
+
@c.dataset._fetch = []
|
|
1225
1381
|
proc {@m.refresh}.should raise_error(Sequel::Error)
|
|
1382
|
+
MODEL_DB.sqls.should == ["SELECT * FROM items WHERE (id = 555) LIMIT 1"]
|
|
1226
1383
|
end
|
|
1227
1384
|
|
|
1228
1385
|
specify "should be aliased by #reload" do
|
|
1229
1386
|
@m = @c.new(:id => 555)
|
|
1230
|
-
@
|
|
1387
|
+
@c.dataset._fetch = {:x => 'kaboom', :id => 555}
|
|
1231
1388
|
@m.reload
|
|
1232
1389
|
@m[:x].should == 'kaboom'
|
|
1390
|
+
MODEL_DB.sqls.should == ["SELECT * FROM items WHERE (id = 555) LIMIT 1"]
|
|
1233
1391
|
end
|
|
1234
1392
|
|
|
1235
1393
|
specify "should remove cached associations" do
|
|
@@ -1243,10 +1401,11 @@ end
|
|
|
1243
1401
|
|
|
1244
1402
|
describe Sequel::Model, "typecasting" do
|
|
1245
1403
|
before do
|
|
1246
|
-
MODEL_DB.reset
|
|
1247
1404
|
@c = Class.new(Sequel::Model(:items)) do
|
|
1248
1405
|
columns :x
|
|
1249
1406
|
end
|
|
1407
|
+
@c.db_schema = {:x=>{:type=>:integer}}
|
|
1408
|
+
MODEL_DB.reset
|
|
1250
1409
|
end
|
|
1251
1410
|
|
|
1252
1411
|
after do
|
|
@@ -1255,14 +1414,13 @@ describe Sequel::Model, "typecasting" do
|
|
|
1255
1414
|
|
|
1256
1415
|
specify "should not convert if typecasting is turned off" do
|
|
1257
1416
|
@c.typecast_on_assignment = false
|
|
1258
|
-
@c.instance_variable_set(:@db_schema, {:x=>{:type=>:integer}})
|
|
1259
1417
|
m = @c.new
|
|
1260
1418
|
m.x = '1'
|
|
1261
1419
|
m.x.should == '1'
|
|
1262
1420
|
end
|
|
1263
1421
|
|
|
1264
1422
|
specify "should convert to integer for an integer field" do
|
|
1265
|
-
@c.
|
|
1423
|
+
@c.db_schema = {:x=>{:type=>:integer}}
|
|
1266
1424
|
m = @c.new
|
|
1267
1425
|
m.x = '1'
|
|
1268
1426
|
m.x.should == 1
|
|
@@ -1274,13 +1432,13 @@ describe Sequel::Model, "typecasting" do
|
|
|
1274
1432
|
|
|
1275
1433
|
specify "should typecast '' to nil unless type is string or blob" do
|
|
1276
1434
|
[:integer, :float, :decimal, :boolean, :date, :time, :datetime].each do |x|
|
|
1277
|
-
@c.
|
|
1435
|
+
@c.db_schema = {:x=>{:type=>x}}
|
|
1278
1436
|
m = @c.new
|
|
1279
1437
|
m.x = ''
|
|
1280
1438
|
m.x.should == nil
|
|
1281
1439
|
end
|
|
1282
1440
|
[:string, :blob].each do |x|
|
|
1283
|
-
@c.
|
|
1441
|
+
@c.db_schema = {:x=>{:type=>x}}
|
|
1284
1442
|
m = @c.new
|
|
1285
1443
|
m.x = ''
|
|
1286
1444
|
m.x.should == ''
|
|
@@ -1288,7 +1446,6 @@ describe Sequel::Model, "typecasting" do
|
|
|
1288
1446
|
end
|
|
1289
1447
|
|
|
1290
1448
|
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
1449
|
m = @c.new
|
|
1293
1450
|
m.typecast_empty_string_to_nil = false
|
|
1294
1451
|
proc{m.x = ''}.should raise_error
|
|
@@ -1297,21 +1454,21 @@ describe Sequel::Model, "typecasting" do
|
|
|
1297
1454
|
end
|
|
1298
1455
|
|
|
1299
1456
|
specify "should not typecast nil if NULLs are allowed" do
|
|
1300
|
-
@c.
|
|
1457
|
+
@c.db_schema[:x][:allow_null] = true
|
|
1301
1458
|
m = @c.new
|
|
1302
1459
|
m.x = nil
|
|
1303
1460
|
m.x.should == nil
|
|
1304
1461
|
end
|
|
1305
1462
|
|
|
1306
1463
|
specify "should raise an error if attempting to typecast nil and NULLs are not allowed" do
|
|
1307
|
-
@c.
|
|
1464
|
+
@c.db_schema[:x][:allow_null] = false
|
|
1308
1465
|
proc{@c.new.x = nil}.should raise_error(Sequel::Error)
|
|
1309
1466
|
proc{@c.new.x = ''}.should raise_error(Sequel::Error)
|
|
1310
1467
|
end
|
|
1311
1468
|
|
|
1312
1469
|
specify "should not raise an error if NULLs are not allowed and typecasting is turned off" do
|
|
1313
1470
|
@c.typecast_on_assignment = false
|
|
1314
|
-
@c.
|
|
1471
|
+
@c.db_schema[:x][:allow_null] = false
|
|
1315
1472
|
m = @c.new
|
|
1316
1473
|
m.x = nil
|
|
1317
1474
|
m.x.should == nil
|
|
@@ -1320,7 +1477,6 @@ describe Sequel::Model, "typecasting" do
|
|
|
1320
1477
|
specify "should not raise when typecasting nil to NOT NULL column but raise_on_typecast_failure is off" do
|
|
1321
1478
|
@c.raise_on_typecast_failure = false
|
|
1322
1479
|
@c.typecast_on_assignment = true
|
|
1323
|
-
@c.instance_variable_set(:@db_schema, {:x=>{:type=>:integer,:allow_null=>false}})
|
|
1324
1480
|
m = @c.new
|
|
1325
1481
|
m.x = ''
|
|
1326
1482
|
m.x.should == nil
|
|
@@ -1329,20 +1485,18 @@ describe Sequel::Model, "typecasting" do
|
|
|
1329
1485
|
end
|
|
1330
1486
|
|
|
1331
1487
|
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
1488
|
proc{@c.new.x = 'a'}.should raise_error(Sequel::InvalidValue)
|
|
1334
1489
|
end
|
|
1335
1490
|
|
|
1336
1491
|
specify "should assign value if raise_on_typecast_failure is off and assigning invalid integer" do
|
|
1337
1492
|
@c.raise_on_typecast_failure = false
|
|
1338
|
-
@c.instance_variable_set(:@db_schema, {:x=>{:type=>:integer}})
|
|
1339
1493
|
model = @c.new
|
|
1340
1494
|
model.x = '1d'
|
|
1341
1495
|
model.x.should == '1d'
|
|
1342
1496
|
end
|
|
1343
1497
|
|
|
1344
1498
|
specify "should convert to float for a float field" do
|
|
1345
|
-
@c.
|
|
1499
|
+
@c.db_schema = {:x=>{:type=>:float}}
|
|
1346
1500
|
m = @c.new
|
|
1347
1501
|
m.x = '1.3'
|
|
1348
1502
|
m.x.should == 1.3
|
|
@@ -1353,20 +1507,20 @@ describe Sequel::Model, "typecasting" do
|
|
|
1353
1507
|
end
|
|
1354
1508
|
|
|
1355
1509
|
specify "should raise an error if invalid data is used in an float field" do
|
|
1356
|
-
@c.
|
|
1510
|
+
@c.db_schema = {:x=>{:type=>:float}}
|
|
1357
1511
|
proc{@c.new.x = 'a'}.should raise_error(Sequel::InvalidValue)
|
|
1358
1512
|
end
|
|
1359
1513
|
|
|
1360
1514
|
specify "should assign value if raise_on_typecast_failure is off and assigning invalid float" do
|
|
1361
1515
|
@c.raise_on_typecast_failure = false
|
|
1362
|
-
@c.
|
|
1516
|
+
@c.db_schema = {:x=>{:type=>:float}}
|
|
1363
1517
|
model = @c.new
|
|
1364
1518
|
model.x = '1d'
|
|
1365
1519
|
model.x.should == '1d'
|
|
1366
1520
|
end
|
|
1367
1521
|
|
|
1368
1522
|
specify "should convert to BigDecimal for a decimal field" do
|
|
1369
|
-
@c.
|
|
1523
|
+
@c.db_schema = {:x=>{:type=>:decimal}}
|
|
1370
1524
|
m = @c.new
|
|
1371
1525
|
bd = BigDecimal.new('1.0')
|
|
1372
1526
|
m.x = '1.0'
|
|
@@ -1380,13 +1534,13 @@ describe Sequel::Model, "typecasting" do
|
|
|
1380
1534
|
end
|
|
1381
1535
|
|
|
1382
1536
|
specify "should raise an error if invalid data is used in an decimal field" do
|
|
1383
|
-
@c.
|
|
1537
|
+
@c.db_schema = {:x=>{:type=>:decimal}}
|
|
1384
1538
|
proc{@c.new.x = Date.today}.should raise_error(Sequel::InvalidValue)
|
|
1385
1539
|
end
|
|
1386
1540
|
|
|
1387
1541
|
specify "should assign value if raise_on_typecast_failure is off and assigning invalid decimal" do
|
|
1388
1542
|
@c.raise_on_typecast_failure = false
|
|
1389
|
-
@c.
|
|
1543
|
+
@c.db_schema = {:x=>{:type=>:decimal}}
|
|
1390
1544
|
model = @c.new
|
|
1391
1545
|
time = Time.now
|
|
1392
1546
|
model.x = time
|
|
@@ -1394,7 +1548,7 @@ describe Sequel::Model, "typecasting" do
|
|
|
1394
1548
|
end
|
|
1395
1549
|
|
|
1396
1550
|
specify "should convert to string for a string field" do
|
|
1397
|
-
@c.
|
|
1551
|
+
@c.db_schema = {:x=>{:type=>:string}}
|
|
1398
1552
|
m = @c.new
|
|
1399
1553
|
m.x = '1.3'
|
|
1400
1554
|
m.x.should == '1.3'
|
|
@@ -1405,7 +1559,7 @@ describe Sequel::Model, "typecasting" do
|
|
|
1405
1559
|
end
|
|
1406
1560
|
|
|
1407
1561
|
specify "should convert to boolean for a boolean field" do
|
|
1408
|
-
@c.
|
|
1562
|
+
@c.db_schema = {:x=>{:type=>:boolean}}
|
|
1409
1563
|
m = @c.new
|
|
1410
1564
|
m.x = '1.3'
|
|
1411
1565
|
m.x.should == true
|
|
@@ -1417,6 +1571,10 @@ describe Sequel::Model, "typecasting" do
|
|
|
1417
1571
|
m.x.should == true
|
|
1418
1572
|
m.x = 'T'
|
|
1419
1573
|
m.x.should == true
|
|
1574
|
+
m.x = 'y'
|
|
1575
|
+
m.x.should == true
|
|
1576
|
+
m.x = 'Y'
|
|
1577
|
+
m.x.should == true
|
|
1420
1578
|
m.x = true
|
|
1421
1579
|
m.x.should == true
|
|
1422
1580
|
m.x = nil
|
|
@@ -1433,6 +1591,14 @@ describe Sequel::Model, "typecasting" do
|
|
|
1433
1591
|
m.x.should == false
|
|
1434
1592
|
m.x = 'FALSE'
|
|
1435
1593
|
m.x.should == false
|
|
1594
|
+
m.x = 'n'
|
|
1595
|
+
m.x.should == false
|
|
1596
|
+
m.x = 'N'
|
|
1597
|
+
m.x.should == false
|
|
1598
|
+
m.x = 'no'
|
|
1599
|
+
m.x.should == false
|
|
1600
|
+
m.x = 'NO'
|
|
1601
|
+
m.x.should == false
|
|
1436
1602
|
m.x = '0'
|
|
1437
1603
|
m.x.should == false
|
|
1438
1604
|
m.x = 0
|
|
@@ -1442,7 +1608,7 @@ describe Sequel::Model, "typecasting" do
|
|
|
1442
1608
|
end
|
|
1443
1609
|
|
|
1444
1610
|
specify "should convert to date for a date field" do
|
|
1445
|
-
@c.
|
|
1611
|
+
@c.db_schema = {:x=>{:type=>:date}}
|
|
1446
1612
|
m = @c.new
|
|
1447
1613
|
y = Date.new(2007,10,21)
|
|
1448
1614
|
m.x = '2007-10-21'
|
|
@@ -1456,7 +1622,7 @@ describe Sequel::Model, "typecasting" do
|
|
|
1456
1622
|
end
|
|
1457
1623
|
|
|
1458
1624
|
specify "should accept a hash with symbol or string keys for a date field" do
|
|
1459
|
-
@c.
|
|
1625
|
+
@c.db_schema = {:x=>{:type=>:date}}
|
|
1460
1626
|
m = @c.new
|
|
1461
1627
|
y = Date.new(2007,10,21)
|
|
1462
1628
|
m.x = {:year=>2007, :month=>10, :day=>21}
|
|
@@ -1466,32 +1632,33 @@ describe Sequel::Model, "typecasting" do
|
|
|
1466
1632
|
end
|
|
1467
1633
|
|
|
1468
1634
|
specify "should raise an error if invalid data is used in a date field" do
|
|
1469
|
-
@c.
|
|
1635
|
+
@c.db_schema = {:x=>{:type=>:date}}
|
|
1470
1636
|
proc{@c.new.x = 'a'}.should raise_error(Sequel::InvalidValue)
|
|
1471
1637
|
proc{@c.new.x = 100}.should raise_error(Sequel::InvalidValue)
|
|
1472
1638
|
end
|
|
1473
1639
|
|
|
1474
1640
|
specify "should assign value if raise_on_typecast_failure is off and assigning invalid date" do
|
|
1475
1641
|
@c.raise_on_typecast_failure = false
|
|
1476
|
-
@c.
|
|
1642
|
+
@c.db_schema = {:x=>{:type=>:date}}
|
|
1477
1643
|
model = @c.new
|
|
1478
1644
|
model.x = 4
|
|
1479
1645
|
model.x.should == 4
|
|
1480
1646
|
end
|
|
1481
1647
|
|
|
1482
|
-
specify "should convert to
|
|
1483
|
-
@c.
|
|
1648
|
+
specify "should convert to Sequel::SQLTime for a time field" do
|
|
1649
|
+
@c.db_schema = {:x=>{:type=>:time}}
|
|
1484
1650
|
m = @c.new
|
|
1485
1651
|
x = '10:20:30'
|
|
1486
|
-
y =
|
|
1652
|
+
y = Sequel::SQLTime.parse(x)
|
|
1487
1653
|
m.x = x
|
|
1488
1654
|
m.x.should == y
|
|
1489
1655
|
m.x = y
|
|
1490
1656
|
m.x.should == y
|
|
1657
|
+
m.x.should be_a_kind_of(Sequel::SQLTime)
|
|
1491
1658
|
end
|
|
1492
1659
|
|
|
1493
1660
|
specify "should accept a hash with symbol or string keys for a time field" do
|
|
1494
|
-
@c.
|
|
1661
|
+
@c.db_schema = {:x=>{:type=>:time}}
|
|
1495
1662
|
m = @c.new
|
|
1496
1663
|
y = Time.parse('10:20:30')
|
|
1497
1664
|
m.x = {:hour=>10, :minute=>20, :second=>30}
|
|
@@ -1501,7 +1668,7 @@ describe Sequel::Model, "typecasting" do
|
|
|
1501
1668
|
end
|
|
1502
1669
|
|
|
1503
1670
|
specify "should raise an error if invalid data is used in a time field" do
|
|
1504
|
-
@c.
|
|
1671
|
+
@c.db_schema = {:x=>{:type=>:time}}
|
|
1505
1672
|
proc{@c.new.x = '0000'}.should raise_error
|
|
1506
1673
|
proc{@c.new.x = Date.parse('2008-10-21')}.should raise_error(Sequel::InvalidValue)
|
|
1507
1674
|
proc{@c.new.x = DateTime.parse('2008-10-21')}.should raise_error(Sequel::InvalidValue)
|
|
@@ -1509,14 +1676,14 @@ describe Sequel::Model, "typecasting" do
|
|
|
1509
1676
|
|
|
1510
1677
|
specify "should assign value if raise_on_typecast_failure is off and assigning invalid time" do
|
|
1511
1678
|
@c.raise_on_typecast_failure = false
|
|
1512
|
-
@c.
|
|
1679
|
+
@c.db_schema = {:x=>{:type=>:time}}
|
|
1513
1680
|
model = @c.new
|
|
1514
1681
|
model.x = '0000'
|
|
1515
1682
|
model.x.should == '0000'
|
|
1516
1683
|
end
|
|
1517
1684
|
|
|
1518
1685
|
specify "should convert to the Sequel.datetime_class for a datetime field" do
|
|
1519
|
-
@c.
|
|
1686
|
+
@c.db_schema = {:x=>{:type=>:datetime}}
|
|
1520
1687
|
m = @c.new
|
|
1521
1688
|
x = '2007-10-21T10:20:30-07:00'
|
|
1522
1689
|
y = Time.parse(x)
|
|
@@ -1541,7 +1708,7 @@ describe Sequel::Model, "typecasting" do
|
|
|
1541
1708
|
end
|
|
1542
1709
|
|
|
1543
1710
|
specify "should accept a hash with symbol or string keys for a datetime field" do
|
|
1544
|
-
@c.
|
|
1711
|
+
@c.db_schema = {:x=>{:type=>:datetime}}
|
|
1545
1712
|
m = @c.new
|
|
1546
1713
|
y = Time.parse('2007-10-21 10:20:30')
|
|
1547
1714
|
m.x = {:year=>2007, :month=>10, :day=>21, :hour=>10, :minute=>20, :second=>30}
|
|
@@ -1557,7 +1724,7 @@ describe Sequel::Model, "typecasting" do
|
|
|
1557
1724
|
end
|
|
1558
1725
|
|
|
1559
1726
|
specify "should raise an error if invalid data is used in a datetime field" do
|
|
1560
|
-
@c.
|
|
1727
|
+
@c.db_schema = {:x=>{:type=>:datetime}}
|
|
1561
1728
|
proc{@c.new.x = '0000'}.should raise_error(Sequel::InvalidValue)
|
|
1562
1729
|
Sequel.datetime_class = DateTime
|
|
1563
1730
|
proc{@c.new.x = '0000'}.should raise_error(Sequel::InvalidValue)
|
|
@@ -1566,7 +1733,7 @@ describe Sequel::Model, "typecasting" do
|
|
|
1566
1733
|
|
|
1567
1734
|
specify "should assign value if raise_on_typecast_failure is off and assigning invalid datetime" do
|
|
1568
1735
|
@c.raise_on_typecast_failure = false
|
|
1569
|
-
@c.
|
|
1736
|
+
@c.db_schema = {:x=>{:type=>:datetime}}
|
|
1570
1737
|
model = @c.new
|
|
1571
1738
|
model.x = '0000'
|
|
1572
1739
|
model.x.should == '0000'
|
|
@@ -1584,11 +1751,7 @@ describe "Model#lock!" do
|
|
|
1584
1751
|
@c = Class.new(Sequel::Model(:items)) do
|
|
1585
1752
|
columns :id
|
|
1586
1753
|
end
|
|
1587
|
-
|
|
1588
|
-
def ds.fetch_rows(sql)
|
|
1589
|
-
db.execute(sql)
|
|
1590
|
-
yield({:id=>1})
|
|
1591
|
-
end
|
|
1754
|
+
@c.dataset._fetch = {:id=>1}
|
|
1592
1755
|
MODEL_DB.reset
|
|
1593
1756
|
end
|
|
1594
1757
|
|