sequel 3.11.0 → 3.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (136) hide show
  1. data/CHANGELOG +70 -0
  2. data/Rakefile +1 -1
  3. data/doc/active_record.rdoc +896 -0
  4. data/doc/advanced_associations.rdoc +46 -31
  5. data/doc/association_basics.rdoc +14 -9
  6. data/doc/dataset_basics.rdoc +3 -3
  7. data/doc/migration.rdoc +1011 -0
  8. data/doc/model_hooks.rdoc +198 -0
  9. data/doc/querying.rdoc +811 -86
  10. data/doc/release_notes/3.12.0.txt +304 -0
  11. data/doc/sharding.rdoc +17 -0
  12. data/doc/sql.rdoc +537 -0
  13. data/doc/validations.rdoc +501 -0
  14. data/lib/sequel/adapters/jdbc.rb +19 -27
  15. data/lib/sequel/adapters/jdbc/postgresql.rb +0 -7
  16. data/lib/sequel/adapters/mysql.rb +5 -4
  17. data/lib/sequel/adapters/odbc.rb +3 -2
  18. data/lib/sequel/adapters/shared/mssql.rb +7 -6
  19. data/lib/sequel/adapters/shared/mysql.rb +2 -7
  20. data/lib/sequel/adapters/shared/postgres.rb +2 -8
  21. data/lib/sequel/adapters/shared/sqlite.rb +2 -5
  22. data/lib/sequel/adapters/sqlite.rb +4 -4
  23. data/lib/sequel/core.rb +0 -1
  24. data/lib/sequel/database.rb +2 -1060
  25. data/lib/sequel/database/connecting.rb +227 -0
  26. data/lib/sequel/database/dataset.rb +58 -0
  27. data/lib/sequel/database/dataset_defaults.rb +127 -0
  28. data/lib/sequel/database/logging.rb +62 -0
  29. data/lib/sequel/database/misc.rb +246 -0
  30. data/lib/sequel/database/query.rb +390 -0
  31. data/lib/sequel/database/schema_generator.rb +7 -3
  32. data/lib/sequel/database/schema_methods.rb +351 -7
  33. data/lib/sequel/dataset/actions.rb +9 -2
  34. data/lib/sequel/dataset/misc.rb +6 -2
  35. data/lib/sequel/dataset/mutation.rb +3 -11
  36. data/lib/sequel/dataset/query.rb +49 -6
  37. data/lib/sequel/exceptions.rb +3 -0
  38. data/lib/sequel/extensions/migration.rb +395 -113
  39. data/lib/sequel/extensions/schema_dumper.rb +21 -13
  40. data/lib/sequel/model.rb +27 -25
  41. data/lib/sequel/model/associations.rb +72 -34
  42. data/lib/sequel/model/base.rb +74 -18
  43. data/lib/sequel/model/errors.rb +8 -1
  44. data/lib/sequel/plugins/active_model.rb +8 -0
  45. data/lib/sequel/plugins/association_pks.rb +87 -0
  46. data/lib/sequel/plugins/association_proxies.rb +8 -0
  47. data/lib/sequel/plugins/boolean_readers.rb +12 -6
  48. data/lib/sequel/plugins/caching.rb +14 -7
  49. data/lib/sequel/plugins/class_table_inheritance.rb +15 -9
  50. data/lib/sequel/plugins/composition.rb +2 -1
  51. data/lib/sequel/plugins/force_encoding.rb +10 -7
  52. data/lib/sequel/plugins/hook_class_methods.rb +12 -11
  53. data/lib/sequel/plugins/identity_map.rb +9 -0
  54. data/lib/sequel/plugins/instance_hooks.rb +23 -13
  55. data/lib/sequel/plugins/lazy_attributes.rb +4 -1
  56. data/lib/sequel/plugins/many_through_many.rb +18 -4
  57. data/lib/sequel/plugins/nested_attributes.rb +1 -0
  58. data/lib/sequel/plugins/optimistic_locking.rb +1 -1
  59. data/lib/sequel/plugins/rcte_tree.rb +9 -8
  60. data/lib/sequel/plugins/schema.rb +8 -0
  61. data/lib/sequel/plugins/serialization.rb +1 -3
  62. data/lib/sequel/plugins/sharding.rb +135 -0
  63. data/lib/sequel/plugins/single_table_inheritance.rb +117 -25
  64. data/lib/sequel/plugins/skip_create_refresh.rb +35 -0
  65. data/lib/sequel/plugins/string_stripper.rb +26 -0
  66. data/lib/sequel/plugins/tactical_eager_loading.rb +8 -0
  67. data/lib/sequel/plugins/timestamps.rb +15 -2
  68. data/lib/sequel/plugins/touch.rb +13 -0
  69. data/lib/sequel/plugins/update_primary_key.rb +48 -0
  70. data/lib/sequel/plugins/validation_class_methods.rb +8 -0
  71. data/lib/sequel/plugins/validation_helpers.rb +1 -1
  72. data/lib/sequel/sql.rb +17 -20
  73. data/lib/sequel/version.rb +1 -1
  74. data/spec/adapters/postgres_spec.rb +5 -5
  75. data/spec/core/core_sql_spec.rb +17 -1
  76. data/spec/core/database_spec.rb +17 -5
  77. data/spec/core/dataset_spec.rb +31 -8
  78. data/spec/core/schema_generator_spec.rb +8 -1
  79. data/spec/core/schema_spec.rb +13 -0
  80. data/spec/extensions/association_pks_spec.rb +85 -0
  81. data/spec/extensions/hook_class_methods_spec.rb +9 -9
  82. data/spec/extensions/migration_spec.rb +339 -219
  83. data/spec/extensions/schema_dumper_spec.rb +28 -17
  84. data/spec/extensions/sharding_spec.rb +272 -0
  85. data/spec/extensions/single_table_inheritance_spec.rb +92 -4
  86. data/spec/extensions/skip_create_refresh_spec.rb +17 -0
  87. data/spec/extensions/string_stripper_spec.rb +23 -0
  88. data/spec/extensions/update_primary_key_spec.rb +65 -0
  89. data/spec/extensions/validation_class_methods_spec.rb +5 -5
  90. data/spec/files/bad_down_migration/001_create_alt_basic.rb +4 -0
  91. data/spec/files/bad_down_migration/002_create_alt_advanced.rb +4 -0
  92. data/spec/files/bad_timestamped_migrations/1273253849_create_sessions.rb +9 -0
  93. data/spec/files/bad_timestamped_migrations/1273253851_create_nodes.rb +9 -0
  94. data/spec/files/bad_timestamped_migrations/1273253853_3_create_users.rb +3 -0
  95. data/spec/files/bad_up_migration/001_create_alt_basic.rb +4 -0
  96. data/spec/files/bad_up_migration/002_create_alt_advanced.rb +3 -0
  97. data/spec/files/convert_to_timestamp_migrations/001_create_sessions.rb +9 -0
  98. data/spec/files/convert_to_timestamp_migrations/002_create_nodes.rb +9 -0
  99. data/spec/files/convert_to_timestamp_migrations/003_3_create_users.rb +4 -0
  100. data/spec/files/convert_to_timestamp_migrations/1273253850_create_artists.rb +9 -0
  101. data/spec/files/convert_to_timestamp_migrations/1273253852_create_albums.rb +9 -0
  102. data/spec/files/duplicate_integer_migrations/001_create_alt_advanced.rb +4 -0
  103. data/spec/files/duplicate_integer_migrations/001_create_alt_basic.rb +4 -0
  104. data/spec/files/duplicate_timestamped_migrations/1273253849_create_sessions.rb +9 -0
  105. data/spec/files/duplicate_timestamped_migrations/1273253853_create_nodes.rb +9 -0
  106. data/spec/files/duplicate_timestamped_migrations/1273253853_create_users.rb +4 -0
  107. data/spec/files/integer_migrations/001_create_sessions.rb +9 -0
  108. data/spec/files/integer_migrations/002_create_nodes.rb +9 -0
  109. data/spec/files/integer_migrations/003_3_create_users.rb +4 -0
  110. data/spec/files/interleaved_timestamped_migrations/1273253849_create_sessions.rb +9 -0
  111. data/spec/files/interleaved_timestamped_migrations/1273253850_create_artists.rb +9 -0
  112. data/spec/files/interleaved_timestamped_migrations/1273253851_create_nodes.rb +9 -0
  113. data/spec/files/interleaved_timestamped_migrations/1273253852_create_albums.rb +9 -0
  114. data/spec/files/interleaved_timestamped_migrations/1273253853_3_create_users.rb +4 -0
  115. data/spec/files/missing_integer_migrations/001_create_alt_basic.rb +4 -0
  116. data/spec/files/missing_integer_migrations/003_create_alt_advanced.rb +4 -0
  117. data/spec/files/missing_timestamped_migrations/1273253849_create_sessions.rb +9 -0
  118. data/spec/files/missing_timestamped_migrations/1273253853_3_create_users.rb +4 -0
  119. data/spec/files/timestamped_migrations/1273253849_create_sessions.rb +9 -0
  120. data/spec/files/timestamped_migrations/1273253851_create_nodes.rb +9 -0
  121. data/spec/files/timestamped_migrations/1273253853_3_create_users.rb +4 -0
  122. data/spec/files/uppercase_timestamped_migrations/1273253849_CREATE_SESSIONS.RB +9 -0
  123. data/spec/files/uppercase_timestamped_migrations/1273253851_CREATE_NODES.RB +9 -0
  124. data/spec/files/uppercase_timestamped_migrations/1273253853_3_CREATE_USERS.RB +4 -0
  125. data/spec/integration/eager_loader_test.rb +20 -20
  126. data/spec/integration/migrator_test.rb +187 -0
  127. data/spec/integration/plugin_test.rb +150 -0
  128. data/spec/integration/schema_test.rb +13 -2
  129. data/spec/model/associations_spec.rb +41 -14
  130. data/spec/model/base_spec.rb +69 -0
  131. data/spec/model/eager_loading_spec.rb +7 -3
  132. data/spec/model/record_spec.rb +79 -4
  133. data/spec/model/validations_spec.rb +21 -9
  134. metadata +66 -5
  135. data/doc/schema.rdoc +0 -36
  136. data/lib/sequel/database/schema_sql.rb +0 -320
