sequel 5.21.0 → 5.26.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +80 -0
  3. data/README.rdoc +1 -1
  4. data/doc/dataset_filtering.rdoc +15 -0
  5. data/doc/opening_databases.rdoc +3 -0
  6. data/doc/postgresql.rdoc +2 -2
  7. data/doc/release_notes/5.22.0.txt +48 -0
  8. data/doc/release_notes/5.23.0.txt +56 -0
  9. data/doc/release_notes/5.24.0.txt +56 -0
  10. data/doc/release_notes/5.25.0.txt +32 -0
  11. data/doc/release_notes/5.26.0.txt +35 -0
  12. data/doc/testing.rdoc +1 -0
  13. data/lib/sequel/adapters/jdbc.rb +7 -1
  14. data/lib/sequel/adapters/jdbc/postgresql.rb +1 -13
  15. data/lib/sequel/adapters/jdbc/sqlite.rb +29 -0
  16. data/lib/sequel/adapters/mysql2.rb +0 -1
  17. data/lib/sequel/adapters/shared/mssql.rb +11 -9
  18. data/lib/sequel/adapters/shared/postgres.rb +42 -12
  19. data/lib/sequel/adapters/shared/sqlite.rb +16 -2
  20. data/lib/sequel/adapters/tinytds.rb +12 -0
  21. data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -1
  22. data/lib/sequel/database/logging.rb +7 -1
  23. data/lib/sequel/database/schema_generator.rb +11 -2
  24. data/lib/sequel/database/schema_methods.rb +2 -0
  25. data/lib/sequel/dataset.rb +4 -2
  26. data/lib/sequel/dataset/actions.rb +3 -2
  27. data/lib/sequel/dataset/query.rb +4 -0
  28. data/lib/sequel/dataset/sql.rb +11 -7
  29. data/lib/sequel/extensions/named_timezones.rb +51 -9
  30. data/lib/sequel/extensions/pg_array.rb +4 -0
  31. data/lib/sequel/extensions/pg_json.rb +88 -17
  32. data/lib/sequel/extensions/pg_json_ops.rb +124 -0
  33. data/lib/sequel/extensions/pg_range.rb +12 -2
  34. data/lib/sequel/extensions/pg_row.rb +3 -1
  35. data/lib/sequel/extensions/sql_comments.rb +2 -2
  36. data/lib/sequel/model/base.rb +12 -5
  37. data/lib/sequel/plugins/association_multi_add_remove.rb +83 -0
  38. data/lib/sequel/plugins/association_proxies.rb +3 -2
  39. data/lib/sequel/plugins/caching.rb +3 -0
  40. data/lib/sequel/plugins/class_table_inheritance.rb +10 -0
  41. data/lib/sequel/plugins/csv_serializer.rb +26 -9
  42. data/lib/sequel/plugins/dirty.rb +3 -9
  43. data/lib/sequel/plugins/insert_conflict.rb +72 -0
  44. data/lib/sequel/plugins/nested_attributes.rb +7 -0
  45. data/lib/sequel/plugins/pg_auto_constraint_validations.rb +89 -30
  46. data/lib/sequel/plugins/sharding.rb +11 -5
  47. data/lib/sequel/plugins/static_cache.rb +8 -3
  48. data/lib/sequel/plugins/static_cache_cache.rb +53 -0
  49. data/lib/sequel/plugins/typecast_on_load.rb +3 -2
  50. data/lib/sequel/sql.rb +18 -4
  51. data/lib/sequel/timezones.rb +50 -11
  52. data/lib/sequel/version.rb +1 -1
  53. data/spec/adapters/postgres_spec.rb +174 -0
  54. data/spec/bin_spec.rb +2 -2
  55. data/spec/core/database_spec.rb +50 -0
  56. data/spec/core/dataset_spec.rb +33 -1
  57. data/spec/core/expression_filters_spec.rb +32 -3
  58. data/spec/core/schema_spec.rb +18 -0
  59. data/spec/core/spec_helper.rb +1 -1
  60. data/spec/core_extensions_spec.rb +1 -1
  61. data/spec/extensions/association_multi_add_remove_spec.rb +1041 -0
  62. data/spec/extensions/dirty_spec.rb +33 -0
  63. data/spec/extensions/insert_conflict_spec.rb +103 -0
  64. data/spec/extensions/named_timezones_spec.rb +109 -2
  65. data/spec/extensions/nested_attributes_spec.rb +48 -0
  66. data/spec/extensions/pg_auto_constraint_validations_spec.rb +37 -0
  67. data/spec/extensions/pg_json_ops_spec.rb +67 -0
  68. data/spec/extensions/pg_json_spec.rb +12 -0
  69. data/spec/extensions/pg_range_spec.rb +90 -9
  70. data/spec/extensions/sharding_spec.rb +8 -0
  71. data/spec/extensions/spec_helper.rb +9 -2
  72. data/spec/extensions/static_cache_cache_spec.rb +35 -0
  73. data/spec/guards_helper.rb +1 -1
  74. data/spec/integration/dataset_test.rb +24 -8
  75. data/spec/integration/plugin_test.rb +27 -0
  76. data/spec/integration/schema_test.rb +16 -2
  77. data/spec/model/spec_helper.rb +1 -1
  78. metadata +32 -2
