sequel 5.24.0 → 5.29.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 +58 -0
- data/MIT-LICENSE +1 -1
- data/README.rdoc +1 -1
- data/doc/cheat_sheet.rdoc +1 -0
- data/doc/postgresql.rdoc +2 -2
- data/doc/release_notes/5.25.0.txt +32 -0
- data/doc/release_notes/5.26.0.txt +35 -0
- data/doc/release_notes/5.27.0.txt +21 -0
- data/doc/release_notes/5.28.0.txt +16 -0
- data/doc/release_notes/5.29.0.txt +22 -0
- data/doc/testing.rdoc +11 -6
- data/lib/sequel/adapters/jdbc/postgresql.rb +6 -0
- data/lib/sequel/adapters/postgres.rb +5 -1
- data/lib/sequel/adapters/shared/mssql.rb +4 -2
- data/lib/sequel/adapters/shared/mysql.rb +1 -1
- data/lib/sequel/adapters/shared/postgres.rb +15 -0
- data/lib/sequel/adapters/shared/sqlite.rb +7 -2
- data/lib/sequel/adapters/tinytds.rb +1 -1
- data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -1
- data/lib/sequel/database/schema_generator.rb +1 -1
- data/lib/sequel/database/transactions.rb +3 -3
- data/lib/sequel/dataset/features.rb +6 -0
- data/lib/sequel/dataset/misc.rb +2 -2
- data/lib/sequel/dataset/query.rb +15 -2
- data/lib/sequel/dataset/sql.rb +17 -4
- data/lib/sequel/extensions/any_not_empty.rb +45 -0
- data/lib/sequel/extensions/exclude_or_null.rb +68 -0
- data/lib/sequel/extensions/pg_array_ops.rb +10 -6
- data/lib/sequel/extensions/pg_enum.rb +4 -1
- data/lib/sequel/extensions/pg_json.rb +1 -1
- data/lib/sequel/extensions/pg_json_ops.rb +124 -0
- data/lib/sequel/extensions/pg_range.rb +9 -0
- data/lib/sequel/extensions/sql_comments.rb +2 -2
- data/lib/sequel/model/base.rb +12 -5
- data/lib/sequel/plugins/association_multi_add_remove.rb +83 -0
- data/lib/sequel/plugins/caching.rb +3 -0
- data/lib/sequel/plugins/csv_serializer.rb +26 -9
- data/lib/sequel/plugins/dirty.rb +3 -9
- data/lib/sequel/plugins/empty_failure_backtraces.rb +38 -0
- data/lib/sequel/plugins/json_serializer.rb +15 -4
- data/lib/sequel/plugins/nested_attributes.rb +7 -0
- data/lib/sequel/plugins/sharding.rb +11 -5
- data/lib/sequel/plugins/throw_failures.rb +1 -1
- data/lib/sequel/plugins/typecast_on_load.rb +3 -2
- data/lib/sequel/sql.rb +4 -1
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/postgres_spec.rb +82 -17
- data/spec/adapters/sqlite_spec.rb +1 -1
- data/spec/bin_spec.rb +1 -1
- data/spec/core/database_spec.rb +1 -1
- data/spec/core/dataset_spec.rb +0 -3
- data/spec/core/expression_filters_spec.rb +26 -7
- data/spec/core/spec_helper.rb +1 -1
- data/spec/core_extensions_spec.rb +1 -1
- data/spec/extensions/any_not_empty_spec.rb +23 -0
- data/spec/extensions/association_multi_add_remove_spec.rb +1041 -0
- data/spec/extensions/caller_logging_spec.rb +1 -1
- data/spec/extensions/dirty_spec.rb +33 -0
- data/spec/extensions/empty_failure_backtraces_spec.rb +60 -0
- data/spec/extensions/exclude_or_null_spec.rb +15 -0
- data/spec/extensions/json_serializer_spec.rb +10 -0
- data/spec/extensions/named_timezones_spec.rb +5 -5
- data/spec/extensions/nested_attributes_spec.rb +48 -0
- data/spec/extensions/pg_array_ops_spec.rb +3 -3
- data/spec/extensions/pg_json_ops_spec.rb +67 -0
- data/spec/extensions/pg_range_spec.rb +35 -21
- data/spec/extensions/sharding_spec.rb +8 -0
- data/spec/extensions/spec_helper.rb +1 -1
- data/spec/guards_helper.rb +1 -1
- data/spec/integration/associations_test.rb +1 -1
- data/spec/integration/dataset_test.rb +57 -17
- data/spec/integration/plugin_test.rb +1 -1
- data/spec/integration/schema_test.rb +9 -0
- data/spec/integration/spec_helper.rb +7 -1
- data/spec/model/plugins_spec.rb +2 -2
- data/spec/model/spec_helper.rb +1 -1
- data/spec/sequel_warning.rb +1 -0
- metadata +35 -3
@@ -42,7 +42,7 @@ describe "caller_logging extension" do
|
|
42
42
|
|
43
43
|
it "should not log caller information if all callers lines are filtered" do
|
44
44
|
@db.caller_logging_ignore = /./
|
45
|
-
exec_sql("SELECT * FROM items")
|
45
|
+
exec_sql("SELECT * FROM items")
|
46
46
|
@log_stream.rewind
|
47
47
|
lines = @log_stream.read.split("\n")
|
48
48
|
lines.length.must_equal 1
|
@@ -162,6 +162,39 @@ describe "Sequel::Plugins::Dirty" do
|
|
162
162
|
@o.save
|
163
163
|
@o.column_changes.must_equal({})
|
164
164
|
end
|
165
|
+
|
166
|
+
it "should work with the typecast_on_load plugin" do
|
167
|
+
@c.instance_variable_set(:@db_schema, :initial=>{:type=>:integer})
|
168
|
+
@c.plugin :typecast_on_load, :initial
|
169
|
+
|
170
|
+
@o = @c.call(:initial=>'1')
|
171
|
+
@o.column_changes.must_equal({})
|
172
|
+
@o.save
|
173
|
+
@o.previous_changes.must_equal({})
|
174
|
+
end
|
175
|
+
|
176
|
+
it "should have column_changes work with the typecast_on_load in after hooks" do
|
177
|
+
@c.instance_variable_set(:@db_schema, :initial=>{:type=>:integer})
|
178
|
+
@c.plugin :typecast_on_load, :initial
|
179
|
+
|
180
|
+
@o = @c.new
|
181
|
+
@o.initial = 1
|
182
|
+
@o.column_changes.must_equal({:initial=>[nil, 1]})
|
183
|
+
column_changes_in_after_save = nil
|
184
|
+
@o.define_singleton_method(:after_save) do
|
185
|
+
column_changes_in_after_save = column_changes
|
186
|
+
super()
|
187
|
+
end
|
188
|
+
@db.fetch = {:initial=>1}
|
189
|
+
@o.save
|
190
|
+
column_changes_in_after_save.must_equal({:initial=>[nil, 1]})
|
191
|
+
|
192
|
+
@o.initial = 2
|
193
|
+
@o.column_changes.must_equal({:initial=>[1, 2]})
|
194
|
+
@o.save
|
195
|
+
column_changes_in_after_save.must_equal({:initial=>[1, 2]})
|
196
|
+
@o.previous_changes.must_equal({:initial=>[1, 2]})
|
197
|
+
end
|
165
198
|
end
|
166
199
|
|
167
200
|
describe "with existing instance" do
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require_relative "spec_helper"
|
2
|
+
|
3
|
+
describe "empty_failure_backtraces plugin" do
|
4
|
+
before do
|
5
|
+
@c = Class.new(Sequel::Model(:items)) do
|
6
|
+
plugin :empty_failure_backtraces
|
7
|
+
columns :x
|
8
|
+
set_primary_key :x
|
9
|
+
unrestrict_primary_key
|
10
|
+
def before_create
|
11
|
+
super
|
12
|
+
cancel_action 'bc' if x == 2
|
13
|
+
end
|
14
|
+
def before_destroy
|
15
|
+
super
|
16
|
+
cancel_action 'bd' if x == 2
|
17
|
+
end
|
18
|
+
def validate
|
19
|
+
super
|
20
|
+
errors.add(:x, "3") if x == 3
|
21
|
+
end
|
22
|
+
end
|
23
|
+
DB.reset
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should work normally if no exceptions are thrown/raised" do
|
27
|
+
o = @c.create(:x=>1)
|
28
|
+
o.must_be_kind_of @c
|
29
|
+
o.valid?.must_equal true
|
30
|
+
o.destroy.must_equal o
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should work normally when not rescuing exceptions internally when calling save" do
|
34
|
+
@c.new.set(:x => 2).save(:raise_on_failure=>false).must_be_nil
|
35
|
+
@c.raise_on_save_failure = false
|
36
|
+
@c.create(:x => 2).must_be_nil
|
37
|
+
@c.load(:x => 2).destroy(:raise_on_failure=>false).must_be_nil
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should work normally when not rescuing exceptions internally when calling valid?" do
|
41
|
+
@c.send(:define_method, :before_validation){cancel_action "bv"}
|
42
|
+
@c.new(:x => 2).valid?.must_equal false
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should raise exceptions with empty backtraces" do
|
46
|
+
begin
|
47
|
+
@c.create(:x => 2)
|
48
|
+
rescue Sequel::HookFailed => e
|
49
|
+
e.backtrace.must_be_empty
|
50
|
+
1
|
51
|
+
end.must_equal 1
|
52
|
+
|
53
|
+
begin
|
54
|
+
@c.create(:x => 3)
|
55
|
+
rescue Sequel::ValidationFailed => e
|
56
|
+
e.backtrace.must_be_empty
|
57
|
+
1
|
58
|
+
end.must_equal 1
|
59
|
+
end
|
60
|
+
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
|
@@ -187,6 +187,16 @@ describe "Sequel::Plugins::JsonSerializer" do
|
|
187
187
|
Album.array_from_json(Album.dataset.to_json(:only=>:name)).must_equal [Album.load(:name=>@album.name)]
|
188
188
|
end
|
189
189
|
|
190
|
+
it "should support setting json_serializer_opts for datasets" do
|
191
|
+
Album.dataset = Album.dataset.with_fetch(:id=>1, :name=>'RF', :artist_id=>2)
|
192
|
+
Album.array_from_json(Album.dataset.json_serializer_opts(:only=>:name).to_json).must_equal [Album.load(:name=>@album.name)]
|
193
|
+
Album.plugin :json_serializer, :only=>:id
|
194
|
+
Album.array_from_json(Album.dataset.json_serializer_opts(:only=>:name).to_json).must_equal [Album.load(:name=>@album.name)]
|
195
|
+
Album.array_from_json(Album.dataset.json_serializer_opts(:only=>:name).to_json(:only=>:artist_id)).must_equal [Album.load(:artist_id=>2)]
|
196
|
+
json = Album.dataset.json_serializer_opts(:only=>:name, :root=>true).to_json(:only=>:artist_id)
|
197
|
+
Album.array_from_json(JSON.parse(json)['albums'].to_json).must_equal [Album.load(:artist_id=>2)]
|
198
|
+
end
|
199
|
+
|
190
200
|
it "should have dataset to_json method work with eager_graph datasets" do
|
191
201
|
ds = Album.dataset.eager_graph(:artist).with_fetch(:id=>1, :name=>'RF', :artist_id=>2, :artist_id_0=>2, :artist_name=>'YM')
|
192
202
|
Sequel.parse_json(ds.to_json(:only=>:name, :include=>{:artist=>{:only=>:name}})).must_equal [{"name"=>"RF", "artist"=>{"name"=>"YM"}}]
|
@@ -158,12 +158,12 @@ describe "Sequel named_timezones extension with Time class" do
|
|
158
158
|
dt = Sequel.database_to_application_timestamp('2009-06-01 06:20:30-0400')
|
159
159
|
dt.must_be_instance_of Time
|
160
160
|
dt.must_equal Time.new(2009,6,1,3,20,30,-25200)
|
161
|
-
dt.utc_offset.must_equal
|
161
|
+
dt.utc_offset.must_equal(-25200)
|
162
162
|
|
163
163
|
dt = Sequel.database_to_application_timestamp('2009-06-01 10:20:30+0000')
|
164
164
|
dt.must_be_instance_of Time
|
165
165
|
dt.must_equal Time.new(2009,6,1,3,20,30,-25200)
|
166
|
-
dt.utc_offset.must_equal
|
166
|
+
dt.utc_offset.must_equal(-25200)
|
167
167
|
end
|
168
168
|
|
169
169
|
it "should raise an error for ambiguous timezones by default" do
|
@@ -175,19 +175,19 @@ describe "Sequel named_timezones extension with Time class" do
|
|
175
175
|
Sequel.database_to_application_timestamp('2004-10-31T01:30:00').must_equal Time.new(2004, 10, 30, 22, 30, 0, -25200)
|
176
176
|
dt = Sequel.database_to_application_timestamp('2004-10-31T01:30:00')
|
177
177
|
dt.must_equal Time.new(2004, 10, 30, 22, 30, 0, -25200)
|
178
|
-
dt.utc_offset.must_equal
|
178
|
+
dt.utc_offset.must_equal(-25200)
|
179
179
|
end
|
180
180
|
|
181
181
|
it "should assume datetimes coming out of the database that don't have an offset as coming from database_timezone" do
|
182
182
|
dt = Sequel.database_to_application_timestamp('2009-06-01 06:20:30')
|
183
183
|
dt.must_be_instance_of Time
|
184
184
|
dt.must_equal Time.new(2009,6,1,3,20,30, -25200)
|
185
|
-
dt.utc_offset.must_equal
|
185
|
+
dt.utc_offset.must_equal(-25200)
|
186
186
|
|
187
187
|
dt = Sequel.database_to_application_timestamp('2009-06-01 10:20:30')
|
188
188
|
dt.must_be_instance_of Time
|
189
189
|
dt.must_equal Time.new(2009,6,1,7,20,30, -25200)
|
190
|
-
dt.utc_offset.must_equal
|
190
|
+
dt.utc_offset.must_equal(-25200)
|
191
191
|
end
|
192
192
|
|
193
193
|
it "should work with the thread_local_timezones extension" do
|
@@ -492,6 +492,54 @@ describe "NestedAttributes plugin" do
|
|
492
492
|
@db.sqls.must_equal ["UPDATE artists SET name = 'Ar' WHERE (id = 10)"]
|
493
493
|
end
|
494
494
|
|
495
|
+
it "should raise a NoExistingObject error if object to be updated no longer exists, if the :require_modification=>true option is used" do
|
496
|
+
@Artist.nested_attributes :albums, :require_modification=>true, :destroy=>true
|
497
|
+
al = @Album.load(:id=>10, :name=>'Al')
|
498
|
+
ar = @Artist.load(:id=>20, :name=>'Ar')
|
499
|
+
ar.associations[:albums] = [al]
|
500
|
+
ar.set(:albums_attributes=>[{:id=>10, :name=>'L'}])
|
501
|
+
@db.sqls.must_equal []
|
502
|
+
@db.numrows = [1, 0]
|
503
|
+
proc{ar.save}.must_raise Sequel::NoExistingObject
|
504
|
+
@db.sqls.must_equal ["UPDATE artists SET name = 'Ar' WHERE (id = 20)", "UPDATE albums SET name = 'L' WHERE (id = 10)"]
|
505
|
+
end
|
506
|
+
|
507
|
+
it "should not raise an Error if object to be updated no longer exists, if the :require_modification=>false option is used" do
|
508
|
+
@Artist.nested_attributes :albums, :require_modification=>false, :destroy=>true
|
509
|
+
al = @Album.load(:id=>10, :name=>'Al')
|
510
|
+
ar = @Artist.load(:id=>20, :name=>'Ar')
|
511
|
+
ar.associations[:albums] = [al]
|
512
|
+
ar.set(:albums_attributes=>[{:id=>10, :name=>'L'}])
|
513
|
+
@db.sqls.must_equal []
|
514
|
+
@db.numrows = [1, 0]
|
515
|
+
ar.save
|
516
|
+
@db.sqls.must_equal ["UPDATE artists SET name = 'Ar' WHERE (id = 20)", "UPDATE albums SET name = 'L' WHERE (id = 10)"]
|
517
|
+
end
|
518
|
+
|
519
|
+
it "should raise a NoExistingObject error if object to be deleted no longer exists, if the :require_modification=>true option is used" do
|
520
|
+
@Artist.nested_attributes :albums, :require_modification=>true, :destroy=>true
|
521
|
+
al = @Album.load(:id=>10, :name=>'Al')
|
522
|
+
ar = @Artist.load(:id=>20, :name=>'Ar')
|
523
|
+
ar.associations[:albums] = [al]
|
524
|
+
ar.set(:albums_attributes=>[{:id=>10, :_delete=>'t'}])
|
525
|
+
@db.sqls.must_equal []
|
526
|
+
@db.numrows = [1, 0]
|
527
|
+
proc{ar.save}.must_raise Sequel::NoExistingObject
|
528
|
+
@db.sqls.must_equal ["UPDATE artists SET name = 'Ar' WHERE (id = 20)", "DELETE FROM albums WHERE (id = 10)"]
|
529
|
+
end
|
530
|
+
|
531
|
+
it "should not raise an Error if object to be deleted no longer exists, if the :require_modification=>false option is used" do
|
532
|
+
@Artist.nested_attributes :albums, :require_modification=>false, :destroy=>true
|
533
|
+
al = @Album.load(:id=>10, :name=>'Al')
|
534
|
+
ar = @Artist.load(:id=>20, :name=>'Ar')
|
535
|
+
ar.associations[:albums] = [al]
|
536
|
+
ar.set(:albums_attributes=>[{:id=>10, :_delete=>'t'}])
|
537
|
+
@db.sqls.must_equal []
|
538
|
+
@db.numrows = [1, 0]
|
539
|
+
ar.save
|
540
|
+
@db.sqls.must_equal ["UPDATE artists SET name = 'Ar' WHERE (id = 20)", "DELETE FROM albums WHERE (id = 10)"]
|
541
|
+
end
|
542
|
+
|
495
543
|
it "should not attempt to validate nested attributes twice for one_to_many associations when creating them" do
|
496
544
|
@Artist.nested_attributes :albums
|
497
545
|
validated = []
|
@@ -83,9 +83,9 @@ describe "Sequel::Postgres::ArrayOp" do
|
|
83
83
|
end
|
84
84
|
|
85
85
|
it "#to_string/join should use the array_to_string function" do
|
86
|
-
@db.literal(@a.to_string).must_equal "array_to_string(a, ''
|
87
|
-
@db.literal(@a.join).must_equal "array_to_string(a, ''
|
88
|
-
@db.literal(@a.join(':')).must_equal "array_to_string(a, ':'
|
86
|
+
@db.literal(@a.to_string).must_equal "array_to_string(a, '')"
|
87
|
+
@db.literal(@a.join).must_equal "array_to_string(a, '')"
|
88
|
+
@db.literal(@a.join(':')).must_equal "array_to_string(a, ':')"
|
89
89
|
@db.literal(@a.join(':', '*')).must_equal "array_to_string(a, ':', '*')"
|
90
90
|
end
|
91
91
|
|
@@ -286,4 +286,71 @@ describe "Sequel::Postgres::JSONOp" do
|
|
286
286
|
it "should allow transforming JSONBHash instances into ArrayOp instances" do
|
287
287
|
@db.literal(Sequel.pg_jsonb('a'=>1).op['a']).must_equal "('{\"a\":1}'::jsonb -> 'a')"
|
288
288
|
end
|
289
|
+
|
290
|
+
it "#path_exists should use the @? operator" do
|
291
|
+
@l[@jb.path_exists('$')].must_equal "(j @? '$')"
|
292
|
+
end
|
293
|
+
|
294
|
+
it "#path_exists result should be a boolean expression" do
|
295
|
+
@jb.path_exists('$').must_be_kind_of Sequel::SQL::BooleanExpression
|
296
|
+
end
|
297
|
+
|
298
|
+
it "#path_match should use the @@ operator" do
|
299
|
+
@l[@jb.path_match('$')].must_equal "(j @@ '$')"
|
300
|
+
end
|
301
|
+
|
302
|
+
it "#path_match result should be a boolean expression" do
|
303
|
+
@jb.path_match('$').must_be_kind_of Sequel::SQL::BooleanExpression
|
304
|
+
end
|
305
|
+
|
306
|
+
it "#path_exists! should use the jsonb_path_exists function" do
|
307
|
+
@l[@jb.path_exists!('$')].must_equal "jsonb_path_exists(j, '$')"
|
308
|
+
@l[@jb.path_exists!('$', '{"x":2}')].must_equal "jsonb_path_exists(j, '$', '{\"x\":2}')"
|
309
|
+
@l[@jb.path_exists!('$', x: 2)].must_equal "jsonb_path_exists(j, '$', '{\"x\":2}')"
|
310
|
+
@l[@jb.path_exists!('$', {x: 2}, true)].must_equal "jsonb_path_exists(j, '$', '{\"x\":2}', true)"
|
311
|
+
end
|
312
|
+
|
313
|
+
it "#path_exists! result should be a boolean expression" do
|
314
|
+
@jb.path_exists!('$').must_be_kind_of Sequel::SQL::BooleanExpression
|
315
|
+
end
|
316
|
+
|
317
|
+
it "#path_match! should use the jsonb_path_match function" do
|
318
|
+
@l[@jb.path_match!('$')].must_equal "jsonb_path_match(j, '$')"
|
319
|
+
@l[@jb.path_match!('$', '{"x":2}')].must_equal "jsonb_path_match(j, '$', '{\"x\":2}')"
|
320
|
+
@l[@jb.path_match!('$', x: 2)].must_equal "jsonb_path_match(j, '$', '{\"x\":2}')"
|
321
|
+
@l[@jb.path_match!('$', {x: 2}, true)].must_equal "jsonb_path_match(j, '$', '{\"x\":2}', true)"
|
322
|
+
end
|
323
|
+
|
324
|
+
it "#path_match! result should be a boolean expression" do
|
325
|
+
@jb.path_match!('$').must_be_kind_of Sequel::SQL::BooleanExpression
|
326
|
+
end
|
327
|
+
|
328
|
+
it "#path_query should use the jsonb_path_query function" do
|
329
|
+
@l[@jb.path_query('$')].must_equal "jsonb_path_query(j, '$')"
|
330
|
+
@l[@jb.path_query('$', '{"x":2}')].must_equal "jsonb_path_query(j, '$', '{\"x\":2}')"
|
331
|
+
@l[@jb.path_query('$', x: 2)].must_equal "jsonb_path_query(j, '$', '{\"x\":2}')"
|
332
|
+
@l[@jb.path_query('$', {x: 2}, true)].must_equal "jsonb_path_query(j, '$', '{\"x\":2}', true)"
|
333
|
+
end
|
334
|
+
|
335
|
+
it "#path_query_array should use the jsonb_path_query_array function" do
|
336
|
+
@l[@jb.path_query_array('$')].must_equal "jsonb_path_query_array(j, '$')"
|
337
|
+
@l[@jb.path_query_array('$', '{"x":2}')].must_equal "jsonb_path_query_array(j, '$', '{\"x\":2}')"
|
338
|
+
@l[@jb.path_query_array('$', x: 2)].must_equal "jsonb_path_query_array(j, '$', '{\"x\":2}')"
|
339
|
+
@l[@jb.path_query_array('$', {x: 2}, true)].must_equal "jsonb_path_query_array(j, '$', '{\"x\":2}', true)"
|
340
|
+
end
|
341
|
+
|
342
|
+
it "#path_query_array result should be a JSONBOp" do
|
343
|
+
@l[@jb.path_query_array('$').path_query_array('$')].must_equal "jsonb_path_query_array(jsonb_path_query_array(j, '$'), '$')"
|
344
|
+
end
|
345
|
+
|
346
|
+
it "#path_query_first should use the jsonb_path_query_first function" do
|
347
|
+
@l[@jb.path_query_first('$')].must_equal "jsonb_path_query_first(j, '$')"
|
348
|
+
@l[@jb.path_query_first('$', '{"x":2}')].must_equal "jsonb_path_query_first(j, '$', '{\"x\":2}')"
|
349
|
+
@l[@jb.path_query_first('$', x: 2)].must_equal "jsonb_path_query_first(j, '$', '{\"x\":2}')"
|
350
|
+
@l[@jb.path_query_first('$', {x: 2}, true)].must_equal "jsonb_path_query_first(j, '$', '{\"x\":2}', true)"
|
351
|
+
end
|
352
|
+
|
353
|
+
it "#path_query_first result should be a JSONBOp" do
|
354
|
+
@l[@jb.path_query_first('$').path_query_first('$')].must_equal "jsonb_path_query_first(jsonb_path_query_first(j, '$'), '$')"
|
355
|
+
end
|
289
356
|
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
|
@@ -136,6 +136,20 @@ describe "pg_range extension" do
|
|
136
136
|
s[1][1][:ruby_default].must_equal Sequel::Postgres::PGRange.new(1, 5, :exclude_end=>true, :db_type=>'int4range')
|
137
137
|
end
|
138
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
|
+
|
139
153
|
describe "database typecasting" do
|
140
154
|
before do
|
141
155
|
@o = @R.new(1, 2, :db_type=>'int4range')
|
@@ -456,21 +470,21 @@ describe "pg_range extension" do
|
|
456
470
|
end
|
457
471
|
|
458
472
|
it "should consider PGRanges equal with a endless Range they represent" do
|
459
|
-
@R.new(1, nil).must_be :==, eval('1..')
|
460
|
-
@R.new(1, nil, :exclude_end=>true).must_be :==, eval('1...')
|
461
|
-
@R.new(1, nil).wont_be :==, eval('1...')
|
462
|
-
@R.new(1, nil, :exclude_end=>true).wont_be :==, eval('1..')
|
463
|
-
@R.new(1, nil).wont_be :==, eval('2..')
|
464
|
-
@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...)')
|
465
479
|
end if endless_range_support
|
466
480
|
|
467
481
|
it "should consider PGRanges equal with a startless Range they represent" do
|
468
|
-
@R.new(nil, 1).must_be :==, eval('..1')
|
469
|
-
@R.new(nil, 1, :exclude_end=>true).must_be :==, eval('...1')
|
470
|
-
@R.new(nil, 1).wont_be :==, eval('...1')
|
471
|
-
@R.new(nil, 1, :exclude_end=>true).wont_be :==, eval('..1')
|
472
|
-
@R.new(nil, 1).wont_be :==, eval('..2')
|
473
|
-
@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)')
|
474
488
|
end if startless_range_support
|
475
489
|
|
476
490
|
it "should consider PGRanges equal with a startless, endless Range they represent" do
|
@@ -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
|
data/spec/guards_helper.rb
CHANGED