sequel 3.46.0 → 3.47.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.
Files changed (170) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +96 -0
  3. data/Rakefile +7 -1
  4. data/bin/sequel +6 -4
  5. data/doc/active_record.rdoc +1 -1
  6. data/doc/advanced_associations.rdoc +14 -35
  7. data/doc/association_basics.rdoc +66 -4
  8. data/doc/migration.rdoc +4 -0
  9. data/doc/opening_databases.rdoc +6 -0
  10. data/doc/postgresql.rdoc +302 -0
  11. data/doc/release_notes/3.47.0.txt +270 -0
  12. data/doc/security.rdoc +6 -0
  13. data/lib/sequel/adapters/ibmdb.rb +9 -9
  14. data/lib/sequel/adapters/jdbc.rb +22 -7
  15. data/lib/sequel/adapters/jdbc/postgresql.rb +7 -2
  16. data/lib/sequel/adapters/mock.rb +2 -0
  17. data/lib/sequel/adapters/postgres.rb +44 -13
  18. data/lib/sequel/adapters/shared/mssql.rb +1 -1
  19. data/lib/sequel/adapters/shared/mysql.rb +2 -2
  20. data/lib/sequel/adapters/shared/postgres.rb +94 -55
  21. data/lib/sequel/adapters/shared/sqlite.rb +3 -1
  22. data/lib/sequel/adapters/sqlite.rb +2 -2
  23. data/lib/sequel/adapters/utils/pg_types.rb +1 -14
  24. data/lib/sequel/adapters/utils/split_alter_table.rb +3 -3
  25. data/lib/sequel/connection_pool/threaded.rb +1 -1
  26. data/lib/sequel/core.rb +1 -1
  27. data/lib/sequel/database/connecting.rb +2 -2
  28. data/lib/sequel/database/features.rb +5 -0
  29. data/lib/sequel/database/misc.rb +47 -5
  30. data/lib/sequel/database/query.rb +2 -2
  31. data/lib/sequel/dataset/actions.rb +4 -2
  32. data/lib/sequel/dataset/misc.rb +1 -1
  33. data/lib/sequel/dataset/prepared_statements.rb +1 -1
  34. data/lib/sequel/dataset/query.rb +8 -6
  35. data/lib/sequel/dataset/sql.rb +8 -6
  36. data/lib/sequel/extensions/constraint_validations.rb +5 -2
  37. data/lib/sequel/extensions/migration.rb +10 -8
  38. data/lib/sequel/extensions/pagination.rb +3 -0
  39. data/lib/sequel/extensions/pg_array.rb +85 -25
  40. data/lib/sequel/extensions/pg_hstore.rb +8 -1
  41. data/lib/sequel/extensions/pg_hstore_ops.rb +4 -1
  42. data/lib/sequel/extensions/pg_inet.rb +16 -13
  43. data/lib/sequel/extensions/pg_interval.rb +6 -2
  44. data/lib/sequel/extensions/pg_json.rb +18 -11
  45. data/lib/sequel/extensions/pg_range.rb +17 -2
  46. data/lib/sequel/extensions/pg_range_ops.rb +7 -5
  47. data/lib/sequel/extensions/pg_row.rb +29 -12
  48. data/lib/sequel/extensions/pretty_table.rb +3 -0
  49. data/lib/sequel/extensions/query.rb +3 -0
  50. data/lib/sequel/extensions/schema_caching.rb +2 -0
  51. data/lib/sequel/extensions/schema_dumper.rb +3 -1
  52. data/lib/sequel/extensions/select_remove.rb +3 -0
  53. data/lib/sequel/model.rb +8 -2
  54. data/lib/sequel/model/associations.rb +39 -27
  55. data/lib/sequel/model/base.rb +99 -38
  56. data/lib/sequel/model/plugins.rb +25 -0
  57. data/lib/sequel/plugins/association_autoreloading.rb +27 -22
  58. data/lib/sequel/plugins/association_dependencies.rb +1 -7
  59. data/lib/sequel/plugins/auto_validations.rb +110 -0
  60. data/lib/sequel/plugins/boolean_readers.rb +1 -6
  61. data/lib/sequel/plugins/caching.rb +6 -13
  62. data/lib/sequel/plugins/class_table_inheritance.rb +1 -0
  63. data/lib/sequel/plugins/composition.rb +14 -7
  64. data/lib/sequel/plugins/constraint_validations.rb +2 -13
  65. data/lib/sequel/plugins/defaults_setter.rb +1 -6
  66. data/lib/sequel/plugins/dirty.rb +8 -0
  67. data/lib/sequel/plugins/error_splitter.rb +54 -0
  68. data/lib/sequel/plugins/force_encoding.rb +1 -5
  69. data/lib/sequel/plugins/hook_class_methods.rb +1 -6
  70. data/lib/sequel/plugins/input_transformer.rb +79 -0
  71. data/lib/sequel/plugins/instance_filters.rb +7 -1
  72. data/lib/sequel/plugins/instance_hooks.rb +7 -1
  73. data/lib/sequel/plugins/json_serializer.rb +5 -10
  74. data/lib/sequel/plugins/lazy_attributes.rb +20 -7
  75. data/lib/sequel/plugins/list.rb +1 -6
  76. data/lib/sequel/plugins/many_through_many.rb +1 -2
  77. data/lib/sequel/plugins/many_to_one_pk_lookup.rb +23 -39
  78. data/lib/sequel/plugins/optimistic_locking.rb +1 -5
  79. data/lib/sequel/plugins/pg_row.rb +4 -2
  80. data/lib/sequel/plugins/pg_typecast_on_load.rb +3 -7
  81. data/lib/sequel/plugins/prepared_statements.rb +1 -5
  82. data/lib/sequel/plugins/prepared_statements_safe.rb +2 -11
  83. data/lib/sequel/plugins/rcte_tree.rb +2 -2
  84. data/lib/sequel/plugins/serialization.rb +11 -13
  85. data/lib/sequel/plugins/serialization_modification_detection.rb +13 -1
  86. data/lib/sequel/plugins/single_table_inheritance.rb +4 -4
  87. data/lib/sequel/plugins/static_cache.rb +67 -19
  88. data/lib/sequel/plugins/string_stripper.rb +7 -27
  89. data/lib/sequel/plugins/subclasses.rb +3 -5
  90. data/lib/sequel/plugins/tactical_eager_loading.rb +2 -2
  91. data/lib/sequel/plugins/timestamps.rb +2 -7
  92. data/lib/sequel/plugins/touch.rb +5 -8
  93. data/lib/sequel/plugins/tree.rb +1 -6
  94. data/lib/sequel/plugins/typecast_on_load.rb +1 -5
  95. data/lib/sequel/plugins/update_primary_key.rb +26 -14
  96. data/lib/sequel/plugins/validation_class_methods.rb +31 -16
  97. data/lib/sequel/plugins/validation_helpers.rb +50 -26
  98. data/lib/sequel/plugins/xml_serializer.rb +3 -6
  99. data/lib/sequel/sql.rb +1 -1
  100. data/lib/sequel/version.rb +1 -1
  101. data/spec/adapters/postgres_spec.rb +131 -15
  102. data/spec/adapters/sqlite_spec.rb +1 -1
  103. data/spec/core/connection_pool_spec.rb +16 -17
  104. data/spec/core/database_spec.rb +111 -40
  105. data/spec/core/dataset_spec.rb +65 -74
  106. data/spec/core/expression_filters_spec.rb +6 -5
  107. data/spec/core/object_graph_spec.rb +0 -1
  108. data/spec/core/schema_spec.rb +23 -23
  109. data/spec/core/spec_helper.rb +5 -1
  110. data/spec/extensions/association_dependencies_spec.rb +1 -1
  111. data/spec/extensions/association_proxies_spec.rb +1 -1
  112. data/spec/extensions/auto_validations_spec.rb +90 -0
  113. data/spec/extensions/caching_spec.rb +6 -0
  114. data/spec/extensions/class_table_inheritance_spec.rb +8 -1
  115. data/spec/extensions/composition_spec.rb +12 -5
  116. data/spec/extensions/constraint_validations_spec.rb +4 -4
  117. data/spec/extensions/core_refinements_spec.rb +29 -79
  118. data/spec/extensions/dirty_spec.rb +14 -0
  119. data/spec/extensions/error_splitter_spec.rb +18 -0
  120. data/spec/extensions/identity_map_spec.rb +0 -1
  121. data/spec/extensions/input_transformer_spec.rb +54 -0
  122. data/spec/extensions/instance_filters_spec.rb +6 -0
  123. data/spec/extensions/instance_hooks_spec.rb +12 -1
  124. data/spec/extensions/json_serializer_spec.rb +0 -1
  125. data/spec/extensions/lazy_attributes_spec.rb +64 -55
  126. data/spec/extensions/looser_typecasting_spec.rb +1 -1
  127. data/spec/extensions/many_through_many_spec.rb +3 -4
  128. data/spec/extensions/many_to_one_pk_lookup_spec.rb +53 -15
  129. data/spec/extensions/migration_spec.rb +16 -0
  130. data/spec/extensions/null_dataset_spec.rb +1 -1
  131. data/spec/extensions/pg_array_spec.rb +48 -1
  132. data/spec/extensions/pg_hstore_ops_spec.rb +10 -2
  133. data/spec/extensions/pg_hstore_spec.rb +5 -0
  134. data/spec/extensions/pg_inet_spec.rb +5 -0
  135. data/spec/extensions/pg_interval_spec.rb +7 -3
  136. data/spec/extensions/pg_json_spec.rb +6 -1
  137. data/spec/extensions/pg_range_ops_spec.rb +4 -1
  138. data/spec/extensions/pg_range_spec.rb +5 -0
  139. data/spec/extensions/pg_row_plugin_spec.rb +13 -0
  140. data/spec/extensions/pg_row_spec.rb +28 -19
  141. data/spec/extensions/pg_typecast_on_load_spec.rb +6 -1
  142. data/spec/extensions/prepared_statements_associations_spec.rb +1 -1
  143. data/spec/extensions/query_literals_spec.rb +1 -1
  144. data/spec/extensions/rcte_tree_spec.rb +2 -2
  145. data/spec/extensions/schema_spec.rb +2 -2
  146. data/spec/extensions/serialization_modification_detection_spec.rb +8 -0
  147. data/spec/extensions/serialization_spec.rb +15 -1
  148. data/spec/extensions/sharding_spec.rb +1 -1
  149. data/spec/extensions/single_table_inheritance_spec.rb +1 -1
  150. data/spec/extensions/static_cache_spec.rb +59 -9
  151. data/spec/extensions/tactical_eager_loading_spec.rb +19 -4
  152. data/spec/extensions/update_primary_key_spec.rb +17 -1
  153. data/spec/extensions/validation_class_methods_spec.rb +25 -0
  154. data/spec/extensions/validation_helpers_spec.rb +59 -3
  155. data/spec/integration/associations_test.rb +5 -5
  156. data/spec/integration/eager_loader_test.rb +32 -63
  157. data/spec/integration/model_test.rb +2 -2
  158. data/spec/integration/plugin_test.rb +88 -56
  159. data/spec/integration/prepared_statement_test.rb +1 -1
  160. data/spec/integration/schema_test.rb +1 -1
  161. data/spec/integration/timezone_test.rb +0 -1
  162. data/spec/integration/transaction_test.rb +0 -1
  163. data/spec/model/association_reflection_spec.rb +1 -1
  164. data/spec/model/associations_spec.rb +106 -84
  165. data/spec/model/base_spec.rb +4 -4
  166. data/spec/model/eager_loading_spec.rb +8 -8
  167. data/spec/model/model_spec.rb +27 -9
  168. data/spec/model/plugins_spec.rb +71 -0
  169. data/spec/model/record_spec.rb +99 -13
  170. metadata +12 -2