@@ -241,6 +241,18 @@ describe "pg_json extension" do
241
241
  Sequel.pg_json_wrap(false).must_equal false
242
242
  Sequel.pg_json_wrap(nil).class.must_equal Sequel::Postgres::JSONNull
243
243
  Sequel.pg_json_wrap(nil).must_be_nil
244
+
245
+ c = Class.new(Hash).new
246
+ Sequel.pg_json_wrap(c).class.must_equal Sequel::Postgres::JSONHash
247
+ Sequel.pg_json_wrap(c).must_equal(c)
248
+
249
+ c = Class.new(Array).new
250
+ Sequel.pg_json_wrap(c).class.must_equal Sequel::Postgres::JSONArray
251
+ Sequel.pg_json_wrap(c).must_equal c
252
+
253
+ c = Class.new(String).new('a')
254
+ Sequel.pg_json_wrap(c).class.must_equal Sequel::Postgres::JSONString
255
+ Sequel.pg_json_wrap(c).must_equal c
244
256
  end
245
257
 
246
258
  it "Sequel.pg_json_wrap should fail when passed an unsupported object" do
@@ -17,6 +17,7 @@ describe "pg_range extension" do
17
17
  end
18
18
 
19
19
  endless_range_support = RUBY_VERSION >= '2.6'
20
+ startless_range_support = RUBY_VERSION >= '2.7'
20
21
 
21
22
  it "should set up conversion procs correctly" do
22
23
  cp = @db.conversion_procs
@@ -52,8 +53,19 @@ describe "pg_range extension" do
52
53
 
53
54
  it "should literalize endless Range instances to strings correctly" do
54
55
  @db.literal(eval('1..')).must_equal "'[1,]'"
56
+ @db.literal(eval('1...')).must_equal "'[1,)'"
55
57
  end if endless_range_support
56
58
 
59
+ it "should literalize startless Range instances to strings correctly" do
60
+ @db.literal(eval('..1')).must_equal "'[,1]'"
61
+ @db.literal(eval('...1')).must_equal "'[,1)'"
62
+ end if startless_range_support
63
+
64
+ it "should literalize startless, endless Range instances to strings correctly" do
65
+ @db.literal(eval('nil..nil')).must_equal "'[,]'"
66
+ @db.literal(eval('nil...nil')).must_equal "'[,)'"
67
+ end if startless_range_support
68
+
57
69
  it "should literalize PGRange instances to strings correctly" do
58
70
  @db.literal(@R.new(1, 2)).must_equal "'[1,2]'"
59
71
  @db.literal(@R.new(true, false)).must_equal "'[true,false]'"
@@ -79,8 +91,19 @@ describe "pg_range extension" do
79
91
 
80
92
  it "should support using endless Range instances as bound variables" do
81
93
  @db.bound_variable_arg(eval('1..'), nil).must_equal "[1,]"
94
+ @db.bound_variable_arg(eval('1...'), nil).must_equal "[1,)"
82
95
  end if endless_range_support
83
96
 
97
+ it "should support using startless Range instances as bound variables" do
98
+ @db.bound_variable_arg(eval('..1'), nil).must_equal "[,1]"
99
+ @db.bound_variable_arg(eval('...1'), nil).must_equal "[,1)"
100
+ end if startless_range_support
101
+
102
+ it "should support using startless, endless Range instances as bound variables" do
103
+ @db.bound_variable_arg(eval('nil..nil'), nil).must_equal "[,]"
104
+ @db.bound_variable_arg(eval('nil...nil'), nil).must_equal "[,)"
105
+ end if startless_range_support
106
+
84
107
  it "should support using PGRange instances as bound variables" do
