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
@@ -6,7 +6,7 @@ shared_examples_for "eager limit strategies" do
6
6
  Artist.one_to_one :last_album, {:clone=>:last_album}.merge(@els) if @els
7
7
  @album.update(:artist => @artist)
8
8
  diff_album = @diff_album.call
9
- al, ar, t = @pr.call
9
+ ar = @pr.call[1]
10
10
 
11
11
  a = Artist.eager(:first_album, :last_album).order(:name).all
12
12
  a.should == [@artist, ar]
@@ -33,7 +33,7 @@ shared_examples_for "eager limit strategies" do
33
33
  @album.update(:artist => @artist)
34
34
  middle_album = @middle_album.call
35
35
  diff_album = @diff_album.call
36
- al, ar, t = @pr.call
36
+ ar = @pr.call[1]
37
37
 
38
38
  ars = Artist.eager(:first_two_albums, :second_two_albums, :last_two_albums).order(:name).all
39
39
  ars.should == [@artist, ar]
@@ -58,7 +58,7 @@ shared_examples_for "eager limit strategies" do
58
58
  Album.many_to_many :second_two_tags, {:clone=>:second_two_tags}.merge(@els) if @els
59
59
  Album.many_to_many :last_two_tags, {:clone=>:last_two_tags}.merge(@els) if @els
60
60
  tu, tv = @other_tags.call
61
- al, ar, t = @pr.call
61
+ al = @pr.call.first
62
62
 
63
63
  als = Album.eager(:first_two_tags, :second_two_tags, :last_two_tags).order(:name).all
64
64
  als.should == [@album, al]
@@ -84,7 +84,7 @@ shared_examples_for "eager limit strategies" do
84
84
  Artist.many_through_many :last_two_tags, {:clone=>:last_two_tags}.merge(@els) if @els
85
85
  @album.update(:artist => @artist)
86
86
  tu, tv = @other_tags.call
87
- al, ar, t = @pr.call
87
+ ar = @pr.call[1]
88
88
 
89
89
  ars = Artist.eager(:first_two_tags, :second_two_tags, :last_two_tags).order(:name).all
90
90
  ars.should == [@artist, ar]
@@ -229,7 +229,7 @@ shared_examples_for "filtering/excluding by associations" do
229
229
  @album.add_tag(@tag)
230
230
  @Album.filter(:tags=>@tag).all.should == [@album]
231
231
  @Album.filter(:alias_tags=>@tag).all.should == [@album]
232
- album, artist, tag = @pr.call
232
+ album, tag = @pr.call.values_at(0, 2)
233
233
  @Album.exclude(:tags=>@tag).all.should == [album]
234
234
  @Album.exclude(:alias_tags=>@tag).all.should == [album]
235
235
  @Album.exclude(:tags=>tag).all.sort_by{|x| x.pk}.should == [@album, album]
@@ -330,71 +330,50 @@ describe "Polymorphic Associations" do
330
330
  end
331
331
  class ::Asset < Sequel::Model
332
332
  m = method(:constantize)
333
- many_to_one :attachable, :reciprocal=>:assets, \
333
+ many_to_one :attachable, :reciprocal=>:assets,
334
+ :setter=>(proc do |attachable|
335
+ self[:attachable_id] = (attachable.pk if attachable)
336
+ self[:attachable_type] = (attachable.class.name if attachable)
337
+ end),
334
338
  :dataset=>(proc do
335
339
  klass = m.call(attachable_type)
336
340
  klass.where(klass.primary_key=>attachable_id)
337
- end), \
341
+ end),
338
342
  :eager_loader=>(proc do |eo|
339
343
  id_map = {}
340
344
  eo[:rows].each do |asset|
341
345
  asset.associations[:attachable] = nil
342
346
  ((id_map[asset.attachable_type] ||= {})[asset.attachable_id] ||= []) << asset
343
347
  end
344
- id_map.each do |klass_name, id_map|
348
+ id_map.each do |klass_name, idmap|
345
349
  klass = m.call(klass_name)
346
- klass.where(klass.primary_key=>id_map.keys).all do |attach|
347
- id_map[attach.pk].each do |asset|
350
+ klass.where(klass.primary_key=>idmap.keys).all do |attach|
351
+ idmap[attach.pk].each do |asset|
348
352
  asset.associations[:attachable] = attach
349
353
  end
350
354
  end
351
355
  end
352
356
  end)
