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
@@ -134,7 +134,7 @@ describe "An SQLite database" do
134
134
  @db.create_table!(:fk){timestamp :t; datetime :d}
135
135
  @db.use_timestamp_timezones = true
136
136
  t1 = Time.at(1)
137
- @db[:fk] << {:t => t1, :d => t1}
137
+ @db[:fk].insert(:t => t1, :d => t1)
138
138
  @db[:fk].map(:t).must_equal [t1]
139
139
  @db[:fk].map(:d).must_equal [t1]
140
140
  Sequel.datetime_class = DateTime
@@ -145,9 +145,9 @@ describe "An SQLite database" do
145
145
 
146
146
  it "should support sequential primary keys" do
147
147
  @db.create_table!(:fk) {primary_key :id; text :name}
148
- @db[:fk] << {:name => 'abc'}
149
- @db[:fk] << {:name => 'def'}
150
- @db[:fk] << {:name => 'ghi'}
148
+ @db[:fk].insert(:name => 'abc')
149
+ @db[:fk].insert(:name => 'def')
150
+ @db[:fk].insert(:name => 'ghi')
151
151
  @db[:fk].order(:name).all.must_equal [
152
152
  {:id => 1, :name => 'abc'},
153
153
  {:id => 2, :name => 'def'},
@@ -347,9 +347,9 @@ describe "SQLite::Dataset#delete" do
347
347
  end
348
348
  @d = DB[:items]
349
349
  @d.delete # remove all records
350
- @d << {:name => 'abc', :value => 1.23}
351
- @d << {:name => 'def', :value => 4.56}
352
- @d << {:name => 'ghi', :value => 7.89}
350
+ @d.insert(:name => 'abc', :value => 1.23)
351
+ @d.insert(:name => 'def', :value => 4.56)
352
+ @d.insert(:name => 'ghi', :value => 7.89)
353
353
  end
354
354
  after do
355
355
  DB.drop_table?(:items)
@@ -382,9 +382,9 @@ describe "SQLite::Dataset#update" do
382
382
  end
383
383
  @d = DB[:items]
384
384
  @d.delete # remove all records
385
- @d << {:name => 'abc', :value => 1.23}
386
- @d << {:name => 'def', :value => 4.56}
387
- @d << {:name => 'ghi', :value => 7.89}
385
+ @d.insert(:name => 'abc', :value => 1.23)
386
+ @d.insert(:name => 'def', :value => 4.56)
387
+ @d.insert(:name => 'ghi', :value => 7.89)
388
388
  end
389
389
 
390
390
  it "should return the number of records affected" do
@@ -444,16 +444,16 @@ describe "SQLite dataset" do
444
444
  Float :value
445
445
  end
446
446
  @d = DB[:items]
447
- @d << {:name => 'abc', :value => 1.23}
448
- @d << {:name => 'def', :value => 4.56}
449
- @d << {:name => 'ghi', :value => 7.89}
447
+ @d.insert(:name => 'abc', :value => 1.23)
448
+ @d.insert(:name => 'def', :value => 4.56)
449
+ @d.insert(:name => 'ghi', :value => 7.89)
450
450
  end
451
451
  after do
452
452
  DB.drop_table?(:test, :items)
453
453
  end
454
454
 
455
455
  it "should be able to insert from a subquery" do
456
- DB[:test] << @d
456
+ DB[:test].insert(@d)
457
457
  DB[:test].count.must_equal 3
458
458
  DB[:test].select(:name, :value).order(:value).to_a.must_equal \
459
459
  @d.select(:name, :value).order(:value).to_a
@@ -484,21 +484,21 @@ describe "A SQLite database" do
484
484
  @db.add_column :test2, :xyz, :text
485
485
 
486
486
  @db[:test2].columns.must_equal [:name, :value, :xyz]
487
- @db[:test2] << {:name => 'mmm', :value => 111, :xyz=>'000'}
487
+ @db[:test2].insert(:name => 'mmm', :value => 111, :xyz=>'000')
488
488
  @db[:test2].first.must_equal(:name => 'mmm', :value => 111, :xyz=>'000')
489
489
  end
490
490
 
491
491
  it "should support drop_column operations" do
492
492
  @db.drop_column :test2, :value
493
493
  @db[:test2].columns.must_equal [:name]
494
- @db[:test2] << {:name => 'mmm'}
494
+ @db[:test2].insert(:name => 'mmm')
495
495
  @db[:test2].first.must_equal(:name => 'mmm')
496
496
  end
497
497
 
498
498
  it "should support drop_column operations in a transaction" do
499
499
  @db.transaction{@db.drop_column :test2, :value}
500
500
  @db[:test2].columns.must_equal [:name]
501
- @db[:test2] << {:name => 'mmm'}
501
+ @db[:test2].insert(:name => 'mmm')
502
502
  @db[:test2].first.must_equal(:name => 'mmm')
503
503
  end
504
504
 
@@ -506,9 +506,9 @@ describe "A SQLite database" do
506
506
  @db.create_table!(:test2){Integer :a; Integer :b; Integer :c; primary_key [:a, :b]}
507
507
  @db.drop_column :test2, :c
508
508
  @db[:test2].columns.must_equal [:a, :b]
509
- @db[:test2] << {:a=>1, :b=>2}
510
- @db[:test2] << {:a=>2, :b=>3}
511
- proc{@db[:test2] << {:a=>2, :b=>3}}.must_raise(Sequel::UniqueConstraintViolation, Sequel::ConstraintViolation, Sequel::DatabaseError)
509
+ @db[:test2].insert(:a=>1, :b=>2)
510
+ @db[:test2].insert(:a=>2, :b=>3)
511
+ proc{@db[:test2].insert(:a=>2, :b=>3)}.must_raise(Sequel::UniqueConstraintViolation, Sequel::ConstraintViolation, Sequel::DatabaseError)
512
512
  end
513
513
 
514
514
  it "should keep column attributes when dropping a column" do
@@ -520,9 +520,9 @@ describe "A SQLite database" do
520
520
 
521
521
  # This lame set of additions and deletions are to test that the primary keys
522
522
  # don't get messed up when we recreate the database.
523
- @db[:test3] << { :name => "foo", :value => 1}
524
- @db[:test3] << { :name => "foo", :value => 2}
525
- @db[:test3] << { :name => "foo", :value => 3}
523
+ @db[:test3].insert( :name => "foo", :value => 1)
524
+ @db[:test3].insert( :name => "foo", :value => 2)
525
+ @db[:test3].insert( :name => "foo", :value => 3)
526
526
  @db[:test3].filter(:id => 2).delete
527
527
 
528
528
  @db.drop_column :test3, :value
@@ -558,7 +558,7 @@ describe "A SQLite database" do
558
558
  it "should support rename_column operations" do
559
559
  @db[:test2].delete
560
560
  @db.add_column :test2, :xyz, :text
561
- @db[:test2] << {:name => 'mmm', :value => 111, :xyz => 'qqqq'}
561
+ @db[:test2].insert(:name => 'mmm', :value => 111, :xyz => 'qqqq')
562
562
 
563
563
  @db[:test2].columns.must_equal [:name, :value, :xyz]
564
564
  @db.rename_column :test2, :xyz, :zyx, :type => :text
@@ -717,4 +717,9 @@ describe "A SQLite database" do
717
717
  @db[:test2].insert(:name=>'a')
718
718
  proc{@db[:test2].insert(:name=>'a')}.must_raise(Sequel::ConstraintViolation, Sequel::UniqueConstraintViolation)
719
719
  end
720
+
721
+ it "should show unique constraints in Database#indexes" do
722
+ @db.alter_table(:test2){add_unique_constraint :name}
723
+ @db.indexes(:test2).values.first[:columns].must_equal [:name]
724
+ end if DB.sqlite_version >= 30808
720
725
  end
@@ -259,6 +259,23 @@ ThreadedConnectionPoolSpecs = shared_description do
259
259
  t.join
260
260
  end
261
261
 
262
+ it "should work when acquire fails and then succeeds" do
263
+ pool = Sequel::ConnectionPool.get_pool(mock_db.call(&@icpp), @cp_opts.merge(:max_connections=>2, :pool_timeout=>0))
264
+ def pool._acquire(*)
265
+ if @called
266
+ super
267
+ else
268
+ @called = true
269
+ nil
270
+ end
271
+ end
272
+ c = nil
273
+ pool.hold do |c1|
274
+ c = c1
275
+ end
276
+ c.wont_be_nil
277
+ end
278
+
262
279
  it "should wait until a connection is available if all are checked out" do
263
280
  pool = Sequel::ConnectionPool.get_pool(mock_db.call(&@icpp), @cp_opts.merge(:max_connections=>1, :pool_timeout=>0.1, :pool_sleep_time=>0))
264
281
  q, q1 = Queue.new, Queue.new
@@ -12,6 +12,12 @@ describe "A new Database" do
12
12
  end
13
13
  end
14
14
 
15
+ deprecated "should support DatasetClass constant" do
16
+ dbc = Class.new(Sequel::Database)
17
+ dbc::DatasetClass = dsc = Class.new(Sequel::Dataset)
18
+ dbc.new.dataset.must_be_kind_of(dsc)
19
+ end
20
+
15
21
  deprecated "should allow dup/clone" do
16
22
  @db.dup.must_be_kind_of @db.class
17
23
  @db.clone.must_be_kind_of @db.class
@@ -765,11 +765,11 @@ describe "Dataset#and" do
765
765
  @d1 = @dataset.where(:x => 1)
766
766
  end
767
767
 
768
- it "should add a WHERE filter if none exists" do
768
+ deprecated "should add a WHERE filter if none exists" do
769
769
  @dataset.and(:a => 1).sql.must_equal 'SELECT * FROM test WHERE (a = 1)'
770
770
  end
771
771
 
772
- it "should add an expression to the where clause" do
772
+ deprecated "should add an expression to the where clause" do
773
773
  @d1.and(:y => 2).sql.must_equal 'SELECT * FROM test WHERE ((x = 1) AND (y = 2))'
774
774
  end
775
775
 
@@ -777,19 +777,19 @@ describe "Dataset#and" do
777
777
  @d1.and('y > ?', 2).sql.must_equal 'SELECT * FROM test WHERE ((x = 1) AND (y > 2))'
778
778
  end
779
779
 
780
- it "should accept placeholder literal string filters" do
780
+ deprecated "should accept placeholder literal string filters" do
781
781
  @d1.and(Sequel.lit('y > ?', 2)).sql.must_equal 'SELECT * FROM test WHERE ((x = 1) AND (y > 2))'
782
782
  end
783
783
 
784
- it "should accept expression filters" do
784
+ deprecated "should accept expression filters" do
785
785
  @d1.and(Sequel.expr(:yy) > 3).sql.must_equal 'SELECT * FROM test WHERE ((x = 1) AND (yy > 3))'
786
786
  end
787
787
 
788
- it "should accept blocks passed to filter" do
788
+ deprecated "should accept blocks passed to filter" do
789
789
  @d1.and{yy > 3}.sql.must_equal 'SELECT * FROM test WHERE ((x = 1) AND (yy > 3))'
790
790
  end
791
791
 
792
- it "should correctly add parens to give predictable results" do
792
+ deprecated "should correctly add parens to give predictable results" do
793
793
  @d1.or(:y => 2).and(:z => 3).sql.must_equal 'SELECT * FROM test WHERE (((x = 1) OR (y = 2)) AND (z = 3))'
794
794
  @d1.and(:y => 2).or(:z => 3).sql.must_equal 'SELECT * FROM test WHERE (((x = 1) AND (y = 2)) OR (z = 3))'
795
795
  end
@@ -845,19 +845,19 @@ describe "Dataset#exclude_where" do
845
845
  @dataset = Sequel.mock.dataset.from(:test)
846
846
  end
847
847
 
848
- it "should correctly negate the expression and add it to the where clause" do
848
+ deprecated "should correctly negate the expression and add it to the where clause" do
849
849
  @dataset.exclude_where(:region=>'Asia').sql.must_equal "SELECT * FROM test WHERE (region != 'Asia')"
850
850
  @dataset.exclude_where(:region=>'Asia').exclude_where(:region=>'NA').sql.must_equal "SELECT * FROM test WHERE ((region != 'Asia') AND (region != 'NA'))"
851
851
  end
852
852
 
853
- it "should affect the where clause even if having clause is already used" do
853
+ deprecated "should affect the where clause even if having clause is already used" do
854
854
  @dataset.group_and_count(:name).having{count > 2}.exclude_where(:region=>'Asia').sql.
855
855
  must_equal "SELECT name, count(*) AS count FROM test WHERE (region != 'Asia') GROUP BY name HAVING (count > 2)"
856
856
  end
857
857
  end
858
858
 
859
859
  describe "Dataset#exclude_having" do
860
- it "should correctly negate the expression and add it to the having clause" do
860
+ deprecated "should correctly negate the expression and add it to the having clause" do
861
861
  Sequel.mock.dataset.from(:test).exclude_having{count > 2}.exclude_having{count < 0}.sql.must_equal "SELECT * FROM test HAVING ((count <= 2) AND (count >= 0))"
862
862
  end
863
863
  end
@@ -1976,46 +1976,51 @@ describe "Dataset#map" do
1976
1976
  end
1977
1977
  end
1978
1978
 
1979
- describe "Dataset#to_hash" do
1979
+ describe "Dataset#as_hash" do
1980
1980
  before do
1981
1981
  @d = Sequel.mock(:fetch=>[{:a => 1, :b => 2}, {:a => 3, :b => 4}, {:a => 5, :b => 6}])[:items]
1982
1982
  end
1983
1983
 
1984
1984
  it "should provide a hash with the first column as key and the second as value" do
1985
+ @d.as_hash(:a, :b).must_equal(1 => 2, 3 => 4, 5 => 6)
1986
+ @d.as_hash(:b, :a).must_equal(2 => 1, 4 => 3, 6 => 5)
1987
+ end
1988
+
1989
+ it "should be aliased as #to_hash" do
1985
1990
  @d.to_hash(:a, :b).must_equal(1 => 2, 3 => 4, 5 => 6)
1986
1991
  @d.to_hash(:b, :a).must_equal(2 => 1, 4 => 3, 6 => 5)
1987
1992
  end
1988
1993
 
1989
1994
  it "should provide a hash with the first column as key and the entire hash as value if the value column is blank or nil" do
1990
- @d.to_hash(:a).must_equal(1 => {:a => 1, :b => 2}, 3 => {:a => 3, :b => 4}, 5 => {:a => 5, :b => 6})
1991
- @d.to_hash(:b).must_equal(2 => {:a => 1, :b => 2}, 4 => {:a => 3, :b => 4}, 6 => {:a => 5, :b => 6})
1995
+ @d.as_hash(:a).must_equal(1 => {:a => 1, :b => 2}, 3 => {:a => 3, :b => 4}, 5 => {:a => 5, :b => 6})
1996
+ @d.as_hash(:b).must_equal(2 => {:a => 1, :b => 2}, 4 => {:a => 3, :b => 4}, 6 => {:a => 5, :b => 6})
1992
1997
  end
1993
1998
 
1994
1999
  it "should accept an optional :hash parameter into which entries can be merged" do
1995
- @d.to_hash(:a, :b, :hash => (tmp = {})).must_be_same_as(tmp)
2000
+ @d.as_hash(:a, :b, :hash => (tmp = {})).must_be_same_as(tmp)
1996
2001
  end
1997
2002
 
1998
2003
  it "should support using an array of columns as either the key or the value" do
1999
- @d.to_hash([:a, :b], :b).must_equal([1, 2] => 2, [3, 4] => 4, [5, 6] => 6)
2000
- @d.to_hash(:b, [:a, :b]).must_equal(2 => [1, 2], 4 => [3, 4], 6 => [5, 6])
2001
- @d.to_hash([:b, :a], [:a, :b]).must_equal([2, 1] => [1, 2], [4, 3] => [3, 4], [6, 5] => [5, 6])
2002
- @d.to_hash([:a, :b]).must_equal([1, 2] => {:a => 1, :b => 2}, [3, 4] => {:a => 3, :b => 4}, [5, 6] => {:a => 5, :b => 6})
2004
+ @d.as_hash([:a, :b], :b).must_equal([1, 2] => 2, [3, 4] => 4, [5, 6] => 6)
2005
+ @d.as_hash(:b, [:a, :b]).must_equal(2 => [1, 2], 4 => [3, 4], 6 => [5, 6])
2006
+ @d.as_hash([:b, :a], [:a, :b]).must_equal([2, 1] => [1, 2], [4, 3] => [3, 4], [6, 5] => [5, 6])
2007
+ @d.as_hash([:a, :b]).must_equal([1, 2] => {:a => 1, :b => 2}, [3, 4] => {:a => 3, :b => 4}, [5, 6] => {:a => 5, :b => 6})
2003
2008
  end
2004
2009
 
2005
2010
  it "should not call the row_proc if two arguments are given" do
2006
2011
  @d = @d.with_row_proc(proc{|r| h = {}; r.keys.each{|k| h[k] = r[k] * 2}; h})
2007
- @d.to_hash(:a, :b).must_equal(1 => 2, 3 => 4, 5 => 6)
2008
- @d.to_hash(:b, :a).must_equal(2 => 1, 4 => 3, 6 => 5)
2009
- @d.to_hash([:a, :b], :b).must_equal([1, 2] => 2, [3, 4] => 4, [5, 6] => 6)
2010
- @d.to_hash(:b, [:a, :b]).must_equal(2 => [1, 2], 4 => [3, 4], 6 => [5, 6])
2011
- @d.to_hash([:b, :a], [:a, :b]).must_equal([2, 1] => [1, 2], [4, 3] => [3, 4], [6, 5] => [5, 6])
2012
+ @d.as_hash(:a, :b).must_equal(1 => 2, 3 => 4, 5 => 6)
2013
+ @d.as_hash(:b, :a).must_equal(2 => 1, 4 => 3, 6 => 5)
2014
+ @d.as_hash([:a, :b], :b).must_equal([1, 2] => 2, [3, 4] => 4, [5, 6] => 6)
2015
+ @d.as_hash(:b, [:a, :b]).must_equal(2 => [1, 2], 4 => [3, 4], 6 => [5, 6])
2016
+ @d.as_hash([:b, :a], [:a, :b]).must_equal([2, 1] => [1, 2], [4, 3] => [3, 4], [6, 5] => [5, 6])
2012
2017
  end
2013
2018
 
2014
2019
  it "should call the row_proc if only a single argument is given" do
2015
2020
  @d = @d.with_row_proc(proc{|r| h = {}; r.keys.each{|k| h[k] = r[k] * 2}; h})
2016
- @d.to_hash(:a).must_equal(2 => {:a => 2, :b => 4}, 6 => {:a => 6, :b => 8}, 10 => {:a => 10, :b => 12})
2017
- @d.to_hash(:b).must_equal(4 => {:a => 2, :b => 4}, 8 => {:a => 6, :b => 8}, 12 => {:a => 10, :b => 12})
2018
- @d.to_hash([:a, :b]).must_equal([2, 4] => {:a => 2, :b => 4}, [6, 8] => {:a => 6, :b => 8}, [10, 12] => {:a => 10, :b => 12})
2021
+ @d.as_hash(:a).must_equal(2 => {:a => 2, :b => 4}, 6 => {:a => 6, :b => 8}, 10 => {:a => 10, :b => 12})
2022
+ @d.as_hash(:b).must_equal(4 => {:a => 2, :b => 4}, 8 => {:a => 6, :b => 8}, 12 => {:a => 10, :b => 12})
2023
+ @d.as_hash([:a, :b]).must_equal([2, 4] => {:a => 2, :b => 4}, [6, 8] => {:a => 6, :b => 8}, [10, 12] => {:a => 10, :b => 12})
2019
2024
  end
2020
2025
 
2021
2026
  it "should handle a single composite key when using a row_proc" do
@@ -2026,7 +2031,7 @@ describe "Dataset#to_hash" do
2026
2031
  def h; @h; end
2027
2032
  def ==(o) @h == o.h; end
2028
2033
  end
2029
- @d.with_row_proc(c).to_hash([:a, :b]).must_equal([1, 2] => c.call(:a => 1, :b => 2), [3, 4] => c.call(:a => 3, :b => 4), [5, 6] => c.call(:a => 5, :b => 6))
2034
+ @d.with_row_proc(c).as_hash([:a, :b]).must_equal([1, 2] => c.call(:a => 1, :b => 2), [3, 4] => c.call(:a => 3, :b => 4), [5, 6] => c.call(:a => 5, :b => 6))
2030
2035
  end
2031
2036
  end
2032
2037
 
@@ -2755,7 +2760,7 @@ describe "Dataset#range" do
2755
2760
  @ds = @db[:test].freeze
2756
2761
  end
2757
2762
 
2758
- it "should generate a correct SQL statement" do
2763
+ deprecated "should generate a correct SQL statement" do
2759
2764
  5.times do
2760
2765
  @ds.range(:stamp)
2761
2766
  @db.sqls.must_equal ["SELECT min(stamp) AS v1, max(stamp) AS v2 FROM test LIMIT 1"]
@@ -2765,18 +2770,18 @@ describe "Dataset#range" do
2765
2770
  @db.sqls.must_equal ["SELECT min(stamp) AS v1, max(stamp) AS v2 FROM test WHERE (price > 100) LIMIT 1"]
2766
2771
  end
2767
2772
 
2768
- it "should return a range object" do
2773
+ deprecated "should return a range object" do
2769
2774
  5.times do
2770
2775
  @ds.range(:tryme).must_equal(1..10)
2771
2776
  end
2772
2777
  end
2773
2778
 
2774
- it "should use a subselect for the same conditions as count" do
2779
+ deprecated "should use a subselect for the same conditions as count" do
2775
2780
  @ds.order(:stamp).limit(5).range(:stamp).must_equal(1..10)
2776
2781
  @db.sqls.must_equal ['SELECT min(stamp) AS v1, max(stamp) AS v2 FROM (SELECT * FROM test ORDER BY stamp LIMIT 5) AS t1 LIMIT 1']
2777
2782
  end
2778
2783
 
2779
- it "should accept virtual row blocks" do
2784
+ deprecated "should accept virtual row blocks" do
2780
2785
  5.times do
2781
2786
  @ds.range{a(b)}
2782
2787
  @db.sqls.must_equal ["SELECT min(a(b)) AS v1, max(a(b)) AS v2 FROM test LIMIT 1"]
@@ -2790,7 +2795,7 @@ describe "Dataset#interval" do
2790
2795
  @ds = @db[:test].freeze
2791
2796
  end
2792
2797
 
2793
- it "should generate the correct SQL statement" do
2798
+ deprecated "should generate the correct SQL statement" do
2794
2799
  5.times do
2795
2800
  @ds.interval(:stamp)
2796
2801
  @db.sqls.must_equal ["SELECT (max(stamp) - min(stamp)) AS interval FROM test LIMIT 1"]
@@ -2800,7 +2805,7 @@ describe "Dataset#interval" do
2800
2805
  @db.sqls.must_equal ["SELECT (max(stamp) - min(stamp)) AS interval FROM test WHERE (price > 100) LIMIT 1"]
2801
2806
  end
2802
2807
 
2803
- it "should use a subselect for the same conditions as count" do
2808
+ deprecated "should use a subselect for the same conditions as count" do
2804
2809
  ds = @ds.order(:stamp).limit(5)
2805
2810
  5.times do
2806
2811
  ds.interval(:stamp).must_equal 1234
@@ -2808,7 +2813,7 @@ describe "Dataset#interval" do
2808
2813
  end
2809
2814
  end
2810
2815
 
2811
- it "should accept virtual row blocks" do
2816
+ deprecated "should accept virtual row blocks" do
2812
2817
  5.times do
2813
2818
  @ds.interval{a(b)}
2814
2819
  @db.sqls.must_equal ["SELECT (max(a(b)) - min(a(b))) AS interval FROM test LIMIT 1"]
@@ -3241,7 +3246,7 @@ describe "Dataset#get" do
3241
3246
  end
3242
3247
  end
3243
3248
 
3244
- describe "Dataset#set_row_proc" do
3249
+ describe "Dataset#with_row_proc" do
3245
3250
  before do
3246
3251
  @db = Sequel.mock(:fetch=>[{:a=>1}, {:a=>2}])
3247
3252
  @dataset = @db[:items].with_row_proc(proc{|h| h[:der] = h[:a] + 2; h})
@@ -3911,6 +3916,7 @@ describe "Dataset prepared statements and bound variables " do
3911
3916
  @ds.filter(:num=>:$n).bind({:n=>1}.freeze).call(:each)
3912
3917
  @ds.filter(:num=>:$n).call(:select, :n=>1)
3913
3918
  @ds.filter(:num=>:$n).call([:map, :a], :n=>1)
3919
+ @ds.filter(:num=>:$n).call([:as_hash, :a, :b], :n=>1)
3914
3920
  @ds.filter(:num=>:$n).call([:to_hash, :a, :b], :n=>1)
3915
3921
  @ds.filter(:num=>:$n).call([:to_hash_groups, :a, :b], :n=>1)
3916
3922
  @ds.filter(:num=>:$n).call(:first, :n=>1)
@@ -3925,6 +3931,7 @@ describe "Dataset prepared statements and bound variables " do
3925
3931
  'SELECT * FROM items WHERE (num = 1)',
3926
3932
  'SELECT * FROM items WHERE (num = 1)',
3927
3933
  'SELECT * FROM items WHERE (num = 1)',
3934
+ 'SELECT * FROM items WHERE (num = 1)',
3928
3935
  'SELECT * FROM items WHERE (num = 1) LIMIT 1',
3929
3936
  'DELETE FROM items WHERE (num = 1)',
3930
3937
  'UPDATE items SET num = 2 WHERE (num = 1)',
@@ -3938,6 +3945,7 @@ describe "Dataset prepared statements and bound variables " do
3938
3945
  pss << @ds.filter(:num=>:$n).prepare(:each, :en)
3939
3946
  pss << @ds.filter(:num=>:$n).prepare(:select, :sn)
3940
3947
  pss << @ds.filter(:num=>:$n).prepare([:map, :a], :sm)
3948
+ pss << @ds.filter(:num=>:$n).prepare([:as_hash, :a, :b], :ah)
3941
3949
  pss << @ds.filter(:num=>:$n).prepare([:to_hash, :a, :b], :sh)
3942
3950
  pss << @ds.filter(:num=>:$n).prepare([:to_hash_groups, :a, :b], :shg)
3943
3951
  pss << @ds.filter(:num=>:$n).prepare(:first, :fn)
@@ -3945,11 +3953,12 @@ describe "Dataset prepared statements and bound variables " do
3945
3953
  pss << @ds.filter(:num=>:$n).prepare(:update, :un, :num=>:$n2)
3946
3954
  pss << @ds.prepare(:insert, :in, :num=>:$n)
3947
3955
  pss << @ds.prepare(:insert_select, :ins, :num=>:$n)
3948
- @db.prepared_statements.keys.sort_by{|k| k.to_s}.must_equal [:dn, :en, :fn, :in, :ins, :sh, :shg, :sm, :sn, :un]
3949
- [:en, :sn, :sm, :sh, :shg, :fn, :dn, :un, :in, :ins].each_with_index{|x, i| @db.prepared_statements[x].must_equal pss[i]}
3956
+ @db.prepared_statements.keys.sort_by{|k| k.to_s}.must_equal [:ah, :dn, :en, :fn, :in, :ins, :sh, :shg, :sm, :sn, :un]
3957
+ [:en, :sn, :sm, :ah, :sh, :shg, :fn, :dn, :un, :in, :ins].each_with_index{|x, i| @db.prepared_statements[x].must_equal pss[i]}
3950
3958
  @db.call(:en, :n=>1){}
3951
3959
  @db.call(:sn, :n=>1)
3952
3960
  @db.call(:sm, :n=>1)
3961
+ @db.call(:ah, :n=>1)
3953
3962
  @db.call(:sh, :n=>1)
3954
3963
  @db.call(:shg, :n=>1)
3955
3964
  @db.call(:fn, :n=>1)
@@ -3963,6 +3972,7 @@ describe "Dataset prepared statements and bound variables " do
3963
3972
  'SELECT * FROM items WHERE (num = 1)',
3964
3973
  'SELECT * FROM items WHERE (num = 1)',
3965
3974
  'SELECT * FROM items WHERE (num = 1)',
3975
+ 'SELECT * FROM items WHERE (num = 1)',
3966
3976
  'SELECT * FROM items WHERE (num = 1) LIMIT 1',
3967
3977
  'DELETE FROM items WHERE (num = 1)',
3968
3978
  'UPDATE items SET num = 2 WHERE (num = 1)',
@@ -5,6 +5,11 @@ describe "DB#create_table" do
5
5
  @db = Sequel.mock
6
6
  end
7
7
 
8
+ deprecated "should support an CreateTableGenerator as second argument" do
9
+ @db.create_table(:cats, Sequel::Schema::CreateTableGenerator.new(@db){})
10
+ @db.sqls.must_equal ['CREATE TABLE cats ()']
11
+ end
12
+
8
13
  it "should accept the table name" do
9
14
  @db.create_table(:cats) {}
10
15
  @db.sqls.must_equal ['CREATE TABLE cats ()']
@@ -516,6 +521,12 @@ describe "DB#create_table" do
516
521
  @db.sqls.must_equal ['CREATE TABLE cats (id integer)', 'CREATE INDEX cats_id_index ON cats (id)']
517
522
  end
518
523
 
524
+ it "should use savepoints around index creation if running inside a transaction if :ignore_index_errors option is used" do
525
+ meta_def(@db, :execute_ddl){|*a| super(*a); raise Sequel::DatabaseError if /blah/.match(a.first)}
526
+ @db.transaction{@db.create_table(:cats, :ignore_index_errors=>true){Integer :id; index :blah; index :id}}
527
+ @db.sqls.must_equal ["BEGIN", "CREATE TABLE cats (id integer)", "SAVEPOINT autopoint_1", "CREATE INDEX cats_blah_index ON cats (blah)", "ROLLBACK TO SAVEPOINT autopoint_1", "SAVEPOINT autopoint_1", "CREATE INDEX cats_id_index ON cats (id)", "RELEASE SAVEPOINT autopoint_1", "COMMIT"]
528
+ end
529
+
519
530
  it "should accept multiple index definitions" do
520
531
  @db.create_table(:cats) do
521
532
  integer :id
@@ -1007,6 +1018,11 @@ describe "DB#alter_table" do
1007
1018
  @db = Sequel.mock
1008
1019
  end
1009
1020
 
1021
+ deprecated "should support an AlterTableGenerator as second argument" do
1022
+ @db.alter_table(:cats, Sequel::Schema::AlterTableGenerator.new(@db){set_column_allow_null :score, false})
1023
+ @db.sqls.must_equal ["ALTER TABLE cats ALTER COLUMN score SET NOT NULL"]
1024
+ end
1025
+
1010
1026
  it "should allow adding not null constraint via set_column_allow_null with false argument" do
1011
1027
  @db.alter_table(:cats) do
1012
1028
  set_column_allow_null :score, false