85
108
  @db.bound_variable_arg(@R.new(1, 2), nil).must_equal "[1,2]"
86
109
  end
@@ -113,6 +136,20 @@ describe "pg_range extension" do
113
136
  s[1][1][:ruby_default].must_equal Sequel::Postgres::PGRange.new(1, 5, :exclude_end=>true, :db_type=>'int4range')
114
137
  end
115
138
 
139
+ it "should work correctly in hashes" do
140
+ h = Hash.new(1)
141
+ h[@R.new(1, 2)] = 2
142
+ h[@R.new(nil, nil, :empty => true)] = 3
143
+ h[@R.new(1, 2)].must_equal 2
144
+ h[@R.new(1, 3)].must_equal 1
145
+ h[@R.new(2, 2)].must_equal 1
146
+ h[@R.new(1, 2, :exclude_begin => true)].must_equal 1
147
+ h[@R.new(1, 2, :exclude_end => true)].must_equal 1
148
+ h[@R.new(1, 2, :db_type => :int)].must_equal 1
149
+ h[@R.new(nil, nil, :empty => true)].must_equal 3
150
+ h[@R.new(nil, nil, :empty => true, :db_type => :int)].must_equal 1
151
+ end
152
+
116
153
  describe "database typecasting" do
117
154
  before do
118
155
  @o = @R.new(1, 2, :db_type=>'int4range')
@@ -406,12 +443,12 @@ describe "pg_range extension" do
406
443
  @R.new(nil, nil).wont_equal @R.new(nil, nil, :empty=>true)
407
444
  end
408
445
 
409
- it "should only consider empty PGRanges equal if they have the same bounds" do
446
+ it "should only consider PGRanges equal if they have the same bounds" do
410
447
  @R.new(1, 2).must_equal @R.new(1, 2)
411
448
  @R.new(1, 2).wont_equal @R.new(1, 3)
412
449
  end
413
450
 
414
- it "should only consider empty PGRanges equal if they have the same bound exclusions" do
451
+ it "should only consider PGRanges equal if they have the same bound exclusions" do
415
452
  @R.new(1, 2, :exclude_begin=>true).must_equal @R.new(1, 2, :exclude_begin=>true)
416
453
  @R.new(1, 2, :exclude_end=>true).must_equal @R.new(1, 2, :exclude_end=>true)
417
454
  @R.new(1, 2, :exclude_begin=>true).wont_equal @R.new(1, 2, :exclude_end=>true)
@@ -427,16 +464,39 @@ describe "pg_range extension" do
427
464
 
428
465
  it "should not consider a PGRange equal with a Range if it can't be expressed as a range" do
429
466
  @R.new(nil, nil).wont_be :==, (1..2)
467
+ if startless_range_support
468
+ @R.new(nil, nil, :exclude_begin=>true).wont_be :==, eval('nil..nil')
469
+ end
430
470
  end
431
471
 
432
472
  it "should consider PGRanges equal with a endless Range they represent" do
433
473
  @R.new(1, nil).must_be :==, eval('1..')
434
- end if endless_range_support
435
-
436
- it "should not consider a PGRange equal with a Range if it can't be expressed as a range" do
474
+ @R.new(1, nil, :exclude_end=>true).must_be :==, eval('1...')
475
+ @R.new(1, nil).wont_be :==, eval('1...')
476
+ @R.new(1, nil, :exclude_end=>true).wont_be :==, eval('1..')
437
477
  @R.new(1, nil).wont_be :==, eval('2..')
478
+ @R.new(1, nil, :exclude_end=>true).wont_be :==, eval('2...')
438
479
  end if endless_range_support
439
480
 