353
-
354
- private
355
-
356
- def _attachable=(attachable)
357
- self[:attachable_id] = (attachable.pk if attachable)
358
- self[:attachable_type] = (attachable.class.name if attachable)
359
- end
360
357
  end
361
358
 
362
359
  INTEGRATION_DB.create_table!(:posts) do
363
360
  primary_key :id
364
361
  end
365
362
  class ::Post < Sequel::Model
366
- one_to_many :assets, :key=>:attachable_id, :reciprocal=>:attachable, :conditions=>{:attachable_type=>'Post'}
367
-
368
- private
369
-
370
- def _add_asset(asset)
371
- asset.update(:attachable_id=>pk, :attachable_type=>'Post')
372
- end
373
- def _remove_asset(asset)
374
- asset.update(:attachable_id=>nil, :attachable_type=>nil)
375
- end
376
- def _remove_all_assets
377
- assets_dataset.update(:attachable_id=>nil, :attachable_type=>nil)
378
- end
363
+ one_to_many :assets, :key=>:attachable_id, :reciprocal=>:attachable, :conditions=>{:attachable_type=>'Post'},
364
+ :adder=>proc{|asset| asset.update(:attachable_id=>pk, :attachable_type=>'Post')},
365
+ :remover=>proc{|asset| asset.update(:attachable_id=>nil, :attachable_type=>nil)},
366
+ :clearer=>proc{assets_dataset.update(:attachable_id=>nil, :attachable_type=>nil)}
379
367
  end
380
368
 
381
369
  INTEGRATION_DB.create_table!(:notes) do
382
370
  primary_key :id
383
371
  end
384
372
  class ::Note < Sequel::Model
385
- one_to_many :assets, :key=>:attachable_id, :reciprocal=>:attachable, :conditions=>{:attachable_type=>'Note'}
386
-
387
- private
388
-
389
- def _add_asset(asset)
390
- asset.update(:attachable_id=>pk, :attachable_type=>'Note')
391
- end
392
- def _remove_asset(asset)
393
- asset.update(:attachable_id=>nil, :attachable_type=>nil)
394
- end
395
- def _remove_all_assets
396
- assets_dataset.update(:attachable_id=>nil, :attachable_type=>nil)
397
- end
373
+ one_to_many :assets, :key=>:attachable_id, :reciprocal=>:attachable, :conditions=>{:attachable_type=>'Note'},
374
+ :adder=>proc{|asset| asset.update(:attachable_id=>pk, :attachable_type=>'Note')},
375
+ :remover=>proc{|asset| asset.update(:attachable_id=>nil, :attachable_type=>nil)},
376
+ :clearer=>proc{assets_dataset.update(:attachable_id=>nil, :attachable_type=>nil)}
398
377
  end
399
378
  end
400
379
  before do
@@ -475,8 +454,17 @@ describe "many_to_one/one_to_many not referencing primary key" do
475
454
  String :name
476
455
  end
477
456
  class ::Client < Sequel::Model
478
- one_to_many :invoices, :reciprocal=>:client, \
479
- :dataset=>proc{Invoice.filter(:client_name=>name)}, \
457
+ one_to_many :invoices, :reciprocal=>:client,
458
+ :adder=>(proc do |invoice|
459
+ invoice.client_name = name
460
+ invoice.save
461
+ end),
462
+ :remover=>(proc do |invoice|
463
+ invoice.client_name = nil
464
+ invoice.save
465
+ end),
466
+ :clearer=>proc{invoices_dataset.update(:client_name=>nil)},
467
+ :dataset=>proc{Invoice.filter(:client_name=>name)},
480
468
  :eager_loader=>(proc do |eo|
481
469
  id_map = {}
482
470
  eo[:rows].each do |client|
@@ -488,20 +476,6 @@ describe "many_to_one/one_to_many not referencing primary key" do
488
476
  client.associations[:invoices] << inv
489
477
  end
490
478
  end)
491
-
492
- private
493
-
494
- def _add_invoice(invoice)
495
- invoice.client_name = name
496
- invoice.save
497
- end
498
- def _remove_invoice(invoice)
499
- invoice.client_name = nil
500
- invoice.save
501
- end
502
- def _remove_all_invoices
503
- Invoice.filter(:client_name=>name).update(:client_name=>nil)
504
- end
505
479
  end
