sequel 5.27.0 → 5.28.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 512f72ad99402b33be776e759611a9299b638f49344fb1f349120c8cd1643107
4
- data.tar.gz: ea0852b3ea61ef9a5a192637a2b457fe47f2374c8ee2eb20d9b02e6eb25a25ac
3
+ metadata.gz: e206de897422ca8260c788bcfc20bcb154c9122dd17a12dc4b45ecdca023eb9a
4
+ data.tar.gz: 319df67cbb77d1b93d12cd0a1f429de0b674543ebd62b6407d40e1bd992e2352
5
5
  SHA512:
6
- metadata.gz: 4397a4a7530bd3234d7c1e3bf8b1c2b8a6845e659b86b7177dc704edf8ebf2185c499ac7ba04bb7d52006cf1367b8c0835787be1483e7bb481fa4ea2d775680b
7
- data.tar.gz: 653238c46ae32bd74127bddb87dc4c99637f5eadfb7515a51e8da5bc57df10de57c2e9a97d085828cc45b97303fa66580c1c8832a5f6fbb5cdaffd585ce0ff86
6
+ metadata.gz: a69c5b0bdfdb9c32503204b19d7dc18a7f78f7af7d46c44a7a4413ed4561c3ed3d0a796742045b158714a45f165957a0b9e5d6830bb110e53872a17a1ccb1ed8
7
+ data.tar.gz: 73a7df723afa66c70f72218e0327f10ef659a22614e5a4438d8fdc2ba16ec97d6e33213c4fd2ed08e806f2860f968786543015b34f38449093d71194aadb3655
data/CHANGELOG CHANGED
@@ -1,3 +1,11 @@
1
+ === 5.28.0 (2020-01-01)
2
+
3
+ * Warn when calling Sequel::JDBC::Postgres::Dataset#with_fetch_size (jeremyevans) (#1665)
4
+
5
+ * Add exclude_or_null extension, for filtering datasets where the condition is false or NULL (jeremyevans)
6
+
7
+ * Add any_not_empty extension, for making Dataset#any? without a block mean !empty? (jeremyevans)
8
+
1
9
  === 5.27.0 (2019-12-01)
2
10
 
3
11
  * Add Sequel::DEFAULT for a DEFAULT expression, useful for assigning to default values (jeremyevans)
@@ -55,6 +55,7 @@ Without a filename argument, the sqlite adapter will setup a new sqlite database
55
55
 
56
56
  dataset.exclude(:active).delete
57
57
  dataset.where{price < 100}.update(:active => true)
58
+ dataset.where(:active).update(:price => Sequel[:price] * 0.90)
58
59
 
59
60
  == Datasets are Enumerable
60
61
 
@@ -0,0 +1,16 @@
1
+ = New Features
2
+
3
+ * An any_not_empty extension has been added, for making Dataset#any?
4
+ without a block be the same as !empty?. This can result in a
5
+ much faster database query.
6
+
7
+ * An exclude_or_null extension has been added, adding a
8
+ Dataset#exclude_or_null method that returns rows where the given
9
+ expression is false or NULL. This extension is supported on
10
+ PostgreSQL, SQLite, MySQL, H2, and HSQLDB.
11
+
12
+ = Other Improvements
13
+
14
+ * When using the jdbc/postgresql adapter, calling with_fetch_size
15
+ on a dataset will emit a warning. This is because the driver
16
+ will ignore the setting.
@@ -8,17 +8,20 @@ These run each test in its own transaction, the recommended way to test.
8
8
 
9
9
  === minitest/spec
10
10
 
11
- ==== with minitest-hooks
12
-
11
+ ==== with minitest-hooks
13
12
  require 'minitest/hooks/default'
13
+
14
+ DB = Sequel.postgres # change if using sqlite etc
15
+
14
16
  class Minitest::HooksSpec
15
17
  def around
16
18
  DB.transaction(:rollback=>:always, :auto_savepoint=>true){super}
17
19
  end
18
20
  end