481
+ it "should consider PGRanges equal with a startless Range they represent" do
482
+ @R.new(nil, 1).must_be :==, eval('..1')
483
+ @R.new(nil, 1, :exclude_end=>true).must_be :==, eval('...1')
484
+ @R.new(nil, 1).wont_be :==, eval('...1')
485
+ @R.new(nil, 1, :exclude_end=>true).wont_be :==, eval('..1')
486
+ @R.new(nil, 1).wont_be :==, eval('..2')
487
+ @R.new(nil, 1, :exclude_end=>true).wont_be :==, eval('...2')
488
+ end if startless_range_support
489
+
490
+ it "should consider PGRanges equal with a startless, endless Range they represent" do
491
+ @R.new(nil, nil).must_be :==, eval('nil..nil')
492
+ @R.new(nil, nil, :exclude_end=>true).must_be :==, eval('nil...nil')
493
+ @R.new(nil, nil).wont_be :==, eval('nil...nil')
494
+ @R.new(nil, nil, :exclude_end=>true).wont_be :==, eval('nil..nil')
495
+ @R.new(nil, nil).wont_be :==, eval('nil..1')
496
+ @R.new(nil, nil).wont_be :==, eval('1..nil')
497
+ @R.new(1, nil).wont_be :==, eval('nil..nil')
498
+ end if startless_range_support
499
+
440
500
  it "should not consider a PGRange equal to other objects" do
441
501
  @R.new(nil, nil).wont_equal 1
442
502
  end
@@ -444,7 +504,6 @@ describe "pg_range extension" do
444
504
  it "should have #=== be true if given an equal PGRange" do
445
505
  @R.new(1, 2).must_be :===, @R.new(1, 2)
446
506
  @R.new(1, 2).wont_be :===, @R.new(1, 3)
447
-
448
507
  end
449
508
 
450
509
  it "should have #=== be true if it would be true for the Range represented by the PGRange" do
@@ -453,7 +512,7 @@ describe "pg_range extension" do
453
512
  end
454
513
 
455
514
  it "should have #=== be false if the PGRange cannot be represented by a Range" do
456
- @R.new(nil, nil).wont_be :===, 1.5
515
+ @R.new(1, 2, :exclude_begin=>true).wont_be :===, 1.5
457
516
  end
458
517
 
459
518
  it "should have #empty? indicate whether the range is empty" do
@@ -471,7 +530,6 @@ describe "pg_range extension" do
471
530
  end
472
531
 
473
532
  it "should have #to_range raise an exception if the PGRange cannot be represented by a Range" do
474
- proc{@R.new(nil, 1).to_range}.must_raise(Sequel::Error)
475
533
  proc{@R.new(0, 1, :exclude_begin=>true).to_range}.must_raise(Sequel::Error)
476
534
  proc{@R.empty.to_range}.must_raise(Sequel::Error)
477
535
  end
@@ -488,6 +546,22 @@ describe "pg_range extension" do
488
546
  proc{@R.new(1, nil).to_range}.must_raise(Sequel::Error)
489
547
  end unless endless_range_support
490
548
 
549
+ it "should have #to_range return the represented range for startless ranges" do
550
+ @R.new(nil, 1).to_range.must_be :==, eval('..1')
551
+ end if startless_range_support
552
+
553
+ it "should have #to_range raise an exception for startless ranges" do
554
+ proc{@R.new(nil, 1).to_range}.must_raise(Sequel::Error)
555
+ end unless startless_range_support
556
+
557
+ it "should have #to_range return the represented range for startless, endless ranges" do
558
+ @R.new(nil, nil).to_range.must_be :==, eval('nil..nil')
559
+ end if startless_range_support
560
+
561
+ it "should have #to_range raise an exception for startless, endless ranges" do
562
+ proc{@R.new(nil, nil).to_range}.must_raise(Sequel::Error)
563
+ end unless startless_range_support
564
+
491
565
  it "should have #to_range cache the returned value" do
492
566
  @r1.to_range.must_be_same_as(@r1.to_range)
493
567
  end
@@ -507,7 +581,6 @@ describe "pg_range extension" do
507
581
  end
508
582
 
509
583
  it "should have #valid_ruby_range? return false if the PGRange cannot be represented as a Range" do
510
- @R.new(nil, 1).valid_ruby_range?.must_equal false
511
584
  @R.new(0, 1, :exclude_begin=>true).valid_ruby_range?.must_equal false
512
585
  @R.empty.valid_ruby_range?.must_equal false
513
586
  end
@@ -515,5 +588,13 @@ describe "pg_range extension" do
515
588
  it "should have #valid_ruby_range return #{endless_range_support} for endless ranges" do