@@ -136,7 +136,7 @@ describe Sequel::Model::Associations::AssociationReflection, "#select" do
136
136
  @c.association_reflection(:cs).keys.should_not include(:select)
137
137
  @c.association_reflection(:cs).select.should == Sequel::SQL::ColumnAll.new(:par_parents)
138
138
  end
139
- it "should be if :select is not present for a many_to_one and one_to_many associaiton" do
139
+ it "should be blank if :select is not present for a many_to_one and one_to_many associaiton" do
140
140
  @c.one_to_many :cs, :class=>'ParParent'
141
141
  @c.association_reflection(:cs).keys.should_not include(:select)
142
142
  @c.association_reflection(:cs).select.should == nil
@@ -200,7 +200,7 @@ describe Sequel::Model, "many_to_one" do
200
200
  MODEL_DB.sqls.should == ["SELECT * FROM nodes WHERE (nodes.id = 234) LIMIT 1"]
201
201
  end
202
202
 
203
- it "should allow association with the same name as the key if :key_alias is given" do
203
+ it "should allow association with the same name as the key if :key_column is given" do
204
204
  @c2.def_column_alias(:parent_id_id, :parent_id)
205
205
  @c2.many_to_one :parent_id, :key_column=>:parent_id, :class => @c2
206
206
  d = @c2.load(:id => 1, :parent_id => 234)