19
21
 
20
- ==== without minitest-hooks
21
-
22
+ ==== without minitest-hooks
23
+ DB = Sequel.postgres # change if using sqlite etc
24
+
22
25
  class Minitest::Spec
23
26
  def run(*args, &block)
24
27
  DB.transaction(:rollback=>:always, :auto_savepoint=>true){super}
@@ -26,7 +29,8 @@ These run each test in its own transaction, the recommended way to test.
26
29
  end
27
30
 
28
31
  === minitest/test
29
-
32
+ DB = Sequel.postgres # change if using sqlite etc
33
+
30
34
  # Use this class as the base class for your tests
31
35
  class SequelTestCase < Minitest::Test
32
36
  def run(*args, &block)
@@ -35,7 +39,8 @@ These run each test in its own transaction, the recommended way to test.
35
39
  end
36
40
 
37
41
  === rspec >= 2.8
38
-
42
+ DB = Sequel.postgres # change the database if you are using sqlite etc.
43
+
39
44
  RSpec.configure do |c|
40
45
  c.around(:each) do |example|
41
46
  DB.transaction(:rollback=>:always, :auto_savepoint=>true){example.run}
@@ -180,6 +180,12 @@ module Sequel
180
180
 
181
181
  class Dataset < JDBC::Dataset
182
182
  include Sequel::Postgres::DatasetMethods
183
+
184
+ # Warn when calling as the fetch size is ignored by the JDBC adapter currently.
185
+ def with_fetch_size(size)
186
+ warn("Sequel::JDBC::Postgres::Dataset#with_fetch_size does not currently have an effect.", :uplevel=>1)
187
+ super
188
+ end
183
189
 
184
190
  private
185
191
 
@@ -1237,6 +1237,20 @@ module Sequel
1237
1237
  self
1238
1238
  end
1239
1239
 
1240
+ # If invert is true, invert the condition.
1241
+ def _invert_filter(cond, invert)
1242
+ if invert
1243
+ SQL::BooleanExpression.invert(cond)
1244
+ else
1245
+ cond
1246
+ end
1247
+ end
1248
+
1249
+ # Add the given filter condition. Arguments:
1250
+ # clause :: Symbol or which SQL clause to effect, should be :where or :having
1251
+ # cond :: The filter condition to add
1252
+ # invert :: Whether the condition should be inverted (true or false)
1253
+ # combine :: How to combine the condition with an existing condition, should be :AND or :OR
1240
1254
  def add_filter(clause, cond, invert=false, combine=:AND, &block)
1241
1255
  if cond == EMPTY_ARRAY && !block
1242
1256
  raise Error, "must provide an argument to a filtering method if not passing a block"
@@ -1256,8 +1270,7 @@ module Sequel
1256
1270
  cond = nil
1257
1271
  end
1258
1272
 
1259
- cond = filter_expr(cond, &block)
1260
- cond = SQL::BooleanExpression.invert(cond) if invert
1273
+ cond = _invert_filter(filter_expr(cond, &block), invert)
1261
1274
  cond = SQL::BooleanExpression.new(combine, @opts[clause], cond) if @opts[clause]
1262
1275
 
1263
1276
  if cond.nil?