516
589
  @R.new(1, nil).valid_ruby_range?.must_equal(endless_range_support)
517
590
  end
591
+
592
+ it "should have #valid_ruby_range return #{startless_range_support} for endless ranges" do
593
+ @R.new(nil, 1).valid_ruby_range?.must_equal(startless_range_support)
594
+ end
595
+
596
+ it "should have #valid_ruby_range return #{startless_range_support} for startless, endless ranges" do
597
+ @R.new(nil, nil).valid_ruby_range?.must_equal(startless_range_support)
598
+ end
518
599
  end
519
600
  end
@@ -186,4 +186,12 @@ describe "sharding plugin" do
186
186
  ["UPDATE albums SET artist_id = 2, name = 'RF' WHERE (id = 1) -- s1", "UPDATE albums SET name = 'RF', artist_id = 2 WHERE (id = 1) -- s1"].must_include(sqls.slice!(2))
187
187
  sqls.must_equal ["SELECT * FROM albums LIMIT 1 -- s2", "BEGIN -- s1", "COMMIT -- s1"]
188
188
  end
189
+
190
+ it "should have objects retrieved from a specific shard using with_server from server_block extension" do
191
+ album = @db.extension(:server_block).with_server(:s1) do
192
+ @Album.first
193
+ end
194
+ album.update(:name=>'MO')
195
+ @db.sqls.must_equal ["SELECT * FROM albums LIMIT 1 -- s1", "UPDATE albums SET name = 'MO' WHERE (id = 1) -- s1"]
196
+ end
189
197
  end
@@ -7,7 +7,7 @@ end
7
7
 
8
8
  ENV['MT_NO_PLUGINS'] = '1' # Work around stupid autoloading of plugins
9
9
  gem 'minitest'
10
- require 'minitest/autorun'
10
+ require 'minitest/global_expectations/autorun'
11
11
  require 'minitest/hooks/default'
12
12
  require 'minitest/shared_description'
13
13
 
@@ -16,6 +16,11 @@ require_relative "../../lib/sequel"
16
16
 
17
17
  require_relative '../deprecation_helper'
18
18
 
19
+ if ENV['SEQUEL_TZINFO_VERSION']
20
+ # Allow forcing specific TZInfo versions, useful when testing
21
+ gem 'tzinfo', ENV['SEQUEL_TZINFO_VERSION']
22
+ end
23
+
19
24
  begin
20
25
  # Attempt to load ActiveSupport blank extension and inflector first, so Sequel
21
26
  # can override them.
@@ -26,7 +31,9 @@ rescue LoadError
26
31
  nil
27
32
  end
28
33
 
29
- Sequel.extension :core_refinements if RUBY_VERSION >= '2.0.0' && RUBY_ENGINE == 'ruby'
34
+ if (RUBY_VERSION >= '2.0.0' && RUBY_ENGINE == 'ruby') || (RUBY_ENGINE == 'jruby' && (JRUBY_VERSION >= '9.3' || (JRUBY_VERSION.match(/\A9\.2\.(\d+)/) && $1.to_i >= 7)))
35
+ Sequel.extension :core_refinements
36
+ end
30
37
 
31
38
  class << Sequel::Model
32
39
  attr_writer :db_schema
@@ -0,0 +1,35 @@
1
+ require_relative "spec_helper"
2
+
3
+ describe "static_cache_cache plugin" do
4
+ before do
5
+ @db = Sequel.mock
6
+ @db.fetch = [{:id=>1, :name=>'A'}, {:id=>2, :name=>'B'}]
7
+ @c = Class.new(Sequel::Model(@db[:t]))
8
+ def @c.name; 'Foo' end
9
+ @c.columns :id, :name
10
+ @file = "spec/files/static_cache_cache-spec-#{$$}.cache"
11
+ end
12
+ after do
13
+ File.delete(@file) if File.file?(@file)
14
+ end
15
+
16
+ it "should allow dumping and loading static cache rows from a cache file" do
17
+ @c.plugin :static_cache_cache, @file
18
+ @db.sqls
19
+ @c.plugin :static_cache
20
+ @db.sqls.must_equal ['SELECT * FROM t']
21
+ @c.all.must_equal [@c.load(:id=>1, :name=>'A'), @c.load(:id=>2, :name=>'B')]
22
+
23
+ @c.dump_static_cache_cache
24
+
25
+ @db.fetch = []
26
+ c = Class.new(Sequel::Model(@db[:t]))
27
+ def c.name; 'Foo' end
28
+ c.columns :id, :name
29
+ @c.plugin :static_cache_cache, @file
30
+ @db.sqls
31
+ @c.plugin :static_cache
32
+ @db.sqls.must_be_empty
33
+ @c.all.must_equal [@c.load(:id=>1, :name=>'A'), @c.load(:id=>2, :name=>'B')]
34
+ end
35
+ end
@@ -1,6 +1,6 @@
1
1
  ENV['MT_NO_PLUGINS'] = '1' # Work around stupid autoloading of plugins