@@ -378,7 +378,7 @@ describe Sequel::Model, "many_to_one" do
378
378
  MODEL_DB.sqls.should == ['UPDATE nodes SET parent_id = 345 WHERE (id = 1)']
379
379
  end
380
380
 
381
- it "should set cached instance variable when accessed" do
381
+ it "should populate cache when accessed" do
382
382
  @c2.many_to_one :parent, :class => @c2
383
383
 
384
384
  d = @c2.load(:id => 1)
@@ -390,7 +390,7 @@ describe Sequel::Model, "many_to_one" do
390
390
  d.associations[:parent].should == e
391
391
  end
392
392
 
393
- it "should set cached instance variable when assigned" do
393
+ it "should populate cache when assigned" do
394
394
  @c2.many_to_one :parent, :class => @c2
395
395
 
396
396
  d = @c2.create(:id => 1)
@@ -402,7 +402,7 @@ describe Sequel::Model, "many_to_one" do
402
402
  MODEL_DB.sqls.should == []
403
403
  end
404
404
 
405
- it "should use cached instance variable if available" do
405
+ it "should use cache if available" do
406
406
  @c2.many_to_one :parent, :class => @c2
407
407
 
408
408
  d = @c2.create(:id => 1, :parent_id => 234)
@@ -412,7 +412,7 @@ describe Sequel::Model, "many_to_one" do
412
412
  MODEL_DB.sqls.should == []
413
413
  end
414
414
 
415
- it "should not use cached instance variable if asked to reload" do
415
+ it "should not use cache if asked to reload" do
416
416
  @c2.many_to_one :parent, :class => @c2
417
417
 
418
418
  d = @c2.create(:id => 1)
@@ -445,7 +445,7 @@ describe Sequel::Model, "many_to_one" do
445
445
  MODEL_DB.sqls.should == ["SELECT * FROM nodes WHERE ((nodes.id = 234) AND (name > 'M')) LIMIT 1"]
446
446
  end
447
447
 
448
- it "should have the setter add to the reciprocal one_to_many cached association list if it exists" do
448
+ it "should have the setter add to the reciprocal one_to_many cached association array if it exists" do
449
449
  @c2.many_to_one :parent, :class => @c2
450
450
  @c2.one_to_many :children, :class => @c2, :key=>:parent_id
451
451
  @c2.dataset._fetch = []
