sequel 4.47.0 → 4.48.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 (177) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +134 -0
  3. data/Rakefile +1 -1
  4. data/doc/release_notes/4.48.0.txt +293 -0
  5. data/lib/sequel/adapters/ado/access.rb +2 -1
  6. data/lib/sequel/adapters/do/postgres.rb +5 -2
  7. data/lib/sequel/adapters/ibmdb.rb +24 -7
  8. data/lib/sequel/adapters/jdbc.rb +36 -22
  9. data/lib/sequel/adapters/jdbc/db2.rb +12 -3
  10. data/lib/sequel/adapters/jdbc/derby.rb +4 -5
  11. data/lib/sequel/adapters/jdbc/oracle.rb +16 -2
  12. data/lib/sequel/adapters/jdbc/postgresql.rb +43 -18
  13. data/lib/sequel/adapters/jdbc/sqlanywhere.rb +9 -7
  14. data/lib/sequel/adapters/jdbc/sqlserver.rb +11 -4
  15. data/lib/sequel/adapters/mock.rb +24 -19
  16. data/lib/sequel/adapters/mysql.rb +17 -16
  17. data/lib/sequel/adapters/mysql2.rb +4 -5
  18. data/lib/sequel/adapters/oracle.rb +5 -9
  19. data/lib/sequel/adapters/postgres.rb +89 -102
  20. data/lib/sequel/adapters/shared/db2.rb +22 -6
  21. data/lib/sequel/adapters/shared/mssql.rb +5 -4
  22. data/lib/sequel/adapters/shared/mysql.rb +75 -24
  23. data/lib/sequel/adapters/shared/postgres.rb +196 -94
  24. data/lib/sequel/adapters/shared/sqlanywhere.rb +23 -10
  25. data/lib/sequel/adapters/shared/sqlite.rb +72 -82
  26. data/lib/sequel/adapters/sqlanywhere.rb +4 -1
  27. data/lib/sequel/adapters/sqlite.rb +5 -3
  28. data/lib/sequel/adapters/swift/postgres.rb +5 -2
  29. data/lib/sequel/adapters/tinytds.rb +0 -5
  30. data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -1
  31. data/lib/sequel/adapters/utils/pg_types.rb +2 -76
  32. data/lib/sequel/core.rb +2 -2
  33. data/lib/sequel/database/connecting.rb +5 -5
  34. data/lib/sequel/database/dataset.rb +6 -3
  35. data/lib/sequel/database/misc.rb +1 -1
  36. data/lib/sequel/database/query.rb +3 -0
  37. data/lib/sequel/database/schema_methods.rb +1 -1
  38. data/lib/sequel/dataset/actions.rb +18 -10
  39. data/lib/sequel/dataset/graph.rb +1 -1
  40. data/lib/sequel/dataset/misc.rb +1 -0
  41. data/lib/sequel/dataset/prepared_statements.rb +3 -3
  42. data/lib/sequel/dataset/query.rb +19 -8
  43. data/lib/sequel/extensions/core_extensions.rb +4 -1
  44. data/lib/sequel/extensions/duplicate_columns_handler.rb +1 -1
  45. data/lib/sequel/extensions/empty_array_ignore_nulls.rb +3 -0
  46. data/lib/sequel/extensions/filter_having.rb +2 -0
  47. data/lib/sequel/extensions/freeze_datasets.rb +2 -0
  48. data/lib/sequel/extensions/from_block.rb +1 -1
  49. data/lib/sequel/extensions/graph_each.rb +2 -2
  50. data/lib/sequel/extensions/hash_aliases.rb +2 -0
  51. data/lib/sequel/extensions/identifier_mangling.rb +0 -7
  52. data/lib/sequel/extensions/meta_def.rb +2 -0
  53. data/lib/sequel/extensions/migration.rb +6 -6
  54. data/lib/sequel/extensions/no_auto_literal_strings.rb +1 -1
  55. data/lib/sequel/extensions/pagination.rb +1 -1
  56. data/lib/sequel/extensions/pg_array.rb +207 -130
  57. data/lib/sequel/extensions/pg_hstore.rb +38 -20
  58. data/lib/sequel/extensions/pg_inet.rb +18 -6
  59. data/lib/sequel/extensions/pg_interval.rb +19 -12
  60. data/lib/sequel/extensions/pg_json.rb +25 -14
  61. data/lib/sequel/extensions/pg_json_ops.rb +2 -2
  62. data/lib/sequel/extensions/pg_range.rb +133 -100
  63. data/lib/sequel/extensions/pg_range_ops.rb +4 -3
  64. data/lib/sequel/extensions/pg_row.rb +68 -39
  65. data/lib/sequel/extensions/pg_row_ops.rb +11 -5
  66. data/lib/sequel/extensions/query_literals.rb +2 -0
  67. data/lib/sequel/extensions/ruby18_symbol_extensions.rb +2 -0
  68. data/lib/sequel/extensions/s.rb +1 -1
  69. data/lib/sequel/extensions/schema_dumper.rb +24 -24
  70. data/lib/sequel/extensions/sequel_3_dataset_methods.rb +3 -1
  71. data/lib/sequel/extensions/sequel_4_dataset_methods.rb +83 -0
  72. data/lib/sequel/extensions/set_overrides.rb +2 -2
  73. data/lib/sequel/extensions/string_agg.rb +0 -1
  74. data/lib/sequel/extensions/symbol_aref.rb +0 -4
  75. data/lib/sequel/model.rb +25 -57
  76. data/lib/sequel/model/associations.rb +14 -5
  77. data/lib/sequel/model/base.rb +96 -32
  78. data/lib/sequel/plugins/association_pks.rb +73 -46
  79. data/lib/sequel/plugins/association_proxies.rb +1 -1
  80. data/lib/sequel/plugins/auto_validations.rb +6 -2
  81. data/lib/sequel/plugins/boolean_readers.rb +1 -1
  82. data/lib/sequel/plugins/caching.rb +19 -13
  83. data/lib/sequel/plugins/class_table_inheritance.rb +19 -10
  84. data/lib/sequel/plugins/column_conflicts.rb +7 -2
  85. data/lib/sequel/plugins/column_select.rb +1 -1
  86. data/lib/sequel/plugins/csv_serializer.rb +8 -8
  87. data/lib/sequel/plugins/defaults_setter.rb +10 -0
  88. data/lib/sequel/plugins/eager_each.rb +1 -1
  89. data/lib/sequel/plugins/force_encoding.rb +2 -2
  90. data/lib/sequel/plugins/hook_class_methods.rb +9 -12
  91. data/lib/sequel/plugins/identifier_columns.rb +2 -0
  92. data/lib/sequel/plugins/instance_filters.rb +3 -1
  93. data/lib/sequel/plugins/instance_hooks.rb +17 -9
  94. data/lib/sequel/plugins/json_serializer.rb +17 -10
  95. data/lib/sequel/plugins/lazy_attributes.rb +8 -7
  96. data/lib/sequel/plugins/modification_detection.rb +3 -0
  97. data/lib/sequel/plugins/nested_attributes.rb +5 -1
  98. data/lib/sequel/plugins/pg_array_associations.rb +5 -0
  99. data/lib/sequel/plugins/prepared_statements.rb +1 -0
  100. data/lib/sequel/plugins/rcte_tree.rb +4 -4
  101. data/lib/sequel/plugins/serialization.rb +3 -10
  102. data/lib/sequel/plugins/single_table_inheritance.rb +2 -2
  103. data/lib/sequel/plugins/split_values.rb +6 -5
  104. data/lib/sequel/plugins/static_cache.rb +31 -25
  105. data/lib/sequel/plugins/subset_conditions.rb +3 -1
  106. data/lib/sequel/plugins/table_select.rb +1 -1
  107. data/lib/sequel/plugins/touch.rb +2 -1
  108. data/lib/sequel/plugins/validation_class_methods.rb +5 -6
  109. data/lib/sequel/plugins/validation_helpers.rb +2 -4
  110. data/lib/sequel/plugins/xml_serializer.rb +4 -4
  111. data/lib/sequel/sql.rb +2 -2
  112. data/lib/sequel/version.rb +1 -1
  113. data/spec/adapters/db2_spec.rb +115 -14
  114. data/spec/adapters/mysql_spec.rb +78 -28
  115. data/spec/adapters/oracle_spec.rb +24 -24
  116. data/spec/adapters/postgres_spec.rb +38 -24
  117. data/spec/adapters/sqlanywhere_spec.rb +88 -86
  118. data/spec/adapters/sqlite_spec.rb +29 -24
  119. data/spec/core/connection_pool_spec.rb +17 -0
  120. data/spec/core/database_spec.rb +6 -0
  121. data/spec/core/dataset_spec.rb +46 -36
  122. data/spec/core/schema_spec.rb +16 -0
  123. data/spec/core/spec_helper.rb +1 -0
  124. data/spec/core_extensions_spec.rb +6 -2
  125. data/spec/extensions/active_model_spec.rb +1 -1
  126. data/spec/extensions/arbitrary_servers_spec.rb +1 -1
  127. data/spec/extensions/association_pks_spec.rb +34 -2
  128. data/spec/extensions/auto_literal_strings_spec.rb +5 -1
  129. data/spec/extensions/auto_validations_spec.rb +2 -0
  130. data/spec/extensions/boolean_readers_spec.rb +1 -1
  131. data/spec/extensions/boolean_subsets_spec.rb +1 -1
  132. data/spec/extensions/class_table_inheritance_spec.rb +48 -2
  133. data/spec/extensions/column_conflicts_spec.rb +11 -0
  134. data/spec/extensions/connection_validator_spec.rb +1 -1
  135. data/spec/extensions/dataset_associations_spec.rb +8 -8
  136. data/spec/extensions/defaults_setter_spec.rb +1 -1
  137. data/spec/extensions/filter_having_spec.rb +5 -3
  138. data/spec/extensions/hash_aliases_spec.rb +3 -1
  139. data/spec/extensions/identifier_columns_spec.rb +3 -1
  140. data/spec/extensions/implicit_subquery_spec.rb +4 -2
  141. data/spec/extensions/json_serializer_spec.rb +18 -0
  142. data/spec/extensions/lazy_attributes_spec.rb +3 -3
  143. data/spec/extensions/meta_def_spec.rb +9 -0
  144. data/spec/extensions/migration_spec.rb +3 -3
  145. data/spec/extensions/nested_attributes_spec.rb +14 -3
  146. data/spec/extensions/no_auto_literal_strings_spec.rb +8 -4
  147. data/spec/extensions/pg_array_associations_spec.rb +29 -18
  148. data/spec/extensions/pg_array_spec.rb +44 -25
  149. data/spec/extensions/pg_hstore_spec.rb +10 -0
  150. data/spec/extensions/pg_inet_spec.rb +26 -0
  151. data/spec/extensions/pg_interval_spec.rb +20 -0
  152. data/spec/extensions/pg_json_spec.rb +24 -0
  153. data/spec/extensions/pg_range_spec.rb +98 -14
  154. data/spec/extensions/pg_row_spec.rb +14 -4
  155. data/spec/extensions/prepared_statements_safe_spec.rb +1 -1
  156. data/spec/extensions/query_literals_spec.rb +3 -1
  157. data/spec/extensions/schema_dumper_spec.rb +96 -98
  158. data/spec/extensions/sequel_3_dataset_methods_spec.rb +10 -6
  159. data/spec/extensions/sequel_4_dataset_methods_spec.rb +121 -0
  160. data/spec/extensions/single_table_inheritance_spec.rb +1 -1
  161. data/spec/extensions/spec_helper.rb +7 -1
  162. data/spec/extensions/static_cache_spec.rb +75 -24
  163. data/spec/extensions/string_agg_spec.rb +1 -1
  164. data/spec/extensions/touch_spec.rb +9 -0
  165. data/spec/extensions/validation_helpers_spec.rb +9 -3
  166. data/spec/extensions/whitelist_security_spec.rb +26 -0
  167. data/spec/integration/dataset_test.rb +45 -44
  168. data/spec/integration/plugin_test.rb +20 -0
  169. data/spec/integration/prepared_statement_test.rb +3 -0
  170. data/spec/integration/schema_test.rb +21 -1
  171. data/spec/integration/transaction_test.rb +40 -40
  172. data/spec/model/class_dataset_methods_spec.rb +14 -4
  173. data/spec/model/dataset_methods_spec.rb +12 -3
  174. data/spec/model/model_spec.rb +8 -0
  175. metadata +6 -4
  176. data/spec/adapters/firebird_spec.rb +0 -405
  177. data/spec/adapters/informix_spec.rb +0 -100