@@ -0,0 +1,45 @@
1
+ # frozen-string-literal: true
2
+ #
3
+ # The any_not_empty extension changes the behavior of Dataset#any?
4
+ # if called without a block. By default, this method uses the
5
+ # standard Enumerable behavior of enumerating results and seeing
6
+ # if any result is not false or nil. With this extension, it
7
+ # just checks whether the dataset is empty. This approach can
8
+ # be much faster if the dataset is currently large.
9
+ #
10
+ # DB[:table].any?
11
+ # # SELECT * FROM table
12
+ #
13
+ # DB[:table].extension(:any_not_empty).any?
14
+ # # SELECT 1 as one FROM table LIMIT 1
15
+ #
16
+ # You can load this extension into specific datasets:
17
+ #
18
+ # ds = DB[:table]
19
+ # ds = ds.extension(:any_not_empty)
20
+ #
21
+ # Or you can load it into all of a database's datasets, which
22
+ # is probably the desired behavior if you are using this extension:
23
+ #
24
+ # DB.extension(:any_not_empty)
25
+ #
26
+ # Note that this can result in any? returning a different result if
27
+ # the dataset has a row_proc that can return false or nil.
28
+ #
29
+ # Related module: Sequel::AnyNotEmpty
30
+
31
+ #
32
+ module Sequel
33
+ module AnyNotEmpty
34
+ # If a block is not given, return whether the dataset is not empty.
35
+ def any?
36
+ if block_given?
37
+ super
38
+ else
39
+ !empty?
40
+ end
41
+ end
42
+ end
43
+
44
+ Dataset.register_extension(:any_not_empty, AnyNotEmpty)
45
+ end
@@ -0,0 +1,68 @@
1
+ # frozen-string-literal: true
2
+ #
3
+ # The exclude_or_null extension adds Dataset#exclude_or_null and
4
+ # Dataset#exclude_or_null_having. These methods are similar to
5
+ # Dataset#exclude and Dataset#exclude_having, except that they
6
+ # will also exclude rows where the condition IS NULL.
7
+ #
8
+ # DB[:table].exclude_or_null(foo: 1)
9
+ # # SELECT * FROM table WHERE NOT coalesce((foo = 1), false)
10
+ #
11
+ # DB[:table].exclude_or_null{foo(bar) =~ 1}
12
+ # # SELECT * FROM table HAVING NOT coalesce((foo(bar) = 1), false))
13
+ #
14
+ # You can load this extension into specific datasets:
15
+ #
16
+ # ds = DB[:table]
17
+ # ds = ds.extension(:exclude_or_null)
18
+ #
19
+ # Or you can load it into all of a database's datasets, which
20
+ # is probably the desired behavior if you are using this extension:
21
+ #
22
+ # DB.extension(:exclude_or_null)
23
+ #
24
+ # Note, this extension works correctly on PostgreSQL, SQLite, MySQL,
25
+ # H2, and HSQLDB. However, it does not work correctly on Microsoft SQL Server,
26
+ # Oracle, DB2, SQLAnywhere, or Derby.
27
+ #
28
+ # Related module: Sequel::ExcludeOrNull
29
+
30
+ #
31
+ module Sequel
32
+ module ExcludeOrNull
33
+ # Performs the inverse of Dataset#where, but also excludes rows where the given
34
+ # condition IS NULL.
35
+ #
36
+ # DB[:items].exclude_or_null(category: 'software')
37
+ # # SELECT * FROM items WHERE NOT coalesce((category = 'software'), false)
38
+ #
39
+ # DB[:items].exclude_or_null(category: 'software', id: 3)
40
+ # # SELECT * FROM items WHERE NOT coalesce(((category = 'software') AND (id = 3)), false)
41
+ def exclude_or_null(*cond, &block)
42
+ add_filter(:where, cond, :or_null, &block)
43
+ end
44
+
45
+ # The same as exclude_or_null, but affecting the HAVING clause instead of the
46
+ # WHERE clause.
47
+ #
48
+ # DB[:items].select_group(:name).exclude_or_null_having{count(name) < 2}
49
+ # # SELECT name FROM items GROUP BY name HAVING NOT coalesce((count(name) < 2), true)
50
+ def exclude_or_null_having(*cond, &block)
51
+ add_filter(:having, cond, :or_null, &block)
52
+ end
53
+
54
+ private
55
+
56
+ # Recognize :or_null value for invert, returning an expression for
57
+ # the invert of the condition or the condition being null.
58
+ def _invert_filter(cond, invert)
59
+ if invert == :or_null
60
+ ~SQL::Function.new(:coalesce, cond, SQL::Constants::SQLFALSE)
61
+ else
62
+ super
63
+ end
64
+ end
65
+ end
66
+
67
+ Dataset.register_extension(:exclude_or_null, ExcludeOrNull)
68
+ end
@@ -6,7 +6,7 @@ module Sequel
6
6
 