@@ -466,7 +466,7 @@ describe Sequel::Model, "many_to_one" do
466
466
  MODEL_DB.sqls.should == []
467
467
  end
468
468
 
469
- it "should have many_to_one setter deal with a one_to_one reciprocal" do
469
+ it "should have setter deal with a one_to_one reciprocal" do
470
470
  @c2.many_to_one :parent, :class => @c2, :key=>:parent_id
471
471
  @c2.one_to_one :child, :class => @c2, :key=>:parent_id
472
472
 
@@ -488,7 +488,7 @@ describe Sequel::Model, "many_to_one" do
488
488
  e.child.should == d
489
489
  end
490
490
 
491
- it "should have the setter remove the object from the previous associated object's reciprocal one_to_many cached association list if it exists" do
491
+ it "should have the setter remove the object from the previous associated object's reciprocal one_to_many cached association array if it exists" do
492
492
  @c2.many_to_one :parent, :class => @c2
493
493
  @c2.one_to_many :children, :class => @c2, :key=>:parent_id
494
494
  @c2.dataset._fetch = []
@@ -583,6 +583,15 @@ describe Sequel::Model, "many_to_one" do
583
583
  p.instance_variable_get(:@x).should == c
584
584
  end
585
585
 
586
+ it "should have the :setter option define the _association= method" do
587
+ @c2.many_to_one :parent, :class => @c2, :setter=>proc{|x| @x = x}
588
+ p = @c2.new
589
+ c = @c2.load(:id=>123)
590
+ p.should_not_receive(:parent_id=)
591
+ p.parent = c
592
+ p.instance_variable_get(:@x).should == c
593
+ end
594
+
586
595
  it "should support (before|after)_set callbacks" do
587
596
  h = []
588
597
  @c2.many_to_one :parent, :class => @c2, :before_set=>[proc{|x,y| h << x.pk; h << (y ? -y.pk : :y)}, :blah], :after_set=>proc{h << 3}
@@ -656,28 +665,6 @@ describe Sequel::Model, "many_to_one" do
656
665
  @c2.many_to_one :parent, :class => @c2, :before_set=>Object.new
657
666
  proc{@c2.new.parent = @c2.load(:id=>1)}.should raise_error(Sequel::Error)
658
667
  end
659
-
660
- it "should call the remove callbacks for the previous object and the add callbacks for the new object" do
661
- c = @c2.load(:id=>123)
662
- d = @c2.load(:id=>321)
663
- p = @c2.new
664
- p.associations[:parent] = d
665
- @c2.many_to_one :parent, :class => @c2, :before_set=>:bs, :after_set=>:as
666
- @c2.class_eval do
667
- self::Foo = []
668
- def []=(a, v)
669
- a == :parent_id ? (model::Foo << 5) : super
670
- end
671
- def bs(x)
672
- model::Foo << x.pk
673
- end
674
- def as(x)
675
- model::Foo << x.pk * 2
676
- end
677
- end
678
- p.parent = c
679
- @c2::Foo.should == [123, 5, 246]
680
- end
681
668
  end
682
669
 
683
670
  describe Sequel::Model, "one_to_one" do
@@ -918,7 +905,7 @@ describe Sequel::Model, "one_to_one" do
918
905
  "UPDATE nodes SET node_id = 1 WHERE (id = 3)"]
919
906
  end
920
907
 
921
- it "should set cached instance variable when accessed" do
908
+ it "should populate cache when accessed" do
922
909
  @c2.one_to_one :parent, :class => @c2
923
910
 
924
911
  d = @c2.load(:id => 1)
@@ -931,7 +918,7 @@ describe Sequel::Model, "one_to_one" do
931
918
  d.associations[:parent].should == e
932
919
  end
933
920
 
934
- it "should set cached instance variable when assigned" do
921
+ it "should populate cache when assigned" do
935
922
  @c2.one_to_one :parent, :class => @c2
936
923
 
937
924
  d = @c2.load(:id => 1)
@@ -943,7 +930,7 @@ describe Sequel::Model, "one_to_one" do
943
930
  e.should == f
944
931
  end
945
932
 
946
- it "should use cached instance variable if available" do
933
+ it "should use cache if available" do
947
934
  @c2.one_to_one :parent, :class => @c2
948
935
  d = @c2.load(:id => 1, :parent_id => 234)
949
936
  d.associations[:parent] = 42
@@ -951,7 +938,7 @@ describe Sequel::Model, "one_to_one" do
951
938
  MODEL_DB.sqls.should == []
952
939
  end
953
940
 
954
- it "should not use cached instance variable if asked to reload" do
941
+ it "should not use cache if asked to reload" do
955
942
  @c2.one_to_one :parent, :class => @c2
956
943
  d = @c2.load(:id => 1)
957
944
  d.associations[:parent] = [42]
@@ -974,7 +961,7 @@ describe Sequel::Model, "one_to_one" do
974
961
  MODEL_DB.sqls.should == ["UPDATE nodes SET parent_id = NULL WHERE (parent_id = 1)"]
975
962
  end
976
963
 
977
- it "should have the setter remove the object from the previous associated object's reciprocal many_to_one cached association list if it exists" do
964
+ it "should have the setter remove the object from the previous associated object's reciprocal many_to_one cached association array if it exists" do
978
965
  @c2.one_to_one :parent, :class => @c2, :key=>:parent_id
