sequel 5.7.1 → 5.8.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 (39) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +53 -1
  3. data/doc/association_basics.rdoc +2 -2
  4. data/doc/migration.rdoc +11 -10
  5. data/doc/postgresql.rdoc +71 -0
  6. data/doc/release_notes/5.8.0.txt +170 -0
  7. data/lib/sequel/adapters/jdbc.rb +6 -1
  8. data/lib/sequel/adapters/jdbc/postgresql.rb +3 -3
  9. data/lib/sequel/adapters/mysql2.rb +2 -1
  10. data/lib/sequel/adapters/postgres.rb +32 -10
  11. data/lib/sequel/adapters/shared/mssql.rb +11 -11
  12. data/lib/sequel/adapters/shared/mysql.rb +51 -6
  13. data/lib/sequel/adapters/shared/oracle.rb +12 -2
  14. data/lib/sequel/adapters/shared/postgres.rb +97 -30
  15. data/lib/sequel/adapters/shared/sqlanywhere.rb +2 -2
  16. data/lib/sequel/adapters/shared/sqlite.rb +6 -1
  17. data/lib/sequel/dataset/features.rb +5 -0
  18. data/lib/sequel/dataset/query.rb +48 -19
  19. data/lib/sequel/exceptions.rb +7 -0
  20. data/lib/sequel/extensions/connection_expiration.rb +8 -3
  21. data/lib/sequel/extensions/pg_enum.rb +28 -5
  22. data/lib/sequel/plugins/association_proxies.rb +16 -4
  23. data/lib/sequel/plugins/error_splitter.rb +16 -11
  24. data/lib/sequel/plugins/pg_auto_constraint_validations.rb +260 -0
  25. data/lib/sequel/plugins/subclasses.rb +1 -1
  26. data/lib/sequel/plugins/tactical_eager_loading.rb +1 -1
  27. data/lib/sequel/version.rb +2 -2
  28. data/spec/adapters/mysql_spec.rb +0 -1
  29. data/spec/adapters/postgres_spec.rb +169 -4
  30. data/spec/adapters/sqlite_spec.rb +13 -0
  31. data/spec/core/dataset_spec.rb +21 -0
  32. data/spec/extensions/association_proxies_spec.rb +21 -7
  33. data/spec/extensions/connection_expiration_spec.rb +13 -1
  34. data/spec/extensions/pg_auto_constraint_validations_spec.rb +165 -0
  35. data/spec/extensions/pg_enum_spec.rb +26 -22
  36. data/spec/extensions/tactical_eager_loading_spec.rb +11 -0
  37. data/spec/integration/dataset_test.rb +30 -6
  38. data/spec/integration/plugin_test.rb +2 -2
  39. metadata +6 -2
@@ -42,6 +42,13 @@ describe "pg_enum extension" do
42
42
  @db.sqls.first.must_equal "CREATE TYPE sch.foo AS ENUM ('a', 'b', 'c')"
43
43
  end
44
44
 
45
+ it "should support #rename_enum method for renameing an enum" do
46
+ @db.rename_enum(:foo, :bar)
47
+ @db.sqls.first.must_equal "ALTER TYPE foo RENAME TO bar"
48
+ @db.rename_enum(Sequel[:sch][:foo], Sequel[:sch][:bar])
49
+ @db.sqls.first.must_equal "ALTER TYPE sch.foo RENAME TO sch.bar"
50
+ end
51
+
45
52
  it "should support #drop_enum method for dropping an enum" do
46
53
  @db.drop_enum(:foo)
47
54
  @db.sqls.first.must_equal "DROP TYPE foo"
@@ -82,28 +89,25 @@ describe "pg_enum extension" do
82
89
  end
83
90
 
84
91
  it "should reverse a create_enum directive in a migration" do
85
- c = Class.new do
86
- attr_reader :actions
87
- def initialize(&block)
88
- @actions = []
89
- end
90
- def method_missing(*args)
91
- @actions << args
92
- end
93
- end
94
-
95
- db = c.new
96
-
97
- p = Proc.new do
98
- create_enum(:type_name, %w'value1 value2 value3')
99
- end
100
-
101
- Sequel.migration{change(&p)}.apply(db, :up)
102
- Sequel.migration{change(&p)}.apply(db, :down)
92
+ m = Sequel.migration{change{create_enum(:type_name, %w'value1 value2 value3')}}
93
+ m.apply(@db, :up)
94
+ @db.sqls.must_equal ["CREATE TYPE type_name AS ENUM ('value1', 'value2', 'value3')",
95
+ "SELECT CAST(enumtypid AS integer) AS v, enumlabel FROM pg_enum ORDER BY enumtypid, enumsortorder",
96
+ "SELECT typname, CAST(typarray AS integer) AS v FROM pg_type WHERE ((1 = 0) AND (typarray != 0))"]
97
+ m.apply(@db, :down)
98
+ @db.sqls.must_equal ["DROP TYPE type_name", "SELECT CAST(enumtypid AS integer) AS v, enumlabel FROM pg_enum ORDER BY enumtypid, enumsortorder",
99
+ "SELECT typname, CAST(typarray AS integer) AS v FROM pg_type WHERE ((1 = 0) AND (typarray != 0))"]
100
+ end
103
101
 