7
7
  # The minor version of Sequel. Bumped for every non-patch level
8
8
  # release, generally around once a month.
9
- MINOR = 27
9
+ MINOR = 28
10
10
 
11
11
  # The tiny version of Sequel. Usually 0, only bumped for bugfix
12
12
  # releases that fix regressions from previous versions.
@@ -3685,19 +3685,19 @@ describe 'PostgreSQL range types' do
3685
3685
  end if uses_pg_or_jdbc
3686
3686
 
3687
3687
  it 'handle endless ranges' do
3688
- @db.get(Sequel.cast(eval('1...'), :int4range)).must_be :==, eval('1...')
3689
- @db.get(Sequel.cast(eval('1...'), :int4range)).wont_be :==, eval('2...')
3690
- @db.get(Sequel.cast(eval('1...'), :int4range)).wont_be :==, eval('1..')
3691
- @db.get(Sequel.cast(eval('2...'), :int4range)).must_be :==, eval('2...')
3692
- @db.get(Sequel.cast(eval('2...'), :int4range)).wont_be :==, eval('2..')
3693
- @db.get(Sequel.cast(eval('2...'), :int4range)).wont_be :==, eval('1...')
3688
+ @db.get(Sequel.cast(eval('(1...)'), :int4range)).must_be :==, eval('(1...)')
3689
+ @db.get(Sequel.cast(eval('(1...)'), :int4range)).wont_be :==, eval('(2...)')
3690
+ @db.get(Sequel.cast(eval('(1...)'), :int4range)).wont_be :==, eval('(1..)')
3691
+ @db.get(Sequel.cast(eval('(2...)'), :int4range)).must_be :==, eval('(2...)')
3692
+ @db.get(Sequel.cast(eval('(2...)'), :int4range)).wont_be :==, eval('(2..)')
3693
+ @db.get(Sequel.cast(eval('(2...)'), :int4range)).wont_be :==, eval('(1...)')
3694
3694
  end if RUBY_VERSION >= '2.6'
3695
3695
 
3696
3696
  it 'handle startless ranges' do
3697
- @db.get(Sequel.cast(eval('...1'), :int4range)).must_be :==, Sequel::Postgres::PGRange.new(nil, 1, :exclude_begin=>true, :exclude_end=>true, :db_type=>"int4range")
3698
- @db.get(Sequel.cast(eval('...1'), :int4range)).wont_be :==, Sequel::Postgres::PGRange.new(nil, 2, :exclude_begin=>true, :exclude_end=>true, :db_type=>"int4range")
3699
- @db.get(Sequel.cast(eval('...1'), :int4range)).wont_be :==, Sequel::Postgres::PGRange.new(nil, 1, :exclude_end=>true, :db_type=>"int4range")
3700
- @db.get(Sequel.cast(eval('...1'), :int4range)).wont_be :==, Sequel::Postgres::PGRange.new(nil, 1, :exclude_begin=>true, :db_type=>"int4range")
3697
+ @db.get(Sequel.cast(eval('(...1)'), :int4range)).must_be :==, Sequel::Postgres::PGRange.new(nil, 1, :exclude_begin=>true, :exclude_end=>true, :db_type=>"int4range")
3698
+ @db.get(Sequel.cast(eval('(...1)'), :int4range)).wont_be :==, Sequel::Postgres::PGRange.new(nil, 2, :exclude_begin=>true, :exclude_end=>true, :db_type=>"int4range")
3699
+ @db.get(Sequel.cast(eval('(...1)'), :int4range)).wont_be :==, Sequel::Postgres::PGRange.new(nil, 1, :exclude_end=>true, :db_type=>"int4range")
3700
+ @db.get(Sequel.cast(eval('(...1)'), :int4range)).wont_be :==, Sequel::Postgres::PGRange.new(nil, 1, :exclude_begin=>true, :db_type=>"int4range")
3701
3701
  end if RUBY_VERSION >= '2.7'