979
966
  @c2.many_to_one :child, :class => @c2, :key=>:parent_id
980
967
  @c2.dataset._fetch = []
@@ -1034,6 +1021,15 @@ describe Sequel::Model, "one_to_one" do
1034
1021
  p.instance_variable_get(:@x).should == c
1035
1022
  end
1036
1023
 
1024
+ it "should have a :setter option define the _association= method" do
1025
+ @c2.one_to_one :parent, :class => @c2, :setter=>proc{|x| @x = x}
1026
+ c = @c2.new
1027
+ p = @c2.load(:id=>123)
1028
+ p.should_not_receive(:parent_id=)
1029
+ p.parent = c
1030
+ p.instance_variable_get(:@x).should == c
1031
+ end
1032
+
1037
1033
  it "should support (before|after)_set callbacks" do
1038
1034
  h = []
1039
1035
  @c2.one_to_one :parent, :class => @c2, :before_set=>[proc{|x,y| h << x.pk; h << (y ? -y.pk : :y)}, :blah], :after_set=>proc{h << 3}
@@ -1093,29 +1089,6 @@ describe Sequel::Model, "one_to_one" do
1093
1089
  proc{@c2.new.parent = @c2.load(:id=>1)}.should raise_error(Sequel::Error)
1094
1090
  end
1095
1091
 
1096
- it "should call the set callbacks" do
1097
- c = @c2.load(:id=>123)
1098
- d = @c2.load(:id=>321)
1099
- p = @c2.load(:id=>32)
1100
- p.associations[:parent] = [d]
1101
- h = []
1102
- @c2.one_to_one :parent, :class => @c2, :before_set=>:bs, :after_set=>:as
1103
- @c2.class_eval do
1104
- self::Foo = h
1105
- def []=(a, v)
1106
- a == :node_id ? (model::Foo << 5) : super
1107
- end
1108
- def bs(x)
1109
- model::Foo << x.pk
1110
- end
1111
- def as(x)
1112
- model::Foo << x.pk * 2
1113
- end
1114
- end
1115
- p.parent = c
1116
- h.should == [123, 5, 246]
1117
- end
1118
-
1119
1092
  it "should work_correctly when used with associate" do
1120
1093
  @c2.associate :one_to_one, :parent, :class => @c2
1121
1094
  @c2.load(:id => 567).parent.should == @c2.load({})
@@ -1419,21 +1392,21 @@ describe Sequel::Model, "one_to_many" do
1419
1392
  @c2.new(:id => 1234).attributes_dataset.sql.should == "SELECT * FROM attributes WHERE (attributes.node_id = 1234) ORDER BY kind1, kind2"
1420
1393
  end
1421
1394
 
1422
- it "should return array with all members of the association" do
1395
+ it "should have a dataset method for the associated object dataset" do
1423
1396
  @c2.one_to_many :attributes, :class => @c1
1424
1397
  @c2.new(:id => 1234).attributes_dataset.sql.should == 'SELECT * FROM attributes WHERE (attributes.node_id = 1234)'
1425
1398
  end
1426
1399
 
1427
1400
  it "should accept a block" do
1428
1401
  @c2.one_to_many :attributes, :class => @c1 do |ds|
1429
- ds.filter(:xxx => @xxx)
1402
+ ds.filter(:xxx => nil)
1430
1403
  end
1431
1404
  @c2.new(:id => 1234).attributes_dataset.sql.should == 'SELECT * FROM attributes WHERE ((attributes.node_id = 1234) AND (xxx IS NULL))'
1432
1405
  end
1433
1406
 
1434
1407
  it "should support :order option with block" do
1435
1408
  @c2.one_to_many :attributes, :class => @c1, :order => :kind do |ds|
1436
- ds.filter(:xxx => @xxx)
1409
+ ds.filter(:xxx => nil)
1437
1410
  end
1438
1411
  @c2.new(:id => 1234).attributes_dataset.sql.should == 'SELECT * FROM attributes WHERE ((attributes.node_id = 1234) AND (xxx IS NULL)) ORDER BY kind'
1439
1412
  end
@@ -1467,7 +1440,7 @@ describe Sequel::Model, "one_to_many" do
1467
1440
  @c2.new(:id => 1234).attributes_dataset.opts[:eager].should == {:attributes=>nil}
1468
1441
  end
1469
1442
 
1470
- it "should set cached instance variable when accessed" do
1443
+ it "should populate cache when accessed" do
1471
1444
  @c2.one_to_many :attributes, :class => @c1
1472
1445
  n = @c2.new(:id => 1234)
1473
1446
  n.associations.include?(:attributes).should == false
@@ -1476,7 +1449,7 @@ describe Sequel::Model, "one_to_many" do
1476
1449
  MODEL_DB.sqls.should == ['SELECT * FROM attributes WHERE (attributes.node_id = 1234)']
1477
1450
  end
1478
1451
 
1479
- it "should use cached instance variable if available" do
1452
+ it "should use cache if available" do
1480
1453
  @c2.one_to_many :attributes, :class => @c1
1481
1454
  n = @c2.new(:id => 1234)
1482
1455
  n.associations[:attributes] = 42