506
480
 
507
481
  INTEGRATION_DB.create_table!(:invoices) do
@@ -509,8 +483,9 @@ describe "many_to_one/one_to_many not referencing primary key" do
509
483
  String :client_name
510
484
  end
511
485
  class ::Invoice < Sequel::Model
512
- many_to_one :client, :key=>:client_name, \
513
- :dataset=>proc{Client.filter(:name=>client_name)}, \
486
+ many_to_one :client, :key=>:client_name,
487
+ :setter=>proc{|client| self.client_name = (client.name if client)},
488
+ :dataset=>proc{Client.filter(:name=>client_name)},
514
489
  :eager_loader=>(proc do |eo|
515
490
  id_map = eo[:id_map]
516
491
  eo[:rows].each{|inv| inv.associations[:client] = nil}
@@ -518,12 +493,6 @@ describe "many_to_one/one_to_many not referencing primary key" do
518
493
  id_map[client.name].each{|inv| inv.associations[:client] = client}
519
494
  end
520
495
  end)
521
-
522
- private
523
-
524
- def _client=(client)
525
- self.client_name = (client.name if client)
526
- end
527
496
  end
528
497
  end
529
498
  before do
@@ -596,7 +565,7 @@ describe "many_to_one/one_to_many not referencing primary key" do
596
565
  end
597
566
 
598
567
  it "should remove all associated objects correctly" do
599
- invs = @client1.remove_all_invoices
568
+ @client1.remove_all_invoices
600
569
  @invoice1.refresh.client.should == nil
601
570
  @invoice1.client_name.should == nil
602
571
  @invoice2.refresh.client.should == nil
@@ -159,12 +159,12 @@ describe "Sequel::Model basic support" do
159
159
  end
160
160
 
161
161
  specify ".to_hash should return a hash keyed on primary key if no argument provided" do
162
- i = Item.create(:name=>'J')
162
+ Item.create(:name=>'J')
163
163
  Item.to_hash.should == {1=>Item.load(:id=>1, :name=>'J')}
164
164
  end
165
165
 
166
166
  specify ".to_hash should return a hash keyed on argument if one argument provided" do
167
- i = Item.create(:name=>'J')
167
+ Item.create(:name=>'J')
168
168
  Item.to_hash(:name).should == {'J'=>Item.load(:id=>1, :name=>'J')}
169
169
  end
170
170
 
@@ -429,14 +429,12 @@ describe "Lazy Attributes plugin" do
429
429
 
430
430
  specify "should load lazy attribute for all items returned when accessing any item if using identity map " do
431
431
  Item.create(:name=>'K', :num=>2)
432
- Item.with_identity_map do
433
- a = Item.order(:name).all
434
- a.should == [Item.load(:id=>1, :name=>'J'), Item.load(:id=>2, :name=>'K')]
435
- a.map{|x| x[:num]}.should == [nil, nil]
436
- a.first.num.should == 1
437
- a.map{|x| x[:num]}.should == [1, 2]
438
- a.last.num.should == 2
439
- end
432
+ a = Item.order(:name).all
433
+ a.should == [Item.load(:id=>1, :name=>'J'), Item.load(:id=>2, :name=>'K')]
434
+ a.map{|x| x[:num]}.should == [nil, nil]
435
+ a.first.num.should == 1
436
+ a.map{|x| x[:num]}.should == [1, 2]
437
+ a.last.num.should == 2
440
438
  end
441
439
  end
442
440
 
@@ -1879,20 +1877,23 @@ describe "Sequel::Plugins::ConstraintValidations" do
1879
1877
  @db.create_constraint_validations_table
1880
1878
  @ds = @db[:cv_test]
1881
1879
  @regexp = regexp = @db.dataset.supports_regexp?
1882
- @validate_block = proc do
1883
- presence :pre, :name=>:p
1884
- exact_length 5, :exactlen, :name=>:el
1885
- min_length 5, :minlen, :name=>:minl
1886
- max_length 5, :maxlen, :name=>:maxl
1887
- length_range 3..5, :lenrange, :name=>:lr
1880
+ @validation_opts = {}
1881
+ opts_proc = proc{@validation_opts}
1882
+ @validate_block = proc do |opts|
1883
+ opts = opts_proc.call
1884
+ presence :pre, opts.merge(:name=>:p)
1885
+ exact_length 5, :exactlen, opts.merge(:name=>:el)
1886
+ min_length 5, :minlen, opts.merge(:name=>:minl)
1887
+ max_length 5, :maxlen, opts.merge(:name=>:maxl)
1888
+ length_range 3..5, :lenrange, opts.merge(:name=>:lr)
1888
1889
  if regexp