3702
3702
 
3703
3703
  it 'handle startless ranges' do
@@ -2467,7 +2467,7 @@ describe "Database#typecast_value" do
2467
2467
  @db.typecast_value(:date, 'a')
2468
2468
  true.must_equal false
2469
2469
  rescue Sequel::InvalidValue => e
2470
- e.inspect.must_equal '#<Sequel::InvalidValue: ArgumentError: invalid date>'
2470
+ e.inspect.must_match(/\A#\<Sequel::InvalidValue: (Argument|Date::)Error: invalid date\>\z/)
2471
2471
  end
2472
2472
  end
2473
2473
  end
@@ -537,21 +537,21 @@ describe "Blockless Ruby Filters" do
537
537
  end
538
538
 
539
539
  it "should handle endless ranges" do
540
- endless = eval('1..')
540
+ endless = eval('(1..)')
541
541
  @d.l{x =~ endless}.must_equal '(x >= 1)'
542
542
  @d.l(:x => endless).must_equal '(x >= 1)'
543
543
 
544
- endless = eval('1...')
544
+ endless = eval('(1...)')
545
545
  @d.l{x =~ endless}.must_equal '(x >= 1)'
546
546
  @d.l(:x => endless).must_equal '(x >= 1)'
547
547
  end if RUBY_VERSION >= '2.6'
548
548
 
549
549
  it "should handle startless ranges" do
550
- endless = eval('..1')
550
+ endless = eval('(..1)')
551
551
  @d.l{x =~ endless}.must_equal '(x <= 1)'
552
552
  @d.l(:x => endless).must_equal '(x <= 1)'
553
553
 
554
- endless = eval('...1')
554
+ endless = eval('(...1)')
555
555
  @d.l{x =~ endless}.must_equal '(x < 1)'
556
556
  @d.l(:x => endless).must_equal '(x < 1)'
557
557
  end if RUBY_VERSION >= '2.7'
@@ -0,0 +1,23 @@
1
+ require_relative "spec_helper"
2
+
3
+ describe "any_not_empty extension" do
4
+ before do
5
+ @ds = Sequel.mock[:t].extension(:any_not_empty)
6
+ end
7
+
8
+ it "should use a limited query if no block is given" do
9
+ @ds.with_fetch(:one=>1).any?.must_equal true
10
+ @ds.db.sqls.must_equal ["SELECT 1 AS one FROM t LIMIT 1"]
11
+ @ds.with_fetch([]).any?.must_equal false
12
+ @ds.db.sqls.must_equal ["SELECT 1 AS one FROM t LIMIT 1"]
13
+ end
14
+
15
+ it "should use default behavior if block is given" do
16
+ @ds.with_fetch(:one=>1).any?{|x| x[:one] == 1}.must_equal true
17
+ @ds.db.sqls.must_equal ["SELECT * FROM t"]
18
+ @ds.with_fetch(:one=>1).any?{|x| x[:one] != 1}.must_equal false
19
+ @ds.db.sqls.must_equal ["SELECT * FROM t"]
20
+ @ds.with_fetch([]).any?{|x| x[:one] == 1}.must_equal false
21
+ @ds.db.sqls.must_equal ["SELECT * FROM t"]
22
+ end
23
+ end
@@ -0,0 +1,15 @@
1
+ require_relative "spec_helper"
2
+
3
+ describe "exclude_or_null extension" do
4
+ before do
5
+ @ds = Sequel.mock[:t].extension(:exclude_or_null)
6
+ end
7
+
8
+ it "should add condition where a is false or NULL" do
9
+ @ds.exclude_or_null(:a).sql.must_equal "SELECT * FROM t WHERE NOT coalesce(a, 'f')"
10
+ end
11
+
12
+ it "should not effect normal exclude" do
13
+ @ds.exclude(:a).sql.must_equal "SELECT * FROM t WHERE NOT a"
14
+ end
15
+ end
@@ -52,13 +52,13 @@ describe "pg_range extension" do
52
52
  end
53
53
 
54
54
  it "should literalize endless Range instances to strings correctly" do
55
- @db.literal(eval('1..')).must_equal "'[1,]'"
56
- @db.literal(eval('1...')).must_equal "'[1,)'"
55
+ @db.literal(eval('(1..)')).must_equal "'[1,]'"
56
+ @db.literal(eval('(1...)')).must_equal "'[1,)'"
57
57
  end if endless_range_support
58
58
 
59
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)'"
60
+ @db.literal(eval('(..1)')).must_equal "'[,1]'"
61
+ @db.literal(eval('(...1)')).must_equal "'[,1)'"
62
62
  end if startless_range_support