@@ -1228,7 +1228,7 @@ describe Sequel::Model, "one_to_many" do
1228
1228
  end
1229
1229
  MODEL_DB.reset
1230
1230
  @c1.load(:node_id => nil, :id => 234).should == n.remove_attribute(234)
1231
- MODEL_DB.sqls.should == ['SELECT * FROM attributes WHERE ((attributes.node_id = 1234) AND (id = 234)) LIMIT 1',
1231
+ MODEL_DB.sqls.should == ['SELECT * FROM attributes WHERE ((attributes.node_id = 1234) AND (attributes.id = 234)) LIMIT 1',
1232
1232
  'UPDATE attributes SET node_id = NULL WHERE (id = 234)']
1233
1233
  end
1234
1234
 
@@ -1293,7 +1293,7 @@ describe Sequel::Model, "one_to_many" do
1293
1293
  MODEL_DB.reset
1294
1294
  @c1.load(:node_id => nil, :y => 5, :id => 234).should == n.remove_attribute([234, 5])
1295
1295
  MODEL_DB.sqls.length.should == 2
1296
- MODEL_DB.sqls.first.should =~ /SELECT \* FROM attributes WHERE \(\(attributes.node_id = 123\) AND \((id|y) = (234|5)\) AND \((id|y) = (234|5)\)\) LIMIT 1/
1296
+ MODEL_DB.sqls.first.should =~ /SELECT \* FROM attributes WHERE \(\(attributes.node_id = 123\) AND \(attributes\.(id|y) = (234|5)\) AND \(attributes\.(id|y) = (234|5)\)\) LIMIT 1/
1297
1297
  MODEL_DB.sqls.last.should =~ /UPDATE attributes SET node_id = NULL WHERE \(\((id|y) = (234|5)\) AND \((id|y) = (234|5)\)\)/
1298
1298
  end
1299
1299
 
@@ -2076,8 +2076,8 @@ describe Sequel::Model, "many_to_many" do
2076
2076
  end
2077
2077
  MODEL_DB.reset
2078
2078
  @c1.load(:id => 234).should == n.remove_attribute(234)
2079
- MODEL_DB.sqls.should == ['SELECT * FROM attributes WHERE (id = 234) LIMIT 1',
2080
- 'DELETE FROM attributes_nodes WHERE ((node_id = 1234) AND (attribute_id = 234))']
2079
+ 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)) WHERE (attributes.id = 234) LIMIT 1",
2080
+ "DELETE FROM attributes_nodes WHERE ((node_id = 1234) AND (attribute_id = 234))"]
2081
2081
  end
