sequel 3.21.0 → 3.31.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 +485 -3
- data/README.rdoc +20 -6
- data/Rakefile +37 -19
- data/bin/sequel +1 -5
- data/doc/association_basics.rdoc +249 -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/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 +45 -0
- data/lib/sequel/adapters/jdbc/derby.rb +247 -0
- data/lib/sequel/adapters/jdbc/firebird.rb +29 -0
- data/lib/sequel/adapters/jdbc/h2.rb +56 -29
- data/lib/sequel/adapters/jdbc/hsqldb.rb +170 -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 +81 -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 +335 -0
- data/lib/sequel/adapters/mysql.rb +82 -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 +351 -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 +321 -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 +231 -106
- data/lib/sequel/adapters/shared/mysql.rb +181 -63
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +149 -0
- data/lib/sequel/adapters/shared/oracle.rb +231 -41
- data/lib/sequel/adapters/shared/postgres.rb +214 -82
- data/lib/sequel/adapters/shared/progress.rb +4 -7
- data/lib/sequel/adapters/shared/sqlite.rb +201 -57
- 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 +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 +104 -19
- data/lib/sequel/database/query.rb +153 -58
- data/lib/sequel/database/schema_generator.rb +17 -7
- data/lib/sequel/database/schema_methods.rb +59 -29
- data/lib/sequel/dataset/actions.rb +231 -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 +5 -6
- data/lib/sequel/dataset/prepared_statements.rb +48 -27
- data/lib/sequel/dataset/query.rb +236 -43
- data/lib/sequel/dataset/sql.rb +665 -253
- 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 +1020 -337
- data/lib/sequel/model/base.rb +414 -132
- 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 +88 -44
- data/lib/sequel/plugins/serialization_modification_detection.rb +51 -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 +111 -29
- data/spec/adapters/mysql_spec.rb +135 -123
- data/spec/adapters/oracle_spec.rb +49 -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 +788 -512
- data/spec/core/dataset_spec.rb +1073 -1053
- 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/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/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 +37 -0
- data/spec/extensions/serialization_spec.rb +72 -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 +537 -21
- data/spec/integration/database_test.rb +4 -2
- data/spec/integration/dataset_test.rb +461 -65
- 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 +212 -122
- 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 +201 -7
- data/spec/model/associations_spec.rb +865 -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 +309 -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 +115 -73
data/spec/model/base_spec.rb
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
2
2
|
|
|
3
3
|
describe "Model attribute setters" do
|
|
4
|
-
|
|
5
|
-
before(:each) do
|
|
6
|
-
MODEL_DB.reset
|
|
7
|
-
|
|
4
|
+
before do
|
|
8
5
|
@c = Class.new(Sequel::Model(:items)) do
|
|
9
6
|
columns :id, :x, :y, :"x y"
|
|
10
7
|
end
|
|
11
8
|
@o = @c.new
|
|
9
|
+
MODEL_DB.reset
|
|
12
10
|
end
|
|
13
11
|
|
|
14
12
|
it "should mark the column value as changed" do
|
|
@@ -37,22 +35,37 @@ describe "Model attribute setters" do
|
|
|
37
35
|
end
|
|
38
36
|
end
|
|
39
37
|
|
|
38
|
+
describe "Model.def_column_alias" do
|
|
39
|
+
before do
|
|
40
|
+
@o = Class.new(Sequel::Model(:items)) do
|
|
41
|
+
columns :id
|
|
42
|
+
def_column_alias(:id2, :id)
|
|
43
|
+
end.load(:id=>1)
|
|
44
|
+
MODEL_DB.reset
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "should create an getter alias for the column" do
|
|
48
|
+
@o.id2.should == 1
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it "should create an setter alias for the column" do
|
|
52
|
+
@o.id2 = 2
|
|
53
|
+
@o.id2.should == 2
|
|
54
|
+
@o.values.should == {:id => 2}
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
40
58
|
describe Sequel::Model, "dataset" do
|
|
41
59
|
before do
|
|
42
60
|
@a = Class.new(Sequel::Model(:items))
|
|
43
61
|
@b = Class.new(Sequel::Model)
|
|
44
|
-
|
|
45
|
-
class
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
class ShoeSize < Sequel::Model
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
class BootSize < ShoeSize
|
|
55
|
-
end
|
|
62
|
+
class ::Elephant < Sequel::Model(:ele1); end
|
|
63
|
+
class ::Maggot < Sequel::Model; end
|
|
64
|
+
class ::ShoeSize < Sequel::Model; end
|
|
65
|
+
class ::BootSize < ShoeSize; end
|
|
66
|
+
end
|
|
67
|
+
after do
|
|
68
|
+
[:Elephant, :Maggot, :ShoeSize, :BootSize].each{|x| Object.send(:remove_const, x)}
|
|
56
69
|
end
|
|
57
70
|
|
|
58
71
|
specify "should default to the plural of the class name" do
|
|
@@ -74,33 +87,59 @@ describe Sequel::Model, "dataset" do
|
|
|
74
87
|
end
|
|
75
88
|
|
|
76
89
|
specify "should disregard namespaces for the table name" do
|
|
77
|
-
|
|
78
|
-
|
|
90
|
+
begin
|
|
91
|
+
module ::BlahBlah
|
|
92
|
+
class MwaHaHa < Sequel::Model
|
|
93
|
+
end
|
|
79
94
|
end
|
|
80
|
-
end
|
|
81
95
|
|
|
82
|
-
|
|
96
|
+
BlahBlah::MwaHaHa.dataset.sql.should == 'SELECT * FROM mwa_ha_has'
|
|
97
|
+
ensure
|
|
98
|
+
Object.send(:remove_const, :BlahBlah)
|
|
99
|
+
end
|
|
83
100
|
end
|
|
84
101
|
end
|
|
85
102
|
|
|
86
103
|
describe Sequel::Model, ".def_dataset_method" do
|
|
87
104
|
before do
|
|
88
|
-
@c = Class.new(Sequel::Model(:items))
|
|
89
|
-
end
|
|
105
|
+
@c = Class.new(Sequel::Model(:items))
|
|
90
106
|
end
|
|
91
107
|
|
|
92
108
|
it "should add a method to the dataset and model if called with a block argument" do
|
|
93
|
-
@c.
|
|
94
|
-
def_dataset_method(:return_3){3}
|
|
95
|
-
end
|
|
109
|
+
@c.def_dataset_method(:return_3){3}
|
|
96
110
|
@c.return_3.should == 3
|
|
97
111
|
@c.dataset.return_3.should == 3
|
|
98
112
|
end
|
|
99
113
|
|
|
100
|
-
it "should
|
|
114
|
+
it "should handle weird method names" do
|
|
115
|
+
@c.def_dataset_method(:"return 3"){3}
|
|
116
|
+
@c.send(:"return 3").should == 3
|
|
117
|
+
@c.dataset.send(:"return 3").should == 3
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
it "should not add a model method if the model already responds to the method" do
|
|
101
121
|
@c.instance_eval do
|
|
102
|
-
|
|
122
|
+
def foo
|
|
123
|
+
1
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
private
|
|
127
|
+
|
|
128
|
+
def bar
|
|
129
|
+
2
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def_dataset_method(:foo){3}
|
|
133
|
+
def_dataset_method(:bar){4}
|
|
103
134
|
end
|
|
135
|
+
@c.foo.should == 1
|
|
136
|
+
@c.dataset.foo.should == 3
|
|
137
|
+
@c.send(:bar).should == 2
|
|
138
|
+
@c.dataset.bar.should == 4
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
it "should add all passed methods to the model if called without a block argument" do
|
|
142
|
+
@c.def_dataset_method(:return_3, :return_4)
|
|
104
143
|
proc{@c.return_3}.should raise_error(NoMethodError)
|
|
105
144
|
proc{@c.return_4}.should raise_error(NoMethodError)
|
|
106
145
|
@c.dataset.instance_eval do
|
|
@@ -112,18 +151,14 @@ describe Sequel::Model, ".def_dataset_method" do
|
|
|
112
151
|
end
|
|
113
152
|
|
|
114
153
|
it "should cache calls and readd methods if set_dataset is used" do
|
|
115
|
-
@c.
|
|
116
|
-
def_dataset_method(:return_3){3}
|
|
117
|
-
end
|
|
154
|
+
@c.def_dataset_method(:return_3){3}
|
|
118
155
|
@c.set_dataset :items
|
|
119
156
|
@c.return_3.should == 3
|
|
120
157
|
@c.dataset.return_3.should == 3
|
|
121
158
|
end
|
|
122
159
|
|
|
123
160
|
it "should readd methods to subclasses, if set_dataset is used in a subclass" do
|
|
124
|
-
@c.
|
|
125
|
-
def_dataset_method(:return_3){3}
|
|
126
|
-
end
|
|
161
|
+
@c.def_dataset_method(:return_3){3}
|
|
127
162
|
c = Class.new(@c)
|
|
128
163
|
c.set_dataset :items
|
|
129
164
|
c.return_3.should == 3
|
|
@@ -131,11 +166,98 @@ describe Sequel::Model, ".def_dataset_method" do
|
|
|
131
166
|
end
|
|
132
167
|
end
|
|
133
168
|
|
|
169
|
+
describe Sequel::Model, ".dataset_module" do
|
|
170
|
+
before do
|
|
171
|
+
@c = Class.new(Sequel::Model(:items))
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
it "should extend the dataset with the module if the model has a dataset" do
|
|
175
|
+
@c.dataset_module{def return_3() 3 end}
|
|
176
|
+
@c.dataset.return_3.should == 3
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
it "should add methods defined in the module to the class" do
|
|
180
|
+
@c.dataset_module{def return_3() 3 end}
|
|
181
|
+
@c.return_3.should == 3
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
it "should cache calls and readd methods if set_dataset is used" do
|
|
185
|
+
@c.dataset_module{def return_3() 3 end}
|
|
186
|
+
@c.set_dataset :items
|
|
187
|
+
@c.return_3.should == 3
|
|
188
|
+
@c.dataset.return_3.should == 3
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
it "should readd methods to subclasses, if set_dataset is used in a subclass" do
|
|
192
|
+
@c.dataset_module{def return_3() 3 end}
|
|
193
|
+
c = Class.new(@c)
|
|
194
|
+
c.set_dataset :items
|
|
195
|
+
c.return_3.should == 3
|
|
196
|
+
c.dataset.return_3.should == 3
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
it "should only have a single dataset_module per class" do
|
|
200
|
+
@c.dataset_module{def return_3() 3 end}
|
|
201
|
+
@c.dataset_module{def return_3() 3 + (begin; super; rescue NoMethodError; 1; end) end}
|
|
202
|
+
@c.return_3.should == 4
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
it "should not have subclasses share the dataset_module" do
|
|
206
|
+
@c.dataset_module{def return_3() 3 end}
|
|
207
|
+
c = Class.new(@c)
|
|
208
|
+
c.dataset_module{def return_3() 3 + (begin; super; rescue NoMethodError; 1; end) end}
|
|
209
|
+
c.return_3.should == 6
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
it "should accept a module object and extend the dataset with it" do
|
|
213
|
+
@c.dataset_module Module.new{def return_3() 3 end}
|
|
214
|
+
@c.dataset.return_3.should == 3
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
it "should be able to call dataset_module with a module multiple times" do
|
|
218
|
+
@c.dataset_module Module.new{def return_3() 3 end}
|
|
219
|
+
@c.dataset_module Module.new{def return_4() 4 end}
|
|
220
|
+
@c.dataset.return_3.should == 3
|
|
221
|
+
@c.dataset.return_4.should == 4
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
it "should be able mix dataset_module calls with and without arguments" do
|
|
225
|
+
@c.dataset_module{def return_3() 3 end}
|
|
226
|
+
@c.dataset_module Module.new{def return_4() 4 end}
|
|
227
|
+
@c.dataset.return_3.should == 3
|
|
228
|
+
@c.dataset.return_4.should == 4
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
it "should have modules provided to dataset_module extend subclass datasets" do
|
|
232
|
+
@c.dataset_module{def return_3() 3 end}
|
|
233
|
+
@c.dataset_module Module.new{def return_4() 4 end}
|
|
234
|
+
c = Class.new(@c)
|
|
235
|
+
c.set_dataset :a
|
|
236
|
+
c.dataset.return_3.should == 3
|
|
237
|
+
c.dataset.return_4.should == 4
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
it "should return the dataset module if given a block" do
|
|
241
|
+
Object.new.extend(@c.dataset_module{def return_3() 3 end}).return_3.should == 3
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
it "should return the argument if given one" do
|
|
245
|
+
Object.new.extend(@c.dataset_module Module.new{def return_3() 3 end}).return_3.should == 3
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
it "should raise error if called with both an argument and ablock" do
|
|
249
|
+
proc{@c.dataset_module(Module.new{def return_3() 3 end}){}}.should raise_error(Sequel::Error)
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
|
|
134
253
|
describe "A model class with implicit table name" do
|
|
135
254
|
before do
|
|
136
|
-
class Donkey < Sequel::Model
|
|
255
|
+
class ::Donkey < Sequel::Model
|
|
137
256
|
end
|
|
138
257
|
end
|
|
258
|
+
after do
|
|
259
|
+
Object.send(:remove_const, :Donkey)
|
|
260
|
+
end
|
|
139
261
|
|
|
140
262
|
specify "should have a dataset associated with the model class" do
|
|
141
263
|
Donkey.dataset.model.should == Donkey
|
|
@@ -144,11 +266,12 @@ end
|
|
|
144
266
|
|
|
145
267
|
describe "A model inheriting from a model" do
|
|
146
268
|
before do
|
|
147
|
-
class Feline < Sequel::Model
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
269
|
+
class ::Feline < Sequel::Model; end
|
|
270
|
+
class ::Leopard < Feline; end
|
|
271
|
+
end
|
|
272
|
+
after do
|
|
273
|
+
Object.send(:remove_const, :Leopard)
|
|
274
|
+
Object.send(:remove_const, :Feline)
|
|
152
275
|
end
|
|
153
276
|
|
|
154
277
|
specify "should have a dataset associated with itself" do
|
|
@@ -228,29 +351,27 @@ end
|
|
|
228
351
|
|
|
229
352
|
describe "Model.db=" do
|
|
230
353
|
before do
|
|
231
|
-
|
|
232
|
-
|
|
354
|
+
@db1 = Sequel.mock
|
|
355
|
+
@db2 = Sequel.mock
|
|
233
356
|
|
|
234
|
-
|
|
235
|
-
set_dataset $db1[:blue].filter(:x=>1)
|
|
236
|
-
end
|
|
357
|
+
@m = Class.new(Sequel::Model(@db1[:blue].filter(:x=>1)))
|
|
237
358
|
end
|
|
238
359
|
|
|
239
360
|
specify "should affect the underlying dataset" do
|
|
240
|
-
|
|
361
|
+
@m.db = @db2
|
|
241
362
|
|
|
242
|
-
|
|
243
|
-
|
|
363
|
+
@m.dataset.db.should === @db2
|
|
364
|
+
@m.dataset.db.should_not === @db1
|
|
244
365
|
end
|
|
245
366
|
|
|
246
367
|
specify "should keep the same dataset options" do
|
|
247
|
-
|
|
248
|
-
|
|
368
|
+
@m.db = @db2
|
|
369
|
+
@m.dataset.sql.should == 'SELECT * FROM blue WHERE (x = 1)'
|
|
249
370
|
end
|
|
250
371
|
|
|
251
372
|
specify "should use the database for subclasses" do
|
|
252
|
-
|
|
253
|
-
Class.new(
|
|
373
|
+
@m.db = @db2
|
|
374
|
+
Class.new(@m).db.should === @db2
|
|
254
375
|
end
|
|
255
376
|
end
|
|
256
377
|
|
|
@@ -258,9 +379,6 @@ describe Sequel::Model, ".(allowed|restricted)_columns " do
|
|
|
258
379
|
before do
|
|
259
380
|
@c = Class.new(Sequel::Model(:blahblah)) do
|
|
260
381
|
columns :x, :y, :z
|
|
261
|
-
def _refresh(ds)
|
|
262
|
-
self
|
|
263
|
-
end
|
|
264
382
|
end
|
|
265
383
|
@c.strict_param_setting = false
|
|
266
384
|
@c.instance_variable_set(:@columns, [:x, :y, :z])
|
|
@@ -288,9 +406,12 @@ describe Sequel::Model, ".(allowed|restricted)_columns " do
|
|
|
288
406
|
i.values.should == {:x => 1, :y => 2}
|
|
289
407
|
i.set(:x => 4, :y => 5, :z => 6)
|
|
290
408
|
i.values.should == {:x => 4, :y => 5}
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
i
|
|
409
|
+
|
|
410
|
+
@c.dataset._fetch = {:x => 7}
|
|
411
|
+
i = @c.new
|
|
412
|
+
i.update(:x => 7, :z => 9)
|
|
413
|
+
i.values.should == {:x => 7}
|
|
414
|
+
MODEL_DB.sqls.should == ["INSERT INTO blahblah (x) VALUES (7)", "SELECT * FROM blahblah WHERE (id = 10) LIMIT 1"]
|
|
294
415
|
end
|
|
295
416
|
|
|
296
417
|
it "should not set restricted columns by default" do
|
|
@@ -299,9 +420,12 @@ describe Sequel::Model, ".(allowed|restricted)_columns " do
|
|
|
299
420
|
i.values.should == {:x => 1, :y => 2}
|
|
300
421
|
i.set(:x => 4, :y => 5, :z => 6)
|
|
301
422
|
i.values.should == {:x => 4, :y => 5}
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
i
|
|
423
|
+
|
|
424
|
+
@c.dataset._fetch = {:x => 7}
|
|
425
|
+
i = @c.new
|
|
426
|
+
i.update(:x => 7, :z => 9)
|
|
427
|
+
i.values.should == {:x => 7}
|
|
428
|
+
MODEL_DB.sqls.should == ["INSERT INTO blahblah (x) VALUES (7)", "SELECT * FROM blahblah WHERE (id = 10) LIMIT 1"]
|
|
305
429
|
end
|
|
306
430
|
|
|
307
431
|
it "should have allowed take precedence over restricted" do
|
|
@@ -311,9 +435,12 @@ describe Sequel::Model, ".(allowed|restricted)_columns " do
|
|
|
311
435
|
i.values.should == {:x => 1, :y => 2}
|
|
312
436
|
i.set(:x => 4, :y => 5, :z => 6)
|
|
313
437
|
i.values.should == {:x => 4, :y => 5}
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
i
|
|
438
|
+
|
|
439
|
+
@c.dataset._fetch = {:y => 7}
|
|
440
|
+
i = @c.new
|
|
441
|
+
i.update(:y => 7, :z => 9)
|
|
442
|
+
i.values.should == {:y => 7}
|
|
443
|
+
MODEL_DB.sqls.should == ["INSERT INTO blahblah (y) VALUES (7)", "SELECT * FROM blahblah WHERE (id = 10) LIMIT 1"]
|
|
317
444
|
end
|
|
318
445
|
end
|
|
319
446
|
|
|
@@ -322,12 +449,8 @@ describe Sequel::Model, ".(un)?restrict_primary_key\\??" do
|
|
|
322
449
|
@c = Class.new(Sequel::Model(:blahblah)) do
|
|
323
450
|
set_primary_key :id
|
|
324
451
|
columns :x, :y, :z, :id
|
|
325
|
-
def refresh
|
|
326
|
-
self
|
|
327
|
-
end
|
|
328
452
|
end
|
|
329
453
|
@c.strict_param_setting = false
|
|
330
|
-
@c.instance_variable_set(:@columns, [:x, :y, :z])
|
|
331
454
|
end
|
|
332
455
|
|
|
333
456
|
it "should restrict updates to primary key by default" do
|
|
@@ -364,11 +487,7 @@ describe Sequel::Model, ".strict_param_setting" do
|
|
|
364
487
|
@c = Class.new(Sequel::Model(:blahblah)) do
|
|
365
488
|
columns :x, :y, :z, :id
|
|
366
489
|
set_restricted_columns :z
|
|
367
|
-
def refresh
|
|
368
|
-
self
|
|
369
|
-
end
|
|
370
490
|
end
|
|
371
|
-
@c.instance_variable_set(:@columns, [:x, :y, :z])
|
|
372
491
|
end
|
|
373
492
|
|
|
374
493
|
it "should be enabled by default" do
|
|
@@ -425,20 +544,18 @@ end
|
|
|
425
544
|
|
|
426
545
|
describe Sequel::Model, ".[] optimization" do
|
|
427
546
|
before do
|
|
428
|
-
@
|
|
429
|
-
@
|
|
430
|
-
|
|
431
|
-
@simple_table
|
|
432
|
-
end
|
|
433
|
-
end
|
|
547
|
+
@db = MODEL_DB.clone
|
|
548
|
+
@db.quote_identifiers = true
|
|
549
|
+
@c = Class.new(Sequel::Model(@db))
|
|
434
550
|
end
|
|
435
551
|
|
|
436
552
|
it "should set simple_pk to the literalized primary key column name if a single primary key" do
|
|
437
|
-
@c.
|
|
553
|
+
@c.set_primary_key :id
|
|
554
|
+
@c.simple_pk.should == '"id"'
|
|
438
555
|
@c.set_primary_key :b
|
|
439
|
-
@c.simple_pk.should == 'b'
|
|
556
|
+
@c.simple_pk.should == '"b"'
|
|
440
557
|
@c.set_primary_key :b__a.identifier
|
|
441
|
-
@c.simple_pk.should == 'b__a'
|
|
558
|
+
@c.simple_pk.should == '"b__a"'
|
|
442
559
|
end
|
|
443
560
|
|
|
444
561
|
it "should have simple_pk be blank if compound or no primary key" do
|
|
@@ -452,36 +569,99 @@ describe Sequel::Model, ".[] optimization" do
|
|
|
452
569
|
|
|
453
570
|
it "should have simple table set if passed a Symbol to set_dataset" do
|
|
454
571
|
@c.set_dataset :a
|
|
455
|
-
@c.simple_table.should == 'a'
|
|
572
|
+
@c.simple_table.should == '"a"'
|
|
456
573
|
@c.set_dataset :b
|
|
457
|
-
@c.simple_table.should == 'b'
|
|
574
|
+
@c.simple_table.should == '"b"'
|
|
458
575
|
@c.set_dataset :b__a
|
|
459
|
-
@c.simple_table.should == 'b.a'
|
|
576
|
+
@c.simple_table.should == '"b"."a"'
|
|
460
577
|
end
|
|
461
578
|
|
|
462
|
-
it "should have simple_table
|
|
463
|
-
@c.set_dataset @
|
|
579
|
+
it "should have simple_table set if passed a simple select all dataset to set_dataset" do
|
|
580
|
+
@c.set_dataset @db[:a]
|
|
581
|
+
@c.simple_table.should == '"a"'
|
|
582
|
+
@c.set_dataset @db[:b]
|
|
583
|
+
@c.simple_table.should == '"b"'
|
|
584
|
+
@c.set_dataset @db[:b__a]
|
|
585
|
+
@c.simple_table.should == '"b"."a"'
|
|
586
|
+
end
|
|
587
|
+
|
|
588
|
+
it "should simple_pk and simple_table respect dataset's identifier input methods" do
|
|
589
|
+
ds = @db[:ab]
|
|
590
|
+
ds.identifier_input_method = :reverse
|
|
591
|
+
@c.set_dataset ds
|
|
592
|
+
@c.simple_table.should == '"ba"'
|
|
593
|
+
@c.set_primary_key :cd
|
|
594
|
+
@c.simple_pk.should == '"dc"'
|
|
595
|
+
|
|
596
|
+
@c.set_dataset ds.from(:ef__gh)
|
|
597
|
+
@c.simple_table.should == '"fe"."hg"'
|
|
598
|
+
end
|
|
599
|
+
|
|
600
|
+
it "should have simple_table = nil if passed a non-simple select all dataset to set_dataset" do
|
|
601
|
+
@c.set_dataset @c.db[:a].filter(:active)
|
|
464
602
|
@c.simple_table.should == nil
|
|
465
603
|
end
|
|
466
604
|
|
|
467
605
|
it "should have simple_table superclasses setting if inheriting" do
|
|
468
|
-
@c.set_dataset :a
|
|
469
|
-
Class.new(@c).simple_table.should == 'a'
|
|
470
|
-
@c.instance_variable_set(:@simple_table, nil)
|
|
471
606
|
Class.new(@c).simple_table.should == nil
|
|
472
|
-
@c.
|
|
473
|
-
Class.new(@c).simple_table.should == "'
|
|
607
|
+
@c.set_dataset :a
|
|
608
|
+
Class.new(@c).simple_table.should == '"a"'
|
|
474
609
|
end
|
|
475
610
|
|
|
476
611
|
it "should use Dataset#with_sql if simple_table and simple_pk are true" do
|
|
477
612
|
@c.set_dataset :a
|
|
478
|
-
@c.dataset.
|
|
479
|
-
@c[1]
|
|
613
|
+
@c.dataset._fetch = {:id => 1}
|
|
614
|
+
@c[1].should == @c.load(:id=>1)
|
|
615
|
+
@db.sqls.should == ['SELECT * FROM "a" WHERE "id" = 1']
|
|
480
616
|
end
|
|
481
617
|
|
|
482
618
|
it "should not use Dataset#with_sql if either simple_table or simple_pk is nil" do
|
|
483
|
-
@c.set_dataset @
|
|
484
|
-
@c.dataset.
|
|
485
|
-
@c[1]
|
|
619
|
+
@c.set_dataset @db[:a].filter(:active)
|
|
620
|
+
@c.dataset._fetch = {:id => 1}
|
|
621
|
+
@c[1].should == @c.load(:id=>1)
|
|
622
|
+
@db.sqls.should == ['SELECT * FROM "a" WHERE ("active" AND ("id" = 1)) LIMIT 1']
|
|
623
|
+
end
|
|
624
|
+
end
|
|
625
|
+
|
|
626
|
+
describe "Model datasets #with_pk" do
|
|
627
|
+
before do
|
|
628
|
+
@c = Class.new(Sequel::Model(:a))
|
|
629
|
+
@ds = @c.dataset
|
|
630
|
+
@ds._fetch = {:id=>1}
|
|
631
|
+
MODEL_DB.reset
|
|
632
|
+
end
|
|
633
|
+
|
|
634
|
+
it "should return the first record where the primary key matches" do
|
|
635
|
+
@ds.with_pk(1).should == @c.load(:id=>1)
|
|
636
|
+
MODEL_DB.sqls.should == ["SELECT * FROM a WHERE (a.id = 1) LIMIT 1"]
|
|
637
|
+
end
|
|
638
|
+
|
|
639
|
+
it "should handle existing filters" do
|
|
640
|
+
@ds.filter(:a=>2).with_pk(1)
|
|
641
|
+
MODEL_DB.sqls.should == ["SELECT * FROM a WHERE ((a = 2) AND (a.id = 1)) LIMIT 1"]
|
|
642
|
+
end
|
|
643
|
+
|
|
644
|
+
it "should work with string values" do
|
|
645
|
+
@ds.with_pk("foo")
|
|
646
|
+
MODEL_DB.sqls.should == ["SELECT * FROM a WHERE (a.id = 'foo') LIMIT 1"]
|
|
647
|
+
end
|
|
648
|
+
|
|
649
|
+
it "should handle an array for composite primary keys" do
|
|
650
|
+
@c.set_primary_key :id1, :id2
|
|
651
|
+
@ds.with_pk([1, 2])
|
|
652
|
+
sqls = MODEL_DB.sqls
|
|
653
|
+
["SELECT * FROM a WHERE ((a.id1 = 1) AND (a.id2 = 2)) LIMIT 1",
|
|
654
|
+
"SELECT * FROM a WHERE ((a.id2 = 2) AND (a.id1 = 1)) LIMIT 1"].should include(sqls.pop)
|
|
655
|
+
sqls.should == []
|
|
656
|
+
end
|
|
657
|
+
|
|
658
|
+
it "should have #[] consider an integer as a primary key lookup" do
|
|
659
|
+
@ds[1].should == @c.load(:id=>1)
|
|
660
|
+
MODEL_DB.sqls.should == ["SELECT * FROM a WHERE (a.id = 1) LIMIT 1"]
|
|
661
|
+
end
|
|
662
|
+
|
|
663
|
+
it "should not have #[] consider a string as a primary key lookup" do
|
|
664
|
+
@ds['foo'].should == @c.load(:id=>1)
|
|
665
|
+
MODEL_DB.sqls.should == ["SELECT * FROM a WHERE (foo) LIMIT 1"]
|
|
486
666
|
end
|
|
487
667
|
end
|
|
@@ -3,39 +3,25 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
|
3
3
|
describe Sequel::Model::DatasetMethods, "#destroy" do
|
|
4
4
|
before do
|
|
5
5
|
@c = Class.new(Sequel::Model(:items)) do
|
|
6
|
-
|
|
6
|
+
self::Destroyed = []
|
|
7
7
|
def destroy
|
|
8
|
-
|
|
9
|
-
end
|
|
10
|
-
def self.destroyed
|
|
11
|
-
class_variable_get(:@@destroyed)
|
|
8
|
+
model::Destroyed << self
|
|
12
9
|
end
|
|
13
10
|
end
|
|
14
11
|
@d = @c.dataset
|
|
12
|
+
@d._fetch = [{:id=>1}, {:id=>2}]
|
|
15
13
|
MODEL_DB.reset
|
|
16
14
|
end
|
|
17
15
|
|
|
18
16
|
it "should instantiate objects in the dataset and call destroy on each" do
|
|
19
|
-
def @d.fetch_rows(sql)
|
|
20
|
-
yield({:id=>1})
|
|
21
|
-
yield({:id=>2})
|
|
22
|
-
end
|
|
23
17
|
@d.destroy
|
|
24
|
-
@c.
|
|
18
|
+
@c::Destroyed.collect{|x| x.values}.should == [{:id=>1}, {:id=>2}]
|
|
25
19
|
end
|
|
26
20
|
|
|
27
21
|
it "should return the number of records destroyed" do
|
|
28
|
-
def @d.fetch_rows(sql)
|
|
29
|
-
yield({:id=>1})
|
|
30
|
-
yield({:id=>2})
|
|
31
|
-
end
|
|
32
22
|
@d.destroy.should == 2
|
|
33
|
-
|
|
34
|
-
yield({:id=>1})
|
|
35
|
-
end
|
|
23
|
+
@d._fetch = [[{:i=>1}], []]
|
|
36
24
|
@d.destroy.should == 1
|
|
37
|
-
def @d.fetch_rows(sql)
|
|
38
|
-
end
|
|
39
25
|
@d.destroy.should == 0
|
|
40
26
|
end
|
|
41
27
|
|
|
@@ -61,10 +47,7 @@ describe Sequel::Model::DatasetMethods, "#to_hash" do
|
|
|
61
47
|
end
|
|
62
48
|
|
|
63
49
|
it "should result in a hash with primary key value keys and model object values" do
|
|
64
|
-
|
|
65
|
-
yield({:name=>1})
|
|
66
|
-
yield({:name=>2})
|
|
67
|
-
end
|
|
50
|
+
@d._fetch = [{:name=>1}, {:name=>2}]
|
|
68
51
|
h = @d.to_hash
|
|
69
52
|
h.should be_a_kind_of(Hash)
|
|
70
53
|
a = h.to_a
|
|
@@ -73,10 +56,7 @@ describe Sequel::Model::DatasetMethods, "#to_hash" do
|
|
|
73
56
|
end
|
|
74
57
|
|
|
75
58
|
it "should result in a hash with given value keys and model object values" do
|
|
76
|
-
|
|
77
|
-
yield({:name=>1, :number=>3})
|
|
78
|
-
yield({:name=>2, :number=>4})
|
|
79
|
-
end
|
|
59
|
+
@d._fetch = [{:name=>1, :number=>3}, {:name=>2, :number=>4}]
|
|
80
60
|
h = @d.to_hash(:number)
|
|
81
61
|
h.should be_a_kind_of(Hash)
|
|
82
62
|
a = h.to_a
|