63
63
 
64
64
  it "should literalize startless, endless Range instances to strings correctly" do
@@ -90,13 +90,13 @@ describe "pg_range extension" do
90
90
  end
91
91
 
92
92
  it "should support using endless Range instances as bound variables" do
93
- @db.bound_variable_arg(eval('1..'), nil).must_equal "[1,]"
94
- @db.bound_variable_arg(eval('1...'), nil).must_equal "[1,)"
93
+ @db.bound_variable_arg(eval('(1..)'), nil).must_equal "[1,]"
94
+ @db.bound_variable_arg(eval('(1...)'), nil).must_equal "[1,)"
95
95
  end if endless_range_support
96
96
 
97
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)"
98
+ @db.bound_variable_arg(eval('(..1)'), nil).must_equal "[,1]"
99
+ @db.bound_variable_arg(eval('(...1)'), nil).must_equal "[,1)"
100
100
  end if startless_range_support
101
101
 
102
102
  it "should support using startless, endless Range instances as bound variables" do
@@ -113,7 +113,7 @@ describe "pg_range extension" do
113
113
  end
114
114
 
115
115
  it "should support using arrays of endless Range instances as bound variables" do
116
- @db.bound_variable_arg([eval('1..'), eval('2..')], nil).must_equal '{"[1,]","[2,]"}'
116
+ @db.bound_variable_arg([eval('(1..)'), eval('(2..)')], nil).must_equal '{"[1,]","[2,]"}'
117
117
  end if endless_range_support
118
118
 
119
119
  it "should support using PGRange instances as bound variables" do
@@ -470,21 +470,21 @@ describe "pg_range extension" do
470
470
  end
471
471
 
472
472
  it "should consider PGRanges equal with a endless Range they represent" do
473
- @R.new(1, nil).must_be :==, eval('1..')
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..')
477
- @R.new(1, nil).wont_be :==, eval('2..')
478
- @R.new(1, nil, :exclude_end=>true).wont_be :==, eval('2...')
473
+ @R.new(1, nil).must_be :==, eval('(1..)')
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..)')
477
+ @R.new(1, nil).wont_be :==, eval('(2..)')
478
+ @R.new(1, nil, :exclude_end=>true).wont_be :==, eval('(2...)')
479
479
  end if endless_range_support
480
480
 
481
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')
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
488
  end if startless_range_support
489
489
 
490
490
  it "should consider PGRanges equal with a startless, endless Range they represent" do
@@ -593,22 +593,21 @@ describe Sequel::Dataset do
593
593
  end
594
594
 
595
595
  describe "Simple Dataset operations" do
596
- before do
596
+ before(:all) do
597
597
  DB.create_table!(:items) do
598
598
  Integer :number
599
599
  TrueClass :flag
600
600
  end
601
- @ds = DB[:items]
601
+ @ds = DB[:items].order(:number)
602
+ @ds.insert(:number=>1, :flag=>true)
603
+ @ds.insert(:number=>2, :flag=>false)
604
+ @ds.insert(:number=>3, :flag=>nil)
602
605
  end
603
- after do
606
+ after(:all) do
604
607
  DB.drop_table?(:items)
605
608
  end
606
609
 
607
610
  it "should deal with boolean conditions correctly" do
