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.
- checksums.yaml +4 -4
- data/CHANGELOG +134 -0
- data/Rakefile +1 -1
- data/doc/release_notes/4.48.0.txt +293 -0
- data/lib/sequel/adapters/ado/access.rb +2 -1
- data/lib/sequel/adapters/do/postgres.rb +5 -2
- data/lib/sequel/adapters/ibmdb.rb +24 -7
- data/lib/sequel/adapters/jdbc.rb +36 -22
- data/lib/sequel/adapters/jdbc/db2.rb +12 -3
- data/lib/sequel/adapters/jdbc/derby.rb +4 -5
- data/lib/sequel/adapters/jdbc/oracle.rb +16 -2
- data/lib/sequel/adapters/jdbc/postgresql.rb +43 -18
- data/lib/sequel/adapters/jdbc/sqlanywhere.rb +9 -7
- data/lib/sequel/adapters/jdbc/sqlserver.rb +11 -4
- data/lib/sequel/adapters/mock.rb +24 -19
- data/lib/sequel/adapters/mysql.rb +17 -16
- data/lib/sequel/adapters/mysql2.rb +4 -5
- data/lib/sequel/adapters/oracle.rb +5 -9
- data/lib/sequel/adapters/postgres.rb +89 -102
- data/lib/sequel/adapters/shared/db2.rb +22 -6
- data/lib/sequel/adapters/shared/mssql.rb +5 -4
- data/lib/sequel/adapters/shared/mysql.rb +75 -24
- data/lib/sequel/adapters/shared/postgres.rb +196 -94
- data/lib/sequel/adapters/shared/sqlanywhere.rb +23 -10
- data/lib/sequel/adapters/shared/sqlite.rb +72 -82
- data/lib/sequel/adapters/sqlanywhere.rb +4 -1
- data/lib/sequel/adapters/sqlite.rb +5 -3
- data/lib/sequel/adapters/swift/postgres.rb +5 -2
- data/lib/sequel/adapters/tinytds.rb +0 -5
- data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -1
- data/lib/sequel/adapters/utils/pg_types.rb +2 -76
- data/lib/sequel/core.rb +2 -2
- data/lib/sequel/database/connecting.rb +5 -5
- data/lib/sequel/database/dataset.rb +6 -3
- data/lib/sequel/database/misc.rb +1 -1
- data/lib/sequel/database/query.rb +3 -0
- data/lib/sequel/database/schema_methods.rb +1 -1
- data/lib/sequel/dataset/actions.rb +18 -10
- data/lib/sequel/dataset/graph.rb +1 -1
- data/lib/sequel/dataset/misc.rb +1 -0
- data/lib/sequel/dataset/prepared_statements.rb +3 -3
- data/lib/sequel/dataset/query.rb +19 -8
- data/lib/sequel/extensions/core_extensions.rb +4 -1
- data/lib/sequel/extensions/duplicate_columns_handler.rb +1 -1
- data/lib/sequel/extensions/empty_array_ignore_nulls.rb +3 -0
- data/lib/sequel/extensions/filter_having.rb +2 -0
- data/lib/sequel/extensions/freeze_datasets.rb +2 -0
- data/lib/sequel/extensions/from_block.rb +1 -1
- data/lib/sequel/extensions/graph_each.rb +2 -2
- data/lib/sequel/extensions/hash_aliases.rb +2 -0
- data/lib/sequel/extensions/identifier_mangling.rb +0 -7
- data/lib/sequel/extensions/meta_def.rb +2 -0
- data/lib/sequel/extensions/migration.rb +6 -6
- data/lib/sequel/extensions/no_auto_literal_strings.rb +1 -1
- data/lib/sequel/extensions/pagination.rb +1 -1
- data/lib/sequel/extensions/pg_array.rb +207 -130
- data/lib/sequel/extensions/pg_hstore.rb +38 -20
- data/lib/sequel/extensions/pg_inet.rb +18 -6
- data/lib/sequel/extensions/pg_interval.rb +19 -12
- data/lib/sequel/extensions/pg_json.rb +25 -14
- data/lib/sequel/extensions/pg_json_ops.rb +2 -2
- data/lib/sequel/extensions/pg_range.rb +133 -100
- data/lib/sequel/extensions/pg_range_ops.rb +4 -3
- data/lib/sequel/extensions/pg_row.rb +68 -39
- data/lib/sequel/extensions/pg_row_ops.rb +11 -5
- data/lib/sequel/extensions/query_literals.rb +2 -0
- data/lib/sequel/extensions/ruby18_symbol_extensions.rb +2 -0
- data/lib/sequel/extensions/s.rb +1 -1
- data/lib/sequel/extensions/schema_dumper.rb +24 -24
- data/lib/sequel/extensions/sequel_3_dataset_methods.rb +3 -1
- data/lib/sequel/extensions/sequel_4_dataset_methods.rb +83 -0
- data/lib/sequel/extensions/set_overrides.rb +2 -2
- data/lib/sequel/extensions/string_agg.rb +0 -1
- data/lib/sequel/extensions/symbol_aref.rb +0 -4
- data/lib/sequel/model.rb +25 -57
- data/lib/sequel/model/associations.rb +14 -5
- data/lib/sequel/model/base.rb +96 -32
- data/lib/sequel/plugins/association_pks.rb +73 -46
- data/lib/sequel/plugins/association_proxies.rb +1 -1
- data/lib/sequel/plugins/auto_validations.rb +6 -2
- data/lib/sequel/plugins/boolean_readers.rb +1 -1
- data/lib/sequel/plugins/caching.rb +19 -13
- data/lib/sequel/plugins/class_table_inheritance.rb +19 -10
- data/lib/sequel/plugins/column_conflicts.rb +7 -2
- data/lib/sequel/plugins/column_select.rb +1 -1
- data/lib/sequel/plugins/csv_serializer.rb +8 -8
- data/lib/sequel/plugins/defaults_setter.rb +10 -0
- data/lib/sequel/plugins/eager_each.rb +1 -1
- data/lib/sequel/plugins/force_encoding.rb +2 -2
- data/lib/sequel/plugins/hook_class_methods.rb +9 -12
- data/lib/sequel/plugins/identifier_columns.rb +2 -0
- data/lib/sequel/plugins/instance_filters.rb +3 -1
- data/lib/sequel/plugins/instance_hooks.rb +17 -9
- data/lib/sequel/plugins/json_serializer.rb +17 -10
- data/lib/sequel/plugins/lazy_attributes.rb +8 -7
- data/lib/sequel/plugins/modification_detection.rb +3 -0
- data/lib/sequel/plugins/nested_attributes.rb +5 -1
- data/lib/sequel/plugins/pg_array_associations.rb +5 -0
- data/lib/sequel/plugins/prepared_statements.rb +1 -0
- data/lib/sequel/plugins/rcte_tree.rb +4 -4
- data/lib/sequel/plugins/serialization.rb +3 -10
- data/lib/sequel/plugins/single_table_inheritance.rb +2 -2
- data/lib/sequel/plugins/split_values.rb +6 -5
- data/lib/sequel/plugins/static_cache.rb +31 -25
- data/lib/sequel/plugins/subset_conditions.rb +3 -1
- data/lib/sequel/plugins/table_select.rb +1 -1
- data/lib/sequel/plugins/touch.rb +2 -1
- data/lib/sequel/plugins/validation_class_methods.rb +5 -6
- data/lib/sequel/plugins/validation_helpers.rb +2 -4
- data/lib/sequel/plugins/xml_serializer.rb +4 -4
- data/lib/sequel/sql.rb +2 -2
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +115 -14
- data/spec/adapters/mysql_spec.rb +78 -28
- data/spec/adapters/oracle_spec.rb +24 -24
- data/spec/adapters/postgres_spec.rb +38 -24
- data/spec/adapters/sqlanywhere_spec.rb +88 -86
- data/spec/adapters/sqlite_spec.rb +29 -24
- data/spec/core/connection_pool_spec.rb +17 -0
- data/spec/core/database_spec.rb +6 -0
- data/spec/core/dataset_spec.rb +46 -36
- data/spec/core/schema_spec.rb +16 -0
- data/spec/core/spec_helper.rb +1 -0
- data/spec/core_extensions_spec.rb +6 -2
- data/spec/extensions/active_model_spec.rb +1 -1
- data/spec/extensions/arbitrary_servers_spec.rb +1 -1
- data/spec/extensions/association_pks_spec.rb +34 -2
- data/spec/extensions/auto_literal_strings_spec.rb +5 -1
- data/spec/extensions/auto_validations_spec.rb +2 -0
- data/spec/extensions/boolean_readers_spec.rb +1 -1
- data/spec/extensions/boolean_subsets_spec.rb +1 -1
- data/spec/extensions/class_table_inheritance_spec.rb +48 -2
- data/spec/extensions/column_conflicts_spec.rb +11 -0
- data/spec/extensions/connection_validator_spec.rb +1 -1
- data/spec/extensions/dataset_associations_spec.rb +8 -8
- data/spec/extensions/defaults_setter_spec.rb +1 -1
- data/spec/extensions/filter_having_spec.rb +5 -3
- data/spec/extensions/hash_aliases_spec.rb +3 -1
- data/spec/extensions/identifier_columns_spec.rb +3 -1
- data/spec/extensions/implicit_subquery_spec.rb +4 -2
- data/spec/extensions/json_serializer_spec.rb +18 -0
- data/spec/extensions/lazy_attributes_spec.rb +3 -3
- data/spec/extensions/meta_def_spec.rb +9 -0
- data/spec/extensions/migration_spec.rb +3 -3
- data/spec/extensions/nested_attributes_spec.rb +14 -3
- data/spec/extensions/no_auto_literal_strings_spec.rb +8 -4
- data/spec/extensions/pg_array_associations_spec.rb +29 -18
- data/spec/extensions/pg_array_spec.rb +44 -25
- data/spec/extensions/pg_hstore_spec.rb +10 -0
- data/spec/extensions/pg_inet_spec.rb +26 -0
- data/spec/extensions/pg_interval_spec.rb +20 -0
- data/spec/extensions/pg_json_spec.rb +24 -0
- data/spec/extensions/pg_range_spec.rb +98 -14
- data/spec/extensions/pg_row_spec.rb +14 -4
- data/spec/extensions/prepared_statements_safe_spec.rb +1 -1
- data/spec/extensions/query_literals_spec.rb +3 -1
- data/spec/extensions/schema_dumper_spec.rb +96 -98
- data/spec/extensions/sequel_3_dataset_methods_spec.rb +10 -6
- data/spec/extensions/sequel_4_dataset_methods_spec.rb +121 -0
- data/spec/extensions/single_table_inheritance_spec.rb +1 -1
- data/spec/extensions/spec_helper.rb +7 -1
- data/spec/extensions/static_cache_spec.rb +75 -24
- data/spec/extensions/string_agg_spec.rb +1 -1
- data/spec/extensions/touch_spec.rb +9 -0
- data/spec/extensions/validation_helpers_spec.rb +9 -3
- data/spec/extensions/whitelist_security_spec.rb +26 -0
- data/spec/integration/dataset_test.rb +45 -44
- data/spec/integration/plugin_test.rb +20 -0
- data/spec/integration/prepared_statement_test.rb +3 -0
- data/spec/integration/schema_test.rb +21 -1
- data/spec/integration/transaction_test.rb +40 -40
- data/spec/model/class_dataset_methods_spec.rb +14 -4
- data/spec/model/dataset_methods_spec.rb +12 -3
- data/spec/model/model_spec.rb +8 -0
- metadata +6 -4
- data/spec/adapters/firebird_spec.rb +0 -405
- 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]
|
|
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]
|
|
149
|
-
@db[:fk]
|
|
150
|
-
@db[:fk]
|
|
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
|
|
351
|
-
@d
|
|
352
|
-
@d
|
|
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
|
|
386
|
-
@d
|
|
387
|
-
@d
|
|
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
|
|
448
|
-
@d
|
|
449
|
-
@d
|
|
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]
|
|
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]
|
|
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]
|
|
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]
|
|
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]
|
|
510
|
-
@db[:test2]
|
|
511
|
-
proc{@db[:test2]
|
|
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]
|
|
524
|
-
@db[:test3]
|
|
525
|
-
@db[:test3]
|
|
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]
|
|
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
|
data/spec/core/database_spec.rb
CHANGED
|
@@ -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
|
data/spec/core/dataset_spec.rb
CHANGED
|
@@ -765,11 +765,11 @@ describe "Dataset#and" do
|
|
|
765
765
|
@d1 = @dataset.where(:x => 1)
|
|
766
766
|
end
|
|
767
767
|
|
|
768
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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#
|
|
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.
|
|
1991
|
-
@d.
|
|
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.
|
|
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.
|
|
2000
|
-
@d.
|
|
2001
|
-
@d.
|
|
2002
|
-
@d.
|
|
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.
|
|
2008
|
-
@d.
|
|
2009
|
-
@d.
|
|
2010
|
-
@d.
|
|
2011
|
-
@d.
|
|
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.
|
|
2017
|
-
@d.
|
|
2018
|
-
@d.
|
|
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).
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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#
|
|
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)',
|
data/spec/core/schema_spec.rb
CHANGED
|
@@ -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
|