104
- db.actions.must_equal [
105
- [:create_enum, :type_name, ["value1", "value2", "value3"] ],
106
- [:drop_enum, :type_name]
107
- ]
102
+ it "should reverse a rename_enum directive in a migration" do
103
+ m = Sequel.migration{change{rename_enum(:old_type_name, :new_type_name)}}
104
+ m.apply(@db, :up)
105
+ @db.sqls.must_equal ["ALTER TYPE old_type_name RENAME TO new_type_name",
106
+ "SELECT CAST(enumtypid AS integer) AS v, enumlabel FROM pg_enum ORDER BY enumtypid, enumsortorder",
107
+ "SELECT typname, CAST(typarray AS integer) AS v FROM pg_type WHERE ((1 = 0) AND (typarray != 0))"]
108
+ m.apply(@db, :down)
109
+ @db.sqls.must_equal ["ALTER TYPE new_type_name RENAME TO old_type_name",
110
+ "SELECT CAST(enumtypid AS integer) AS v, enumlabel FROM pg_enum ORDER BY enumtypid, enumsortorder",
111
+ "SELECT typname, CAST(typarray AS integer) AS v FROM pg_type WHERE ((1 = 0) AND (typarray != 0))"]
108
112
  end
109
113
  end
@@ -28,6 +28,8 @@ describe "Sequel::Plugins::TacticalEagerLoading" do
28
28
  [{:id=>$1.to_i, :parent_id=>nil}]
29
29
  elsif sql =~ /WHERE.*\bid IN \(([\d, ]*)\)/
30
30
  $1.split(', ').map{|x| {:id=>x.to_i, :parent_id=>nil}}
31
+ elsif sql =~ /WHERE.*\bparent_id = (\d+)/
32
+ {:id=>$1.to_i - 100, :parent_id=>$1.to_i} if $1.to_i > 100
31
33
  elsif sql =~ /WHERE.*\bparent_id IN \(([\d, ]*)\)/
32
34
  $1.split(', ').map{|x| {:id=>x.to_i - 100, :parent_id=>x.to_i} if x.to_i > 100}.compact
33
35
  end
@@ -105,6 +107,15 @@ describe "Sequel::Plugins::TacticalEagerLoading" do
105
107
  parents[0..1].map{|x| x.children}.must_equal [[ts[0]], [ts[1]]]
106
108
  end
107
109
 
110
+ it "should not eager load when association uses :allow_eager=>false option" do
111
+ @c.many_to_one :parent, :clone=>:parent, :allow_eager=>false
112
+ @c.one_to_many :children, :clone=>:children, :allow_eager=>false
113
+ ts.map{|x| x.parent}.must_equal [ts[2], ts[3], nil, nil]
114
+ sql_match('SELECT * FROM t WHERE id = 101', 'SELECT * FROM t WHERE id = 102')
115
+ ts.map{|x| x.children}.must_equal [[], [], [ts[0]], [ts[1]]]
116
+ sql_match('SELECT * FROM t WHERE (t.parent_id = 1)', 'SELECT * FROM t WHERE (t.parent_id = 2)', 'SELECT * FROM t WHERE (t.parent_id = 101)', 'SELECT * FROM t WHERE (t.parent_id = 102)')
117
+ end
118
+
108
119
  it "should handle case where an association is valid on an instance, but not on all instances" do
109
120
  c = Class.new(@c)
110
121
  c.many_to_one :parent2, :class=>@c, :key=>:parent_id
@@ -183,6 +183,24 @@ describe "Simple Dataset operations" do
183
183
  end
184
184
  end if DB.dataset.supports_skip_locked?
185
185
 
186
+ it "should raise error instead of waiting for rows correctly" do
187
+ @ds.insert(:number=>10)
188
+ q1 = Queue.new
189
+ q2 = Queue.new
190
+ ds = @ds.order(:id).for_update.nowait
191
+ begin
192
+ t = Thread.new{@db.transaction(:isolation=>:committed){q2.push(ds.get(:id)); q1.pop}}
193
+ q2.pop.must_equal 1
194
+ # Some databases do row level locking, others do page level locking
195
+ proc{@db.transaction(:isolation=>:committed){ds.get(:id)}}.must_raise Sequel::DatabaseLockTimeout
196
+ ensure
197
+ q1.push(nil)
198
+ t.join
199
+ # Keep only one active connection, as some other specs expect that
200
+ @db.disconnect
201
+ end
202
+ end if DB.dataset.supports_nowait?
203
+
186
204
  it "should raise exception if raising on duplication columns" do
187
205
  proc{@ds.select_map([:id, :id])}.must_raise Sequel::DuplicateColumnError
188
206
  end if DB.opts[:on_duplicate_columns] == :raise
@@ -749,8 +767,8 @@ if DB.dataset.supports_cte?
749
767
  end
750
768
  end
751
769
 
