sequel 5.7.1 → 5.8.0

Sign up to get free protection for your applications and to get access to all the features.
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