1889
- format /^foo\d+/, :form, :name=>:f
1890
+ format(/^foo\d+/, :form, opts.merge(:name=>:f))
1890
1891
  end
1891
- like 'foo%', :lik, :name=>:l
1892
- ilike 'foo%', :ilik, :name=>:il
1893
- includes %w'abc def', :inc, :name=>:i
1894
- unique :uniq, :name=>:u
1895
- max_length 6, :minlen, :name=>:maxl2
1892
+ like 'foo%', :lik, opts.merge(:name=>:l)
1893
+ ilike 'foo%', :ilik, opts.merge(:name=>:il)
1894
+ includes %w'abc def', :inc, opts.merge(:name=>:i)
1895
+ unique :uniq, opts.merge(:name=>:u)
1896
+ max_length 6, :minlen, opts.merge(:name=>:maxl2)
1896
1897
  end
1897
1898
  @valid_row = {:pre=>'a', :exactlen=>'12345', :minlen=>'12345', :maxlen=>'12345', :lenrange=>'1234', :lik=>'fooabc', :ilik=>'FooABC', :inc=>'abc', :uniq=>'u'}
1898
1899
  @violations = [
@@ -1927,6 +1928,7 @@ describe "Sequel::Plugins::ConstraintValidations" do
1927
1928
  try = @valid_row.dup
1928
1929
  vals += ['1234567'] if col == :minlen
1929
1930
  vals.each do |val|
1931
+ next if val.nil? && @validation_opts[:allow_nil]
1930
1932
  try[col] = val
1931
1933
  proc{@ds.insert(try)}.should raise_error(Sequel::DatabaseError)
1932
1934
  end
@@ -1950,32 +1952,36 @@ describe "Sequel::Plugins::ConstraintValidations" do
1950
1952
  @violations.each do |col, vals|
1951
1953
  try = @valid_row.dup
1952
1954
  vals.each do |val|
1955
+ next if val.nil? && @validation_opts[:allow_nil]
1953
1956
  try[col] = val
1954
1957
  c.new(try).should_not be_valid
1955
1958
  end
1956
1959
  end
1960
+ c.db.constraint_validations = nil
1957
1961
  end
1958
1962
  end
1959
1963
 
1960
1964
  describe "via create_table" do
1961
1965
  before(:all) do
1962
- regexp = @regexp
1963
- validate_block = @validate_block
1964
- @db.create_table!(:cv_test) do
1965
- primary_key :id
1966
- String :pre
1967
- String :exactlen
1968
- String :minlen
1969
- String :maxlen
1970
- String :lenrange
1971
- if regexp
1972
- String :form
1966
+ @table_block = proc do
1967
+ regexp = @regexp
1968
+ validate_block = @validate_block
1969
+ @db.create_table!(:cv_test) do
1970
+ primary_key :id
1971
+ String :pre
1972
+ String :exactlen
1973
+ String :minlen
1974
+ String :maxlen
1975
+ String :lenrange
1976
+ if regexp
1977
+ String :form
1978
+ end
1979
+ String :lik
1980
+ String :ilik
1981
+ String :inc
1982
+ String :uniq, :null=>false
1983
+ validate(&validate_block)
1973
1984
  end
1974
- String :lik
1975
- String :ilik
1976
- String :inc
1977
- String :uniq, :null=>false
1978
- validate(&validate_block)
1979
1985
  end
1980
1986
  end
1981
1987
  after(:all) do
@@ -1983,30 +1989,44 @@ describe "Sequel::Plugins::ConstraintValidations" do
1983
1989
  @db.drop_constraint_validations_for(:table=>:cv_test)
1984
1990
  end
1985
1991
 
1986
- it_should_behave_like "constraint validations"
1992
+ describe "with :allow_nil=>true" do
1993
+ before(:all) do
1994
+ @validation_opts = {:allow_nil=>true}
1995
+ @table_block.call
1996
+ end
1997
+ it_should_behave_like "constraint validations"
1998
+ end
1999
+ describe "with :allow_nil=>false" do
2000
+ before(:all) do
2001
+ @table_block.call
2002
+ end
2003
+ it_should_behave_like "constraint validations"
2004
+ end
1987
2005
  end
1988
2006
 
1989
2007
  describe "via alter_table" do
1990
2008
  before(:all) do
1991
- regexp = @regexp
1992
- validate_block = @validate_block
1993
- @db.create_table!(:cv_test) do
1994
- primary_key :id
1995
- String :lik
1996
- String :ilik
1997
- String :inc
1998
- String :uniq, :null=>false
1999
- end
2000
- @db.alter_table(:cv_test) do
2001
- add_column :pre, String
2002
- add_column :exactlen, String
2003
- add_column :minlen, String
2004
- add_column :maxlen, String
2005
- add_column :lenrange, String
2006
- if regexp
2007
- add_column :form, String
2009
+ @table_block = proc do
2010
+ regexp = @regexp
2011
+ validate_block = @validate_block
2012
+ @db.create_table!(:cv_test) do
2013
+ primary_key :id
2014
+ String :lik
2015
+ String :ilik
2016
+ String :inc
2017
+ String :uniq, :null=>false
2018
+ end
2019
+ @db.alter_table(:cv_test) do
2020
+ add_column :pre, String
2021
+ add_column :exactlen, String
2022
+ add_column :minlen, String
2023
+ add_column :maxlen, String
2024
+ add_column :lenrange, String
2025
+ if regexp
2026
+ add_column :form, String
2027
+ end
2028
+ validate(&validate_block)
2008
2029
  end
2009
- validate(&validate_block)
2010
2030
  end
2011
2031
  end
2012
2032
  after(:all) do
@@ -2014,7 +2034,19 @@ describe "Sequel::Plugins::ConstraintValidations" do
2014
2034
  @db.drop_constraint_validations_for(:table=>:cv_test)
2015
2035
  end
2016
2036
 
2017
- it_should_behave_like "constraint validations"
2037
+ describe "with :allow_nil=>true" do
2038
+ before(:all) do
2039
+ @validation_opts = {:allow_nil=>true}
2040
+ @table_block.call
2041
+ end
2042
+ it_should_behave_like "constraint validations"
2043
+ end
2044
+ describe "with :allow_nil=>false" do
2045
+ before(:all) do
2046
+ @table_block.call
2047
+ end
2048
+ it_should_behave_like "constraint validations"
2049
+ end
2018
2050
  end
2019
2051
  end
2020
2052
 
@@ -350,7 +350,7 @@ describe "Dataset#unbind" do
350
350
  end
351
351
  ds.insert(:c=>v)
352
352
  end
353
- @u = proc{|ds| ds, bv = ds.unbind; ds.call(:first, bv)}
353
+ @u = proc{|ds1| ds2, bv = ds1.unbind; ds2.call(:first, bv)}
354
354
  end
355
355
  after do
356
356
  INTEGRATION_DB.drop_table?(:items)
@@ -146,7 +146,7 @@ describe "Database schema parser" do
146
146
  INTEGRATION_DB.create_table!(:items){FalseClass :number}
147
147
  INTEGRATION_DB.schema(:items).first.last[:type].should == :boolean
148
148
  end
149
- end if INTEGRATION_DB.respond_to?(:schema_parse_table, true)
149
+ end if INTEGRATION_DB.supports_schema_parsing?
150
150
 
151
151
  test_indexes = begin
152
152
  INTEGRATION_DB.drop_table?(:blah)
@@ -2,7 +2,6 @@ require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
2
2
 
3
3
  describe "Sequel timezone support" do
4
4
  def test_timezone(timezone=Sequel.application_timezone)
5
- tz = timezone
6
5
  Sequel.datetime_class = Time
7
6
  # Tests should cover both DST and non-DST times.
8
7
  [Time.now, Time.local(2010,1,1,12), Time.local(2010,6,1,12)].each do |t|
@@ -114,7 +114,6 @@ describe "Database transactions" do
114
114
  transaction do
115
115
  self[:items] << {:name => 'abc'}
116
116
  return
117
- self[:items] << {:name => 'd'}
118
117
  end
119
118
  end
120
119