608
- @ds.insert(:number=>1, :flag=>true)
609
- @ds.insert(:number=>2, :flag=>false)
610
- @ds.insert(:number=>3, :flag=>nil)
611
- @ds = @ds.order(:number)
612
611
  @ds.filter(:flag=>true).map(:number).must_equal [1]
613
612
  @ds.filter(:flag=>false).map(:number).must_equal [2]
614
613
  @ds.filter(:flag=>nil).map(:number).must_equal [3]
@@ -616,6 +615,22 @@ describe "Simple Dataset operations" do
616
615
  @ds.exclude(:flag=>false).map(:number).must_equal [1, 3]
617
616
  @ds.exclude(:flag=>nil).map(:number).must_equal [1, 2]
618
617
  end
618
+
619
+ cspecify "should deal with boolean equality conditions correctly", :derby do
620
+ @ds.filter(true=>:flag).map(:number).must_equal [1]
621
+ @ds.filter(false=>:flag).map(:number).must_equal [2]
622
+ @ds.filter(nil=>:flag).map(:number).must_equal []
623
+ @ds.exclude(true=>:flag).map(:number).must_equal [2]
624
+ @ds.exclude(false=>:flag).map(:number).must_equal [1]
625
+ @ds.exclude(nil=>:flag).map(:number).must_equal []
626
+ end
627
+
628
+ cspecify "should have exclude_or_null work correctly", :mssql, :derby, :oracle, :db2, :sqlanywhere do
629
+ @ds = @ds.extension(:exclude_or_null)
630
+ @ds.exclude_or_null(true=>:flag).map(:number).must_equal [2, 3]
631
+ @ds.exclude_or_null(false=>:flag).map(:number).must_equal [1, 3]
632
+ @ds.exclude_or_null(nil=>:flag).map(:number).must_equal [1, 2, 3]
633
+ end
619
634
  end
620
635
 
621
636
  describe "Simple Dataset operations in transactions" do
@@ -1578,20 +1593,20 @@ describe "Sequel::Dataset DSL support" do
1578
1593
 
1579
1594
  it "should work with endless ranges as hash values" do
1580
1595
  @ds.insert(20, 10)
1581
- @ds.filter(:a=>eval('30..')).all.must_equal []
1582
- @ds.filter(:a=>eval('20...')).all.must_equal [{:a=>20, :b=>10}]
1583
- @ds.filter(:a=>eval('20..')).all.must_equal [{:a=>20, :b=>10}]
1584
- @ds.filter(:a=>eval('10..')).all.must_equal [{:a=>20, :b=>10}]
1596
+ @ds.filter(:a=>eval('(30..)')).all.must_equal []
1597
+ @ds.filter(:a=>eval('(20...)')).all.must_equal [{:a=>20, :b=>10}]
1598
+ @ds.filter(:a=>eval('(20..)')).all.must_equal [{:a=>20, :b=>10}]
1599
+ @ds.filter(:a=>eval('(10..)')).all.must_equal [{:a=>20, :b=>10}]
1585
1600
  end if RUBY_VERSION >= '2.6'
1586
1601
 
1587
1602
  it "should work with startless ranges as hash values" do
1588
1603
  @ds.insert(20, 10)
1589
- @ds.filter(:a=>eval('..30')).all.must_equal [{:a=>20, :b=>10}]
1590
- @ds.filter(:a=>eval('...30')).all.must_equal [{:a=>20, :b=>10}]
1591
- @ds.filter(:a=>eval('..20')).all.must_equal [{:a=>20, :b=>10}]
1592
- @ds.filter(:a=>eval('...20')).all.must_equal []
1593
- @ds.filter(:a=>eval('..10')).all.must_equal []
1594
- @ds.filter(:a=>eval('...10')).all.must_equal []
1604
+ @ds.filter(:a=>eval('(..30)')).all.must_equal [{:a=>20, :b=>10}]
1605
+ @ds.filter(:a=>eval('(...30)')).all.must_equal [{:a=>20, :b=>10}]
1606
+ @ds.filter(:a=>eval('(..20)')).all.must_equal [{:a=>20, :b=>10}]
1607
+ @ds.filter(:a=>eval('(...20)')).all.must_equal []
1608
+ @ds.filter(:a=>eval('(..10)')).all.must_equal []
1609
+ @ds.filter(:a=>eval('(...10)')).all.must_equal []
1595
1610
 
