sequel 5.8.0 → 5.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG +30 -0
- data/doc/release_notes/5.9.0.txt +99 -0
- data/doc/testing.rdoc +10 -10
- data/lib/sequel/adapters/ado.rb +1 -1
- data/lib/sequel/adapters/amalgalite.rb +1 -1
- data/lib/sequel/adapters/jdbc.rb +19 -7
- data/lib/sequel/adapters/jdbc/oracle.rb +1 -1
- data/lib/sequel/adapters/jdbc/postgresql.rb +0 -5
- data/lib/sequel/adapters/postgres.rb +3 -3
- data/lib/sequel/adapters/shared/access.rb +5 -6
- data/lib/sequel/adapters/shared/mysql.rb +28 -2
- data/lib/sequel/adapters/shared/postgres.rb +16 -6
- data/lib/sequel/adapters/shared/sqlite.rb +1 -1
- data/lib/sequel/adapters/sqlanywhere.rb +1 -1
- data/lib/sequel/adapters/sqlite.rb +2 -2
- data/lib/sequel/connection_pool.rb +2 -1
- data/lib/sequel/connection_pool/sharded_threaded.rb +12 -4
- data/lib/sequel/connection_pool/threaded.rb +19 -7
- data/lib/sequel/core.rb +1 -1
- data/lib/sequel/database/connecting.rb +6 -6
- data/lib/sequel/database/misc.rb +3 -3
- data/lib/sequel/database/query.rb +2 -2
- data/lib/sequel/database/schema_generator.rb +9 -3
- data/lib/sequel/database/schema_methods.rb +12 -5
- data/lib/sequel/dataset/features.rb +5 -0
- data/lib/sequel/dataset/misc.rb +1 -1
- data/lib/sequel/dataset/prepared_statements.rb +4 -4
- data/lib/sequel/dataset/query.rb +5 -0
- data/lib/sequel/dataset/sql.rb +8 -6
- data/lib/sequel/extensions/escaped_like.rb +100 -0
- data/lib/sequel/extensions/eval_inspect.rb +3 -1
- data/lib/sequel/extensions/looser_typecasting.rb +3 -3
- data/lib/sequel/extensions/pg_extended_date_support.rb +23 -10
- data/lib/sequel/model/associations.rb +18 -4
- data/lib/sequel/model/base.rb +9 -2
- data/lib/sequel/plugins/defaults_setter.rb +1 -1
- data/lib/sequel/plugins/many_through_many.rb +1 -1
- data/lib/sequel/plugins/nested_attributes.rb +2 -2
- data/lib/sequel/plugins/pg_auto_constraint_validations.rb +2 -2
- data/lib/sequel/plugins/rcte_tree.rb +5 -7
- data/lib/sequel/plugins/sharding.rb +2 -2
- data/lib/sequel/plugins/tactical_eager_loading.rb +1 -1
- data/lib/sequel/plugins/tree.rb +2 -2
- data/lib/sequel/plugins/validation_class_methods.rb +1 -1
- data/lib/sequel/sql.rb +2 -2
- data/lib/sequel/version.rb +4 -1
- data/spec/adapters/mysql_spec.rb +24 -0
- data/spec/adapters/postgres_spec.rb +9 -9
- data/spec/adapters/sqlite_spec.rb +10 -10
- data/spec/core/connection_pool_spec.rb +22 -0
- data/spec/core/database_spec.rb +6 -6
- data/spec/core/dataset_spec.rb +16 -5
- data/spec/core/expression_filters_spec.rb +1 -1
- data/spec/core/schema_spec.rb +1 -1
- data/spec/core/version_spec.rb +7 -0
- data/spec/extensions/connection_expiration_spec.rb +20 -2
- data/spec/extensions/connection_validator_spec.rb +20 -3
- data/spec/extensions/escaped_like_spec.rb +40 -0
- data/spec/extensions/eval_inspect_spec.rb +1 -1
- data/spec/extensions/nested_attributes_spec.rb +6 -0
- data/spec/extensions/pg_array_spec.rb +13 -13
- data/spec/extensions/pg_auto_constraint_validations_spec.rb +0 -1
- data/spec/extensions/pg_range_spec.rb +1 -1
- data/spec/extensions/schema_dumper_spec.rb +2 -2
- data/spec/extensions/sql_expr_spec.rb +1 -1
- data/spec/extensions/string_agg_spec.rb +1 -1
- data/spec/extensions/timestamps_spec.rb +2 -2
- data/spec/extensions/validation_helpers_spec.rb +1 -1
- data/spec/integration/associations_test.rb +12 -0
- data/spec/integration/dataset_test.rb +21 -0
- data/spec/integration/type_test.rb +4 -4
- data/spec/model/base_spec.rb +9 -0
- data/spec/model/eager_loading_spec.rb +25 -0
- data/spec/model/record_spec.rb +1 -1
- metadata +6 -2
@@ -0,0 +1,40 @@
|
|
1
|
+
require_relative "spec_helper"
|
2
|
+
|
3
|
+
describe "escaped_like extension" do
|
4
|
+
before do
|
5
|
+
Sequel.extension(:escaped_like)
|
6
|
+
@ds = Sequel.mock[:t]
|
7
|
+
@c = Sequel[:c]
|
8
|
+
end
|
9
|
+
|
10
|
+
it "escaped_like should support creating case sensitive pattern matches" do
|
11
|
+
@ds.where(@c.escaped_like('?', 'a')).sql.must_equal "SELECT * FROM t WHERE (c LIKE 'a' ESCAPE '\\')"
|
12
|
+
@ds.where(@c.escaped_like('?%', 'a')).sql.must_equal "SELECT * FROM t WHERE (c LIKE 'a%' ESCAPE '\\')"
|
13
|
+
@ds.where(@c.escaped_like('?', 'a%')).sql.must_equal "SELECT * FROM t WHERE (c LIKE 'a\\%' ESCAPE '\\')"
|
14
|
+
@ds.where(@c.escaped_like('?', ['a%'])).sql.must_equal "SELECT * FROM t WHERE (c LIKE 'a\\%' ESCAPE '\\')"
|
15
|
+
@ds.where(@c.escaped_like('??', ['a', '%'])).sql.must_equal "SELECT * FROM t WHERE (c LIKE 'a\\%' ESCAPE '\\')"
|
16
|
+
end
|
17
|
+
|
18
|
+
it "escaped_ilike should support creating case insensitive pattern matches" do
|
19
|
+
@ds.where(@c.escaped_ilike('?', 'a')).sql.must_equal "SELECT * FROM t WHERE (UPPER(c) LIKE UPPER('a') ESCAPE '\\')"
|
20
|
+
@ds.where(@c.escaped_ilike('?%', 'a')).sql.must_equal "SELECT * FROM t WHERE (UPPER(c) LIKE UPPER('a%') ESCAPE '\\')"
|
21
|
+
@ds.where(@c.escaped_ilike('?', 'a%')).sql.must_equal "SELECT * FROM t WHERE (UPPER(c) LIKE UPPER('a\\%') ESCAPE '\\')"
|
22
|
+
@ds.where(@c.escaped_ilike('?', ['a%'])).sql.must_equal "SELECT * FROM t WHERE (UPPER(c) LIKE UPPER('a\\%') ESCAPE '\\')"
|
23
|
+
@ds.where(@c.escaped_ilike('??', ['a', '%'])).sql.must_equal "SELECT * FROM t WHERE (UPPER(c) LIKE UPPER('a\\%') ESCAPE '\\')"
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should raise an Error for a mismatched number of placeholders" do
|
27
|
+
proc{@ds.where(@c.escaped_like('?', [])).sql}.must_raise Sequel::Error
|
28
|
+
proc{@ds.where(@c.escaped_like('??', ['a'])).sql}.must_raise Sequel::Error
|
29
|
+
proc{@ds.where(@c.escaped_ilike('', ['a'])).sql}.must_raise Sequel::Error
|
30
|
+
proc{@ds.where(@c.escaped_ilike('?', ['a', 'a'])).sql}.must_raise Sequel::Error
|
31
|
+
end
|
32
|
+
|
33
|
+
it "escaped_like and escaped_ilike should return expressions" do
|
34
|
+
@ds.select(@c.escaped_like('?', 'a').as(:b)).sql.must_equal "SELECT (c LIKE 'a' ESCAPE '\\') AS b FROM t"
|
35
|
+
@ds.select(@c.escaped_like('?', 'a').cast(String)).sql.must_equal "SELECT CAST((c LIKE 'a' ESCAPE '\\') AS varchar(255)) FROM t"
|
36
|
+
@ds.order(@c.escaped_like('?', 'a').desc).sql.must_equal "SELECT * FROM t ORDER BY (c LIKE 'a' ESCAPE '\\') DESC"
|
37
|
+
@ds.where(@c.escaped_like('?', 'a') | @c.escaped_like('?', 'b')).sql.must_equal "SELECT * FROM t WHERE ((c LIKE 'a' ESCAPE '\\') OR (c LIKE 'b' ESCAPE '\\'))"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
@@ -62,7 +62,7 @@ describe "eval_inspect extension" do
|
|
62
62
|
Sequel::SQL::AliasedExpression.new(Time.local(2011, 9, 11, 10, 20, 30, 500000.125), :a),
|
63
63
|
Sequel::SQL::AliasedExpression.new(Time.utc(2011, 9, 11, 10, 20, 30), :a),
|
64
64
|
Sequel::SQL::AliasedExpression.new(Time.utc(2011, 9, 11, 10, 20, 30, 500000.125), :a),
|
65
|
-
Sequel::SQL::AliasedExpression.new(BigDecimal
|
65
|
+
Sequel::SQL::AliasedExpression.new(BigDecimal('1.000000000000000000000000000000000000000000000001'), :a),
|
66
66
|
Sequel::SQL::AliasedExpression.new(Sequel::CURRENT_DATE, :a),
|
67
67
|
Sequel::SQL::AliasedExpression.new(Sequel::CURRENT_TIMESTAMP, :a),
|
68
68
|
].each do |o|
|
@@ -49,6 +49,12 @@ describe "NestedAttributes plugin" do
|
|
49
49
|
@db.sqls
|
50
50
|
end
|
51
51
|
|
52
|
+
it "should not modify options hash when loading plugin" do
|
53
|
+
h = {}
|
54
|
+
@Concert.nested_attributes :albums, h
|
55
|
+
h.must_equal({})
|
56
|
+
end
|
57
|
+
|
52
58
|
it "should support creating new many_to_one objects" do
|
53
59
|
a = @Album.new({:name=>'Al', :artist_attributes=>{:name=>'Ar'}})
|
54
60
|
@db.sqls.must_equal []
|
@@ -92,30 +92,30 @@ describe "pg_array extension" do
|
|
92
92
|
it "should parse single dimensional decimal arrays" do
|
93
93
|
c = @converter[1231]
|
94
94
|
c.call("{}").to_a.must_equal []
|
95
|
-
c.call("{1.5}").to_a.must_equal [BigDecimal
|
96
|
-
c.call('{2.5,3.5}').to_a.must_equal [BigDecimal
|
97
|
-
c.call('{3.5,4.5,5.5}').to_a.must_equal [BigDecimal
|
95
|
+
c.call("{1.5}").to_a.must_equal [BigDecimal('1.5')]
|
96
|
+
c.call('{2.5,3.5}').to_a.must_equal [BigDecimal('2.5'), BigDecimal('3.5')]
|
97
|
+
c.call('{3.5,4.5,5.5}').to_a.must_equal [BigDecimal('3.5'), BigDecimal('4.5'), BigDecimal('5.5')]
|
98
98
|
end
|
99
99
|
|
100
100
|
it "should parse multiple dimensional decimal arrays" do
|
101
101
|
c = @converter[1231]
|
102
102
|
c.call("{{}}").to_a.must_equal [[]]
|
103
|
-
c.call("{{1.5}}").to_a.must_equal [[BigDecimal
|
104
|
-
c.call('{{2.5},{3.5}}').to_a.must_equal [[BigDecimal
|
105
|
-
c.call('{{{1.5,2.5},{3.5,4.5}},{{5.5,6.5},{7.5,8.5}}}').to_a.must_equal [[[BigDecimal
|
103
|
+
c.call("{{1.5}}").to_a.must_equal [[BigDecimal('1.5')]]
|
104
|
+
c.call('{{2.5},{3.5}}').to_a.must_equal [[BigDecimal('2.5')], [BigDecimal('3.5')]]
|
105
|
+
c.call('{{{1.5,2.5},{3.5,4.5}},{{5.5,6.5},{7.5,8.5}}}').to_a.must_equal [[[BigDecimal('1.5'), BigDecimal('2.5')], [BigDecimal('3.5'), BigDecimal('4.5')]], [[BigDecimal('5.5'), BigDecimal('6.5')], [BigDecimal('7.5'), BigDecimal('8.5')]]]
|
106
106
|
end
|
107
107
|
|
108
108
|
it "should parse decimal values with arbitrary precision" do
|
109
109
|
c = @converter[1231]
|
110
|
-
c.call("{1.000000000000000000005}").to_a.must_equal [BigDecimal
|
111
|
-
c.call("{{1.000000000000000000005,2.000000000000000000005},{3.000000000000000000005,4.000000000000000000005}}").to_a.must_equal [[BigDecimal
|
110
|
+
c.call("{1.000000000000000000005}").to_a.must_equal [BigDecimal('1.000000000000000000005')]
|
111
|
+
c.call("{{1.000000000000000000005,2.000000000000000000005},{3.000000000000000000005,4.000000000000000000005}}").to_a.must_equal [[BigDecimal('1.000000000000000000005'), BigDecimal('2.000000000000000000005')], [BigDecimal('3.000000000000000000005'), BigDecimal('4.000000000000000000005')]]
|
112
112
|
end
|
113
113
|
|
114
114
|
it "should parse integers in decimal arrays as BigDecimals" do
|
115
115
|
c = @converter[1231]
|
116
116
|
c.call("{1}").to_a.first.must_be_kind_of(BigDecimal)
|
117
|
-
c.call("{1}").to_a.must_equal [BigDecimal
|
118
|
-
c.call('{{{1,2},{3,4}},{{5,6},{7,8}}}').to_a.must_equal [[[BigDecimal
|
117
|
+
c.call("{1}").to_a.must_equal [BigDecimal('1')]
|
118
|
+
c.call('{{{1,2},{3,4}},{{5,6},{7,8}}}').to_a.must_equal [[[BigDecimal('1'), BigDecimal('2')], [BigDecimal('3'), BigDecimal('4')]], [[BigDecimal('5'), BigDecimal('6')], [BigDecimal('7'), BigDecimal('8')]]]
|
119
119
|
end
|
120
120
|
|
121
121
|
it "should parse arrays with NULL values" do
|
@@ -149,7 +149,7 @@ describe "pg_array extension" do
|
|
149
149
|
@db.literal(@m::PGArray.new([nil])).must_equal 'ARRAY[NULL]'
|
150
150
|
@db.literal(@m::PGArray.new([nil, 1])).must_equal 'ARRAY[NULL,1]'
|
151
151
|
@db.literal(@m::PGArray.new([1.0, 2.5])).must_equal 'ARRAY[1.0,2.5]'
|
152
|
-
@db.literal(@m::PGArray.new([BigDecimal
|
152
|
+
@db.literal(@m::PGArray.new([BigDecimal('1'), BigDecimal('2.000000000000000000005')])).must_equal 'ARRAY[1.0,2.000000000000000000005]'
|
153
153
|
@db.literal(@m::PGArray.new([nil, "NULL"])).must_equal "ARRAY[NULL,'NULL']"
|
154
154
|
@db.literal(@m::PGArray.new([nil, "{},[]'\""])).must_equal "ARRAY[NULL,'{},[]''\"']"
|
155
155
|
end
|
@@ -169,7 +169,7 @@ describe "pg_array extension" do
|
|
169
169
|
@db.literal(@m::PGArray.new([nil], :text)).must_equal 'ARRAY[NULL]::text[]'
|
170
170
|
@db.literal(@m::PGArray.new([nil, 1], :int8)).must_equal 'ARRAY[NULL,1]::int8[]'
|
171
171
|
@db.literal(@m::PGArray.new([1.0, 2.5], :real)).must_equal 'ARRAY[1.0,2.5]::real[]'
|
172
|
-
@db.literal(@m::PGArray.new([BigDecimal
|
172
|
+
@db.literal(@m::PGArray.new([BigDecimal('1'), BigDecimal('2.000000000000000000005')], :decimal)).must_equal 'ARRAY[1.0,2.000000000000000000005]::decimal[]'
|
173
173
|
@db.literal(@m::PGArray.new([nil, "NULL"], :varchar)).must_equal "ARRAY[NULL,'NULL']::varchar[]"
|
174
174
|
@db.literal(@m::PGArray.new([nil, "{},[]'\""], :"varchar(255)")).must_equal "ARRAY[NULL,'{},[]''\"']::varchar(255)[]"
|
175
175
|
end
|
@@ -224,7 +224,7 @@ describe "pg_array extension" do
|
|
224
224
|
{
|
225
225
|
:integer=>{:class=>Integer, :convert=>['1', 1, '1']},
|
226
226
|
:float=>{:db_type=>'double precision', :class=>Float, :convert=>['1.1', 1.1, '1.1']},
|
227
|
-
:decimal=>{:db_type=>'numeric', :class=>BigDecimal, :convert=>['1.00000000000000000000000001', BigDecimal
|
227
|
+
:decimal=>{:db_type=>'numeric', :class=>BigDecimal, :convert=>['1.00000000000000000000000001', BigDecimal('1.00000000000000000000000001'), '1.00000000000000000000000001']},
|
228
228
|
:string=>{:db_type=>'text', :class=>String, :convert=>[1, '1', "'1'"]},
|
229
229
|
:bigint=>{:class=>Integer, :convert=>['1', 1, '1']},
|
230
230
|
:boolean=>{:class=>TrueClass, :convert=>['t', true, 'true']},
|
@@ -12,7 +12,6 @@ describe "pg_auto_constraint_validations plugin" do
|
|
12
12
|
|
13
13
|
before do
|
14
14
|
info = @info = {:schema=>'public', :table=>'items'}
|
15
|
-
error = @error = []
|
16
15
|
@db = Sequel.mock(:host=>'postgres')
|
17
16
|
def @db.schema(*) [[:i, {}], [:id, {}]] end
|
18
17
|
@set_error = lambda{|ec, ei| @db.fetch = @db.autoid = @db.numrows = ec; info.merge!(ei)}
|
@@ -43,7 +43,7 @@ describe "pg_range extension" do
|
|
43
43
|
@db.literal(DateTime.new(2011, 1, 2, 10, 20, 30)...DateTime.new(2011, 2, 3, 10, 20, 30)).must_equal "'[2011-01-02 10:20:30,2011-02-03 10:20:30)'"
|
44
44
|
@db.literal(1..2).must_equal "'[1,2]'"
|
45
45
|
@db.literal(1.0..2.0).must_equal "'[1.0,2.0]'"
|
46
|
-
@db.literal(BigDecimal
|
46
|
+
@db.literal(BigDecimal('1.0')..BigDecimal('2.0')).must_equal "'[1.0,2.0]'"
|
47
47
|
@db.literal(Sequel.lit('a')..Sequel.lit('z')).must_equal "'[a,z]'"
|
48
48
|
@db.literal(''..'()[]",\\2').must_equal "'[\"\",\\(\\)\\[\\]\\\"\\,\\\\2]'"
|
49
49
|
end
|
@@ -673,8 +673,8 @@ END_MIG
|
|
673
673
|
s
|
674
674
|
end
|
675
675
|
e = RUBY_VERSION >= '2.4' ? 'e' : 'E'
|
676
|
-
@d.dump_table_schema(:t4).gsub(/[+-]\d\d\d\d"\)/, '")').gsub(/\.0+/, '.0').must_equal "create_table(:t4) do\n TrueClass :c1, :default=>false\n String :c2, :default=>\"blah\"\n Integer :c3, :default=>-1\n Float :c4, :default=>1.0\n BigDecimal :c5, :default=>BigDecimal
|
677
|
-
@d.dump_table_schema(:t4, :same_db=>true).gsub(/[+-]\d\d\d\d"\)/, '")').gsub(/\.0+/, '.0').must_equal "create_table(:t4) do\n column :c1, \"boolean\", :default=>false\n column :c2, \"varchar\", :default=>\"blah\"\n column :c3, \"integer\", :default=>-1\n column :c4, \"float\", :default=>1.0\n column :c5, \"decimal\", :default=>BigDecimal
|
676
|
+
@d.dump_table_schema(:t4).gsub(/[+-]\d\d\d\d"\)/, '")').gsub(/\.0+/, '.0').must_equal "create_table(:t4) do\n TrueClass :c1, :default=>false\n String :c2, :default=>\"blah\"\n Integer :c3, :default=>-1\n Float :c4, :default=>1.0\n BigDecimal :c5, :default=>BigDecimal(\"0.1005#{e}3\")\n File :c6, :default=>Sequel::SQL::Blob.new(\"blah\")\n Date :c7, :default=>Date.new(2008, 10, 29)\n DateTime :c8, :default=>DateTime.parse(\"2008-10-29T10:20:30.0\")\n Time :c9, :default=>Sequel::SQLTime.parse(\"10:20:30.0\"), :only_time=>true\n String :c10\n Date :c11, :default=>Sequel::CURRENT_DATE\n DateTime :c12, :default=>Sequel::CURRENT_TIMESTAMP\nend"
|
677
|
+
@d.dump_table_schema(:t4, :same_db=>true).gsub(/[+-]\d\d\d\d"\)/, '")').gsub(/\.0+/, '.0').must_equal "create_table(:t4) do\n column :c1, \"boolean\", :default=>false\n column :c2, \"varchar\", :default=>\"blah\"\n column :c3, \"integer\", :default=>-1\n column :c4, \"float\", :default=>1.0\n column :c5, \"decimal\", :default=>BigDecimal(\"0.1005#{e}3\")\n column :c6, \"blob\", :default=>Sequel::SQL::Blob.new(\"blah\")\n column :c7, \"date\", :default=>Date.new(2008, 10, 29)\n column :c8, \"datetime\", :default=>DateTime.parse(\"2008-10-29T10:20:30.0\")\n column :c9, \"time\", :default=>Sequel::SQLTime.parse(\"10:20:30.0\")\n column :c10, \"foo\", :default=>Sequel::LiteralString.new(\"'6 weeks'\")\n column :c11, \"date\", :default=>Sequel::CURRENT_DATE\n column :c12, \"timestamp\", :default=>Sequel::CURRENT_TIMESTAMP\nend"
|
678
678
|
end
|
679
679
|
|
680
680
|
it "should not use a literal string as a fallback if using MySQL with the :same_db option" do
|
@@ -24,7 +24,7 @@ describe "Sequel sql_expr extension" do
|
|
24
24
|
end
|
25
25
|
|
26
26
|
it "Numeric#sql_expr should wrap the object in a NumericExpression" do
|
27
|
-
[1, 2.0, 2^70, BigDecimal
|
27
|
+
[1, 2.0, 2^70, BigDecimal('1.0')].each do |o|
|
28
28
|
@ds.literal(o.sql_expr).must_equal @ds.literal(o)
|
29
29
|
@ds.literal(o.sql_expr + 1).must_equal "(#{@ds.literal(o)} + 1)"
|
30
30
|
end
|
@@ -79,7 +79,7 @@ describe "string_agg extension" do
|
|
79
79
|
it "should handle operations on object" do
|
80
80
|
ds = dbf.call(:postgres).dataset.with_quote_identifiers(false)
|
81
81
|
ds.literal(@sa1 + 'b').must_equal "(string_agg(c, ',') || 'b')"
|
82
|
-
ds.literal(@sa1.like('b')).must_equal "(string_agg(c, ',') LIKE 'b'
|
82
|
+
ds.literal(@sa1.like('b')).must_equal "(string_agg(c, ',') LIKE 'b')"
|
83
83
|
ds.literal(@sa1 < 'b').must_equal "(string_agg(c, ',') < 'b')"
|
84
84
|
ds.literal(@sa1.as(:b)).must_equal "string_agg(c, ',') AS b"
|
85
85
|
ds.literal(@sa1.cast(:b)).must_equal "CAST(string_agg(c, ',') AS b)"
|
@@ -63,9 +63,9 @@ describe "Sequel::Plugins::Timestamps" do
|
|
63
63
|
it "should work with current_datetime_timestamp extension" do
|
64
64
|
Sequel.datetime_class = Time
|
65
65
|
@c.dataset = @c.dataset.extension(:current_datetime_timestamp)
|
66
|
-
|
66
|
+
@c.create
|
67
67
|
@c.db.sqls.must_equal ["INSERT INTO t (created_at) VALUES (CURRENT_TIMESTAMP)"]
|
68
|
-
|
68
|
+
@c.load(:id=>1).save
|
69
69
|
@c.db.sqls.must_equal ["UPDATE t SET updated_at = CURRENT_TIMESTAMP WHERE (id = 1)"]
|
70
70
|
end
|
71
71
|
|
@@ -293,7 +293,7 @@ describe "Sequel::Plugins::ValidationHelpers" do
|
|
293
293
|
@m.must_be :valid?
|
294
294
|
@m.value = 1.0
|
295
295
|
@m.must_be :valid?
|
296
|
-
@m.value = BigDecimal
|
296
|
+
@m.value = BigDecimal('1.0')
|
297
297
|
@m.wont_be :valid?
|
298
298
|
@m.errors.full_messages.must_equal ['value is not a valid integer or float']
|
299
299
|
end
|
@@ -2059,6 +2059,18 @@ describe "Sequel::Model Simple Associations" do
|
|
2059
2059
|
artist.albums.first.tags.must_equal [tag2]
|
2060
2060
|
end
|
2061
2061
|
|
2062
|
+
it "should not produce duplicates when eager graphing many_to_one=>one_to_many association" do
|
2063
|
+
@pr.call
|
2064
|
+
@album.update(:artist => @artist)
|
2065
|
+
album2 = Album.last
|
2066
|
+
album2.update(:artist => @artist)
|
2067
|
+
|
2068
|
+
a = Album.eager_graph(:artist=>:albums).order{[albums[:id], albums_0[:id]]}.all
|
2069
|
+
a.must_equal [@album, album2]
|
2070
|
+
a.map(&:artist).must_equal [@artist, @artist]
|
2071
|
+
a.map(&:artist).map(&:albums).must_equal [[@album, album2], [@album, album2]]
|
2072
|
+
end
|
2073
|
+
|
2062
2074
|
it "should have remove method raise an error for one_to_many records if the object isn't already associated" do
|
2063
2075
|
proc{@artist.remove_album(@album.id)}.must_raise(Sequel::Error)
|
2064
2076
|
proc{@artist.remove_album(@album)}.must_raise(Sequel::Error)
|
@@ -1698,6 +1698,27 @@ describe "Dataset string methods" do
|
|
1698
1698
|
@ds.filter(Sequel.expr(:b).ilike(@ds.escape_like('[Bar%]'))).select_order_map(:b).must_equal ['[bar%]']
|
1699
1699
|
@ds.filter(Sequel.expr(:b).ilike("#{@ds.escape_like('Bar%')}_")).select_order_map(:b).must_equal ['bar%.']
|
1700
1700
|
@ds.filter(Sequel.expr(:b).ilike("#{@ds.escape_like('Bar%')}%")).select_order_map(:b).must_equal ['bar%', 'bar%.', 'bar%..']
|
1701
|
+
|
1702
|
+
Sequel.extension(:escaped_like)
|
1703
|
+
@ds.filter(Sequel.expr(:a).escaped_like('?', 'Foo_')).select_order_map(:a).must_equal []
|
1704
|
+
@ds.filter(Sequel.expr(:a).escaped_like('?', 'foo_')).select_order_map(:a).must_equal ['foo_']
|
1705
|
+
@ds.filter(Sequel.expr(:b).escaped_like('?', ['bar%'])).select_order_map(:b).must_equal ['bar%']
|
1706
|
+
@ds.filter(Sequel.expr(:a).escaped_like('??', ['fo', 'o\\_'])).select_order_map(:a).must_equal ['foo\\_']
|
1707
|
+
@ds.filter(Sequel.expr(:b).escaped_like('?', 'bar\\%')).select_order_map(:b).must_equal ['bar\\%']
|
1708
|
+
@ds.filter(Sequel.expr(:a).escaped_like('?', '[f#*?oo_]')).select_order_map(:a).must_equal ['[f#*?oo_]']
|
1709
|
+
@ds.filter(Sequel.expr(:b).escaped_like('?', '[bar%]')).select_order_map(:b).must_equal ['[bar%]']
|
1710
|
+
@ds.filter(Sequel.expr(:b).escaped_like('?_', 'bar%')).select_order_map(:b).must_equal ['bar%.']
|
1711
|
+
@ds.filter(Sequel.expr(:b).escaped_like('?%', 'bar%')).select_order_map(:b).must_equal ['bar%', 'bar%.', 'bar%..']
|
1712
|
+
|
1713
|
+
@ds.filter(Sequel.expr(:a).escaped_ilike('?', 'Foo_')).select_order_map(:a).must_equal ['foo_']
|
1714
|
+
@ds.filter(Sequel.expr(:a).escaped_ilike('?', 'Foo_')).select_order_map(:a).must_equal ['foo_']
|
1715
|
+
@ds.filter(Sequel.expr(:b).escaped_ilike('?', ['Bar%'])).select_order_map(:b).must_equal ['bar%']
|
1716
|
+
@ds.filter(Sequel.expr(:a).escaped_ilike('??', ['Fo', 'o\\_'])).select_order_map(:a).must_equal ['foo\\_']
|
1717
|
+
@ds.filter(Sequel.expr(:b).escaped_ilike('?', 'Bar\\%')).select_order_map(:b).must_equal ['bar\\%']
|
1718
|
+
@ds.filter(Sequel.expr(:a).escaped_ilike('?', '[F#*?oo_]')).select_order_map(:a).must_equal ['[f#*?oo_]']
|
1719
|
+
@ds.filter(Sequel.expr(:b).escaped_ilike('?', '[Bar%]')).select_order_map(:b).must_equal ['[bar%]']
|
1720
|
+
@ds.filter(Sequel.expr(:b).escaped_ilike('?_', 'Bar%')).select_order_map(:b).must_equal ['bar%.']
|
1721
|
+
@ds.filter(Sequel.expr(:b).escaped_ilike('?%', 'Bar%')).select_order_map(:b).must_equal ['bar%', 'bar%.', 'bar%..']
|
1701
1722
|
end
|
1702
1723
|
|
1703
1724
|
if DB.dataset.supports_regexp?
|
@@ -45,11 +45,11 @@ describe "Supported types" do
|
|
45
45
|
|
46
46
|
cspecify "should support generic numeric type", [:odbc, :mssql] do
|
47
47
|
ds = create_items_table_with_column(:number, Numeric, :size=>[15, 10])
|
48
|
-
ds.insert(:number => BigDecimal
|
49
|
-
ds.all.must_equal [{:number=>BigDecimal
|
48
|
+
ds.insert(:number => BigDecimal('2.123456789'))
|
49
|
+
ds.all.must_equal [{:number=>BigDecimal('2.123456789')}]
|
50
50
|
ds = create_items_table_with_column(:number, BigDecimal, :size=>[15, 10])
|
51
|
-
ds.insert(:number => BigDecimal
|
52
|
-
ds.all.must_equal [{:number=>BigDecimal
|
51
|
+
ds.insert(:number => BigDecimal('2.123456789'))
|
52
|
+
ds.all.must_equal [{:number=>BigDecimal('2.123456789')}]
|
53
53
|
end
|
54
54
|
|
55
55
|
it "should support generic string type" do
|
data/spec/model/base_spec.rb
CHANGED
@@ -100,6 +100,15 @@ describe Sequel::Model, "dataset" do
|
|
100
100
|
end
|
101
101
|
end
|
102
102
|
|
103
|
+
describe Sequel::Model, "has_dataset?" do
|
104
|
+
it "should return whether the model has a dataset" do
|
105
|
+
c = Class.new(Sequel::Model)
|
106
|
+
c.has_dataset?.must_equal false
|
107
|
+
c.dataset = c.db[:table]
|
108
|
+
c.has_dataset?.must_equal true
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
103
112
|
describe Sequel::Model, "implicit table names" do
|
104
113
|
after do
|
105
114
|
Object.send(:remove_const, :BlahBlah)
|
@@ -2168,6 +2168,21 @@ describe Sequel::Model, "#eager_graph" do
|
|
2168
2168
|
a.al_genre.must_equal GraphGenre.load(:id=>12)
|
2169
2169
|
end
|
2170
2170
|
|
2171
|
+
it "should not include duplicate objects when eager graphing many_to_one=>one_to_many" do
|
2172
|
+
ds = GraphAlbum.eager_graph(:band=>:albums)
|
2173
|
+
ds.sql.must_equal "SELECT albums.id, albums.band_id, band.id AS band_id_0, band.vocalist_id, albums_0.id AS albums_0_id, albums_0.band_id AS albums_0_band_id FROM albums LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id) LEFT OUTER JOIN albums AS albums_0 ON (albums_0.band_id = band.id)"
|
2174
|
+
a = ds.with_fetch([
|
2175
|
+
{:id=>1, :band_id=>2, :band_id_0=>2, :vocalist_id=>1, :albums_0_id=>1, :albums_0_band_id=>2},
|
2176
|
+
{:id=>2, :band_id=>2, :band_id_0=>2, :vocalist_id=>1, :albums_0_id=>1, :albums_0_band_id=>2},
|
2177
|
+
{:id=>1, :band_id=>2, :band_id_0=>2, :vocalist_id=>1, :albums_0_id=>2, :albums_0_band_id=>2},
|
2178
|
+
{:id=>2, :band_id=>2, :band_id_0=>2, :vocalist_id=>1, :albums_0_id=>2, :albums_0_band_id=>2}
|
2179
|
+
]).all
|
2180
|
+
albums = [GraphAlbum.load(:id => 1, :band_id => 2), GraphAlbum.load(:id => 2, :band_id => 2)]
|
2181
|
+
a.must_equal albums
|
2182
|
+
a.map(&:band).must_equal [GraphBand.load(:id=>2, :vocalist_id=>1), GraphBand.load(:id=>2, :vocalist_id=>1)]
|
2183
|
+
a.map(&:band).map(&:albums).must_equal [albums, albums]
|
2184
|
+
end
|
2185
|
+
|
2171
2186
|
it "should eagerly load a many_to_one association with a custom callback" do
|
2172
2187
|
ds = GraphAlbum.eager_graph(:band => proc {|ds1| ds1.select(:id).columns(:id)})
|
2173
2188
|
ds.sql.must_equal 'SELECT albums.id, albums.band_id, band.id AS band_id_0 FROM albums LEFT OUTER JOIN (SELECT id FROM bands) AS band ON (band.id = albums.band_id)'
|
@@ -2229,6 +2244,16 @@ describe Sequel::Model, "#eager_graph" do
|
|
2229
2244
|
a.album.band.must_equal GraphBand.load(:id => 2, :vocalist_id=>6)
|
2230
2245
|
a.album.tracks.must_equal [GraphTrack.load(:id => 3, :album_id => 1)]
|
2231
2246
|
end
|
2247
|
+
|
2248
|
+
it "should have frozen internal data structures" do
|
2249
|
+
ds = GraphAlbum.eager_graph(:band)
|
2250
|
+
ds.opts[:eager_graph].must_be :frozen?
|
2251
|
+
ds.opts[:eager_graph].each_value{|v| v.must_be :frozen? if v.is_a?(Hash)}
|
2252
|
+
|
2253
|
+
ds = ds.eager_graph(:tracks)
|
2254
|
+
ds.opts[:eager_graph].must_be :frozen?
|
2255
|
+
ds.opts[:eager_graph].each_value{|v| v.must_be :frozen? if v.is_a?(Hash)}
|
2256
|
+
end
|
2232
2257
|
end
|
2233
2258
|
|
2234
2259
|
describe "Sequel::Models with double underscores in table names" do
|
data/spec/model/record_spec.rb
CHANGED
@@ -1835,7 +1835,7 @@ describe Sequel::Model, "typecasting" do
|
|
1835
1835
|
it "should convert to BigDecimal for a decimal field" do
|
1836
1836
|
@c.db_schema = {:x=>{:type=>:decimal}}
|
1837
1837
|
m = @c.new
|
1838
|
-
bd = BigDecimal
|
1838
|
+
bd = BigDecimal('1.0')
|
1839
1839
|
m.x = '1.0'
|
1840
1840
|
m.x.must_equal bd
|
1841
1841
|
m.x = 1.0
|
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.9.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-
|
11
|
+
date: 2018-06-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|
@@ -192,6 +192,7 @@ extra_rdoc_files:
|
|
192
192
|
- doc/release_notes/5.4.0.txt
|
193
193
|
- doc/release_notes/5.8.0.txt
|
194
194
|
- doc/release_notes/5.7.0.txt
|
195
|
+
- doc/release_notes/5.9.0.txt
|
195
196
|
files:
|
196
197
|
- CHANGELOG
|
197
198
|
- MIT-LICENSE
|
@@ -278,6 +279,7 @@ files:
|
|
278
279
|
- doc/release_notes/5.6.0.txt
|
279
280
|
- doc/release_notes/5.7.0.txt
|
280
281
|
- doc/release_notes/5.8.0.txt
|
282
|
+
- doc/release_notes/5.9.0.txt
|
281
283
|
- doc/schema_modification.rdoc
|
282
284
|
- doc/security.rdoc
|
283
285
|
- doc/sharding.rdoc
|
@@ -385,6 +387,7 @@ files:
|
|
385
387
|
- lib/sequel/extensions/duplicate_columns_handler.rb
|
386
388
|
- lib/sequel/extensions/empty_array_consider_nulls.rb
|
387
389
|
- lib/sequel/extensions/error_sql.rb
|
390
|
+
- lib/sequel/extensions/escaped_like.rb
|
388
391
|
- lib/sequel/extensions/eval_inspect.rb
|
389
392
|
- lib/sequel/extensions/freeze_datasets.rb
|
390
393
|
- lib/sequel/extensions/from_block.rb
|
@@ -596,6 +599,7 @@ files:
|
|
596
599
|
- spec/extensions/empty_array_consider_nulls_spec.rb
|
597
600
|
- spec/extensions/error_splitter_spec.rb
|
598
601
|
- spec/extensions/error_sql_spec.rb
|
602
|
+
- spec/extensions/escaped_like_spec.rb
|
599
603
|
- spec/extensions/eval_inspect_spec.rb
|
600
604
|
- spec/extensions/finder_spec.rb
|
601
605
|
- spec/extensions/force_encoding_spec.rb
|