2
2
  gem 'minitest'
3
- require 'minitest/autorun'
3
+ require 'minitest/global_expectations/autorun'
4
4
  require 'minitest/hooks/default'
5
5
  require 'minitest/shared_description'
6
6
 
@@ -1109,6 +1109,12 @@ describe "Sequel::Dataset#import and #multi_insert :return=>:primary_key " do
1109
1109
  @ds.order(:id).map([:id, :i]).must_equal [[1, 10], [2, 20], [3, 30], [4, 40], [5, 50], [6, 60]]
1110
1110
  end
1111
1111
 
1112
+ it "should handle dataset with row_proc" do
1113
+ ds = @ds.with_row_proc(lambda{|h| Object.new})
1114
+ ds.multi_insert([{:i=>10}, {:i=>20}, {:i=>30}], :return=>:primary_key).must_equal [1, 2, 3]
1115
+ ds.import([:i], [[40], [50], [60]], :return=>:primary_key).must_equal [4, 5, 6]
1116
+ end
1117
+
1112
1118
  it "should return primary key values when :slice is used" do
1113
1119
  @ds.multi_insert([{:i=>10}, {:i=>20}, {:i=>30}], :return=>:primary_key, :slice=>2).must_equal [1, 2, 3]
1114
1120
  @ds.import([:i], [[40], [50], [60]], :return=>:primary_key, :slice=>2).must_equal [4, 5, 6]
@@ -1545,15 +1551,25 @@ describe "Sequel::Dataset DSL support" do
1545
1551
  @ds.exclude(:a=>[20, 10]).all.must_equal []
1546
1552
  end
1547
1553
 
1548
- it "should work with ranges as hash values" do
1554
+ it "should work with endless ranges as hash values" do
1549
1555
  @ds.insert(20, 10)
1550
- @ds.filter(:a=>(10..30)).all.must_equal [{:a=>20, :b=>10}]
1551
- @ds.filter(:a=>(25..30)).all.must_equal []
1552
- @ds.filter(:a=>(10..15)).all.must_equal []
1553
- @ds.exclude(:a=>(10..30)).all.must_equal []
1554
- @ds.exclude(:a=>(25..30)).all.must_equal [{:a=>20, :b=>10}]
1555
- @ds.exclude(:a=>(10..15)).all.must_equal [{:a=>20, :b=>10}]
1556
- end
1556
+ @ds.filter(:a=>eval('30..')).all.must_equal []
1557
+ @ds.filter(:a=>eval('20...')).all.must_equal [{:a=>20, :b=>10}]
1558
+ @ds.filter(:a=>eval('20..')).all.must_equal [{:a=>20, :b=>10}]
1559
+ @ds.filter(:a=>eval('10..')).all.must_equal [{:a=>20, :b=>10}]
1560
+ end if RUBY_VERSION >= '2.6'
1561
+
1562
+ it "should work with startless ranges as hash values" do
1563
+ @ds.insert(20, 10)
1564
+ @ds.filter(:a=>eval('..30')).all.must_equal [{:a=>20, :b=>10}]
1565
+ @ds.filter(:a=>eval('...30')).all.must_equal [{:a=>20, :b=>10}]
1566
+ @ds.filter(:a=>eval('..20')).all.must_equal [{:a=>20, :b=>10}]
1567
+ @ds.filter(:a=>eval('...20')).all.must_equal []
1568
+ @ds.filter(:a=>eval('..10')).all.must_equal []
1569
+ @ds.filter(:a=>eval('...10')).all.must_equal []
1570
+
1571
+ @ds.filter(:a=>eval('nil..nil')).all.must_equal [{:a=>20, :b=>10}]
1572
+ end if RUBY_VERSION >= '2.7'
1557
1573
 