1596
1611
  @ds.filter(:a=>eval('nil..nil')).all.must_equal [{:a=>20, :b=>10}]
1597
1612
  end if RUBY_VERSION >= '2.7'
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.27.0
4
+ version: 5.28.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-12-01 00:00:00.000000000 Z
11
+ date: 2020-01-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -225,6 +225,7 @@ extra_rdoc_files:
225
225
  - doc/release_notes/5.25.0.txt
226
226
  - doc/release_notes/5.26.0.txt
227
227
  - doc/release_notes/5.27.0.txt
228
+ - doc/release_notes/5.28.0.txt
228
229
  files:
229
230
  - CHANGELOG
230
231
  - MIT-LICENSE
@@ -323,6 +324,7 @@ files:
323
324
  - doc/release_notes/5.25.0.txt
324
325
  - doc/release_notes/5.26.0.txt
325
326
  - doc/release_notes/5.27.0.txt
327
+ - doc/release_notes/5.28.0.txt
326
328
  - doc/release_notes/5.3.0.txt
327
329
  - doc/release_notes/5.4.0.txt
328
330
  - doc/release_notes/5.5.0.txt
@@ -421,6 +423,7 @@ files:
421
423
  - lib/sequel/extensions/_model_constraint_validations.rb
422
424
  - lib/sequel/extensions/_model_pg_row.rb
423
425
  - lib/sequel/extensions/_pretty_table.rb
426
+ - lib/sequel/extensions/any_not_empty.rb
424
427
  - lib/sequel/extensions/arbitrary_servers.rb
425
428
  - lib/sequel/extensions/auto_literal_strings.rb
426
429
  - lib/sequel/extensions/blank.rb
@@ -441,6 +444,7 @@ files:
441
444
  - lib/sequel/extensions/error_sql.rb
442
445
  - lib/sequel/extensions/escaped_like.rb
443
446
  - lib/sequel/extensions/eval_inspect.rb
447
+ - lib/sequel/extensions/exclude_or_null.rb
444
448
  - lib/sequel/extensions/freeze_datasets.rb
445
449
  - lib/sequel/extensions/from_block.rb
446
450
  - lib/sequel/extensions/graph_each.rb
@@ -619,6 +623,7 @@ files:
619
623
  - spec/extensions/accessed_columns_spec.rb
620
624
  - spec/extensions/active_model_spec.rb
621
625
  - spec/extensions/after_initialize_spec.rb
626
+ - spec/extensions/any_not_empty_spec.rb
622
627
  - spec/extensions/arbitrary_servers_spec.rb
623
628
  - spec/extensions/association_dependencies_spec.rb
624
629
  - spec/extensions/association_multi_add_remove_spec.rb
@@ -662,6 +667,7 @@ files:
662
667
  - spec/extensions/error_sql_spec.rb
663
668
  - spec/extensions/escaped_like_spec.rb
664
669
  - spec/extensions/eval_inspect_spec.rb
670
+ - spec/extensions/exclude_or_null_spec.rb
665
671
  - spec/extensions/finder_spec.rb
666
672
  - spec/extensions/force_encoding_spec.rb
667
673
  - spec/extensions/freeze_datasets_spec.rb
@@ -883,7 +889,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
883
889
  - !ruby/object:Gem::Version
884
890
  version: '0'
885
891
  requirements: []
886
- rubygems_version: 3.0.3
892
+ rubygems_version: 3.1.2
887
893
  signing_key:
888
894
  specification_version: 4
889
895
  summary: The Database Toolkit for Ruby