2082
2082
 
2083
2083
  it "should raise an error in the remove_ method if the passed associated object is not of the correct type" do
@@ -2155,9 +2155,10 @@ describe Sequel::Model, "many_to_many" do
2155
2155
  end
2156
2156
  MODEL_DB.reset
2157
2157
  @c1.load(:id => 234, :y=>8).should == n.remove_attribute([234, 8])
2158
+ ["SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234)) WHERE ((attributes.id = 234) AND (attributes.y = 8)) LIMIT 1",
2159
+ "SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234)) WHERE ((attributes.y = 8) AND (attributes.id = 234)) LIMIT 1"].should include(MODEL_DB.sqls.first)
2160
+ MODEL_DB.sqls.last.should == "DELETE FROM attributes_nodes WHERE ((node_id = 1234) AND (attribute_id = 234))"
2158
2161
  MODEL_DB.sqls.length.should == 2
2159
- MODEL_DB.sqls.first.should =~ /SELECT \* FROM attributes WHERE \(\((id|y) = (234|8)\) AND \((id|y) = (234|8)\)\) LIMIT 1/
2160
- MODEL_DB.sqls.last.should == 'DELETE FROM attributes_nodes WHERE ((node_id = 1234) AND (attribute_id = 234))'
2161
2162
  end
2162
2163
 
2163
2164
  it "should raise an error if the model object doesn't have a valid primary key" do
@@ -2333,14 +2334,6 @@ describe Sequel::Model, "many_to_many" do
2333
2334
  MODEL_DB.sqls.first.should == 'DELETE FROM attributes_nodes WHERE (node_id = 1234)'
2334
2335
  end
2335
2336
 
2336
- it "should have remove_all method respect association filters" do
2337
- @c2.many_to_many :attributes, :class => @c1, :conditions=>{:a=>1} do |ds|
2338
- ds.filter(:b=>2)
2339
- end
2340
- @c2.new(:id => 1234).remove_all_attributes
2341
- MODEL_DB.sqls.should == ['DELETE FROM attributes_nodes WHERE ((node_id = 1234) AND (a = 1) AND (b = 2))']
2342
- end
2343
-
2344
2337
  it "should have the remove_all_ method respect the :left_primary_key option" do
2345
2338
  @c2.many_to_many :attributes, :class => @c1, :left_primary_key=>:xxx
2346
2339
  @c2.new(:id => 1234, :xxx=>5).remove_all_attributes
