sequel 3.46.0 → 3.47.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +96 -0
- data/Rakefile +7 -1
- data/bin/sequel +6 -4
- data/doc/active_record.rdoc +1 -1
- data/doc/advanced_associations.rdoc +14 -35
- data/doc/association_basics.rdoc +66 -4
- data/doc/migration.rdoc +4 -0
- data/doc/opening_databases.rdoc +6 -0
- data/doc/postgresql.rdoc +302 -0
- data/doc/release_notes/3.47.0.txt +270 -0
- data/doc/security.rdoc +6 -0
- data/lib/sequel/adapters/ibmdb.rb +9 -9
- data/lib/sequel/adapters/jdbc.rb +22 -7
- data/lib/sequel/adapters/jdbc/postgresql.rb +7 -2
- data/lib/sequel/adapters/mock.rb +2 -0
- data/lib/sequel/adapters/postgres.rb +44 -13
- data/lib/sequel/adapters/shared/mssql.rb +1 -1
- data/lib/sequel/adapters/shared/mysql.rb +2 -2
- data/lib/sequel/adapters/shared/postgres.rb +94 -55
- data/lib/sequel/adapters/shared/sqlite.rb +3 -1
- data/lib/sequel/adapters/sqlite.rb +2 -2
- data/lib/sequel/adapters/utils/pg_types.rb +1 -14
- data/lib/sequel/adapters/utils/split_alter_table.rb +3 -3
- data/lib/sequel/connection_pool/threaded.rb +1 -1
- data/lib/sequel/core.rb +1 -1
- data/lib/sequel/database/connecting.rb +2 -2
- data/lib/sequel/database/features.rb +5 -0
- data/lib/sequel/database/misc.rb +47 -5
- data/lib/sequel/database/query.rb +2 -2
- data/lib/sequel/dataset/actions.rb +4 -2
- data/lib/sequel/dataset/misc.rb +1 -1
- data/lib/sequel/dataset/prepared_statements.rb +1 -1
- data/lib/sequel/dataset/query.rb +8 -6
- data/lib/sequel/dataset/sql.rb +8 -6
- data/lib/sequel/extensions/constraint_validations.rb +5 -2
- data/lib/sequel/extensions/migration.rb +10 -8
- data/lib/sequel/extensions/pagination.rb +3 -0
- data/lib/sequel/extensions/pg_array.rb +85 -25
- data/lib/sequel/extensions/pg_hstore.rb +8 -1
- data/lib/sequel/extensions/pg_hstore_ops.rb +4 -1
- data/lib/sequel/extensions/pg_inet.rb +16 -13
- data/lib/sequel/extensions/pg_interval.rb +6 -2
- data/lib/sequel/extensions/pg_json.rb +18 -11
- data/lib/sequel/extensions/pg_range.rb +17 -2
- data/lib/sequel/extensions/pg_range_ops.rb +7 -5
- data/lib/sequel/extensions/pg_row.rb +29 -12
- data/lib/sequel/extensions/pretty_table.rb +3 -0
- data/lib/sequel/extensions/query.rb +3 -0
- data/lib/sequel/extensions/schema_caching.rb +2 -0
- data/lib/sequel/extensions/schema_dumper.rb +3 -1
- data/lib/sequel/extensions/select_remove.rb +3 -0
- data/lib/sequel/model.rb +8 -2
- data/lib/sequel/model/associations.rb +39 -27
- data/lib/sequel/model/base.rb +99 -38
- data/lib/sequel/model/plugins.rb +25 -0
- data/lib/sequel/plugins/association_autoreloading.rb +27 -22
- data/lib/sequel/plugins/association_dependencies.rb +1 -7
- data/lib/sequel/plugins/auto_validations.rb +110 -0
- data/lib/sequel/plugins/boolean_readers.rb +1 -6
- data/lib/sequel/plugins/caching.rb +6 -13
- data/lib/sequel/plugins/class_table_inheritance.rb +1 -0
- data/lib/sequel/plugins/composition.rb +14 -7
- data/lib/sequel/plugins/constraint_validations.rb +2 -13
- data/lib/sequel/plugins/defaults_setter.rb +1 -6
- data/lib/sequel/plugins/dirty.rb +8 -0
- data/lib/sequel/plugins/error_splitter.rb +54 -0
- data/lib/sequel/plugins/force_encoding.rb +1 -5
- data/lib/sequel/plugins/hook_class_methods.rb +1 -6
- data/lib/sequel/plugins/input_transformer.rb +79 -0
- data/lib/sequel/plugins/instance_filters.rb +7 -1
- data/lib/sequel/plugins/instance_hooks.rb +7 -1
- data/lib/sequel/plugins/json_serializer.rb +5 -10
- data/lib/sequel/plugins/lazy_attributes.rb +20 -7
- data/lib/sequel/plugins/list.rb +1 -6
- data/lib/sequel/plugins/many_through_many.rb +1 -2
- data/lib/sequel/plugins/many_to_one_pk_lookup.rb +23 -39
- data/lib/sequel/plugins/optimistic_locking.rb +1 -5
- data/lib/sequel/plugins/pg_row.rb +4 -2
- data/lib/sequel/plugins/pg_typecast_on_load.rb +3 -7
- data/lib/sequel/plugins/prepared_statements.rb +1 -5
- data/lib/sequel/plugins/prepared_statements_safe.rb +2 -11
- data/lib/sequel/plugins/rcte_tree.rb +2 -2
- data/lib/sequel/plugins/serialization.rb +11 -13
- data/lib/sequel/plugins/serialization_modification_detection.rb +13 -1
- data/lib/sequel/plugins/single_table_inheritance.rb +4 -4
- data/lib/sequel/plugins/static_cache.rb +67 -19
- data/lib/sequel/plugins/string_stripper.rb +7 -27
- data/lib/sequel/plugins/subclasses.rb +3 -5
- data/lib/sequel/plugins/tactical_eager_loading.rb +2 -2
- data/lib/sequel/plugins/timestamps.rb +2 -7
- data/lib/sequel/plugins/touch.rb +5 -8
- data/lib/sequel/plugins/tree.rb +1 -6
- data/lib/sequel/plugins/typecast_on_load.rb +1 -5
- data/lib/sequel/plugins/update_primary_key.rb +26 -14
- data/lib/sequel/plugins/validation_class_methods.rb +31 -16
- data/lib/sequel/plugins/validation_helpers.rb +50 -26
- data/lib/sequel/plugins/xml_serializer.rb +3 -6
- data/lib/sequel/sql.rb +1 -1
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/postgres_spec.rb +131 -15
- data/spec/adapters/sqlite_spec.rb +1 -1
- data/spec/core/connection_pool_spec.rb +16 -17
- data/spec/core/database_spec.rb +111 -40
- data/spec/core/dataset_spec.rb +65 -74
- data/spec/core/expression_filters_spec.rb +6 -5
- data/spec/core/object_graph_spec.rb +0 -1
- data/spec/core/schema_spec.rb +23 -23
- data/spec/core/spec_helper.rb +5 -1
- data/spec/extensions/association_dependencies_spec.rb +1 -1
- data/spec/extensions/association_proxies_spec.rb +1 -1
- data/spec/extensions/auto_validations_spec.rb +90 -0
- data/spec/extensions/caching_spec.rb +6 -0
- data/spec/extensions/class_table_inheritance_spec.rb +8 -1
- data/spec/extensions/composition_spec.rb +12 -5
- data/spec/extensions/constraint_validations_spec.rb +4 -4
- data/spec/extensions/core_refinements_spec.rb +29 -79
- data/spec/extensions/dirty_spec.rb +14 -0
- data/spec/extensions/error_splitter_spec.rb +18 -0
- data/spec/extensions/identity_map_spec.rb +0 -1
- data/spec/extensions/input_transformer_spec.rb +54 -0
- data/spec/extensions/instance_filters_spec.rb +6 -0
- data/spec/extensions/instance_hooks_spec.rb +12 -1
- data/spec/extensions/json_serializer_spec.rb +0 -1
- data/spec/extensions/lazy_attributes_spec.rb +64 -55
- data/spec/extensions/looser_typecasting_spec.rb +1 -1
- data/spec/extensions/many_through_many_spec.rb +3 -4
- data/spec/extensions/many_to_one_pk_lookup_spec.rb +53 -15
- data/spec/extensions/migration_spec.rb +16 -0
- data/spec/extensions/null_dataset_spec.rb +1 -1
- data/spec/extensions/pg_array_spec.rb +48 -1
- data/spec/extensions/pg_hstore_ops_spec.rb +10 -2
- data/spec/extensions/pg_hstore_spec.rb +5 -0
- data/spec/extensions/pg_inet_spec.rb +5 -0
- data/spec/extensions/pg_interval_spec.rb +7 -3
- data/spec/extensions/pg_json_spec.rb +6 -1
- data/spec/extensions/pg_range_ops_spec.rb +4 -1
- data/spec/extensions/pg_range_spec.rb +5 -0
- data/spec/extensions/pg_row_plugin_spec.rb +13 -0
- data/spec/extensions/pg_row_spec.rb +28 -19
- data/spec/extensions/pg_typecast_on_load_spec.rb +6 -1
- data/spec/extensions/prepared_statements_associations_spec.rb +1 -1
- data/spec/extensions/query_literals_spec.rb +1 -1
- data/spec/extensions/rcte_tree_spec.rb +2 -2
- data/spec/extensions/schema_spec.rb +2 -2
- data/spec/extensions/serialization_modification_detection_spec.rb +8 -0
- data/spec/extensions/serialization_spec.rb +15 -1
- data/spec/extensions/sharding_spec.rb +1 -1
- data/spec/extensions/single_table_inheritance_spec.rb +1 -1
- data/spec/extensions/static_cache_spec.rb +59 -9
- data/spec/extensions/tactical_eager_loading_spec.rb +19 -4
- data/spec/extensions/update_primary_key_spec.rb +17 -1
- data/spec/extensions/validation_class_methods_spec.rb +25 -0
- data/spec/extensions/validation_helpers_spec.rb +59 -3
- data/spec/integration/associations_test.rb +5 -5
- data/spec/integration/eager_loader_test.rb +32 -63
- data/spec/integration/model_test.rb +2 -2
- data/spec/integration/plugin_test.rb +88 -56
- data/spec/integration/prepared_statement_test.rb +1 -1
- data/spec/integration/schema_test.rb +1 -1
- data/spec/integration/timezone_test.rb +0 -1
- data/spec/integration/transaction_test.rb +0 -1
- data/spec/model/association_reflection_spec.rb +1 -1
- data/spec/model/associations_spec.rb +106 -84
- data/spec/model/base_spec.rb +4 -4
- data/spec/model/eager_loading_spec.rb +8 -8
- data/spec/model/model_spec.rb +27 -9
- data/spec/model/plugins_spec.rb +71 -0
- data/spec/model/record_spec.rb +99 -13
- metadata +12 -2
data/spec/model/base_spec.rb
CHANGED
@@ -33,7 +33,7 @@ describe "Model attribute setters" do
|
|
33
33
|
@o.changed_columns.should == [:x, :y]
|
34
34
|
end
|
35
35
|
|
36
|
-
it "should
|
36
|
+
it "should handle columns that can't be called like normal ruby methods" do
|
37
37
|
@o.send(:"x y=", 3)
|
38
38
|
@o.changed_columns.should == [:"x y"]
|
39
39
|
@o.values.should == {:"x y"=>3}
|
@@ -385,7 +385,7 @@ describe "Model.db" do
|
|
385
385
|
Sequel::Model.db = @model_db
|
386
386
|
end
|
387
387
|
|
388
|
-
specify "should be required when
|
388
|
+
specify "should be required when creating named model classes" do
|
389
389
|
begin
|
390
390
|
proc{class ModelTest < Sequel::Model; end}.should raise_error(Sequel::Error)
|
391
391
|
ensure
|
@@ -655,7 +655,7 @@ describe Sequel::Model, ".[] optimization" do
|
|
655
655
|
@c.simple_table.should == '"b"."a"'
|
656
656
|
end
|
657
657
|
|
658
|
-
it "should simple_pk and simple_table respect dataset's identifier input methods" do
|
658
|
+
it "should have simple_pk and simple_table respect dataset's identifier input methods" do
|
659
659
|
ds = @db[:ab]
|
660
660
|
ds.identifier_input_method = :reverse
|
661
661
|
@c.set_dataset ds
|
@@ -672,7 +672,7 @@ describe Sequel::Model, ".[] optimization" do
|
|
672
672
|
@c.simple_table.should == nil
|
673
673
|
end
|
674
674
|
|
675
|
-
it "should have simple_table
|
675
|
+
it "should have simple_table inherit superclass's setting" do
|
676
676
|
Class.new(@c).simple_table.should == nil
|
677
677
|
@c.set_dataset :a
|
678
678
|
Class.new(@c).simple_table.should == '"a"'
|
@@ -293,13 +293,13 @@ describe Sequel::Model, "#eager" do
|
|
293
293
|
|
294
294
|
it "should correctly handle a :select=>[] option to many_to_many" do
|
295
295
|
EagerAlbum.many_to_many :sgenres, :clone=>:genres, :select=>[]
|
296
|
-
|
296
|
+
EagerAlbum.eager(:sgenres).all
|
297
297
|
MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT *, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (1)))"]
|
298
298
|
end
|
299
299
|
|
300
300
|
it "should correctly handle an aliased join table in many_to_many" do
|
301
301
|
EagerAlbum.many_to_many :sgenres, :clone=>:genres, :join_table=>:ag___ga
|
302
|
-
|
302
|
+
EagerAlbum.eager(:sgenres).all
|
303
303
|
MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ga.album_id AS x_foreign_key_x FROM genres INNER JOIN ag AS ga ON ((ga.genre_id = genres.id) AND (ga.album_id IN (1)))"]
|
304
304
|
end
|
305
305
|
|
@@ -1469,7 +1469,7 @@ describe Sequel::Model, "#eager_graph" do
|
|
1469
1469
|
end
|
1470
1470
|
|
1471
1471
|
it "should eagerly load a many_to_one association with a custom callback" do
|
1472
|
-
ds = GraphAlbum.eager_graph(:band => proc {|
|
1472
|
+
ds = GraphAlbum.eager_graph(:band => proc {|ds1| ds1.select(:id).columns(:id)})
|
1473
1473
|
ds.sql.should == 'SELECT albums.id, albums.band_id, band.id AS band_id_0 FROM albums LEFT OUTER JOIN (SELECT id FROM bands) AS band ON (band.id = albums.band_id)'
|
1474
1474
|
ds._fetch = {:id=>1, :band_id=>2, :band_id_0=>2}
|
1475
1475
|
a = ds.all
|
@@ -1479,7 +1479,7 @@ describe Sequel::Model, "#eager_graph" do
|
|
1479
1479
|
|
1480
1480
|
it "should eagerly load a one_to_one association with a custom callback" do
|
1481
1481
|
GraphAlbum.one_to_one :track, :class=>'GraphTrack', :key=>:album_id
|
1482
|
-
ds = GraphAlbum.eager_graph(:track => proc {|
|
1482
|
+
ds = GraphAlbum.eager_graph(:track => proc {|ds1| ds1.select(:album_id).columns(:album_id)})
|
1483
1483
|
ds.sql.should == 'SELECT albums.id, albums.band_id, track.album_id FROM albums LEFT OUTER JOIN (SELECT album_id FROM tracks) AS track ON (track.album_id = albums.id)'
|
1484
1484
|
ds._fetch = {:id=>1, :band_id=>2, :album_id=>1}
|
1485
1485
|
a = ds.all
|
@@ -1488,7 +1488,7 @@ describe Sequel::Model, "#eager_graph" do
|
|
1488
1488
|
end
|
1489
1489
|
|
1490
1490
|
it "should eagerly load a one_to_many association with a custom callback" do
|
1491
|
-
ds = GraphAlbum.eager_graph(:tracks => proc {|
|
1491
|
+
ds = GraphAlbum.eager_graph(:tracks => proc {|ds1| ds1.select(:album_id).columns(:album_id)})
|
1492
1492
|
ds.sql.should == 'SELECT albums.id, albums.band_id, tracks.album_id FROM albums LEFT OUTER JOIN (SELECT album_id FROM tracks) AS tracks ON (tracks.album_id = albums.id)'
|
1493
1493
|
ds._fetch = {:id=>1, :band_id=>2, :album_id=>1}
|
1494
1494
|
a = ds.all
|
@@ -1497,7 +1497,7 @@ describe Sequel::Model, "#eager_graph" do
|
|
1497
1497
|
end
|
1498
1498
|
|
1499
1499
|
it "should eagerly load a many_to_many association with a custom callback" do
|
1500
|
-
ds = GraphAlbum.eager_graph(:genres => proc {|
|
1500
|
+
ds = GraphAlbum.eager_graph(:genres => proc {|ds1| ds1.select(:id).columns(:id)})
|
1501
1501
|
ds.sql.should == 'SELECT albums.id, albums.band_id, genres.id AS genres_id FROM albums LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN (SELECT id FROM genres) AS genres ON (genres.id = ag.genre_id)'
|
1502
1502
|
ds._fetch = {:id=>1, :band_id=>2, :genres_id=>4}
|
1503
1503
|
a = ds.all
|
@@ -1506,7 +1506,7 @@ describe Sequel::Model, "#eager_graph" do
|
|
1506
1506
|
end
|
1507
1507
|
|
1508
1508
|
it "should allow cascading of eager loading with a custom callback with hash value" do
|
1509
|
-
ds = GraphTrack.eager_graph(:album=>{proc{|
|
1509
|
+
ds = GraphTrack.eager_graph(:album=>{proc{|ds1| ds1.select(:id, :band_id).columns(:id, :band_id)}=>{:band=>:members}})
|
1510
1510
|
ds.sql.should == 'SELECT tracks.id, tracks.album_id, album.id AS album_id_0, album.band_id, band.id AS band_id_0, band.vocalist_id, members.id AS members_id FROM tracks LEFT OUTER JOIN (SELECT id, band_id FROM albums) AS album ON (album.id = tracks.album_id) LEFT OUTER JOIN bands AS band ON (band.id = album.band_id) LEFT OUTER JOIN bm ON (bm.band_id = band.id) LEFT OUTER JOIN members ON (members.id = bm.member_id)'
|
1511
1511
|
ds._fetch = {:id=>3, :album_id=>1, :album_id_0=>1, :band_id=>2, :members_id=>5, :band_id_0=>2, :vocalist_id=>6}
|
1512
1512
|
a = ds.all
|
@@ -1518,7 +1518,7 @@ describe Sequel::Model, "#eager_graph" do
|
|
1518
1518
|
end
|
1519
1519
|
|
1520
1520
|
it "should allow cascading of eager loading with a custom callback with array value" do
|
1521
|
-
ds = GraphTrack.eager_graph(:album=>{proc{|
|
1521
|
+
ds = GraphTrack.eager_graph(:album=>{proc{|ds1| ds1.select(:id, :band_id).columns(:id, :band_id)}=>[:band, :tracks]})
|
1522
1522
|
ds.sql.should == 'SELECT tracks.id, tracks.album_id, album.id AS album_id_0, album.band_id, band.id AS band_id_0, band.vocalist_id, tracks_0.id AS tracks_0_id, tracks_0.album_id AS tracks_0_album_id FROM tracks LEFT OUTER JOIN (SELECT id, band_id FROM albums) AS album ON (album.id = tracks.album_id) LEFT OUTER JOIN bands AS band ON (band.id = album.band_id) LEFT OUTER JOIN tracks AS tracks_0 ON (tracks_0.album_id = album.id)'
|
1523
1523
|
ds._fetch = {:id=>3, :album_id=>1, :album_id_0=>1, :band_id=>2, :band_id_0=>2, :vocalist_id=>6, :tracks_0_id=>3, :tracks_0_album_id=>1}
|
1524
1524
|
a = ds.all
|
data/spec/model/model_spec.rb
CHANGED
@@ -164,12 +164,12 @@ describe Sequel::Model do
|
|
164
164
|
end
|
165
165
|
end
|
166
166
|
|
167
|
-
describe Sequel::Model
|
167
|
+
describe Sequel::Model do
|
168
168
|
before do
|
169
169
|
@model = Class.new(Sequel::Model(:items))
|
170
170
|
end
|
171
171
|
|
172
|
-
it "
|
172
|
+
it "has table_name return name of table" do
|
173
173
|
@model.table_name.should == :items
|
174
174
|
end
|
175
175
|
|
@@ -187,31 +187,31 @@ describe Sequel::Model, "dataset & schema" do
|
|
187
187
|
@model.table_name.should == :foo
|
188
188
|
end
|
189
189
|
|
190
|
-
it "set_dataset
|
190
|
+
it "allows set_dataset to accept a Symbol" do
|
191
191
|
@model.db = MODEL_DB
|
192
192
|
@model.set_dataset(:foo)
|
193
193
|
@model.table_name.should == :foo
|
194
194
|
end
|
195
195
|
|
196
|
-
it "set_dataset
|
196
|
+
it "allows set_dataset to accept a LiteralString" do
|
197
197
|
@model.db = MODEL_DB
|
198
198
|
@model.set_dataset(Sequel.lit('foo'))
|
199
199
|
@model.table_name.should == Sequel.lit('foo')
|
200
200
|
end
|
201
201
|
|
202
|
-
it "set_dataset
|
202
|
+
it "allows set_dataset to acceptan SQL::Identifier" do
|
203
203
|
@model.db = MODEL_DB
|
204
204
|
@model.set_dataset(Sequel.identifier(:foo))
|
205
205
|
@model.table_name.should == Sequel.identifier(:foo)
|
206
206
|
end
|
207
207
|
|
208
|
-
it "set_dataset
|
208
|
+
it "allows set_dataset to acceptan SQL::QualifiedIdentifier" do
|
209
209
|
@model.db = MODEL_DB
|
210
210
|
@model.set_dataset(Sequel.qualify(:bar, :foo))
|
211
211
|
@model.table_name.should == Sequel.qualify(:bar, :foo)
|
212
212
|
end
|
213
213
|
|
214
|
-
it "set_dataset
|
214
|
+
it "allows set_dataset to acceptan SQL::AliasedExpression" do
|
215
215
|
@model.db = MODEL_DB
|
216
216
|
@model.set_dataset(Sequel.as(:foo, :bar))
|
217
217
|
@model.table_name.should == :bar
|
@@ -266,6 +266,25 @@ describe Sequel::Model, "dataset & schema" do
|
|
266
266
|
def @model.set_dataset(*) raise Sequel::Error end
|
267
267
|
proc{Class.new(@model)}.should_not raise_error
|
268
268
|
end
|
269
|
+
|
270
|
+
it "should raise if bad inherited instance variable value is used" do
|
271
|
+
def @model.inherited_instance_variables() super.merge(:@a=>:foo) end
|
272
|
+
@model.instance_eval{@a=1}
|
273
|
+
proc{Class.new(@model)}.should raise_error(Sequel::Error)
|
274
|
+
end
|
275
|
+
|
276
|
+
it "copy inherited instance variables into subclass if set" do
|
277
|
+
def @model.inherited_instance_variables() super.merge(:@a=>nil, :@b=>:dup, :@c=>:hash_dup, :@d=>proc{|v| v * 2}) end
|
278
|
+
@model.instance_eval{@a=1; @b=[2]; @c={3=>[4]}; @d=10}
|
279
|
+
m = Class.new(@model)
|
280
|
+
@model.instance_eval{@a=5; @b << 6; @c[3] << 7; @c[8] = [9]; @d=40}
|
281
|
+
m.instance_eval do
|
282
|
+
@a.should == 1
|
283
|
+
@b.should == [2]
|
284
|
+
@c.should == {3=>[4]}
|
285
|
+
@d.should == 20
|
286
|
+
end
|
287
|
+
end
|
269
288
|
end
|
270
289
|
|
271
290
|
describe Sequel::Model, "constructors" do
|
@@ -621,8 +640,7 @@ describe "Model.db_schema" do
|
|
621
640
|
@dataset = @db[:items]
|
622
641
|
end
|
623
642
|
|
624
|
-
specify "should use the database's
|
625
|
-
d = @dataset.db
|
643
|
+
specify "should use the database's schema and set the columns and dataset columns" do
|
626
644
|
def @db.schema(table, opts = {})
|
627
645
|
[[:x, {:type=>:integer}], [:y, {:type=>:string}]]
|
628
646
|
end
|
data/spec/model/plugins_spec.rb
CHANGED
@@ -245,3 +245,74 @@ describe Sequel::Model, ".plugin" do
|
|
245
245
|
@c.plugins.should include(m)
|
246
246
|
end
|
247
247
|
end
|
248
|
+
|
249
|
+
describe Sequel::Plugins do
|
250
|
+
before do
|
251
|
+
@c = Class.new(Sequel::Model(:items))
|
252
|
+
end
|
253
|
+
|
254
|
+
it "should have def_dataset_methods define methods that call methods on the dataset" do
|
255
|
+
m = Module.new do
|
256
|
+
module self::ClassMethods
|
257
|
+
Sequel::Plugins.def_dataset_methods(self, :one)
|
258
|
+
end
|
259
|
+
module self::DatasetMethods
|
260
|
+
def one
|
261
|
+
1
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|
265
|
+
@c.plugin m
|
266
|
+
@c.one.should == 1
|
267
|
+
end
|
268
|
+
|
269
|
+
it "should have def_dataset_methods accept an array with multiple methods" do
|
270
|
+
m = Module.new do
|
271
|
+
module self::ClassMethods
|
272
|
+
Sequel::Plugins.def_dataset_methods(self, [:one, :two])
|
273
|
+
end
|
274
|
+
module self::DatasetMethods
|
275
|
+
def one
|
276
|
+
1
|
277
|
+
end
|
278
|
+
def two
|
279
|
+
2
|
280
|
+
end
|
281
|
+
end
|
282
|
+
end
|
283
|
+
@c.plugin m
|
284
|
+
@c.one.should == 1
|
285
|
+
@c.two.should == 2
|
286
|
+
end
|
287
|
+
|
288
|
+
it "should have inherited_instance_variables add instance variables to copy into the subclass" do
|
289
|
+
m = Module.new do
|
290
|
+
def self.apply(model)
|
291
|
+
model.instance_variable_set(:@one, 1)
|
292
|
+
end
|
293
|
+
module self::ClassMethods
|
294
|
+
attr_reader :one
|
295
|
+
Sequel::Plugins.inherited_instance_variables(self, :@one=>nil)
|
296
|
+
end
|
297
|
+
end
|
298
|
+
@c.plugin m
|
299
|
+
Class.new(@c).one.should == 1
|
300
|
+
end
|
301
|
+
|
302
|
+
it "should have after_set_dataset add a method to call after set_dataset" do
|
303
|
+
m = Module.new do
|
304
|
+
module self::ClassMethods
|
305
|
+
Sequel::Plugins.after_set_dataset(self, :one)
|
306
|
+
private
|
307
|
+
def one
|
308
|
+
dataset.opts[:foo] = 1
|
309
|
+
end
|
310
|
+
end
|
311
|
+
end
|
312
|
+
@c.plugin m
|
313
|
+
@c.dataset.opts[:foo].should == nil
|
314
|
+
@c.set_dataset :blah
|
315
|
+
@c.dataset.opts[:foo].should == 1
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
data/spec/model/record_spec.rb
CHANGED
@@ -367,6 +367,12 @@ describe "Model#freeze" do
|
|
367
367
|
@o.frozen?.should be_true
|
368
368
|
end
|
369
369
|
|
370
|
+
it "should freeze the object if the model doesn't have a primary key" do
|
371
|
+
Album.no_primary_key
|
372
|
+
@o = Album.load(:id=>1).freeze
|
373
|
+
@o.frozen?.should be_true
|
374
|
+
end
|
375
|
+
|
370
376
|
it "should freeze the object's values, associations, changed_columns, errors, and this" do
|
371
377
|
@o.values.frozen?.should be_true
|
372
378
|
@o.changed_columns.frozen?.should be_true
|
@@ -433,7 +439,7 @@ describe "Model#marshallable" do
|
|
433
439
|
end
|
434
440
|
end
|
435
441
|
|
436
|
-
describe "Model#modified
|
442
|
+
describe "Model#modified?" do
|
437
443
|
before do
|
438
444
|
@c = Class.new(Sequel::Model(:items))
|
439
445
|
@c.class_eval do
|
@@ -483,8 +489,47 @@ describe "Model#modified[!?]" do
|
|
483
489
|
o.x = '2'
|
484
490
|
o.modified?.should == true
|
485
491
|
end
|
492
|
+
|
493
|
+
it "should be true if given a column argument and the column has been changed" do
|
494
|
+
o = @c.new
|
495
|
+
o.modified?(:id).should be_false
|
496
|
+
o.id = 1
|
497
|
+
o.modified?(:id).should be_true
|
498
|
+
end
|
486
499
|
end
|
487
500
|
|
501
|
+
describe "Model#modified!" do
|
502
|
+
before do
|
503
|
+
@c = Class.new(Sequel::Model(:items))
|
504
|
+
@c.class_eval do
|
505
|
+
columns :id, :x
|
506
|
+
end
|
507
|
+
MODEL_DB.reset
|
508
|
+
end
|
509
|
+
|
510
|
+
it "should mark the object as modified so that save_changes still runs the callbacks" do
|
511
|
+
o = @c.load(:id=>1, :x=>2)
|
512
|
+
def o.after_save
|
513
|
+
values[:x] = 3
|
514
|
+
end
|
515
|
+
o.update({})
|
516
|
+
o.x.should == 2
|
517
|
+
|
518
|
+
o.modified!
|
519
|
+
o.update({})
|
520
|
+
o.x.should == 3
|
521
|
+
o.db.sqls.should == []
|
522
|
+
end
|
523
|
+
|
524
|
+
it "should mark given column argument as modified" do
|
525
|
+
o = @c.load(:id=>1, :x=>2)
|
526
|
+
o.modified!(:x)
|
527
|
+
o.changed_columns.should == [:x]
|
528
|
+
o.save
|
529
|
+
o.db.sqls.should == ["UPDATE items SET x = 2 WHERE (id = 1)"]
|
530
|
+
end
|
531
|
+
end
|
532
|
+
|
488
533
|
describe "Model#save_changes" do
|
489
534
|
before do
|
490
535
|
@c = Class.new(Sequel::Model(:items)) do
|
@@ -618,8 +663,8 @@ describe "Model#new?" do
|
|
618
663
|
end
|
619
664
|
end
|
620
665
|
|
621
|
-
describe Sequel::Model, "
|
622
|
-
it "should default to
|
666
|
+
describe Sequel::Model, "with a primary key" do
|
667
|
+
it "should default to :id" do
|
623
668
|
model_a = Class.new Sequel::Model
|
624
669
|
model_a.primary_key.should == :id
|
625
670
|
end
|
@@ -640,7 +685,7 @@ describe Sequel::Model, "w/ primary key" do
|
|
640
685
|
end
|
641
686
|
end
|
642
687
|
|
643
|
-
describe Sequel::Model, "
|
688
|
+
describe Sequel::Model, "without a primary key" do
|
644
689
|
it "should return nil for primary key" do
|
645
690
|
Class.new(Sequel::Model){no_primary_key}.primary_key.should be_nil
|
646
691
|
end
|
@@ -651,7 +696,7 @@ describe Sequel::Model, "w/o primary key" do
|
|
651
696
|
end
|
652
697
|
end
|
653
698
|
|
654
|
-
describe Sequel::Model, "
|
699
|
+
describe Sequel::Model, "#this" do
|
655
700
|
before do
|
656
701
|
@example = Class.new(Sequel::Model(:examples))
|
657
702
|
@example.columns :id, :a, :x, :y
|
@@ -682,18 +727,18 @@ describe "Model#pk" do
|
|
682
727
|
@m.columns :id, :x, :y
|
683
728
|
end
|
684
729
|
|
685
|
-
it "should
|
730
|
+
it "should by default return the value of the :id column" do
|
686
731
|
m = @m.load(:id => 111, :x => 2, :y => 3)
|
687
732
|
m.pk.should == 111
|
688
733
|
end
|
689
734
|
|
690
|
-
it "should
|
735
|
+
it "should return the primary key value for custom primary key" do
|
691
736
|
@m.set_primary_key :x
|
692
737
|
m = @m.load(:id => 111, :x => 2, :y => 3)
|
693
738
|
m.pk.should == 2
|
694
739
|
end
|
695
740
|
|
696
|
-
it "should
|
741
|
+
it "should return the primary key value for composite primary key" do
|
697
742
|
@m.set_primary_key [:y, :x]
|
698
743
|
m = @m.load(:id => 111, :x => 2, :y => 3)
|
699
744
|
m.pk.should == [3, 2]
|
@@ -716,18 +761,18 @@ describe "Model#pk_hash" do
|
|
716
761
|
@m.columns :id, :x, :y
|
717
762
|
end
|
718
763
|
|
719
|
-
it "should
|
764
|
+
it "should by default return a hash with the value of the :id column" do
|
720
765
|
m = @m.load(:id => 111, :x => 2, :y => 3)
|
721
766
|
m.pk_hash.should == {:id => 111}
|
722
767
|
end
|
723
768
|
|
724
|
-
it "should
|
769
|
+
it "should return a hash with the primary key value for custom primary key" do
|
725
770
|
@m.set_primary_key :x
|
726
771
|
m = @m.load(:id => 111, :x => 2, :y => 3)
|
727
772
|
m.pk_hash.should == {:x => 2}
|
728
773
|
end
|
729
774
|
|
730
|
-
it "should
|
775
|
+
it "should return a hash with the primary key values for composite primary key" do
|
731
776
|
@m.set_primary_key [:y, :x]
|
732
777
|
m = @m.load(:id => 111, :x => 2, :y => 3)
|
733
778
|
m.pk_hash.should == {:y => 3, :x => 2}
|
@@ -918,7 +963,6 @@ describe Sequel::Model, "#set_fields" do
|
|
918
963
|
set_primary_key :id
|
919
964
|
columns :x, :y, :z, :id
|
920
965
|
end
|
921
|
-
@c.strict_param_setting = true
|
922
966
|
@o1 = @c.new
|
923
967
|
MODEL_DB.reset
|
924
968
|
end
|
@@ -967,6 +1011,29 @@ describe Sequel::Model, "#set_fields" do
|
|
967
1011
|
MODEL_DB.sqls.should == []
|
968
1012
|
end
|
969
1013
|
|
1014
|
+
it "should respect model's default_set_fields_options" do
|
1015
|
+
@c.default_set_fields_options = {:missing=>:skip}
|
1016
|
+
@o1.set_fields({:x => 3}, [:x, :y])
|
1017
|
+
@o1.values.should == {:x => 3}
|
1018
|
+
@o1.set_fields({:x => 4}, [:x, :y], {})
|
1019
|
+
@o1.values.should == {:x => 4}
|
1020
|
+
proc{@o1.set_fields({:x => 3}, [:x, :y], :missing=>:raise)}.should raise_error(Sequel::Error)
|
1021
|
+
@c.default_set_fields_options = {:missing=>:raise}
|
1022
|
+
proc{@o1.set_fields({:x => 3}, [:x, :y])}.should raise_error(Sequel::Error)
|
1023
|
+
proc{@o1.set_fields({:x => 3}, [:x, :y], {})}.should raise_error(Sequel::Error)
|
1024
|
+
@o1.set_fields({:x => 5}, [:x, :y], :missing=>:skip)
|
1025
|
+
@o1.values.should == {:x => 5}
|
1026
|
+
@o1.set_fields({:x => 5}, [:x, :y], :missing=>nil)
|
1027
|
+
@o1.values.should == {:x => 5, :y=>nil}
|
1028
|
+
MODEL_DB.sqls.should == []
|
1029
|
+
end
|
1030
|
+
|
1031
|
+
it "should respect model's default_set_fields_options in a subclass" do
|
1032
|
+
@c.default_set_fields_options = {:missing=>:skip}
|
1033
|
+
o = Class.new(@c).new
|
1034
|
+
o.set_fields({:x => 3}, [:x, :y])
|
1035
|
+
o.values.should == {:x => 3}
|
1036
|
+
end
|
970
1037
|
end
|
971
1038
|
|
972
1039
|
describe Sequel::Model, "#update_fields" do
|
@@ -1001,6 +1068,17 @@ describe Sequel::Model, "#update_fields" do
|
|
1001
1068
|
it "should support :missing=>:raise option" do
|
1002
1069
|
proc{@o1.update_fields({:x => 1}, [:x, :y], :missing=>:raise)}.should raise_error(Sequel::Error)
|
1003
1070
|
end
|
1071
|
+
|
1072
|
+
it "should respect model's default_set_fields_options" do
|
1073
|
+
@c.default_set_fields_options = {:missing=>:skip}
|
1074
|
+
@o1.update_fields({:x => 3}, [:x, :y])
|
1075
|
+
@o1.values.should == {:x => 3, :id=>1}
|
1076
|
+
MODEL_DB.sqls.should == ["UPDATE items SET x = 3 WHERE (id = 1)"]
|
1077
|
+
|
1078
|
+
@c.default_set_fields_options = {:missing=>:raise}
|
1079
|
+
proc{@o1.update_fields({:x => 3}, [:x, :y])}.should raise_error(Sequel::Error)
|
1080
|
+
MODEL_DB.sqls.should == []
|
1081
|
+
end
|
1004
1082
|
end
|
1005
1083
|
|
1006
1084
|
describe Sequel::Model, "#(set|update)_(all|except|only)" do
|
@@ -1449,7 +1527,7 @@ describe Sequel::Model, ".create" do
|
|
1449
1527
|
MODEL_DB.sqls.should == ["INSERT INTO items DEFAULT VALUES", "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
|
1450
1528
|
end
|
1451
1529
|
|
1452
|
-
it "should accept a block and
|
1530
|
+
it "should accept a block and call it" do
|
1453
1531
|
o1, o2, o3 = nil, nil, nil
|
1454
1532
|
o = @c.create {|o4| o1 = o4; o3 = o4; o2 = :blah; o3.x = 333}
|
1455
1533
|
o.class.should == @c
|
@@ -1886,3 +1964,11 @@ describe "Model#lock!" do
|
|
1886
1964
|
MODEL_DB.sqls.should == ["SELECT * FROM items WHERE (id = 1) LIMIT 1 FOR UPDATE"]
|
1887
1965
|
end
|
1888
1966
|
end
|
1967
|
+
|
1968
|
+
describe "Model#schema_type_class" do
|
1969
|
+
specify "should return the class or array of classes for the given type symbol" do
|
1970
|
+
@c = Class.new(Sequel::Model(:items))
|
1971
|
+
@c.class_eval{@db_schema = {:id=>{:type=>:integer}}}
|
1972
|
+
@c.new.send(:schema_type_class, :id).should == Integer
|
1973
|
+
end
|
1974
|
+
end
|