sequel 3.21.0 → 3.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +413 -3
- data/README.rdoc +20 -6
- data/Rakefile +23 -16
- data/bin/sequel +1 -5
- data/doc/association_basics.rdoc +210 -43
- data/doc/dataset_basics.rdoc +4 -4
- data/doc/mass_assignment.rdoc +54 -0
- data/doc/migration.rdoc +15 -538
- data/doc/model_hooks.rdoc +72 -27
- data/doc/opening_databases.rdoc +86 -50
- data/doc/prepared_statements.rdoc +40 -13
- data/doc/reflection.rdoc +8 -2
- data/doc/release_notes/3.22.0.txt +39 -0
- data/doc/release_notes/3.23.0.txt +172 -0
- data/doc/release_notes/3.24.0.txt +420 -0
- data/doc/release_notes/3.25.0.txt +88 -0
- data/doc/release_notes/3.26.0.txt +88 -0
- data/doc/release_notes/3.27.0.txt +82 -0
- data/doc/release_notes/3.28.0.txt +304 -0
- data/doc/release_notes/3.29.0.txt +459 -0
- data/doc/schema_modification.rdoc +547 -0
- data/doc/sharding.rdoc +7 -1
- data/doc/testing.rdoc +115 -0
- data/doc/transactions.rdoc +137 -0
- data/doc/virtual_rows.rdoc +2 -2
- data/lib/sequel/adapters/ado/mssql.rb +18 -6
- data/lib/sequel/adapters/ado.rb +40 -18
- data/lib/sequel/adapters/amalgalite.rb +15 -7
- data/lib/sequel/adapters/db2.rb +175 -86
- data/lib/sequel/adapters/dbi.rb +15 -15
- data/lib/sequel/adapters/do/mysql.rb +0 -5
- data/lib/sequel/adapters/do/postgres.rb +0 -5
- data/lib/sequel/adapters/do/sqlite.rb +0 -5
- data/lib/sequel/adapters/do.rb +17 -36
- data/lib/sequel/adapters/firebird.rb +27 -208
- data/lib/sequel/adapters/ibmdb.rb +448 -0
- data/lib/sequel/adapters/informix.rb +6 -23
- data/lib/sequel/adapters/jdbc/as400.rb +5 -31
- data/lib/sequel/adapters/jdbc/db2.rb +44 -0
- data/lib/sequel/adapters/jdbc/derby.rb +217 -0
- data/lib/sequel/adapters/jdbc/firebird.rb +29 -0
- data/lib/sequel/adapters/jdbc/h2.rb +26 -17
- data/lib/sequel/adapters/jdbc/hsqldb.rb +166 -0
- data/lib/sequel/adapters/jdbc/informix.rb +26 -0
- data/lib/sequel/adapters/jdbc/jtds.rb +29 -0
- data/lib/sequel/adapters/jdbc/mssql.rb +0 -32
- data/lib/sequel/adapters/jdbc/mysql.rb +9 -10
- data/lib/sequel/adapters/jdbc/oracle.rb +67 -25
- data/lib/sequel/adapters/jdbc/postgresql.rb +6 -11
- data/lib/sequel/adapters/jdbc/sqlite.rb +0 -5
- data/lib/sequel/adapters/jdbc/sqlserver.rb +41 -0
- data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
- data/lib/sequel/adapters/jdbc.rb +107 -38
- data/lib/sequel/adapters/mock.rb +315 -0
- data/lib/sequel/adapters/mysql.rb +78 -182
- data/lib/sequel/adapters/mysql2.rb +24 -23
- data/lib/sequel/adapters/odbc/db2.rb +17 -0
- data/lib/sequel/adapters/odbc/mssql.rb +0 -5
- data/lib/sequel/adapters/odbc.rb +28 -9
- data/lib/sequel/adapters/openbase.rb +2 -4
- data/lib/sequel/adapters/oracle.rb +349 -51
- data/lib/sequel/adapters/postgres.rb +169 -21
- data/lib/sequel/adapters/shared/access.rb +21 -6
- data/lib/sequel/adapters/shared/db2.rb +288 -0
- data/lib/sequel/adapters/shared/firebird.rb +214 -0
- data/lib/sequel/adapters/shared/informix.rb +45 -0
- data/lib/sequel/adapters/shared/mssql.rb +108 -65
- data/lib/sequel/adapters/shared/mysql.rb +56 -13
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +149 -0
- data/lib/sequel/adapters/shared/oracle.rb +185 -34
- data/lib/sequel/adapters/shared/postgres.rb +107 -58
- data/lib/sequel/adapters/shared/progress.rb +0 -6
- data/lib/sequel/adapters/shared/sqlite.rb +168 -41
- data/lib/sequel/adapters/sqlite.rb +27 -18
- data/lib/sequel/adapters/swift/mysql.rb +9 -5
- data/lib/sequel/adapters/swift/postgres.rb +0 -5
- data/lib/sequel/adapters/swift/sqlite.rb +6 -4
- data/lib/sequel/adapters/swift.rb +5 -5
- data/lib/sequel/adapters/tinytds.rb +152 -17
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +63 -0
- data/lib/sequel/ast_transformer.rb +190 -0
- data/lib/sequel/connection_pool/threaded.rb +3 -2
- data/lib/sequel/connection_pool.rb +1 -1
- data/lib/sequel/core.rb +46 -5
- data/lib/sequel/database/connecting.rb +5 -6
- data/lib/sequel/database/dataset.rb +4 -4
- data/lib/sequel/database/dataset_defaults.rb +59 -1
- data/lib/sequel/database/logging.rb +1 -1
- data/lib/sequel/database/misc.rb +100 -19
- data/lib/sequel/database/query.rb +153 -58
- data/lib/sequel/database/schema_generator.rb +8 -5
- data/lib/sequel/database/schema_methods.rb +59 -29
- data/lib/sequel/dataset/actions.rb +194 -57
- data/lib/sequel/dataset/features.rb +81 -8
- data/lib/sequel/dataset/graph.rb +8 -7
- data/lib/sequel/dataset/misc.rb +50 -23
- data/lib/sequel/dataset/mutation.rb +5 -6
- data/lib/sequel/dataset/prepared_statements.rb +32 -15
- data/lib/sequel/dataset/query.rb +223 -42
- data/lib/sequel/dataset/sql.rb +58 -61
- data/lib/sequel/dataset.rb +8 -0
- data/lib/sequel/exceptions.rb +4 -0
- data/lib/sequel/extensions/columns_introspection.rb +61 -0
- data/lib/sequel/extensions/migration.rb +6 -4
- data/lib/sequel/extensions/named_timezones.rb +5 -0
- data/lib/sequel/extensions/thread_local_timezones.rb +1 -1
- data/lib/sequel/extensions/to_dot.rb +95 -83
- data/lib/sequel/model/associations.rb +997 -331
- data/lib/sequel/model/base.rb +386 -129
- data/lib/sequel/model/errors.rb +1 -1
- data/lib/sequel/model/exceptions.rb +5 -1
- data/lib/sequel/model.rb +15 -8
- data/lib/sequel/plugins/association_pks.rb +22 -4
- data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
- data/lib/sequel/plugins/dataset_associations.rb +100 -0
- data/lib/sequel/plugins/defaults_setter.rb +58 -0
- data/lib/sequel/plugins/force_encoding.rb +6 -6
- data/lib/sequel/plugins/identity_map.rb +114 -7
- data/lib/sequel/plugins/many_through_many.rb +65 -7
- data/lib/sequel/plugins/prepared_statements.rb +151 -0
- data/lib/sequel/plugins/prepared_statements_associations.rb +84 -0
- data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
- data/lib/sequel/plugins/rcte_tree.rb +29 -15
- data/lib/sequel/plugins/serialization.rb +6 -1
- data/lib/sequel/plugins/serialization_modification_detection.rb +51 -0
- data/lib/sequel/plugins/sharding.rb +12 -25
- data/lib/sequel/plugins/single_table_inheritance.rb +3 -1
- data/lib/sequel/plugins/typecast_on_load.rb +9 -12
- data/lib/sequel/plugins/update_primary_key.rb +2 -2
- data/lib/sequel/plugins/xml_serializer.rb +3 -3
- data/lib/sequel/sql.rb +107 -51
- data/lib/sequel/timezones.rb +44 -35
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +146 -0
- data/spec/adapters/mssql_spec.rb +65 -29
- data/spec/adapters/mysql_spec.rb +122 -123
- data/spec/adapters/oracle_spec.rb +48 -76
- data/spec/adapters/postgres_spec.rb +213 -61
- data/spec/adapters/spec_helper.rb +6 -5
- data/spec/adapters/sqlite_spec.rb +35 -21
- data/spec/core/connection_pool_spec.rb +71 -92
- data/spec/core/core_sql_spec.rb +20 -31
- data/spec/core/database_spec.rb +729 -508
- data/spec/core/dataset_spec.rb +980 -1044
- data/spec/core/expression_filters_spec.rb +159 -42
- data/spec/core/mock_adapter_spec.rb +378 -0
- data/spec/core/object_graph_spec.rb +48 -114
- data/spec/core/schema_generator_spec.rb +3 -3
- data/spec/core/schema_spec.rb +298 -38
- data/spec/core/spec_helper.rb +6 -48
- data/spec/extensions/association_pks_spec.rb +38 -0
- data/spec/extensions/class_table_inheritance_spec.rb +1 -1
- data/spec/extensions/columns_introspection_spec.rb +91 -0
- data/spec/extensions/dataset_associations_spec.rb +199 -0
- data/spec/extensions/defaults_setter_spec.rb +64 -0
- data/spec/extensions/identity_map_spec.rb +162 -0
- data/spec/extensions/instance_hooks_spec.rb +71 -0
- data/spec/extensions/many_through_many_spec.rb +195 -20
- data/spec/extensions/migration_spec.rb +17 -17
- data/spec/extensions/named_timezones_spec.rb +22 -2
- data/spec/extensions/nested_attributes_spec.rb +4 -0
- data/spec/extensions/prepared_statements_associations_spec.rb +126 -0
- data/spec/extensions/prepared_statements_safe_spec.rb +79 -0
- data/spec/extensions/prepared_statements_spec.rb +72 -0
- data/spec/extensions/prepared_statements_with_pk_spec.rb +38 -0
- data/spec/extensions/schema_dumper_spec.rb +2 -2
- data/spec/extensions/schema_spec.rb +13 -21
- data/spec/extensions/serialization_modification_detection_spec.rb +37 -0
- data/spec/extensions/serialization_spec.rb +5 -8
- data/spec/extensions/single_table_inheritance_spec.rb +11 -0
- data/spec/extensions/spec_helper.rb +7 -1
- data/spec/extensions/thread_local_timezones_spec.rb +22 -2
- data/spec/extensions/to_dot_spec.rb +3 -5
- data/spec/extensions/typecast_on_load_spec.rb +1 -6
- data/spec/extensions/xml_serializer_spec.rb +16 -4
- data/spec/integration/associations_test.rb +522 -21
- data/spec/integration/database_test.rb +4 -2
- data/spec/integration/dataset_test.rb +375 -62
- data/spec/integration/eager_loader_test.rb +19 -21
- data/spec/integration/model_test.rb +80 -1
- data/spec/integration/plugin_test.rb +304 -116
- data/spec/integration/prepared_statement_test.rb +200 -120
- data/spec/integration/schema_test.rb +161 -30
- data/spec/integration/spec_helper.rb +39 -30
- data/spec/integration/timezone_test.rb +38 -12
- data/spec/integration/transaction_test.rb +172 -5
- data/spec/integration/type_test.rb +17 -3
- data/spec/model/association_reflection_spec.rb +174 -7
- data/spec/model/associations_spec.rb +849 -661
- data/spec/model/base_spec.rb +255 -95
- data/spec/model/dataset_methods_spec.rb +7 -27
- data/spec/model/eager_loading_spec.rb +640 -676
- data/spec/model/hooks_spec.rb +309 -67
- data/spec/model/model_spec.rb +207 -167
- data/spec/model/plugins_spec.rb +24 -13
- data/spec/model/record_spec.rb +321 -218
- data/spec/model/spec_helper.rb +13 -71
- data/spec/model/validations_spec.rb +11 -0
- metadata +95 -38
data/spec/model/model_spec.rb
CHANGED
|
@@ -12,13 +12,48 @@ describe "Sequel::Model()" do
|
|
|
12
12
|
c.dataset.should == ds
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
it "should return a model subclass with a dataset with the default database and given table name if given a
|
|
15
|
+
it "should return a model subclass with a dataset with the default database and given table name if given a Symbol" do
|
|
16
16
|
c = Sequel::Model(:blah)
|
|
17
17
|
c.superclass.should == Sequel::Model
|
|
18
18
|
c.db.should == @db
|
|
19
19
|
c.table_name.should == :blah
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
+
it "should return a model subclass with a dataset with the default database and given table name if given a LiteralString" do
|
|
23
|
+
c = Sequel::Model('blah'.lit)
|
|
24
|
+
c.superclass.should == Sequel::Model
|
|
25
|
+
c.db.should == @db
|
|
26
|
+
c.table_name.should == 'blah'.lit
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "should return a model subclass with a dataset with the default database and given table name if given an SQL::Identifier" do
|
|
30
|
+
c = Sequel::Model(:blah.identifier)
|
|
31
|
+
c.superclass.should == Sequel::Model
|
|
32
|
+
c.db.should == @db
|
|
33
|
+
c.table_name.should == :blah.identifier
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "should return a model subclass with a dataset with the default database and given table name if given an SQL::QualifiedIdentifier" do
|
|
37
|
+
c = Sequel::Model(:blah.qualify(:boo))
|
|
38
|
+
c.superclass.should == Sequel::Model
|
|
39
|
+
c.db.should == @db
|
|
40
|
+
c.table_name.should == :blah.qualify(:boo)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "should return a model subclass with a dataset with the default database and given table name if given an SQL::AliasedExpression" do
|
|
44
|
+
c = Sequel::Model(:blah.as(:boo))
|
|
45
|
+
c.superclass.should == Sequel::Model
|
|
46
|
+
c.db.should == @db
|
|
47
|
+
c.table_name.should == :boo
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it "should return a model subclass with the given dataset if given a dataset using an SQL::Identifier" do
|
|
51
|
+
ds = @db[:blah.identifier]
|
|
52
|
+
c = Sequel::Model(ds)
|
|
53
|
+
c.superclass.should == Sequel::Model
|
|
54
|
+
c.dataset.should == ds
|
|
55
|
+
end
|
|
56
|
+
|
|
22
57
|
it "should return a model subclass associated to the given database if given a database" do
|
|
23
58
|
db = Sequel::Database.new
|
|
24
59
|
c = Sequel::Model(db)
|
|
@@ -43,6 +78,34 @@ describe "Sequel::Model()" do
|
|
|
43
78
|
end.should_not raise_error
|
|
44
79
|
end
|
|
45
80
|
|
|
81
|
+
it "should work without raising an exception with an SQL::Identifier " do
|
|
82
|
+
proc do
|
|
83
|
+
class ::Album < Sequel::Model(:table.identifier); end
|
|
84
|
+
class ::Album < Sequel::Model(:table.identifier); end
|
|
85
|
+
end.should_not raise_error
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
it "should work without raising an exception with an SQL::QualifiedIdentifier " do
|
|
89
|
+
proc do
|
|
90
|
+
class ::Album < Sequel::Model(:table.qualify(:schema)); end
|
|
91
|
+
class ::Album < Sequel::Model(:table.qualify(:schema)); end
|
|
92
|
+
end.should_not raise_error
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
it "should work without raising an exception with an SQL::AliasedExpression" do
|
|
96
|
+
proc do
|
|
97
|
+
class ::Album < Sequel::Model(:table.as(:alias)); end
|
|
98
|
+
class ::Album < Sequel::Model(:table.as(:alias)); end
|
|
99
|
+
end.should_not raise_error
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
it "should work without raising an exception with an LiteralString" do
|
|
103
|
+
proc do
|
|
104
|
+
class ::Album < Sequel::Model('table'.lit); end
|
|
105
|
+
class ::Album < Sequel::Model('table'.lit); end
|
|
106
|
+
end.should_not raise_error
|
|
107
|
+
end
|
|
108
|
+
|
|
46
109
|
it "should work without raising an exception with a database" do
|
|
47
110
|
proc do
|
|
48
111
|
class ::Album < Sequel::Model(@db); end
|
|
@@ -56,6 +119,13 @@ describe "Sequel::Model()" do
|
|
|
56
119
|
class ::Album < Sequel::Model(@db[:table]); end
|
|
57
120
|
end.should_not raise_error
|
|
58
121
|
end
|
|
122
|
+
|
|
123
|
+
it "should work without raising an exception with a dataset with an SQL::Identifier" do
|
|
124
|
+
proc do
|
|
125
|
+
class ::Album < Sequel::Model(@db[:table.identifier]); end
|
|
126
|
+
class ::Album < Sequel::Model(@db[:table.identifier]); end
|
|
127
|
+
end.should_not raise_error
|
|
128
|
+
end
|
|
59
129
|
end
|
|
60
130
|
end
|
|
61
131
|
|
|
@@ -70,17 +140,16 @@ describe Sequel::Model do
|
|
|
70
140
|
it "should be associated with a dataset" do
|
|
71
141
|
model_a = Class.new(Sequel::Model) { set_dataset MODEL_DB[:as] }
|
|
72
142
|
|
|
73
|
-
model_a.dataset.should be_a_kind_of(
|
|
143
|
+
model_a.dataset.should be_a_kind_of(Sequel::Mock::Dataset)
|
|
74
144
|
model_a.dataset.opts[:from].should == [:as]
|
|
75
145
|
|
|
76
146
|
model_b = Class.new(Sequel::Model) { set_dataset MODEL_DB[:bs] }
|
|
77
147
|
|
|
78
|
-
model_b.dataset.should be_a_kind_of(
|
|
148
|
+
model_b.dataset.should be_a_kind_of(Sequel::Mock::Dataset)
|
|
79
149
|
model_b.dataset.opts[:from].should == [:bs]
|
|
80
150
|
|
|
81
151
|
model_a.dataset.opts[:from].should == [:as]
|
|
82
152
|
end
|
|
83
|
-
|
|
84
153
|
end
|
|
85
154
|
|
|
86
155
|
describe Sequel::Model, "dataset & schema" do
|
|
@@ -106,12 +175,36 @@ describe Sequel::Model, "dataset & schema" do
|
|
|
106
175
|
@model.table_name.should == :foo
|
|
107
176
|
end
|
|
108
177
|
|
|
109
|
-
it "set_dataset should take a
|
|
178
|
+
it "set_dataset should take a Symbol" do
|
|
110
179
|
@model.db = MODEL_DB
|
|
111
180
|
@model.set_dataset(:foo)
|
|
112
181
|
@model.table_name.should == :foo
|
|
113
182
|
end
|
|
114
183
|
|
|
184
|
+
it "set_dataset should take a LiteralString" do
|
|
185
|
+
@model.db = MODEL_DB
|
|
186
|
+
@model.set_dataset('foo'.lit)
|
|
187
|
+
@model.table_name.should == 'foo'.lit
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
it "set_dataset should take an SQL::Identifier" do
|
|
191
|
+
@model.db = MODEL_DB
|
|
192
|
+
@model.set_dataset(:foo.identifier)
|
|
193
|
+
@model.table_name.should == :foo.identifier
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
it "set_dataset should take an SQL::QualifiedIdentifier" do
|
|
197
|
+
@model.db = MODEL_DB
|
|
198
|
+
@model.set_dataset(:foo.qualify(:bar))
|
|
199
|
+
@model.table_name.should == :foo.qualify(:bar)
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
it "set_dataset should take an SQL::AliasedExpression" do
|
|
203
|
+
@model.db = MODEL_DB
|
|
204
|
+
@model.set_dataset(:foo.as(:bar))
|
|
205
|
+
@model.table_name.should == :bar
|
|
206
|
+
end
|
|
207
|
+
|
|
115
208
|
it "table_name should respect table aliases" do
|
|
116
209
|
@model.set_dataset(:foo___x)
|
|
117
210
|
@model.table_name.should == :x
|
|
@@ -130,7 +223,7 @@ describe Sequel::Model, "dataset & schema" do
|
|
|
130
223
|
|
|
131
224
|
it "should raise an error on set_dataset if there is an error connecting to the database" do
|
|
132
225
|
@model.meta_def(:columns){raise Sequel::DatabaseConnectionError}
|
|
133
|
-
proc{@model.set_dataset(
|
|
226
|
+
proc{@model.set_dataset(Sequel::Database.new[:foo].join(:blah))}.should raise_error
|
|
134
227
|
end
|
|
135
228
|
|
|
136
229
|
it "should not raise an error if there is a problem getting the columns for a dataset" do
|
|
@@ -149,9 +242,8 @@ describe Sequel::Model, "dataset & schema" do
|
|
|
149
242
|
end
|
|
150
243
|
end
|
|
151
244
|
|
|
152
|
-
describe Sequel::Model, "
|
|
153
|
-
|
|
154
|
-
before(:each) do
|
|
245
|
+
describe Sequel::Model, "constructors" do
|
|
246
|
+
before do
|
|
155
247
|
@m = Class.new(Sequel::Model)
|
|
156
248
|
@m.columns :a, :b
|
|
157
249
|
end
|
|
@@ -170,11 +262,38 @@ describe Sequel::Model, "constructor" do
|
|
|
170
262
|
m.values[:a].should == 1
|
|
171
263
|
end
|
|
172
264
|
|
|
265
|
+
it "should have dataset row_proc create an existing object" do
|
|
266
|
+
@m.dataset = Sequel::Dataset.new(nil)
|
|
267
|
+
o = @m.dataset.row_proc.call(:a=>1)
|
|
268
|
+
o.should be_a_kind_of(@m)
|
|
269
|
+
o.values.should == {:a=>1}
|
|
270
|
+
o.new?.should be_false
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
it "should have .call create an existing object" do
|
|
274
|
+
o = @m.call(:a=>1)
|
|
275
|
+
o.should be_a_kind_of(@m)
|
|
276
|
+
o.values.should == {:a=>1}
|
|
277
|
+
o.new?.should be_false
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
it "should have .load create an existing object" do
|
|
281
|
+
o = @m.load(:a=>1)
|
|
282
|
+
o.should be_a_kind_of(@m)
|
|
283
|
+
o.values.should == {:a=>1}
|
|
284
|
+
o.new?.should be_false
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
it "should have .new with a second true argument create an existing object" do
|
|
288
|
+
o = @m.new({:a=>1}, true)
|
|
289
|
+
o.should be_a_kind_of(@m)
|
|
290
|
+
o.values.should == {:a=>1}
|
|
291
|
+
o.new?.should be_false
|
|
292
|
+
end
|
|
173
293
|
end
|
|
174
294
|
|
|
175
295
|
describe Sequel::Model, "new" do
|
|
176
|
-
|
|
177
|
-
before(:each) do
|
|
296
|
+
before do
|
|
178
297
|
@m = Class.new(Sequel::Model) do
|
|
179
298
|
set_dataset MODEL_DB[:items]
|
|
180
299
|
columns :x, :id
|
|
@@ -194,15 +313,8 @@ describe Sequel::Model, "new" do
|
|
|
194
313
|
end
|
|
195
314
|
|
|
196
315
|
it "should use the last inserted id as primary key if not in values" do
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
super
|
|
200
|
-
1234
|
|
201
|
-
end
|
|
202
|
-
|
|
203
|
-
def d.first
|
|
204
|
-
{:x => 1, :id => 1234}
|
|
205
|
-
end
|
|
316
|
+
@m.dataset._fetch = {:x => 1, :id => 1234}
|
|
317
|
+
@m.dataset.autoid = 1234
|
|
206
318
|
|
|
207
319
|
o = @m.new(:x => 1)
|
|
208
320
|
o.save
|
|
@@ -212,14 +324,12 @@ describe Sequel::Model, "new" do
|
|
|
212
324
|
o.save
|
|
213
325
|
o.id.should == 333
|
|
214
326
|
end
|
|
215
|
-
|
|
216
327
|
end
|
|
217
328
|
|
|
218
329
|
describe Sequel::Model, ".subset" do
|
|
219
330
|
before do
|
|
220
|
-
MODEL_DB.reset
|
|
221
|
-
|
|
222
331
|
@c = Class.new(Sequel::Model(:items))
|
|
332
|
+
MODEL_DB.reset
|
|
223
333
|
end
|
|
224
334
|
|
|
225
335
|
specify "should create a filter on the underlying dataset" do
|
|
@@ -247,44 +357,31 @@ describe Sequel::Model, ".subset" do
|
|
|
247
357
|
end
|
|
248
358
|
|
|
249
359
|
describe Sequel::Model, ".find" do
|
|
250
|
-
|
|
251
|
-
before(:each) do
|
|
252
|
-
MODEL_DB.reset
|
|
253
|
-
|
|
360
|
+
before do
|
|
254
361
|
@c = Class.new(Sequel::Model(:items))
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
@dataset = @c.dataset
|
|
258
|
-
$sqls = []
|
|
259
|
-
@dataset.extend(Module.new {
|
|
260
|
-
def fetch_rows(sql)
|
|
261
|
-
$sqls << sql
|
|
262
|
-
yield $cache_dataset_row
|
|
263
|
-
end
|
|
264
|
-
})
|
|
362
|
+
@c.dataset._fetch = {:name => 'sharon', :id => 1}
|
|
363
|
+
MODEL_DB.reset
|
|
265
364
|
end
|
|
266
365
|
|
|
267
366
|
it "should return the first record matching the given filter" do
|
|
268
367
|
@c.find(:name => 'sharon').should be_a_kind_of(@c)
|
|
269
|
-
|
|
368
|
+
MODEL_DB.sqls.should == ["SELECT * FROM items WHERE (name = 'sharon') LIMIT 1"]
|
|
270
369
|
|
|
271
370
|
@c.find(:name.like('abc%')).should be_a_kind_of(@c)
|
|
272
|
-
|
|
371
|
+
MODEL_DB.sqls.should == ["SELECT * FROM items WHERE (name LIKE 'abc%') LIMIT 1"]
|
|
273
372
|
end
|
|
274
373
|
|
|
275
374
|
specify "should accept filter blocks" do
|
|
276
375
|
@c.find{:id.sql_number > 1}.should be_a_kind_of(@c)
|
|
277
|
-
|
|
376
|
+
MODEL_DB.sqls.should == ["SELECT * FROM items WHERE (id > 1) LIMIT 1"]
|
|
278
377
|
|
|
279
378
|
@c.find {(:x.sql_number > 1) & (:y.sql_number < 2)}.should be_a_kind_of(@c)
|
|
280
|
-
|
|
379
|
+
MODEL_DB.sqls.should == ["SELECT * FROM items WHERE ((x > 1) AND (y < 2)) LIMIT 1"]
|
|
281
380
|
end
|
|
282
|
-
|
|
283
381
|
end
|
|
284
382
|
|
|
285
383
|
describe Sequel::Model, ".fetch" do
|
|
286
|
-
|
|
287
|
-
before(:each) do
|
|
384
|
+
before do
|
|
288
385
|
MODEL_DB.reset
|
|
289
386
|
@c = Class.new(Sequel::Model(:items))
|
|
290
387
|
end
|
|
@@ -301,80 +398,53 @@ describe Sequel::Model, ".fetch" do
|
|
|
301
398
|
end
|
|
302
399
|
|
|
303
400
|
describe Sequel::Model, ".find_or_create" do
|
|
304
|
-
|
|
305
|
-
before(:each) do
|
|
306
|
-
MODEL_DB.reset
|
|
401
|
+
before do
|
|
307
402
|
@c = Class.new(Sequel::Model(:items)) do
|
|
308
|
-
|
|
403
|
+
set_primary_key :id
|
|
309
404
|
columns :x
|
|
310
405
|
end
|
|
406
|
+
MODEL_DB.reset
|
|
311
407
|
end
|
|
312
408
|
|
|
313
409
|
it "should find the record" do
|
|
314
|
-
@c.find_or_create(:x => 1)
|
|
410
|
+
@c.find_or_create(:x => 1).should == @c.load(:x=>1, :id=>1)
|
|
315
411
|
MODEL_DB.sqls.should == ["SELECT * FROM items WHERE (x = 1) LIMIT 1"]
|
|
316
|
-
|
|
317
|
-
MODEL_DB.reset
|
|
318
412
|
end
|
|
319
413
|
|
|
320
414
|
it "should create the record if not found" do
|
|
321
|
-
@c.
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
MODEL_DB.sqls.should == [
|
|
328
|
-
"SELECT * FROM items WHERE (x = 1) LIMIT 1",
|
|
329
|
-
"INSERT INTO items (x) VALUES (1)"
|
|
330
|
-
]
|
|
415
|
+
@c.dataset._fetch = [[], {:x=>1, :id=>1}]
|
|
416
|
+
@c.dataset.autoid = 1
|
|
417
|
+
@c.find_or_create(:x => 1).should == @c.load(:x=>1, :id=>1)
|
|
418
|
+
MODEL_DB.sqls.should == ["SELECT * FROM items WHERE (x = 1) LIMIT 1",
|
|
419
|
+
"INSERT INTO items (x) VALUES (1)",
|
|
420
|
+
"SELECT * FROM items WHERE (id = 1) LIMIT 1"]
|
|
331
421
|
end
|
|
332
422
|
|
|
333
423
|
it "should pass the new record to be created to the block if no record is found" do
|
|
334
|
-
@c.
|
|
335
|
-
@c.
|
|
336
|
-
|
|
424
|
+
@c.dataset._fetch = [[], {:x=>1, :id=>1}]
|
|
425
|
+
@c.dataset.autoid = 1
|
|
426
|
+
@c.find_or_create(:x => 1){|x| x[:y] = 2}.should == @c.load(:x=>1, :id=>1)
|
|
427
|
+
sqls = MODEL_DB.sqls
|
|
428
|
+
sqls.first.should == "SELECT * FROM items WHERE (x = 1) LIMIT 1"
|
|
429
|
+
["INSERT INTO items (x, y) VALUES (1, 2)", "INSERT INTO items (y, x) VALUES (2, 1)"].should include(sqls[1])
|
|
430
|
+
sqls.last.should == "SELECT * FROM items WHERE (id = 1) LIMIT 1"
|
|
337
431
|
end
|
|
338
432
|
end
|
|
339
433
|
|
|
340
434
|
describe Sequel::Model, ".all" do
|
|
341
|
-
|
|
342
|
-
before(:each) do
|
|
343
|
-
MODEL_DB.reset
|
|
344
|
-
@c = Class.new(Sequel::Model(:items)) do
|
|
345
|
-
no_primary_key
|
|
346
|
-
end
|
|
347
|
-
|
|
348
|
-
@c.dataset.meta_def(:all) {1234}
|
|
349
|
-
end
|
|
350
|
-
|
|
351
435
|
it "should return all records in the dataset" do
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
end
|
|
356
|
-
|
|
357
|
-
class DummyModelBased < Sequel::Model(:blog)
|
|
358
|
-
end
|
|
359
|
-
|
|
360
|
-
describe Sequel::Model, "(:tablename)" do
|
|
361
|
-
|
|
362
|
-
it "should allow reopening of descendant classes" do
|
|
363
|
-
proc do
|
|
364
|
-
eval "class DummyModelBased < Sequel::Model(:blog); end"
|
|
365
|
-
end.should_not raise_error
|
|
436
|
+
c = Class.new(Sequel::Model(:items))
|
|
437
|
+
c.all.should == [c.load(:x=>1, :id=>1)]
|
|
366
438
|
end
|
|
367
|
-
|
|
368
439
|
end
|
|
369
440
|
|
|
370
441
|
describe Sequel::Model, "A model class without a primary key" do
|
|
371
|
-
|
|
372
|
-
before(:each) do
|
|
373
|
-
MODEL_DB.reset
|
|
442
|
+
before do
|
|
374
443
|
@c = Class.new(Sequel::Model(:items)) do
|
|
375
444
|
columns :x
|
|
376
445
|
no_primary_key
|
|
377
446
|
end
|
|
447
|
+
MODEL_DB.reset
|
|
378
448
|
end
|
|
379
449
|
|
|
380
450
|
it "should be able to insert records without selecting them back" do
|
|
@@ -387,8 +457,11 @@ describe Sequel::Model, "A model class without a primary key" do
|
|
|
387
457
|
end
|
|
388
458
|
|
|
389
459
|
it "should raise when deleting" do
|
|
390
|
-
|
|
391
|
-
|
|
460
|
+
proc{@c.load(:x=>1).delete}.should raise_error
|
|
461
|
+
end
|
|
462
|
+
|
|
463
|
+
it "should raise when updating" do
|
|
464
|
+
proc{@c.load(:x=>1).update(:x=>2)}.should raise_error
|
|
392
465
|
end
|
|
393
466
|
|
|
394
467
|
it "should insert a record when saving" do
|
|
@@ -397,24 +470,17 @@ describe Sequel::Model, "A model class without a primary key" do
|
|
|
397
470
|
o.save
|
|
398
471
|
MODEL_DB.sqls.should == ['INSERT INTO items (x) VALUES (2)']
|
|
399
472
|
end
|
|
400
|
-
|
|
401
473
|
end
|
|
402
474
|
|
|
403
475
|
describe Sequel::Model, "attribute accessors" do
|
|
404
476
|
before do
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
@c = Class.new(Sequel::Model) do
|
|
409
|
-
def self.db_schema
|
|
410
|
-
set_columns(Array(@columns))
|
|
411
|
-
@db_schema = {:x=>{:type=>:integer}, :y=>{:type=>:integer}}
|
|
412
|
-
end
|
|
413
|
-
def self.set_dataset(ds, opts={})
|
|
414
|
-
@columns = ds.columns
|
|
415
|
-
db_schema
|
|
416
|
-
end
|
|
477
|
+
db = Sequel.mock
|
|
478
|
+
def db.schema(*)
|
|
479
|
+
[[:x, {:type=>:integer}], [:y, {:type=>:integer}]]
|
|
417
480
|
end
|
|
481
|
+
@dataset = db[:items].columns(:x, :y)
|
|
482
|
+
@c = Class.new(Sequel::Model)
|
|
483
|
+
MODEL_DB.reset
|
|
418
484
|
end
|
|
419
485
|
|
|
420
486
|
it "should be created on set_dataset" do
|
|
@@ -446,7 +512,7 @@ describe Sequel::Model, "attribute accessors" do
|
|
|
446
512
|
end
|
|
447
513
|
|
|
448
514
|
it "should have a working typecasting setter even if the column is not selected" do
|
|
449
|
-
@c.set_dataset(@dataset.select(:y))
|
|
515
|
+
@c.set_dataset(@dataset.select(:y).columns(:y))
|
|
450
516
|
o = @c.new
|
|
451
517
|
|
|
452
518
|
o.x = '34'
|
|
@@ -454,7 +520,7 @@ describe Sequel::Model, "attribute accessors" do
|
|
|
454
520
|
end
|
|
455
521
|
|
|
456
522
|
it "should typecast if the new value is the same as the existing but has a different class" do
|
|
457
|
-
@c.set_dataset(@dataset.select(:y))
|
|
523
|
+
@c.set_dataset(@dataset.select(:y).columns(:y))
|
|
458
524
|
o = @c.new
|
|
459
525
|
|
|
460
526
|
o.x = 34
|
|
@@ -466,58 +532,51 @@ describe Sequel::Model, "attribute accessors" do
|
|
|
466
532
|
end
|
|
467
533
|
|
|
468
534
|
describe Sequel::Model, ".[]" do
|
|
469
|
-
|
|
470
|
-
before(:each) do
|
|
471
|
-
MODEL_DB.reset
|
|
472
|
-
|
|
535
|
+
before do
|
|
473
536
|
@c = Class.new(Sequel::Model(:items))
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
@dataset = @c.dataset
|
|
477
|
-
$sqls = []
|
|
478
|
-
@dataset.extend(Module.new {
|
|
479
|
-
def fetch_rows(sql)
|
|
480
|
-
$sqls << sql
|
|
481
|
-
yield $cache_dataset_row
|
|
482
|
-
end
|
|
483
|
-
})
|
|
537
|
+
@c.dataset._fetch = {:name => 'sharon', :id => 1}
|
|
538
|
+
MODEL_DB.reset
|
|
484
539
|
end
|
|
485
540
|
|
|
486
541
|
it "should return the first record for the given pk" do
|
|
487
|
-
@c[1].should
|
|
488
|
-
|
|
489
|
-
@c[9999].should
|
|
490
|
-
|
|
542
|
+
@c[1].should == @c.load(:name => 'sharon', :id => 1)
|
|
543
|
+
MODEL_DB.sqls.should == ["SELECT * FROM items WHERE id = 1"]
|
|
544
|
+
@c[9999].should == @c.load(:name => 'sharon', :id => 1)
|
|
545
|
+
MODEL_DB.sqls.should == ["SELECT * FROM items WHERE id = 9999"]
|
|
491
546
|
end
|
|
492
547
|
|
|
493
548
|
it "should work correctly for custom primary key" do
|
|
494
549
|
@c.set_primary_key :name
|
|
495
|
-
@c['sharon'].should
|
|
496
|
-
|
|
550
|
+
@c['sharon'].should == @c.load(:name => 'sharon', :id => 1)
|
|
551
|
+
MODEL_DB.sqls.should == ["SELECT * FROM items WHERE name = 'sharon'"]
|
|
552
|
+
end
|
|
553
|
+
|
|
554
|
+
it "should return the first record for the given pk for a filtered dataset" do
|
|
555
|
+
@c.dataset = @c.dataset.filter(:active=>true)
|
|
556
|
+
@c[1].should == @c.load(:name => 'sharon', :id => 1)
|
|
557
|
+
MODEL_DB.sqls.should == ["SELECT * FROM items WHERE ((active IS TRUE) AND (id = 1)) LIMIT 1"]
|
|
497
558
|
end
|
|
498
559
|
|
|
499
560
|
it "should work correctly for composite primary key specified as array" do
|
|
500
561
|
@c.set_primary_key [:node_id, :kind]
|
|
501
562
|
@c[3921, 201].should be_a_kind_of(@c)
|
|
502
|
-
|
|
503
|
-
|
|
563
|
+
sqls = MODEL_DB.sqls
|
|
564
|
+
sqls.length.should == 1
|
|
565
|
+
sqls.first.should =~ /^SELECT \* FROM items WHERE \((\(node_id = 3921\) AND \(kind = 201\))|(\(kind = 201\) AND \(node_id = 3921\))\) LIMIT 1$/
|
|
504
566
|
end
|
|
505
567
|
|
|
506
568
|
it "should work correctly for composite primary key specified as separate arguments" do
|
|
507
569
|
@c.set_primary_key :node_id, :kind
|
|
508
570
|
@c[3921, 201].should be_a_kind_of(@c)
|
|
509
|
-
|
|
510
|
-
|
|
571
|
+
sqls = MODEL_DB.sqls
|
|
572
|
+
sqls.length.should == 1
|
|
573
|
+
sqls.first.should =~ /^SELECT \* FROM items WHERE \((\(node_id = 3921\) AND \(kind = 201\))|(\(kind = 201\) AND \(node_id = 3921\))\) LIMIT 1$/
|
|
511
574
|
end
|
|
512
575
|
end
|
|
513
576
|
|
|
514
577
|
describe "Model#inspect" do
|
|
515
|
-
before do
|
|
516
|
-
@o = Sequel::Model.load(:x => 333)
|
|
517
|
-
end
|
|
518
|
-
|
|
519
578
|
specify "should include the class name and the values" do
|
|
520
|
-
|
|
579
|
+
Sequel::Model.load(:x => 333).inspect.should == '#<Sequel::Model @values={:x=>333}>'
|
|
521
580
|
end
|
|
522
581
|
end
|
|
523
582
|
|
|
@@ -526,16 +585,13 @@ describe "Model.db_schema" do
|
|
|
526
585
|
@c = Class.new(Sequel::Model(:items)) do
|
|
527
586
|
def self.columns; orig_columns; end
|
|
528
587
|
end
|
|
529
|
-
@
|
|
530
|
-
@dataset
|
|
531
|
-
def @dataset.naked; self; end
|
|
532
|
-
def @dataset.columns; []; end
|
|
533
|
-
def @dataset.def_mutation_method(*names); end
|
|
588
|
+
@db = Sequel.mock
|
|
589
|
+
@dataset = @db[:items]
|
|
534
590
|
end
|
|
535
591
|
|
|
536
592
|
specify "should use the database's schema_for_table and set the columns and dataset columns" do
|
|
537
593
|
d = @dataset.db
|
|
538
|
-
def
|
|
594
|
+
def @db.schema(table, opts = {})
|
|
539
595
|
[[:x, {:type=>:integer}], [:y, {:type=>:string}]]
|
|
540
596
|
end
|
|
541
597
|
@c.dataset = @dataset
|
|
@@ -545,36 +601,20 @@ describe "Model.db_schema" do
|
|
|
545
601
|
end
|
|
546
602
|
|
|
547
603
|
specify "should not restrict the schema for datasets with a :select option" do
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
def d.schema(table, opts = {})
|
|
604
|
+
def @c.columns; [:x, :z]; end
|
|
605
|
+
def @db.schema(table, opts = {})
|
|
551
606
|
[[:x, {:type=>:integer}], [:y, {:type=>:string}]]
|
|
552
607
|
end
|
|
553
|
-
|
|
554
|
-
@c.dataset = ds
|
|
608
|
+
@c.dataset = @dataset.select(:x, :y___z)
|
|
555
609
|
@c.db_schema.should == {:x=>{:type=>:integer}, :z=>{}, :y=>{:type=>:string}}
|
|
556
610
|
end
|
|
557
611
|
|
|
558
|
-
specify "should not use schema if the dataset uses multiple tables or custom sql" do
|
|
559
|
-
ds = @dataset.join(:x, :id)
|
|
560
|
-
d = ds.db
|
|
561
|
-
e = false
|
|
562
|
-
d.meta_def(:schema){|table, *opts| e = true}
|
|
563
|
-
def @c.columns; [:x]; end
|
|
564
|
-
@c.dataset = ds
|
|
565
|
-
@c.db_schema.should == {:x=>{}}
|
|
566
|
-
e.should == false
|
|
567
|
-
end
|
|
568
|
-
|
|
569
612
|
specify "should fallback to fetching records if schema raises an error" do
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
def d.schema(table, opts={})
|
|
573
|
-
raise StandardError
|
|
613
|
+
def @db.schema(table, opts={})
|
|
614
|
+
raise Sequel::Error
|
|
574
615
|
end
|
|
575
|
-
|
|
576
|
-
@c.
|
|
577
|
-
@c.db_schema.should == {:x=>{}}
|
|
616
|
+
@c.dataset = @dataset.join(:x, :id).columns(:id, :x)
|
|
617
|
+
@c.db_schema.should == {:x=>{}, :id=>{}}
|
|
578
618
|
end
|
|
579
619
|
|
|
580
620
|
specify "should automatically set a singular primary key based on the schema" do
|
data/spec/model/plugins_spec.rb
CHANGED
|
@@ -125,24 +125,21 @@ describe Sequel::Model, ".plugin" do
|
|
|
125
125
|
def self.configure(model, *args, &block)
|
|
126
126
|
@args << :configure
|
|
127
127
|
end
|
|
128
|
-
|
|
128
|
+
self::InstanceMethods = Module.new do
|
|
129
129
|
def self.included(model)
|
|
130
130
|
model.plugins.last.args << :im
|
|
131
131
|
end
|
|
132
132
|
end
|
|
133
|
-
|
|
133
|
+
self::ClassMethods = Module.new do
|
|
134
134
|
def self.extended(model)
|
|
135
135
|
model.plugins.last.args << :cm
|
|
136
136
|
end
|
|
137
137
|
end
|
|
138
|
-
|
|
138
|
+
self::DatasetMethods = Module.new do
|
|
139
139
|
def self.extended(dataset)
|
|
140
140
|
dataset.model.plugins.last.args << :dm
|
|
141
141
|
end
|
|
142
142
|
end
|
|
143
|
-
const_set(:InstanceMethods, im)
|
|
144
|
-
const_set(:ClassMethods, cm)
|
|
145
|
-
const_set(:DatasetMethods, dm)
|
|
146
143
|
end
|
|
147
144
|
|
|
148
145
|
b = lambda{44}
|
|
@@ -192,11 +189,10 @@ describe Sequel::Model, ".plugin" do
|
|
|
192
189
|
|
|
193
190
|
it "should define class methods for all public instance methods in DatasetMethod" do
|
|
194
191
|
m = Module.new do
|
|
195
|
-
|
|
192
|
+
self::DatasetMethods = Module.new do
|
|
196
193
|
def a; 1; end
|
|
197
194
|
def b; 2; end
|
|
198
195
|
end
|
|
199
|
-
const_set(:DatasetMethods, dm)
|
|
200
196
|
end
|
|
201
197
|
@c.plugin m
|
|
202
198
|
@c.dataset.a.should == 1
|
|
@@ -205,14 +201,13 @@ describe Sequel::Model, ".plugin" do
|
|
|
205
201
|
@c.b.should == 2
|
|
206
202
|
end
|
|
207
203
|
|
|
208
|
-
it "should define class methods for
|
|
204
|
+
it "should not define class methods for private instance methods in DatasetMethod" do
|
|
209
205
|
m = Module.new do
|
|
210
|
-
|
|
206
|
+
self::DatasetMethods = Module.new do
|
|
211
207
|
def b; 2; end
|
|
212
208
|
private
|
|
213
209
|
def a; 1; end
|
|
214
210
|
end
|
|
215
|
-
const_set(:DatasetMethods, dm)
|
|
216
211
|
end
|
|
217
212
|
@c.plugin m
|
|
218
213
|
@c.dataset.b.should == 2
|
|
@@ -225,12 +220,28 @@ describe Sequel::Model, ".plugin" do
|
|
|
225
220
|
|
|
226
221
|
it "should not raise an error if the DatasetMethod module has no public instance methods" do
|
|
227
222
|
m = Module.new do
|
|
228
|
-
|
|
223
|
+
self::DatasetMethods = Module.new do
|
|
229
224
|
private
|
|
230
225
|
def a; 1; end
|
|
231
226
|
end
|
|
232
|
-
const_set(:DatasetMethods, dm)
|
|
233
227
|
end
|
|
234
228
|
lambda{@c.plugin m}.should_not raise_error
|
|
235
229
|
end
|
|
230
|
+
|
|
231
|
+
it "should not raise an error if plugin submodule names exist higher up in the namespace hierarchy" do
|
|
232
|
+
class ::ClassMethods; end
|
|
233
|
+
@c.plugin(m = Module.new)
|
|
234
|
+
Object.send(:remove_const, :ClassMethods)
|
|
235
|
+
@c.plugins.should include(m)
|
|
236
|
+
|
|
237
|
+
class ::InstanceMethods; end
|
|
238
|
+
@c.plugin(m = Module.new)
|
|
239
|
+
Object.send(:remove_const, :InstanceMethods)
|
|
240
|
+
@c.plugins.should include(m)
|
|
241
|
+
|
|
242
|
+
class ::DatasetMethods; end
|
|
243
|
+
@c.plugin(m = Module.new)
|
|
244
|
+
Object.send(:remove_const, :DatasetMethods)
|
|
245
|
+
@c.plugins.should include(m)
|
|
246
|
+
end
|
|
236
247
|
end
|