@@ -2394,6 +2387,17 @@ describe Sequel::Model, "many_to_many" do
2394
2387
  attrib.associations[:nodes].should == []
2395
2388
  end
2396
2389
 
2390
+ it "add, remove, and remove_all methods should respect :join_table_block option" do
2391
+ @c2.many_to_many :attributes, :class => @c1, :join_table_block=>proc{|ds| ds.filter(:x=>123).set_overrides(:x=>123)}
2392
+ o = @c2.load(:id => 1234)
2393
+ o.add_attribute(@c1.load(:id=>44))
2394
+ o.remove_attribute(@c1.load(:id=>45))
2395
+ o.remove_all_attributes
2396
+ MODEL_DB.sqls.first =~ /INSERT INTO attributes_nodes \((node_id|attribute_id|x), (node_id|attribute_id|x), (node_id|attribute_id|x)\) VALUES \((1234|123|44), (1234|123|44), (1234|123|44)\)/
2397
+ MODEL_DB.sqls[1..-1].should == ["DELETE FROM attributes_nodes WHERE ((x = 123) AND (node_id = 1234) AND (attribute_id = 45))",
2398
+ "DELETE FROM attributes_nodes WHERE ((x = 123) AND (node_id = 1234))"]
2399
+ end
2400
+
2397
2401
  it "should call an _add_ method internally to add attributes" do
2398
2402
  @c2.many_to_many :attributes, :class => @c1
2399
2403
  @c2.private_instance_methods.collect{|x| x.to_s}.sort.should(include("_add_attribute"))
@@ -2568,6 +2572,29 @@ describe Sequel::Model, "many_to_many" do
2568
2572
  @c2.many_to_many :attributes, :class => @c1, :distinct=>true
2569
2573
  @c2.load(:id=>10).attributes_dataset.sql.should == "SELECT DISTINCT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 10))"
2570
2574
  end
2575
+
2576
+ it "should not apply association options when removing all associated records" do
2577
+ @c2.many_to_many :attributes, :class => @c1 do |ds|
2578
+ ds.filter(:name=>'John')
2579
+ end
2580
+ @c2.load(:id=>1).remove_all_attributes
2581
+ MODEL_DB.sqls.should == ["DELETE FROM attributes_nodes WHERE (node_id = 1)"]
2582
+ end
2583
+
2584
+ it "should use assocation's dataset when grabbing a record to remove from the assocation by primary key" do
2585
+ @c2.many_to_many :attributes, :class => @c1 do |ds|
2586
+ ds.filter(:join_table_att=>3)
2587
+ end
2588
+ @c1.dataset.instance_eval do
2589
+ def fetch_rows(sql, &block)
2590
+ db.sqls << sql
2591
+ yield(:id=>2)
2592
+ end
2593
+ end
2594
+ @c2.load(:id=>1).remove_attribute(2)
2595
+ MODEL_DB.sqls.should == ["SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1)) WHERE ((join_table_att = 3) AND (attributes.id = 2)) LIMIT 1",
2596
+ "DELETE FROM attributes_nodes WHERE ((node_id = 1) AND (attribute_id = 2))"]
2597
+ end
2571
2598
  end
2572
2599
 
2573
2600
  describe Sequel::Model, " association reflection methods" do
@@ -157,6 +157,75 @@ describe "A model inheriting from a model" do
157
157
  end
158
158
  end
159
159
 
160
+ describe "Model.primary_key" do
161
+ before do
162
+ @c = Class.new(Sequel::Model)
163
+ end
164
+
165
+ specify "should default to id" do
166
+ @c.primary_key.should == :id
167
+ end
168
+
169
+ specify "should be overridden by set_primary_key" do
170
+ @c.set_primary_key :cid
171
+ @c.primary_key.should == :cid
172
+
173
+ @c.set_primary_key([:id1, :id2])
174
+ @c.primary_key.should == [:id1, :id2]
175
+ end
176
+
177
+ specify "should use nil for no primary key" do
178
+ @c.no_primary_key
179
+ @c.primary_key.should == nil
180
+ end
181
+ end
182
+
183
+ describe "Model.primary_key_hash" do
184
+ before do
185
+ @c = Class.new(Sequel::Model)
186
+ end
187
+
188
+ specify "should handle a single primary key" do
189
+ @c.primary_key_hash(1).should == {:id=>1}
190
+ end
191
+
192
+ specify "should handle a composite primary key" do
193
+ @c.set_primary_key([:id1, :id2])
194
+ @c.primary_key_hash([1, 2]).should == {:id1=>1, :id2=>2}
195
+ end
196
+
197
+ specify "should raise an error for no primary key" do
198
+ @c.no_primary_key
199
+ proc{@c.primary_key_hash(1)}.should raise_error(Sequel::Error)
200
+ end
201
+ end
202
+
203
+ describe "Model.qualified_primary_key_hash" do
204
+ before do
205
+ @c = Class.new(Sequel::Model(:items))
206
+ end
207
+
208
+ specify "should handle a single primary key" do
209
+ @c.qualified_primary_key_hash(1).should == {:id.qualify(:items)=>1}
210
+ end
211
+
212
+ specify "should handle a composite primary key" do
213
+ @c.set_primary_key([:id1, :id2])
214
+ @c.qualified_primary_key_hash([1, 2]).should == {:id1.qualify(:items)=>1, :id2.qualify(:items)=>2}
215
+ end
216
+
217
+ specify "should raise an error for no primary key" do
218
+ @c.no_primary_key
219
+ proc{@c.qualified_primary_key_hash(1)}.should raise_error(Sequel::Error)
220
+ end
221
+
222
+ specify "should allow specifying a different qualifier" do
223
+ @c.qualified_primary_key_hash(1, :apple).should == {:id.qualify(:apple)=>1}
224
+ @c.set_primary_key([:id1, :id2])
225
+ @c.qualified_primary_key_hash([1, 2], :bear).should == {:id1.qualify(:bear)=>1, :id2.qualify(:bear)=>2}
226
+ end
227
+ end
228
+
160
229
  describe "Model.db=" do