752
- if DB.dataset.supports_cte?(:update) # Assume INSERT and DELETE support as well
753
- describe "Common Table Expressions in INSERT/UPDATE/DELETE" do
770
+ if DB.dataset.supports_cte?(:insert) || DB.dataset.supports_cte?(:update) || DB.dataset.supports_cte?(:delete)
771
+ describe "Common Table Expressions" do
754
772
  before do
755
773
  @db = DB
756
774
  @db.create_table!(:i1){Integer :id}
@@ -763,14 +781,20 @@ if DB.dataset.supports_cte?(:update) # Assume INSERT and DELETE support as well
763
781
  @db.drop_table?(:i1)
764
782
  end
765
783
 
766
- it "should give correct results for WITH" do
784
+ it "should give correct results for WITH in insert" do
767
785
  @ds2.insert(@db[:t])
768
786
  @ds.select_order_map(:id).must_equal [1, 1, 2, 2]
787
+ end if DB.dataset.supports_cte?(:insert)
788
+
789
+ it "should give correct results for WITH in update" do
769
790
  @ds2.filter(:id=>@db[:t].select{max(id)}).update(:id=>Sequel.+(:id, 1))
770
- @ds.select_order_map(:id).must_equal [1, 1, 3, 3]
791
+ @ds.select_order_map(:id).must_equal [1, 3]
792
+ end if DB.dataset.supports_cte?(:update)
793
+
794
+ it "should give correct results for WITH in delete" do
771
795
  @ds2.filter(:id=>@db[:t].select{max(id)}).delete
772
- @ds.select_order_map(:id).must_equal [1, 1]
773
- end
796
+ @ds.select_order_map(:id).must_equal [1]
797
+ end if DB.dataset.supports_cte?(:delete)
774
798
 
775
799
  it "should support a subselect in an subquery used for INSERT" do
776
800
  @db.transaction(:rollback=>:always) do
@@ -2047,7 +2047,7 @@ describe "Sequel::Plugins::ConstraintValidations" do
2047
2047
  @ds.insert(@valid_row)
2048
2048
 
2049
2049
  # Test for unique constraint
2050
- proc{@ds.insert(@valid_row)}.must_raise(Sequel::DatabaseError, Sequel::UniqueConstraintViolation, Sequel::ConstraintViolation)
2050
+ proc{@ds.insert(@valid_row)}.must_raise(Sequel::DatabaseError)
2051
2051
 
2052
2052
  @ds.delete
2053
2053
  @violations.each do |col, vals|
@@ -2057,7 +2057,7 @@ describe "Sequel::Plugins::ConstraintValidations" do
2057
2057
  next if val.nil? && @validation_opts[:allow_nil]
2058
2058
  next if val == '' && @validation_opts[:allow_nil] && @db.database_type == :oracle
2059
2059
  try[col] = val
2060
- proc{@ds.insert(try)}.must_raise(Sequel::DatabaseError, Sequel::CheckConstraintViolation, Sequel::ConstraintViolation)
2060
+ proc{@ds.insert(try)}.must_raise(Sequel::DatabaseError)
2061
2061
  end
2062
2062
  end
2063
2063
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequel
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.7.1
4
+ version: 5.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-04-04 00:00:00.000000000 Z
11
+ date: 2018-05-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -190,6 +190,7 @@ extra_rdoc_files:
190
190
  - doc/release_notes/5.2.0.txt
191
191
  - doc/release_notes/5.3.0.txt
192
192
  - doc/release_notes/5.4.0.txt
193
+ - doc/release_notes/5.8.0.txt
193
194
  - doc/release_notes/5.7.0.txt
194
195
  files:
195
196
  - CHANGELOG
@@ -276,6 +277,7 @@ files:
276
277
  - doc/release_notes/5.5.0.txt
277
278
  - doc/release_notes/5.6.0.txt
278
279
  - doc/release_notes/5.7.0.txt
280
+ - doc/release_notes/5.8.0.txt
279
281
  - doc/schema_modification.rdoc
280
282
  - doc/security.rdoc
281
283
  - doc/sharding.rdoc
@@ -492,6 +494,7 @@ files:
492
494
  - lib/sequel/plugins/nested_attributes.rb
493
495
  - lib/sequel/plugins/optimistic_locking.rb
494
496
  - lib/sequel/plugins/pg_array_associations.rb
497
+ - lib/sequel/plugins/pg_auto_constraint_validations.rb
495
498
  - lib/sequel/plugins/pg_row.rb
496
499
  - lib/sequel/plugins/prepared_statements.rb
497
500
  - lib/sequel/plugins/prepared_statements_safe.rb
@@ -625,6 +628,7 @@ files:
625
628
  - spec/extensions/pg_array_associations_spec.rb
626
629
  - spec/extensions/pg_array_ops_spec.rb
627
630
  - spec/extensions/pg_array_spec.rb
631
+ - spec/extensions/pg_auto_constraint_validations_spec.rb
628
632
  - spec/extensions/pg_enum_spec.rb
629
633
  - spec/extensions/pg_extended_date_support_spec.rb
630
634
  - spec/extensions/pg_hstore_ops_spec.rb