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 +4 -4
- data/CHANGELOG +8 -0
- data/doc/cheat_sheet.rdoc +1 -0
- data/doc/release_notes/5.28.0.txt +16 -0
- data/doc/testing.rdoc +11 -6
- data/lib/sequel/adapters/jdbc/postgresql.rb +6 -0
- data/lib/sequel/dataset/query.rb +15 -2
- data/lib/sequel/extensions/any_not_empty.rb +45 -0
- data/lib/sequel/extensions/exclude_or_null.rb +68 -0
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/postgres_spec.rb +10 -10
- data/spec/core/database_spec.rb +1 -1
- data/spec/core/expression_filters_spec.rb +4 -4
- data/spec/extensions/any_not_empty_spec.rb +23 -0
- data/spec/extensions/exclude_or_null_spec.rb +15 -0
- data/spec/extensions/pg_range_spec.rb +21 -21
- data/spec/integration/dataset_test.rb +32 -17
- metadata +9 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e206de897422ca8260c788bcfc20bcb154c9122dd17a12dc4b45ecdca023eb9a
|
4
|
+
data.tar.gz: 319df67cbb77d1b93d12cd0a1f429de0b674543ebd62b6407d40e1bd992e2352
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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)
|
data/doc/cheat_sheet.rdoc
CHANGED
@@ -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.
|
data/doc/testing.rdoc
CHANGED
@@ -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
|
|
data/lib/sequel/dataset/query.rb
CHANGED
@@ -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
|
data/lib/sequel/version.rb
CHANGED
@@ -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 =
|
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
|
data/spec/core/database_spec.rb
CHANGED
@@ -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.
|
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.
|
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:
|
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.
|
892
|
+
rubygems_version: 3.1.2
|
887
893
|
signing_key:
|
888
894
|
specification_version: 4
|
889
895
|
summary: The Database Toolkit for Ruby
|