@@ -1484,7 +1457,7 @@ describe Sequel::Model, "one_to_many" do
1484
1457
  MODEL_DB.sqls.should == []
1485
1458
  end
1486
1459
 
1487
- it "should not use cached instance variable if asked to reload" do
1460
+ it "should not use cache if asked to reload" do
1488
1461
  @c2.one_to_many :attributes, :class => @c1
1489
1462
  n = @c2.new(:id => 1234)
1490
1463
  n.associations[:attributes] = 42
@@ -1492,7 +1465,7 @@ describe Sequel::Model, "one_to_many" do
1492
1465
  MODEL_DB.sqls.should == ['SELECT * FROM attributes WHERE (attributes.node_id = 1234)']
1493
1466
  end
1494
1467
 
1495
- it "should add item to cached instance variable if it exists when calling add_" do
1468
+ it "should add item to cache if it exists when calling add_" do
1496
1469
  @c2.one_to_many :attributes, :class => @c1
1497
1470
  n = @c2.new(:id => 1234)
1498
1471
  att = @c1.load(:id => 345)
@@ -1502,7 +1475,7 @@ describe Sequel::Model, "one_to_many" do
1502
1475
  a.should == [att]
1503
1476
  end
1504
1477
 
1505
- it "should set object to item's reciprocal cached association variable when calling add_" do
1478
+ it "should set object to item's reciprocal cache when calling add_" do
1506
1479
  @c2.one_to_many :attributes, :class => @c1
1507
1480
  @c1.many_to_one :node, :class => @c2
1508
1481
 
@@ -1512,7 +1485,7 @@ describe Sequel::Model, "one_to_many" do
1512
1485
  att.node.should == n
1513
1486
  end
1514
1487
 
1515
- it "should remove item from cached instance variable if it exists when calling remove_" do
1488
+ it "should remove item from cache if it exists when calling remove_" do
1516
1489
  @c2.one_to_many :attributes, :class => @c1
1517
1490
 
1518
1491
  n = @c2.load(:id => 1234)
@@ -1523,7 +1496,7 @@ describe Sequel::Model, "one_to_many" do
1523
1496
  a.should == []
1524
1497
  end
1525
1498
 
1526
- it "should remove item's reciprocal cached association variable when calling remove_" do
1499
+ it "should remove item's reciprocal cache calling remove_" do
1527
1500
  @c2.one_to_many :attributes, :class => @c1
1528
1501
  @c1.many_to_one :node, :class => @c2
1529
1502
 
@@ -1561,7 +1534,7 @@ describe Sequel::Model, "one_to_many" do
1561
1534
  im2.should_not(include('remove_all_attributes'))
1562
1535
  end
1563
1536
 
1564
- it "should populate the reciprocal many_to_one instance variable when loading the one_to_many association" do
1537
+ it "should populate the reciprocal many_to_one cache when loading the one_to_many association" do
1565
1538
  @c2.one_to_many :attributes, :class => @c1, :key => :node_id
1566
1539
  @c1.many_to_one :node, :class => @c2, :key => :node_id
1567
1540
 
@@ -1573,7 +1546,7 @@ describe Sequel::Model, "one_to_many" do
1573
1546
  MODEL_DB.sqls.should == []
1574
1547
  end
1575
1548
 
1576
- it "should use an explicit reciprocal instance variable if given" do
1549
+ it "should use an explicit :reciprocal option if given" do
1577
1550
  @c2.one_to_many :attributes, :class => @c1, :key => :node_id, :reciprocal=>:wxyz
1578
1551
 
1579
1552
  n = @c2.new(:id => 1234)
@@ -1584,7 +1557,7 @@ describe Sequel::Model, "one_to_many" do
1584
1557
  MODEL_DB.sqls.should == []
1585
1558
  end
1586
1559
 
1587
- it "should have an remove_all_ method that removes all associations" do
1560
+ it "should have an remove_all_ method that removes all associated objects" do
1588
1561
  @c2.one_to_many :attributes, :class => @c1
1589
1562
  @c2.new(:id => 1234).remove_all_attributes
1590
1563
  MODEL_DB.sqls.should == ['UPDATE attributes SET node_id = NULL WHERE (node_id = 1234)']
@@ -1612,14 +1585,14 @@ describe Sequel::Model, "one_to_many" do
1612
1585
  sqls.should == []
1613
1586
  end
1614
1587
 
1615
- it "remove_all should set the cached instance variable to []" do
1588
+ it "remove_all should set the cache to []" do
1616
1589
  @c2.one_to_many :attributes, :class => @c1
1617
1590
  node = @c2.new(:id => 1234)
1618
1591
  node.remove_all_attributes
1619
1592
  node.associations[:attributes].should == []
1620
1593
  end
1621
1594
 
1622
- it "remove_all should return the array of previously associated items if the cached instance variable exists" do
1595
+ it "remove_all should return the array of previously associated items if the cache is populated" do
1623
1596
  @c2.one_to_many :attributes, :class => @c1
1624
1597
  attrib = @c1.new(:id=>3)
1625
1598
  node = @c2.new(:id => 1234)
@@ -1630,12 +1603,12 @@ describe Sequel::Model, "one_to_many" do
1630
1603
  node.remove_all_attributes.should == [attrib]
1631
1604
  end
1632
1605
 