1558
1574
  it "should work with CASE statements" do
1559
1575
  @ds.insert(20, 10)
@@ -2394,3 +2394,30 @@ describe "string_agg extension" do
2394
2394
  @ds.select_group(:id).select_append(Sequel.string_agg(:s).order(:s).distinct.as(:v)).map([:id, :v]).must_equal [[1, 'a,b,c'], [2, 'aa,bb']]
2395
2395
  end
2396
2396
  end
2397
+
2398
+ describe "insert_conflict plugin" do
2399
+ before(:all) do
2400
+ @db = DB
2401
+ @db.create_table!(:ic_test) do
2402
+ primary_key :id
2403
+ String :s, :unique=>true
2404
+ Integer :o
2405
+ end
2406
+ @model = Class.new(Sequel::Model)
2407
+ @model.set_dataset @db[:ic_test]
2408
+ @model.plugin :insert_conflict
2409
+ end
2410
+ after(:all) do
2411
+ @db.drop_table?(:ic_test)
2412
+ end
2413
+
2414
+ it "should allow Model#insert_conflict to work" do
2415
+ ic_opts = {:target=>:s, :update => {:o => Sequel[:excluded][:o]}}
2416
+ @model.new(:s=>'A', :o=>1).insert_conflict(ic_opts).save
2417
+ @model.select_order_map([:s, :o]).must_equal [['A', 1]]
2418
+ @model.new(:s=>'A', :o=>2).insert_conflict(ic_opts).save
2419
+ @model.select_order_map([:s, :o]).must_equal [['A', 2]]
2420
+ @model.new(:s=>'B', :o=>3).insert_conflict(ic_opts).save
2421
+ @model.select_order_map([:s, :o]).must_equal [['A', 2], ['B', 3]]
2422
+ end
2423
+ end if (DB.database_type == :postgres && DB.server_version >= 90500) || (DB.database_type == :sqlite && DB.sqlite_version >= 32400)
@@ -634,6 +634,15 @@ describe "Database schema modifiers" do
634
634
  @ds.all.must_equal [{:id=>10}, {:id=>20}]
635
635
  end
636
636
 
637
+ it "should set column defaults correctly if column has existing default" do
638
+ @db.create_table!(:items){Integer :id, :default=>10}
639
+ @ds.insert
640
+ @ds.all.must_equal [{:id=>10}]
641
+ @db.alter_table(:items){set_column_default :id, 20}
642
+ @ds.insert
643
+ @ds.all.must_equal [{:id=>10}, {:id=>20}]
644
+ end
645
+
637
646
  it "should set column defaults to nil correctly" do
638
647
  @db.create_table!(:items){Integer :id}
639
648
  @ds.insert(:id=>10)
@@ -750,10 +759,15 @@ describe "Database schema modifiers" do
750
759
  @db.create_table!(:items) do
751
760
  primary_key :id
752
761
  Integer :i, :default=>20
762
+ Integer :j, :default=>10
763
+ String :s, :default=>'a'
753
764
  end
754
- @ds.insert(:i=>10)
765
+ @ds.insert(:i=>10, :j=>20, :s=>'b')
755
766
  @db.drop_column(:items, :i)
756
- @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:id]
767
+ @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:id, :j, :s]
768
+ @ds.first.must_equal(:id=>1, :j=>20, :s=>'b')
769
+ @ds.insert
770
+ @ds.first(:id=>2).must_equal(:id=>2, :j=>10, :s=>'a')
757
771
  end
758
772
 
759
773
  it "should remove foreign key columns from tables correctly" do