@@ -15,8 +15,8 @@ describe "Simple Dataset operations" do
15
15
  end
16
16
 
17
17
  it "should support sequential primary keys" do
18
- @ds << {:number=>20}
19
- @ds << {:number=>30}
18
+ @ds.insert(:number=>20)
19
+ @ds.insert(:number=>30)
20
20
  @ds.order(:number).all.must_equal [
21
21
  {:id => 1, :number=>10},
22
22
  {:id => 2, :number=>20},
@@ -28,8 +28,8 @@ describe "Simple Dataset operations" do
28
28
  primary_key :id, :type=>:Bignum
29
29
  Integer :number
30
30
  end
31
- @ds << {:number=>20}
32
- @ds << {:number=>30}
31
+ @ds.insert(:number=>20)
32
+ @ds.insert(:number=>30)
33
33
  @ds.order(:number).all.must_equal [{:id => 1, :number=>20}, {:id => 2, :number=>30}]
34
34
  end
35
35
 
@@ -49,7 +49,7 @@ describe "Simple Dataset operations" do
49
49
  @ds.filter(:id=>2).first[:number].must_equal 20
50
50
  end
51
51
 
52
- it "should have insert_multiple return primary key values" do
52
+ deprecated "should have insert_multiple return primary key values" do
53
53
  @ds.extension(:sequel_3_dataset_methods).insert_multiple([{:number=>20}, {:number=>30}]).must_equal [2, 3]
54
54
  @ds.filter(:id=>2).get(:number).must_equal 20
55
55
  @ds.filter(:id=>3).get(:number).must_equal 30
@@ -60,7 +60,7 @@ describe "Simple Dataset operations" do
60
60
  end
61
61
 
62
62
  it "should handle LATERAL subqueries correctly" do
63
- @ds << {:number=>20}
63
+ @ds.insert(:number=>20)
64
64
  @ds.from(Sequel[:items].as(:i), @ds.where(Sequel[:items][:number]=>Sequel[:i][:number]).lateral).select_order_map([Sequel[:i][:number].as(:n), Sequel[:t1][:number]]).must_equal [[10, 10], [20, 20]]
65
65
  @ds.from(Sequel[:items].as(:i)).cross_join(@ds.where(Sequel[:items][:number]=>Sequel[:i][:number]).lateral).select_order_map([Sequel[:i][:number].as(:n), Sequel[:t1][:number]]).must_equal [[10, 10], [20, 20]]
66
66
  @ds.from(Sequel[:items].as(:i)).join(@ds.where(Sequel[:items][:number]=>Sequel[:i][:number]).lateral, 1=>1).select_order_map([Sequel[:i][:number].as(:n), Sequel[:t1][:number]]).must_equal [[10, 10], [20, 20]]
@@ -389,9 +389,9 @@ describe Sequel::Dataset do
389
389
 
390
390
  it "should return the correct record count" do
391
391
  @d.count.must_equal 0
392
- @d << {:name => 'abc', :value => 123}
393
- @d << {:name => 'abc', :value => 456}
394
- @d << {:name => 'def', :value => nil}
392
+ @d.insert(:name => 'abc', :value => 123)
393
+ @d.insert(:name => 'abc', :value => 456)
394
+ @d.insert(:name => 'def', :value => nil)
395
395
  5.times do
396
396
  @d.count.must_equal 3
397
397
  @d.count(:name).must_equal 3
@@ -400,14 +400,14 @@ describe Sequel::Dataset do
400
400
  end
401
401
 
402
402
  it "should handle functions with identifier names correctly" do
403
- @d << {:name => 'abc', :value => 6}
403
+ @d.insert(:name => 'abc', :value => 6)
404
404
  @d.get{sum.function(:value)}.must_equal 6
405
405
  end
406
406
 
407
407
  it "should handle aggregate methods on limited datasets correctly" do
408
- @d << {:name => 'abc', :value => 6}
409
- @d << {:name => 'bcd', :value => 12}
410
- @d << {:name => 'def', :value => 18}
408
+ @d.insert(:name => 'abc', :value => 6)
409
+ @d.insert(:name => 'bcd', :value => 12)
410
+ @d.insert(:name => 'def', :value => 18)
411
411
  @d = @d.order(:name).limit(2)
412
412
  @d.count.must_equal 2
413
413
  @d.avg(:value).to_i.must_equal 9
@@ -415,14 +415,14 @@ describe Sequel::Dataset do
415
415
  @d.reverse.min(:value).to_i.must_equal 12
416
416
  @d.max(:value).to_i.must_equal 12
417
417
  @d.sum(:value).to_i.must_equal 18
418
- @d.interval(:value).to_i.must_equal 6
418
+ @d.extension(:sequel_4_dataset_methods).interval(:value).to_i.must_equal 6
419
419
  end
420
420
 
421
421
  it "should return the correct records" do
422
422
  @d.to_a.must_equal []
423
- @d << {:name => 'abc', :value => 123}
424
- @d << {:name => 'abc', :value => 456}
425
- @d << {:name => 'def', :value => 789}
423
+ @d.insert(:name => 'abc', :value => 123)
424
+ @d.insert(:name => 'abc', :value => 456)
425
+ @d.insert(:name => 'def', :value => 789)
426
426
 
427
427
  @d.order(:value).to_a.must_equal [
428
428
  {:name => 'abc', :value => 123},
@@ -432,27 +432,27 @@ describe Sequel::Dataset do
432
432
  end
433
433
 
434
434
  it "should update records correctly" do
435
- @d << {:name => 'abc', :value => 123}
436
- @d << {:name => 'abc', :value => 456}
437
- @d << {:name => 'def', :value => 789}
435
+ @d.insert(:name => 'abc', :value => 123)
436
+ @d.insert(:name => 'abc', :value => 456)
437
+ @d.insert(:name => 'def', :value => 789)
438
438
  @d.filter(:name => 'abc').update(:value => 530)
439
439
  @d[:name => 'def'][:value].must_equal 789
440
440
  @d.filter(:value => 530).count.must_equal 2
441
441
  end
442
442
 
443
443
  it "should delete records correctly" do
444
- @d << {:name => 'abc', :value => 123}
445
- @d << {:name => 'abc', :value => 456}
446
- @d << {:name => 'def', :value => 789}
444
+ @d.insert(:name => 'abc', :value => 123)
445
+ @d.insert(:name => 'abc', :value => 456)
446
+ @d.insert(:name => 'def', :value => 789)
447
447
  @d.filter(:name => 'abc').delete
448
448
  @d.count.must_equal 1
449
449
  @d.first[:name].must_equal 'def'
450
450
  end
451
451
 
452
452
  it "should be able to truncate the table" do
453
- @d << {:name => 'abc', :value => 123}
454
- @d << {:name => 'abc', :value => 456}
455
- @d << {:name => 'def', :value => 789}
453
+ @d.insert(:name => 'abc', :value => 123)
454
+ @d.insert(:name => 'abc', :value => 456)
455
+ @d.insert(:name => 'def', :value => 789)
456
456
  @d.count.must_equal 3
457
457
  @d.truncate.must_be_nil
458
458
  @d.count.must_equal 0
@@ -517,9 +517,9 @@ describe Sequel::Dataset do
517
517
  Integer :value
518
518
  end
519
519
  @d = DB[:items]
520
- @d << {:value => 123}
521
- @d << {:value => 456}
522
- @d << {:value => 789}
520
+ @d.insert(:value => 123)
521
+ @d.insert(:value => 456)
522
+ @d.insert(:value => 789)
523
523
  end
524
524
  after do
525
525
  DB.drop_table?(:items)
@@ -1055,7 +1055,7 @@ describe "Sequel::Dataset convenience methods" do
1055
1055
  @db.drop_table?(:a)
1056
1056
  end
1057
1057
 
1058
- it "#[]= should update matching rows" do
1058
+ deprecated "#[]= should update matching rows" do
1059
1059
  @ds.insert(20, 10)
1060
1060
  @ds.extension(:sequel_3_dataset_methods)[:a=>20] = {:b=>30}
1061
1061
  @ds.all.must_equal [{:a=>20, :b=>30}]
@@ -1104,7 +1104,7 @@ describe "Sequel::Dataset convenience methods" do
1104
1104
  end
1105
1105
 
1106
1106
  it "#range should return the range between the maximum and minimum values" do
1107
- @ds = @ds.unordered
1107
+ @ds = @ds.unordered.extension(:sequel_4_dataset_methods)
1108
1108
  @ds.insert(20, 10)
1109
1109
  @ds.insert(30, 10)
1110
1110
  @ds.range(:a).must_equal(20..30)
@@ -1112,7 +1112,7 @@ describe "Sequel::Dataset convenience methods" do
1112
1112
  end
1113
1113
 
1114
1114
  it "#interval should return the different between the maximum and minimum values" do
1115
- @ds = @ds.unordered
1115
+ @ds = @ds.unordered.extension(:sequel_4_dataset_methods)
1116
1116
  @ds.insert(20, 10)
1117
1117
  @ds.insert(30, 10)
1118
1118
  @ds.interval(:a).to_i.must_equal 10
@@ -1147,10 +1147,10 @@ describe "Sequel::Dataset main SQL methods" do
1147
1147
  @ds.filter(Sequel.lit("b < ?", 15)).invert.all.must_equal [{:a=>20, :b=>30}]
1148
1148
  end
1149
1149
 
1150
- it "#and and #or should work correctly" do
1150
+ it "#where and #or should work correctly" do
1151
1151
  @ds.insert(20, 30)
1152
- @ds.filter(:a=>20).and(:b=>30).all.must_equal [{:a=>20, :b=>30}]
1153
- @ds.filter(:a=>20).and(:b=>15).all.must_equal []
1152
+ @ds.filter(:a=>20).where(:b=>30).all.must_equal [{:a=>20, :b=>30}]
1153
+ @ds.filter(:a=>20).where(:b=>15).all.must_equal []
1154
1154
  @ds.filter(:a=>20).or(:b=>15).all.must_equal [{:a=>20, :b=>30}]
1155
1155
  @ds.filter(:a=>10).or(:b=>15).all.must_equal []
1156
1156
  end
@@ -1212,17 +1212,18 @@ describe "Sequel::Dataset convenience methods" do
1212
1212
  @ds.map([:a, :b]).must_equal [[1, 2], [5, 6]]
1213
1213
  end
1214
1214
 
1215
- it "should have working #to_hash" do
1215
+ it "should have working #as_hash" do
1216
1216
  @ds.to_hash(:a).must_equal(1=>{:a=>1, :b=>2, :c=>3, :d=>4}, 5=>{:a=>5, :b=>6, :c=>7, :d=>8})
1217
- @ds.to_hash(:b).must_equal(2=>{:a=>1, :b=>2, :c=>3, :d=>4}, 6=>{:a=>5, :b=>6, :c=>7, :d=>8})
1218
- @ds.to_hash([:a, :b]).must_equal([1, 2]=>{:a=>1, :b=>2, :c=>3, :d=>4}, [5, 6]=>{:a=>5, :b=>6, :c=>7, :d=>8})
1217
+ @ds.as_hash(:a).must_equal(1=>{:a=>1, :b=>2, :c=>3, :d=>4}, 5=>{:a=>5, :b=>6, :c=>7, :d=>8})
1218
+ @ds.as_hash(:b).must_equal(2=>{:a=>1, :b=>2, :c=>3, :d=>4}, 6=>{:a=>5, :b=>6, :c=>7, :d=>8})
1219
+ @ds.as_hash([:a, :b]).must_equal([1, 2]=>{:a=>1, :b=>2, :c=>3, :d=>4}, [5, 6]=>{:a=>5, :b=>6, :c=>7, :d=>8})
1219
1220
 
1220
- @ds.to_hash(:a, :b).must_equal(1=>2, 5=>6)
1221
- @ds.to_hash([:a, :c], :b).must_equal([1, 3]=>2, [5, 7]=>6)
1222
- @ds.to_hash(:a, [:b, :c]).must_equal(1=>[2, 3], 5=>[6, 7])
1223
- @ds.to_hash([:a, :c], [:b, :d]).must_equal([1, 3]=>[2, 4], [5, 7]=>[6, 8])
1221
+ @ds.as_hash(:a, :b).must_equal(1=>2, 5=>6)
1222
+ @ds.as_hash([:a, :c], :b).must_equal([1, 3]=>2, [5, 7]=>6)
1223
+ @ds.as_hash(:a, [:b, :c]).must_equal(1=>[2, 3], 5=>[6, 7])
1224
+ @ds.as_hash([:a, :c], [:b, :d]).must_equal([1, 3]=>[2, 4], [5, 7]=>[6, 8])
1224
1225
 
1225
- @ds.to_hash(:a, :b, :hash => (tmp = {})).must_be_same_as(tmp)
1226
+ @ds.as_hash(:a, :b, :hash => (tmp = {})).must_be_same_as(tmp)
1226
1227
  end
1227
1228
 
1228
1229
  it "should have working #to_hash_groups" do
@@ -1874,7 +1875,7 @@ describe "Dataset replace" do
1874
1875
  end
1875
1876
 
1876
1877
  it "should update a record if the condition is met" do
1877
- @d << {:id => 111}
1878
+ @d.insert(:id => 111)
1878
1879
  @d.all.must_equal [{:id => 111, :value => nil}]
1879
1880
  @d.replace(:id => 111, :value => 333)
1880
1881
  @d.all.must_equal [{:id => 111, :value => 333}]
@@ -1195,6 +1195,7 @@ describe "AssociationPks plugin" do
1195
1195
  class ::Album < Sequel::Model
1196
1196
  plugin :association_pks
1197
1197
  many_to_many :tags, :order=>:id, :delay_pks=>false
1198
+ many_to_many :uat_tags, :order=>Sequel[:tags][:id], :delay_pks=>false, :class=>:Tag, :right_key=>:tag_id, :association_pks_use_associated_table=>true
1198
1199
  end
1199
1200
  class ::Tag < Sequel::Model
1200
1201
  end
@@ -1260,6 +1261,10 @@ describe "AssociationPks plugin" do
1260
1261
  Album.order(:id).all.map{|a| a.tag_pks.sort}.must_equal [[@t1, @t2, @t3], [@t2], []]
1261
1262
  end
1262
1263
 
1264
+ it "should return correct associated pks for many_to_many associations using :association_pks_use_associated_table" do
1265
+ Album.order(:id).all.map{|a| a.uat_tag_pks.sort}.must_equal [[@t1, @t2, @t3], [@t2], []]
1266
+ end
1267
+
1263
1268
  it "should return correct associated right-side cpks for one_to_many associations" do
1264
1269
  Album.one_to_many :vocalists, :order=>:first
1265
1270
  Album.order(:id).all.map{|a| a.vocalist_pks.sort}.must_equal [[@v1, @v2, @v3], [], []]
@@ -1270,6 +1275,11 @@ describe "AssociationPks plugin" do
1270
1275
  Album.order(:id).all.map{|a| a.vocalist_pks.sort}.must_equal [[@v1, @v2, @v3], [@v2], []]
1271
1276
  end
1272
1277
 
1278
+ it "should return correct associated right-side cpks for many_to_many associations when using :association_pks_use_associated_table" do
1279
+ Album.many_to_many :vocalists, :join_table=>:albums_vocalists, :right_key=>[:first, :last], :order=>Sequel[:vocalists][:first], :association_pks_use_associated_table=>true
1280
+ Album.order(:id).all.map{|a| a.vocalist_pks.sort}.must_equal [[@v1, @v2, @v3], [@v2], []]
1281
+ end
1282
+
1273
1283
  it "should return correct associated pks for left-side cpks for one_to_many associations" do
1274
1284
  Vocalist.one_to_many :instruments, :key=>[:first, :last], :order=>:id
1275
1285
  Vocalist.order(:first, :last).all.map{|a| a.instrument_pks.sort}.must_equal [[@i1, @i2, @i3], [], []]
@@ -1280,6 +1290,11 @@ describe "AssociationPks plugin" do
1280
1290
  Vocalist.order(:first, :last).all.map{|a| a.instrument_pks.sort}.must_equal [[@i1, @i2, @i3], [@i2], []]
1281
1291
  end
1282
1292
 
1293
+ it "should return correct associated pks for left-side cpks for many_to_many associations when using :association_pks_use_associated_table" do
1294
+ Vocalist.many_to_many :instruments, :join_table=>:vocalists_instruments, :left_key=>[:first, :last], :order=>:id, :association_pks_use_associated_table=>true
1295
+ Vocalist.order(:first, :last).all.map{|a| a.instrument_pks.sort}.must_equal [[@i1, @i2, @i3], [@i2], []]
1296
+ end
1297
+
1283
1298
  it "should return correct associated right-side cpks for left-side cpks for one_to_many associations" do
1284
1299
  Vocalist.one_to_many :hits, :key=>[:first, :last], :order=>:week
1285
1300
  Vocalist.order(:first, :last).all.map{|a| a.hit_pks.sort}.must_equal [[@h1, @h2, @h3], [], []]
@@ -1290,6 +1305,11 @@ describe "AssociationPks plugin" do
1290
1305
  Vocalist.order(:first, :last).all.map{|a| a.hit_pks.sort}.must_equal [[@h1, @h2, @h3], [@h2], []]
1291
1306
  end
1292
1307
 
1308
+ it "should return correct associated right-side cpks for left-side cpks for many_to_many associations when using :association_pks_use_associated_table" do
1309
+ Vocalist.many_to_many :hits, :join_table=>:vocalists_hits, :left_key=>[:first, :last], :right_key=>[:year, :week], :order=>Sequel[:vocalists_hits][:week], :association_pks_use_associated_table=>true
1310
+ Vocalist.order(:first, :last).all.map{|a| a.hit_pks.sort}.must_equal [[@h1, @h2, @h3], [@h2], []]
1311
+ end
1312
+
1293
1313
  deprecated "should handle :delay_pks=>true association option for new instances" do
1294
1314
  album_class = Class.new(Album)
1295
1315
  album_class.many_to_many :tags, :clone=>:tags, :delay_pks=>true, :join_table=>:albums_tags, :left_key=>:album_id
@@ -22,6 +22,7 @@ describe "Prepared Statements and Bound Arguments" do
22
22
  @ds.filter(:numb=>:$n).call(:all, :n=>10).must_equal [{:id=>1, :numb=>10}]
23
23
  @ds.filter(:numb=>:$n).call(:first, :n=>10).must_equal(:id=>1, :numb=>10)
24
24
  @ds.filter(:numb=>:$n).call([:map, :numb], :n=>10).must_equal [10]
25
+ @ds.filter(:numb=>:$n).call([:as_hash, :id, :numb], :n=>10).must_equal(1=>10)
25
26
  @ds.filter(:numb=>:$n).call([:to_hash, :id, :numb], :n=>10).must_equal(1=>10)
26
27
  @ds.filter(:numb=>:$n).call([:to_hash_groups, :id, :numb], :n=>10).must_equal(1=>[10])
27
28
  end
@@ -161,6 +162,8 @@ describe "Prepared Statements and Bound Arguments" do
161
162
  @db.call(:select_n, :n=>10).must_equal(:id=>1, :numb=>10)
162
163
  @ds.filter(:numb=>:$n).prepare([:map, :numb], :select_n)
163
164
  @db.call(:select_n, :n=>10).must_equal [10]
165
+ @ds.filter(:numb=>:$n).prepare([:as_hash, :id, :numb], :select_n)
166
+ @db.call(:select_n, :n=>10).must_equal(1=>10)
164
167
  @ds.filter(:numb=>:$n).prepare([:to_hash, :id, :numb], :select_n)
165
168
  @db.call(:select_n, :n=>10).must_equal(1=>10)
166
169
  end
@@ -215,7 +215,7 @@ describe "Database index parsing" do
215
215
  DB.indexes(:items).must_equal({})
216
216
  end
217
217
 
218
- cspecify "should not include partial indexes", :sqlite do
218
+ it "should not include partial indexes" do
219
219
  DB.create_table!(:items){Integer :n; Integer :a; index :n, :where=>proc{n > 10}}
220
220
  DB.indexes(:items).must_equal({})
221
221
  end if DB.supports_partial_indexes?
@@ -387,6 +387,26 @@ describe "Database schema modifiers" do
387
387
  @db.table_exists?(:items).must_equal false
388
388
  end if DB.supports_transactional_ddl?
389
389
 
390
+ it "should handle errors creating indexes when ignoring index errors" do
391
+ @db.drop_table?(:items)
392
+ @db.transaction do
393
+ @db.create_table(:items, :ignore_index_errors=>true) do
394
+ Integer :n1
395
+ Integer :n2
396
+ index :n1, :name=>'items_n1'
397
+ index :foo, :name=>'items_f'
398
+ index :n2, :name=>'items_n2'
399
+ index :bar, :name=>'items_g'
400
+ end
401
+ end
402
+ @db.table_exists?(:items).must_equal true
403
+ indexes = @db.indexes(:items).keys
404
+ indexes.must_include :items_n1
405
+ indexes.must_include :items_n2
406
+ indexes.wont_include :items_f
407
+ indexes.wont_include :items_g
408
+ end if DB.supports_transactional_ddl? && DB.database_type != :mssql
409
+
390
410
  describe "join tables" do
391
411
  after do
392
412
  @db.drop_join_table(:cat_id=>:cats, :dog_id=>:dogs) if @db.table_exists?(:cats_dogs)
@@ -14,7 +14,7 @@ describe "Database transactions" do
14
14
  end
15
15
 
16
16
  it "should support transactions" do
17
- @db.transaction{@d << {:name => 'abc', :value => 1}}
17
+ @db.transaction{@d.insert(:name => 'abc', :value => 1)}
18
18
  @d.count.must_equal 1
19
19
  end
20
20
 
@@ -32,25 +32,25 @@ describe "Database transactions" do
32
32
  it "should correctly rollback transactions" do
33
33
  proc do
34
34
  @db.transaction do
35
- @d << {:name => 'abc', :value => 1}
35
+ @d.insert(:name => 'abc', :value => 1)
36
36
  raise Interrupt, 'asdf'
37
37
  end
38
38
  end.must_raise(Interrupt)
39
39
 
40
40
  @db.transaction do
41
- @d << {:name => 'abc', :value => 1}
41
+ @d.insert(:name => 'abc', :value => 1)
42
42
  raise Sequel::Rollback
43
43
  end.must_be_nil
44
44
 
45
45
  proc do
46
46
  @db.transaction(:rollback=>:reraise) do
47
- @d << {:name => 'abc', :value => 1}
47
+ @d.insert(:name => 'abc', :value => 1)
48
48
  raise Sequel::Rollback
49
49
  end
50
50
  end.must_raise(Sequel::Rollback)
51
51
 
52
52
  @db.transaction(:rollback=>:always) do
53
- @d << {:name => 'abc', :value => 1}
53
+ @d.insert(:name => 'abc', :value => 1)
54
54
  2
55
55
  end.must_equal 2
56
56
 
@@ -60,14 +60,14 @@ describe "Database transactions" do
60
60
  it "should support nested transactions" do
61
61
  @db.transaction do
62
62
  @db.transaction do
63
- @d << {:name => 'abc', :value => 1}
63
+ @d.insert(:name => 'abc', :value => 1)
64
64
  end
65
65
  end
66
66
  @d.count.must_equal 1
67
67
 
68
68
  @d.delete
69
69
  @db.transaction do
70
- @d << {:name => 'abc', :value => 1}
70
+ @d.insert(:name => 'abc', :value => 1)
71
71
  @db.transaction do
72
72
  raise Sequel::Rollback
73
73
  end
@@ -75,7 +75,7 @@ describe "Database transactions" do
75
75
  @d.count.must_equal 0
76
76
 
77
77
  proc {@db.transaction do
78
- @d << {:name => 'abc', :value => 1}
78
+ @d.insert(:name => 'abc', :value => 1)
79
79
  @db.transaction do
80
80
  raise Interrupt, 'asdf'
81
81
  end
@@ -86,9 +86,9 @@ describe "Database transactions" do
86
86
  if DB.supports_savepoints?
87
87
  it "should handle table_exists? failures inside transactions" do
88
88
  @db.transaction do
89
- @d << {:name => '1'}
89
+ @d.insert(:name => '1')
90
90
  @db.table_exists?(:asadf098asd9asd98sa).must_equal false
91
- @d << {:name => '2'}
91
+ @d.insert(:name => '2')
92
92
  end
93
93
  @d.select_order_map(:name).must_equal %w'1 2'
94
94
  end
@@ -96,7 +96,7 @@ describe "Database transactions" do
96
96
  it "should handle :rollback=>:always inside transactions" do
97
97
  @db.transaction do
98
98
  @db.transaction(:rollback=>:always) do
99
- @d << {:name => 'abc', :value => 1}
99
+ @d.insert(:name => 'abc', :value => 1)
100
100
  2
101
101
  end.must_equal 2
102
102
  end
@@ -105,36 +105,36 @@ describe "Database transactions" do
105
105
 
106
106
  it "should handle table_exists? failures inside savepoints" do
107
107
  @db.transaction do
108
- @d << {:name => '1'}
108
+ @d.insert(:name => '1')
109
109
  @db.transaction(:savepoint=>true) do
110
- @d << {:name => '2'}
110
+ @d.insert(:name => '2')
111
111
  @db.table_exists?(:asadf098asd9asd98sa).must_equal false
112
- @d << {:name => '3'}
112
+ @d.insert(:name => '3')
113
113
  end
114
- @d << {:name => '4'}
114
+ @d.insert(:name => '4')
115
115
  end
116
116
  @d.select_order_map(:name).must_equal %w'1 2 3 4'
117
117
  end
118
118
 
119
119
  it "should support nested transactions through savepoints using the savepoint option" do
120
120
  @db.transaction do
121
- @d << {:name => '1'}
121
+ @d.insert(:name => '1')
122
122
  @db.transaction(:savepoint=>true) do
123
- @d << {:name => '2'}
123
+ @d.insert(:name => '2')
124
124
  @db.transaction do
125
- @d << {:name => '3'}
125
+ @d.insert(:name => '3')
126
126
  raise Sequel::Rollback
127
127
  end
128
128
  end
129
- @d << {:name => '4'}
129
+ @d.insert(:name => '4')
130
130
  @db.transaction do
131
- @d << {:name => '6'}
131
+ @d.insert(:name => '6')
132
132
  @db.transaction(:savepoint=>true) do
133
- @d << {:name => '7'}
133
+ @d.insert(:name => '7')
134
134
  raise Sequel::Rollback
135
135
  end
136
136
  end
137
- @d << {:name => '5'}
137
+ @d.insert(:name => '5')
138
138
  end
139
139
 
140
140
  @d.order(:name).map(:name).must_equal %w{1 4 5 6}
@@ -142,23 +142,23 @@ describe "Database transactions" do
142
142
 
143
143
  it "should support nested transactions through savepoints using the auto_savepoint option" do
144
144
  @db.transaction(:auto_savepoint=>true) do
145
- @d << {:name => '1'}
145
+ @d.insert(:name => '1')
146
146
  @db.transaction do
147
- @d << {:name => '2'}
147
+ @d.insert(:name => '2')
148
148
  @db.transaction do
149
- @d << {:name => '3'}
149
+ @d.insert(:name => '3')
150
150
  raise Sequel::Rollback
151
151
  end
152
152
  end
153
- @d << {:name => '4'}
153
+ @d.insert(:name => '4')
154
154
  @db.transaction(:auto_savepoint=>true) do
155
- @d << {:name => '6'}
155
+ @d.insert(:name => '6')
156
156
  @db.transaction do
157
- @d << {:name => '7'}
157
+ @d.insert(:name => '7')
158
158
  raise Sequel::Rollback
159
159
  end
160
160
  end
161
- @d << {:name => '5'}
161
+ @d.insert(:name => '5')
162
162
  end
163
163
 
164
164
  @d.order(:name).map(:name).must_equal %w{1 4 5 6}
@@ -168,7 +168,7 @@ describe "Database transactions" do
168
168
  it "should handle returning inside of the block by committing" do
169
169
  def ret_commit
170
170
  @db.transaction do
171
- @db[:items] << {:name => 'abc'}
171
+ @db[:items].insert(:name => 'abc')
172
172
  return
173
173
  end
174
174
  end
@@ -199,20 +199,20 @@ describe "Database transactions" do
199
199
  end
200
200
 
201
201
  it "should commit prepared transactions using commit_prepared_transaction" do
202
- @db.transaction(:prepare=>'XYZ'){@d << {:name => '1'}}
202
+ @db.transaction(:prepare=>'XYZ'){@d.insert(:name => '1')}
203
203
  @db.commit_prepared_transaction('XYZ')
204
204
  @d.select_order_map(:name).must_equal ['1']
205
205
  end
206
206
 
207
207
  it "should rollback prepared transactions using rollback_prepared_transaction" do
208
- @db.transaction(:prepare=>'XYZ'){@d << {:name => '1'}}
208
+ @db.transaction(:prepare=>'XYZ'){@d.insert(:name => '1')}
209
209
  @db.rollback_prepared_transaction('XYZ')
210
210
  @d.select_order_map(:name).must_equal []
211
211
  end
212
212
 
213
213
  if DB.supports_savepoints_in_prepared_transactions?
214
214
  it "should support savepoints when using prepared transactions" do
215
- @db.transaction(:prepare=>'XYZ'){@db.transaction(:savepoint=>true){@d << {:name => '1'}}}
215
+ @db.transaction(:prepare=>'XYZ'){@db.transaction(:savepoint=>true){@d.insert(:name => '1')}}
216
216
  @db.commit_prepared_transaction('XYZ')
217
217
  @d.select_order_map(:name).must_equal ['1']
218
218
  end
@@ -221,7 +221,7 @@ describe "Database transactions" do
221
221
 
222
222
  it "should support all transaction isolation levels" do
223
223
  [:uncommitted, :committed, :repeatable, :serializable].each_with_index do |l, i|
224
- @db.transaction(:isolation=>l){@d << {:name => 'abc', :value => 1}}
224
+ @db.transaction(:isolation=>l){@d.insert(:name => 'abc', :value => 1)}
225
225
  @d.count.must_equal i + 1
226
226
  end
227
227
  end
@@ -331,10 +331,10 @@ if (! defined?(RUBY_ENGINE) or RUBY_ENGINE == 'ruby') and RUBY_VERSION < '1.9'
331
331
  q1 = Queue.new
332
332
  t = Thread.new do
333
333
  @db.transaction do
334
- @d << {:name => 'abc', :value => 1}
334
+ @d.insert(:name => 'abc', :value => 1)
335
335
  q1.push nil
336
336
  q.pop
337
- @d << {:name => 'def', :value => 2}
337
+ @d.insert(:name => 'def', :value => 2)
338
338
  end
339
339
  end
340
340
  q1.pop
@@ -348,14 +348,14 @@ if (! defined?(RUBY_ENGINE) or RUBY_ENGINE == 'ruby') and RUBY_VERSION < '1.9'
348
348
  q1 = Queue.new
349
349
  t = Thread.new do
350
350
  @db.transaction do
351
- @d << {:name => 'abc', :value => 1}
351
+ @d.insert(:name => 'abc', :value => 1)
352
352
  @db.transaction(:savepoint=>true) do
353
- @d << {:name => 'def', :value => 2}
353
+ @d.insert(:name => 'def', :value => 2)
354
354
  q1.push nil
355
355
  q.pop
356
- @d << {:name => 'ghi', :value => 3}
356
+ @d.insert(:name => 'ghi', :value => 3)
357
357
  end
358
- @d << {:name => 'jkl', :value => 4}
358
+ @d.insert(:name => 'jkl', :value => 4)
359
359
  end
360
360
  end
361
361
  q1.pop