1633
- it "remove_all should return nil if the cached instance variable does not exist" do
1606
+ it "remove_all should return nil if the cache is not populated" do
1634
1607
  @c2.one_to_many :attributes, :class => @c1
1635
1608
  @c2.new(:id => 1234).remove_all_attributes.should == nil
1636
1609
  end
1637
1610
 
1638
- it "remove_all should remove the current item from all reciprocal instance varaibles if it cached instance variable exists" do
1611
+ it "remove_all should remove the current item from all reciprocal association caches if they are populated" do
1639
1612
  @c2.one_to_many :attributes, :class => @c1
1640
1613
  @c1.many_to_one :node, :class => @c2
1641
1614
  @c2.dataset._fetch = []
@@ -1663,6 +1636,15 @@ describe Sequel::Model, "one_to_many" do
1663
1636
  p.instance_variable_get(:@x).should == c
1664
1637
  end
1665
1638
 
1639
+ it "should support an :adder option for defining the _add_ method" do
1640
+ @c2.one_to_many :attributes, :class => @c1, :adder=>proc{|x| @x = x}
1641
+ p = @c2.load(:id=>10)
1642
+ c = @c1.load(:id=>123)
1643
+ c.should_not_receive(:node_id=)
1644
+ p.add_attribute(c)
1645
+ p.instance_variable_get(:@x).should == c
1646
+ end
1647
+
1666
1648
  it "should allow additional arguments given to the add_ method and pass them onwards to the _add_ method" do
1667
1649
  @c2.one_to_many :attributes, :class => @c1
1668
1650
  p = @c2.load(:id=>10)
@@ -1690,6 +1672,15 @@ describe Sequel::Model, "one_to_many" do
1690
1672
  p.instance_variable_get(:@x).should == c
1691
1673
  end
1692
1674
 
1675
+ it "should support a :remover option for defining the _remove_ method" do
1676
+ @c2.one_to_many :attributes, :class => @c1, :remover=>proc{|x| @x = x}
1677
+ p = @c2.load(:id=>10)
1678
+ c = @c1.load(:id=>123)
1679
+ c.should_not_receive(:node_id=)
1680
+ p.remove_attribute(c)
1681
+ p.instance_variable_get(:@x).should == c
1682
+ end
1683
+
1693
1684
  it "should allow additional arguments given to the remove_ method and pass them onwards to the _remove_ method" do
1694
1685
  @c2.one_to_many :attributes, :class => @c1
1695
1686
  p = @c2.load(:id=>10)
@@ -1727,6 +1718,13 @@ describe Sequel::Model, "one_to_many" do
1727
1718
  p.instance_variable_get(:@x).should == :foo
1728
1719
  end
1729
1720
 
1721
+ it "should support a :clearer option for defining the _remove_all_ method" do
1722
+ @c2.one_to_many :attributes, :class => @c1, :clearer=>proc{@x = :foo}
1723
+ p = @c2.load(:id=>10)
1724
+ p.remove_all_attributes
1725
+ p.instance_variable_get(:@x).should == :foo
1726
+ end
1727
+
1730
1728
  it "should support (before|after)_(add|remove) callbacks" do
1731
1729
  h = []
1732
1730
  @c2.one_to_many :attributes, :class => @c1, :before_add=>[proc{|x,y| h << x.pk; h << -y.pk}, :blah], :after_add=>proc{h << 3}, :before_remove=>:blah, :after_remove=>[:blahr]
@@ -1965,7 +1963,6 @@ describe Sequel::Model, "many_to_many" do
1965
1963
  end
1966
1964
 
1967
1965
  it "should support a :dataset option that accepts the reflection as an argument" do
1968
- c1 = @c1
1969
1966
  @c2.many_to_many :attributes, :class => @c1, :dataset=>lambda{|opts| opts.associated_dataset.join_table(:natural, :an).filter(:an__nodeid=>pk)}, :order=> :a, :limit=>10, :select=>nil do |ds|
1970
1967
  ds.filter(:xxx => @xxx)
1971
1968
  end
@@ -2220,7 +2217,7 @@ describe Sequel::Model, "many_to_many" do
2220
2217
  MODEL_DB.sqls.should == ['SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234))']
2221
2218
  end
2222
2219
 
2223
- it "should set cached instance variable when accessed" do
2220
+ it "should populate cache when accessed" do
2224
2221
  @c2.many_to_many :attributes, :class => @c1
2225
2222
 
2226
2223
  n = @c2.new(:id => 1234)
@@ -2229,7 +2226,7 @@ describe Sequel::Model, "many_to_many" do
2229
2226
  atts.should == n.associations[:attributes]
2230
2227
  end
2231
2228
 
2232
- it "should use cached instance variable if available" do
2229
+ it "should use cache if available" do
2233
2230
  @c2.many_to_many :attributes, :class => @c1
2234
2231
 
2235
2232
  n = @c2.new(:id => 1234)
@@ -2238,7 +2235,7 @@ describe Sequel::Model, "many_to_many" do
2238
2235
  MODEL_DB.sqls.should == []
2239
2236
  end
2240
2237
 
2241
- it "should not use cached instance variable if asked to reload" do
2238
+ it "should not use cache if asked to reload" do
2242
2239
  @c2.many_to_many :attributes, :class => @c1