161
230
  before do
162
231
  $db1 = MockDatabase.new
@@ -577,9 +577,9 @@ describe Sequel::Model, "#eager" do
577
577
  item = EagerBand.filter(:album_id=>records.collect{|r| [r.pk, r.pk*2]}.flatten).order(:name).first
578
578
  records.each{|r| r.associations[:special_band] = item}
579
579
  end)
580
- EagerAlbum.one_to_many :special_tracks, :eager_loader=>(proc do |key_hash, records, assocs|
581
- items = EagerTrack.filter(:album_id=>records.collect{|r| [r.pk, r.pk*2]}.flatten).all
582
- records.each{|r| r.associations[:special_tracks] = items}
580
+ EagerAlbum.one_to_many :special_tracks, :eager_loader=>(proc do |eo|
581
+ items = EagerTrack.filter(:album_id=>eo[:rows].collect{|r| [r.pk, r.pk*2]}.flatten).all
582
+ eo[:rows].each{|r| r.associations[:special_tracks] = items}
583
583
  end)
584
584
  EagerAlbum.many_to_many :special_genres, :class=>:EagerGenre, :eager_loader=>(proc do |key_hash, records, assocs|
585
585
  items = EagerGenre.inner_join(:ag, [:genre_id]).filter(:album_id=>records.collect{|r| r.pk}).all
@@ -608,6 +608,10 @@ describe Sequel::Model, "#eager" do
608
608
  a.special_genres.first.values.should == {:id => 4}
609
609
  MODEL_DB.sqls.length.should == 4
610
610
  end
611
+
612
+ it "should raise an error if you use an :eager_loader proc with the wrong arity" do
613
+ proc{EagerAlbum.many_to_one :special_band, :eager_loader=>proc{|a, b|}}.should raise_error(Sequel::Error)
614
+ end
611
615
 
612
616
  it "should respect :after_load callbacks on associations when eager loading" do
613
617
  EagerAlbum.many_to_one :al_band, :class=>'EagerBand', :key=>:band_id, :after_load=>proc{|o, a| a.id *=2}
@@ -63,7 +63,7 @@ describe "Model#save" do
63
63
  MODEL_DB.sqls.should == ["INSERT INTO items (y) VALUES (2)"]
64
64
  end
65
65
 
66
- it "should use value returned by insert as the primary key" do
66
+ it "should use value returned by insert as the primary key and refresh the object" do
67
67
  @c.dataset.meta_def(:insert){|h| super(h); 13}
68
68
  o = @c.new(:x => 11)
69
69
  o.save
@@ -71,6 +71,13 @@ describe "Model#save" do
71
71
  "SELECT * FROM items WHERE (id = 13) LIMIT 1"]
72
72
  end
73
73
 
74
+ it "should allow you to skip refreshing by overridding _save_refresh" do
75
+ @c.dataset.meta_def(:insert){|h| super(h); 13}
76
+ @c.send(:define_method, :_save_refresh){}
77
+ @c.create(:x => 11)
78
+ MODEL_DB.sqls.should == ["INSERT INTO items (x) VALUES (11)"]
79
+ end
80
+
74
81
  it "should work correctly for inserting a record without a primary key" do
75
82
  @c.dataset.meta_def(:insert){|h| super(h); 13}
76
83
  @c.no_primary_key
@@ -737,6 +744,54 @@ describe Sequel::Model, "#update" do
737
744
  end
738
745
  end
739
746
 
747
+ describe Sequel::Model, "#set_fields" do
748
+ before do
749
+ @c = Class.new(Sequel::Model(:items))
750
+ @c.class_eval do
751
+ set_primary_key :id
752
+ columns :x, :y, :z, :id
753
+ end
754
+ @c.strict_param_setting = true
755
+ @o1 = @c.new
756
+ MODEL_DB.reset
757
+ end
758
+
759
+ it "should set only the given fields" do
760
+ @o1.set_fields({:x => 1, :y => 2, :z=>3, :id=>4}, [:x, :y])
761
+ @o1.values.should == {:x => 1, :y => 2}
762
+ @o1.set_fields({:x => 9, :y => 8, :z=>6, :id=>7}, [:x, :y, :id])
763
+ @o1.values.should == {:x => 9, :y => 8, :id=>7}
764
+ MODEL_DB.sqls.should == []
765
+ end
766
+ end
767
+
768
+ describe Sequel::Model, "#update_fields" do
769
+ before do
770
+ @c = Class.new(Sequel::Model(:items))
771
+ @c.class_eval do
772
+ set_primary_key :id
773
+ columns :x, :y, :z, :id
774
+ def _refresh(ds); end
775
+ end
776
+ @c.strict_param_setting = true
777
+ @o1 = @c.load(:id=>1)
778
+ MODEL_DB.reset
779
+ end
780
+
781
+ it "should set only the given fields, and then save the changes to the record" do
782
+ @o1.update_fields({:x => 1, :y => 2, :z=>3, :id=>4}, [:x, :y])
783
+ @o1.values.should == {:x => 1, :y => 2, :id=>1}
784
+ MODEL_DB.sqls.first.should =~ /UPDATE items SET [xy] = [12], [xy] = [12] WHERE \(id = 1\)/
785
+ MODEL_DB.sqls.length.should == 1
786
+ MODEL_DB.reset
787
+
788
+ @o1.update_fields({:x => 1, :y => 5, :z=>6, :id=>7}, [:x, :y])
789
+ @o1.values.should == {:x => 1, :y => 5, :id=>1}
790
+ MODEL_DB.sqls.should == ["UPDATE items SET y = 5 WHERE (id = 1)"]
791
+ MODEL_DB.reset
792
+ end
793
+ end
794
+
740
795
  describe Sequel::Model, "#(set|update)_(all|except|only)" do
741
796
  before do
742
797
  MODEL_DB.reset
@@ -752,7 +807,25 @@ describe Sequel::Model, "#(set|update)_(all|except|only)" do
752
807
  @o1 = @c.new
753
808
  end
754
809
 
755
- it "#set_all should set all attributes" do
810
+ it "should raise errors if not all hash fields can be set and strict_param_setting is true" do
811
+ @c.strict_param_setting = true
812
+
813
+ proc{@c.new.set_all(:x => 1, :y => 2, :z=>3, :id=>4)}.should raise_error(Sequel::Error)
814
+ (o = @c.new).set_all(:x => 1, :y => 2, :z=>3)
815
+ o.values.should == {:x => 1, :y => 2, :z=>3}
816
+
817
+ proc{@c.new.set_only({:x => 1, :y => 2, :z=>3, :id=>4}, :x, :y)}.should raise_error(Sequel::Error)
818
+ proc{@c.new.set_only({:x => 1, :y => 2, :z=>3}, :x, :y)}.should raise_error(Sequel::Error)
819
+ (o = @c.new).set_only({:x => 1, :y => 2}, :x, :y)
820
+ o.values.should == {:x => 1, :y => 2}
821
+
822
+ proc{@c.new.set_except({:x => 1, :y => 2, :z=>3, :id=>4}, :x, :y)}.should raise_error(Sequel::Error)
823
+ proc{@c.new.set_except({:x => 1, :y => 2, :z=>3}, :x, :y)}.should raise_error(Sequel::Error)
824
+ (o = @c.new).set_except({:z => 3}, :x, :y)
825
+ o.values.should == {:z=>3}
826
+ end
827
+
828
+ it "#set_all should set all attributes except the primary key" do
756
829
  @o1.set_all(:x => 1, :y => 2, :z=>3, :id=>4)
757
830
  @o1.values.should == {:x => 1, :y => 2, :z=>3}
758
831
  end
@@ -762,9 +835,11 @@ describe Sequel::Model, "#(set|update)_(all|except|only)" do
762
835
  @o1.values.should == {:x => 1, :y => 2}
763
836
  @o1.set_only({:x => 4, :y => 5, :z=>6, :id=>7}, :x, :y)
764
837
  @o1.values.should == {:x => 4, :y => 5}
838
+ @o1.set_only({:x => 9, :y => 8, :z=>6, :id=>7}, :x, :y, :id)
839
+ @o1.values.should == {:x => 9, :y => 8, :id=>7}
765
840
  end
766
841
 
767
- it "#set_except should not set given attributes" do
842
+ it "#set_except should not set given attributes or the primary key" do
768
843
  @o1.set_except({:x => 1, :y => 2, :z=>3, :id=>4}, [:y, :z])
769
844
  @o1.values.should == {:x => 1}
770
845
  @o1.set_except({:x => 4, :y => 2, :z=>3, :id=>4}, :y, :z)
@@ -1497,4 +1572,4 @@ describe "Model#lock!" do
1497
1572
  called.should == true
1498
1573
  MODEL_DB.sqls.should == ["SELECT * FROM items WHERE (id = 1) LIMIT 1 FOR UPDATE"]
1499
1574
  end
1500
- end
1575
+ end
@@ -12,22 +12,34 @@ describe Sequel::Model::Errors do
12
12
  @errors.should == {}
13
13
  end
14
14
 
15
- specify "should be empty if no errors are added" do
15
+ specify "should be empty if there are no errors" do
16
16
  @errors.should be_empty
17
+ @errors[:blah]
18
+ @errors.should be_empty
19
+ end
20
+
21
+ specify "should not be empty if there are errors" do
17
22
  @errors[:blah] << "blah"
18
23
  @errors.should_not be_empty
19
24
  end
20
25
 
21
- specify "should return errors for a specific attribute using #on or #[]" do
26
+ specify "should return errors for a specific attribute using #[]" do
22
27
  @errors[:blah].should == []
23
- @errors.on(:blah).should == []
24
-
25
28
  @errors[:blah] << 'blah'
26
29
  @errors[:blah].should == ['blah']
27
- @errors.on(:blah).should == ['blah']
28
30
 
29
31
  @errors[:bleu].should == []
30
- @errors.on(:bleu).should == []
32
+ end
33
+
34
+ specify "should return an array of errors for a specific attribute using #on if there are errors" do
35
+ @errors[:blah] << 'blah'
36
+ @errors.on(:blah).should == ['blah']
37
+ end
38
+
39
+ specify "should return nil using #on if there are no errors for that attribute" do
40
+ @errors.on(:blah).should == nil
41
+ @errors[:blah]
42
+ @errors.on(:blah).should == nil
31
43
  end
32
44
 
33
45
  specify "should accept errors using #[] << or #add" do
@@ -116,7 +128,7 @@ describe "Model#save" do
116
128
  columns :id, :x
117
129
 
118
130
  def validate
119
- errors[:id] << 'blah' unless id == 5
131
+ errors[:id] << 'blah' unless x == 7
120
132
  end
121
133
  end
122
134
  @m = @c.load(:id => 4, :x=>6)
@@ -129,10 +141,10 @@ describe "Model#save" do
129
141
  @m.save
130
142
  MODEL_DB.sqls.should be_empty
131
143
 
132
- @m.id = 5
144
+ @m.x = 7
133
145
  @m.should be_valid
134
146
  @m.save.should_not be_false
135
- MODEL_DB.sqls.should == ['UPDATE people SET x = 6 WHERE (id = 5)']
147
+ MODEL_DB.sqls.should == ['UPDATE people SET x = 7 WHERE (id = 4)']
136
148
  end
137
149
 
138
150
  specify "should skip validations if the :validate=>false option is used" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequel
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.11.0
4
+ version: 3.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-05-03 00:00:00 -07:00
12
+ date: 2010-06-01 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -29,12 +29,16 @@ extra_rdoc_files:
29
29
  - doc/opening_databases.rdoc
30
30
  - doc/prepared_statements.rdoc
31
31
  - doc/reflection.rdoc
32
- - doc/schema.rdoc
33
32
  - doc/sharding.rdoc
33
+ - doc/sql.rdoc
34
34
  - doc/virtual_rows.rdoc
35
35
  - doc/dataset_basics.rdoc
36
36
  - doc/association_basics.rdoc
37
37
  - doc/querying.rdoc
38
+ - doc/migration.rdoc
39
+ - doc/validations.rdoc
40
+ - doc/model_hooks.rdoc
41
+ - doc/active_record.rdoc
38
42
  - doc/release_notes/1.0.txt
39
43
  - doc/release_notes/1.1.txt
40
44
  - doc/release_notes/1.3.txt
@@ -65,6 +69,7 @@ extra_rdoc_files:
65
69
  - doc/release_notes/3.9.0.txt
66
70
  - doc/release_notes/3.10.0.txt
67
71
  - doc/release_notes/3.11.0.txt
72
+ - doc/release_notes/3.12.0.txt
68
73
  files:
69
74
  - COPYING
70
75
  - CHANGELOG
@@ -107,12 +112,17 @@ files:
107
112
  - doc/release_notes/3.9.0.txt
108
113
  - doc/release_notes/3.10.0.txt
109
114
  - doc/release_notes/3.11.0.txt
110
- - doc/schema.rdoc
115
+ - doc/release_notes/3.12.0.txt
111
116
  - doc/sharding.rdoc
117
+ - doc/sql.rdoc
112
118
  - doc/virtual_rows.rdoc
113
119
  - doc/dataset_basics.rdoc
114
120
  - doc/association_basics.rdoc
115
121
  - doc/querying.rdoc
122
+ - doc/migration.rdoc
123
+ - doc/validations.rdoc
124
+ - doc/model_hooks.rdoc
125
+ - doc/active_record.rdoc
116
126
  - spec/adapters/firebird_spec.rb
117
127
  - spec/adapters/informix_spec.rb
118
128
  - spec/adapters/mssql_spec.rb
@@ -171,6 +181,11 @@ files:
171
181
  - spec/extensions/composition_spec.rb
172
182
  - spec/extensions/rcte_tree_spec.rb
173
183
  - spec/extensions/instance_filters_spec.rb
184
+ - spec/extensions/sharding_spec.rb
185
+ - spec/extensions/skip_create_refresh_spec.rb
186
+ - spec/extensions/string_stripper_spec.rb
187
+ - spec/extensions/update_primary_key_spec.rb
188
+ - spec/extensions/association_pks_spec.rb
174
189
  - spec/integration/associations_test.rb
175
190
  - spec/integration/database_test.rb
176
191
  - spec/integration/dataset_test.rb
@@ -183,6 +198,7 @@ files:
183
198
  - spec/integration/timezone_test.rb
184
199
  - spec/integration/transaction_test.rb
185
200
  - spec/integration/type_test.rb
201
+ - spec/integration/migrator_test.rb
186
202
  - spec/model/association_reflection_spec.rb
187
203
  - spec/model/associations_spec.rb
188
204
  - spec/model/base_spec.rb
@@ -198,6 +214,41 @@ files:
198
214
  - spec/rcov.opts
199
215
  - spec/spec_config.rb.example
200
216
  - spec/spec_config.rb
217
+ - spec/files/bad_down_migration/001_create_alt_basic.rb
218
+ - spec/files/bad_down_migration/002_create_alt_advanced.rb
219
+ - spec/files/bad_timestamped_migrations/1273253849_create_sessions.rb
220
+ - spec/files/bad_timestamped_migrations/1273253851_create_nodes.rb
221
+ - spec/files/bad_timestamped_migrations/1273253853_3_create_users.rb
222
+ - spec/files/bad_up_migration/001_create_alt_basic.rb
223
+ - spec/files/bad_up_migration/002_create_alt_advanced.rb
224
+ - spec/files/convert_to_timestamp_migrations/001_create_sessions.rb
225
+ - spec/files/convert_to_timestamp_migrations/002_create_nodes.rb
226
+ - spec/files/convert_to_timestamp_migrations/003_3_create_users.rb
227
+ - spec/files/convert_to_timestamp_migrations/1273253850_create_artists.rb
228
+ - spec/files/convert_to_timestamp_migrations/1273253852_create_albums.rb
229
+ - spec/files/duplicate_integer_migrations/001_create_alt_advanced.rb
230
+ - spec/files/duplicate_integer_migrations/001_create_alt_basic.rb
231
+ - spec/files/duplicate_timestamped_migrations/1273253849_create_sessions.rb
232
+ - spec/files/duplicate_timestamped_migrations/1273253853_create_nodes.rb
233
+ - spec/files/duplicate_timestamped_migrations/1273253853_create_users.rb
234
+ - spec/files/integer_migrations/001_create_sessions.rb
235
+ - spec/files/integer_migrations/002_create_nodes.rb
236
+ - spec/files/integer_migrations/003_3_create_users.rb
237
+ - spec/files/interleaved_timestamped_migrations/1273253849_create_sessions.rb
238
+ - spec/files/interleaved_timestamped_migrations/1273253850_create_artists.rb
239
+ - spec/files/interleaved_timestamped_migrations/1273253851_create_nodes.rb
240
+ - spec/files/interleaved_timestamped_migrations/1273253852_create_albums.rb
241
+ - spec/files/interleaved_timestamped_migrations/1273253853_3_create_users.rb
242
+ - spec/files/missing_integer_migrations/001_create_alt_basic.rb
243
+ - spec/files/missing_integer_migrations/003_create_alt_advanced.rb
244
+ - spec/files/missing_timestamped_migrations/1273253849_create_sessions.rb
245
+ - spec/files/missing_timestamped_migrations/1273253853_3_create_users.rb
246
+ - spec/files/timestamped_migrations/1273253849_create_sessions.rb
247
+ - spec/files/timestamped_migrations/1273253851_create_nodes.rb
248
+ - spec/files/timestamped_migrations/1273253853_3_create_users.rb
249
+ - spec/files/uppercase_timestamped_migrations/1273253849_CREATE_SESSIONS.RB
250
+ - spec/files/uppercase_timestamped_migrations/1273253851_CREATE_NODES.RB
251
+ - spec/files/uppercase_timestamped_migrations/1273253853_3_CREATE_USERS.RB
201
252
  - lib/sequel.rb
202
253
  - lib/sequel/adapters/ado.rb
203
254
  - lib/sequel/adapters/ado/mssql.rb
@@ -242,7 +293,12 @@ files:
242
293
  - lib/sequel/database.rb
243
294
  - lib/sequel/database/schema_generator.rb
244
295
  - lib/sequel/database/schema_methods.rb
245
- - lib/sequel/database/schema_sql.rb
296
+ - lib/sequel/database/connecting.rb
297
+ - lib/sequel/database/dataset.rb
298
+ - lib/sequel/database/dataset_defaults.rb
299
+ - lib/sequel/database/logging.rb
300
+ - lib/sequel/database/misc.rb
301
+ - lib/sequel/database/query.rb
246
302
  - lib/sequel/dataset.rb
247
303
  - lib/sequel/dataset/actions.rb
248
304
  - lib/sequel/dataset/features.rb
@@ -301,6 +357,11 @@ files:
301
357
  - lib/sequel/plugins/composition.rb
302
358
  - lib/sequel/plugins/rcte_tree.rb
303
359
  - lib/sequel/plugins/instance_filters.rb
360
+ - lib/sequel/plugins/sharding.rb
361
+ - lib/sequel/plugins/skip_create_refresh.rb
362
+ - lib/sequel/plugins/string_stripper.rb
363
+ - lib/sequel/plugins/update_primary_key.rb
364
+ - lib/sequel/plugins/association_pks.rb
304
365
  - lib/sequel/sql.rb
305
366
  - lib/sequel/timezones.rb
306
367
  - lib/sequel/version.rb