@@ -7,7 +7,7 @@ Sequel::Deprecation.backtrace_filter = lambda{|line, lineno| lineno < 4 || line
7
7
 
8
8
  ENV['MT_NO_PLUGINS'] = '1' # Work around stupid autoloading of plugins
9
9
  gem 'minitest'
10
- require 'minitest/autorun'
10
+ require 'minitest/global_expectations/autorun'
11
11
  require 'minitest/hooks/default'
12
12
 
13
13
  require_relative '../deprecation_helper'
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.21.0
4
+ version: 5.26.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: 2019-06-01 00:00:00.000000000 Z
11
+ date: 2019-11-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest-global_expectations
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: minitest-shared_description
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -205,6 +219,11 @@ extra_rdoc_files:
205
219
  - doc/release_notes/5.19.0.txt
206
220
  - doc/release_notes/5.20.0.txt
207
221
  - doc/release_notes/5.21.0.txt
222
+ - doc/release_notes/5.22.0.txt
223
+ - doc/release_notes/5.23.0.txt
224
+ - doc/release_notes/5.24.0.txt
225
+ - doc/release_notes/5.25.0.txt
226
+ - doc/release_notes/5.26.0.txt
208
227
  files:
209
228
  - CHANGELOG
210
229
  - MIT-LICENSE
@@ -297,6 +316,11 @@ files:
297
316
  - doc/release_notes/5.2.0.txt
298
317
  - doc/release_notes/5.20.0.txt
299
318
  - doc/release_notes/5.21.0.txt
319
+ - doc/release_notes/5.22.0.txt
320
+ - doc/release_notes/5.23.0.txt
321
+ - doc/release_notes/5.24.0.txt
322
+ - doc/release_notes/5.25.0.txt
323
+ - doc/release_notes/5.26.0.txt
300
324
  - doc/release_notes/5.3.0.txt
301
325
  - doc/release_notes/5.4.0.txt
302
326
  - doc/release_notes/5.5.0.txt
@@ -484,6 +508,7 @@ files:
484
508
  - lib/sequel/plugins/active_model.rb
485
509
  - lib/sequel/plugins/after_initialize.rb
486
510
  - lib/sequel/plugins/association_dependencies.rb
511
+ - lib/sequel/plugins/association_multi_add_remove.rb
487
512
  - lib/sequel/plugins/association_pks.rb
488
513
  - lib/sequel/plugins/association_proxies.rb
489
514
  - lib/sequel/plugins/auto_validations.rb
@@ -511,6 +536,7 @@ files:
511
536
  - lib/sequel/plugins/force_encoding.rb
512
537
  - lib/sequel/plugins/hook_class_methods.rb
513
538
  - lib/sequel/plugins/input_transformer.rb
539
+ - lib/sequel/plugins/insert_conflict.rb
514
540
  - lib/sequel/plugins/insert_returning_select.rb
515
541
  - lib/sequel/plugins/instance_filters.rb
516
542
  - lib/sequel/plugins/instance_hooks.rb
@@ -537,6 +563,7 @@ files:
537
563
  - lib/sequel/plugins/skip_create_refresh.rb
538
564
  - lib/sequel/plugins/split_values.rb
539
565
  - lib/sequel/plugins/static_cache.rb
566
+ - lib/sequel/plugins/static_cache_cache.rb
540
567
  - lib/sequel/plugins/string_stripper.rb
541
568
  - lib/sequel/plugins/subclasses.rb
542
569
  - lib/sequel/plugins/subset_conditions.rb
@@ -592,6 +619,7 @@ files:
592
619
  - spec/extensions/after_initialize_spec.rb
593
620
  - spec/extensions/arbitrary_servers_spec.rb
594
621
  - spec/extensions/association_dependencies_spec.rb
622
+ - spec/extensions/association_multi_add_remove_spec.rb
595
623
  - spec/extensions/association_pks_spec.rb
596
624
  - spec/extensions/association_proxies_spec.rb
597
625
  - spec/extensions/auto_literal_strings_spec.rb
@@ -642,6 +670,7 @@ files:
642
670
  - spec/extensions/index_caching_spec.rb
643
671
  - spec/extensions/inflector_spec.rb
644
672
  - spec/extensions/input_transformer_spec.rb
673
+ - spec/extensions/insert_conflict_spec.rb
645
674
  - spec/extensions/insert_returning_select_spec.rb
646
675
  - spec/extensions/instance_filters_spec.rb
647
676
  - spec/extensions/instance_hooks_spec.rb
@@ -706,6 +735,7 @@ files:
706
735
  - spec/extensions/split_values_spec.rb
707
736
  - spec/extensions/sql_comments_spec.rb
708
737
  - spec/extensions/sql_expr_spec.rb
738
+ - spec/extensions/static_cache_cache_spec.rb
709
739
  - spec/extensions/static_cache_spec.rb
710
740
  - spec/extensions/string_agg_spec.rb
711
741
  - spec/extensions/string_date_time_spec.rb