2243
2240
 
2244
2241
  n = @c2.new(:id => 1234)
@@ -2247,7 +2244,7 @@ describe Sequel::Model, "many_to_many" do
2247
2244
  MODEL_DB.sqls.should == ["SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234))"]
2248
2245
  end
2249
2246
 
2250
- it "should add item to cached instance variable if it exists when calling add_" do
2247
+ it "should add item to cache if it exists when calling add_" do
2251
2248
  @c2.many_to_many :attributes, :class => @c1
2252
2249
 
2253
2250
  n = @c2.new(:id => 1234)
@@ -2258,7 +2255,7 @@ describe Sequel::Model, "many_to_many" do
2258
2255
  a.should == [att]
2259
2256
  end
2260
2257
 
2261
- it "should add item to reciprocal cached instance variable if it exists when calling add_" do
2258
+ it "should add item to reciprocal's cache if it exists when calling add_" do
2262
2259
  @c2.many_to_many :attributes, :class => @c1
2263
2260
  @c1.many_to_many :nodes, :class => @c2
2264
2261
 
@@ -2269,7 +2266,7 @@ describe Sequel::Model, "many_to_many" do
2269
2266
  att.nodes.should == [n]
2270
2267
  end
2271
2268
 
2272
- it "should remove item from cached instance variable if it exists when calling remove_" do
2269
+ it "should remove item from cache if it exists when calling remove_" do
2273
2270
  @c2.many_to_many :attributes, :class => @c1
2274
2271
 
2275
2272
  n = @c2.new(:id => 1234)
@@ -2280,7 +2277,7 @@ describe Sequel::Model, "many_to_many" do
2280
2277
  a.should == []
2281
2278
  end
2282
2279
 
2283
- it "should remove item from reciprocal cached instance variable if it exists when calling remove_" do
2280
+ it "should remove item from reciprocal's if it exists when calling remove_" do
2284
2281
  @c2.many_to_many :attributes, :class => @c1
2285
2282
  @c1.many_to_many :nodes, :class => @c2
2286
2283
 
@@ -2398,6 +2395,15 @@ describe Sequel::Model, "many_to_many" do
2398
2395
  MODEL_DB.sqls.should == []
2399
2396
  end
2400
2397
 
2398
+ it "should support an :adder option for defining the _add_ method" do
2399
+ @c2.many_to_many :attributes, :class => @c1, :adder=>proc{|x| @x = x}
2400
+ p = @c2.load(:id=>10)
2401
+ c = @c1.load(:id=>123)
2402
+ p.add_attribute(c)
2403
+ p.instance_variable_get(:@x).should == c
2404
+ MODEL_DB.sqls.should == []
2405
+ end
2406
+
2401
2407
  it "should allow additional arguments given to the add_ method and pass them onwards to the _add_ method" do
2402
2408
  @c2.many_to_many :attributes, :class => @c1
2403
2409
  p = @c2.load(:id=>10)
@@ -2424,6 +2430,15 @@ describe Sequel::Model, "many_to_many" do
2424
2430
  MODEL_DB.sqls.should == []
2425
2431
  end
2426
2432
 
2433
+ it "should support a :remover option for defining the _remove_ method" do
2434
+ @c2.many_to_many :attributes, :class => @c1, :remover=>proc{|x| @x = x}
2435
+ p = @c2.load(:id=>10)
2436
+ c = @c1.load(:id=>123)
2437
+ p.remove_attribute(c)
2438
+ p.instance_variable_get(:@x).should == c
2439
+ MODEL_DB.sqls.should == []
2440
+ end
2441
+
2427
2442
  it "should allow additional arguments given to the remove_ method and pass them onwards to the _remove_ method" do
2428
2443
  @c2.many_to_many :attributes, :class => @c1
2429
2444
  p = @c2.load(:id=>10)
@@ -2440,7 +2455,6 @@ describe Sequel::Model, "many_to_many" do
2440
2455
  it "should allow additional arguments given to the remove_all_ method and pass them onwards to the _remove_all_ method" do
2441
2456
  @c2.many_to_many :attributes, :class => @c1
2442
2457
  p = @c2.load(:id=>10)
2443
- c = @c1.load(:id=>123)
2444
2458
  def p._remove_all_attributes(*y)
2445
2459
  @y = y
2446
2460
  end
@@ -2460,6 +2474,14 @@ describe Sequel::Model, "many_to_many" do
2460
2474
  MODEL_DB.sqls.should == []
2461
2475
  end
2462
2476
 
2477
+ it "should support a :clearer option for defining the _remove_all_ method" do
2478
+ @c2.many_to_many :attributes, :class => @c1, :clearer=>proc{@x = :foo}
2479
+ p = @c2.load(:id=>10)
2480
+ p.remove_all_attributes
2481
+ p.instance_variable_get(:@x).should == :foo
2482
+ MODEL_DB.sqls.should == []
2483
+ end
2484
+
2463
2485
  it "should support (before|after)_(add|remove) callbacks" do
2464
2486
  h = []
2465
2487
  @c2.many_to_many :attributes, :class => @c1, :before_add=>[proc{|x,y| h << x.pk; h << -y.pk}, :blah], :after_add=>proc{h << 3}, :before_remove=>:blah, :after_remove=>[:blahr]