sequel 5.19.0 → 5.20.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 +24 -0
- data/doc/release_notes/5.20.0.txt +89 -0
- data/doc/transactions.rdoc +38 -0
- data/lib/sequel/adapters/mysql2.rb +2 -2
- data/lib/sequel/adapters/shared/postgres.rb +5 -7
- data/lib/sequel/database/query.rb +1 -1
- data/lib/sequel/database/schema_generator.rb +1 -1
- data/lib/sequel/database/transactions.rb +57 -5
- data/lib/sequel/dataset/placeholder_literalizer.rb +4 -1
- data/lib/sequel/dataset/query.rb +1 -1
- data/lib/sequel/extensions/schema_dumper.rb +1 -1
- data/lib/sequel/model/associations.rb +35 -9
- data/lib/sequel/model/plugins.rb +104 -0
- data/lib/sequel/plugins/association_dependencies.rb +3 -3
- data/lib/sequel/plugins/association_pks.rb +14 -4
- data/lib/sequel/plugins/class_table_inheritance.rb +1 -0
- data/lib/sequel/plugins/composition.rb +13 -9
- data/lib/sequel/plugins/finder.rb +2 -2
- data/lib/sequel/plugins/hook_class_methods.rb +17 -5
- data/lib/sequel/plugins/inverted_subsets.rb +2 -2
- data/lib/sequel/plugins/pg_auto_constraint_validations.rb +61 -32
- data/lib/sequel/plugins/subset_conditions.rb +2 -2
- data/lib/sequel/plugins/validation_class_methods.rb +5 -3
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/postgres_spec.rb +32 -0
- data/spec/core/database_spec.rb +73 -2
- data/spec/core/schema_spec.rb +6 -0
- data/spec/extensions/class_table_inheritance_spec.rb +30 -8
- data/spec/extensions/core_refinements_spec.rb +1 -1
- data/spec/extensions/hook_class_methods_spec.rb +22 -0
- data/spec/extensions/migration_spec.rb +13 -0
- data/spec/extensions/pg_auto_constraint_validations_spec.rb +8 -0
- data/spec/extensions/s_spec.rb +1 -1
- data/spec/extensions/schema_dumper_spec.rb +4 -2
- data/spec/integration/plugin_test.rb +15 -0
- data/spec/integration/transaction_test.rb +50 -0
- data/spec/model/associations_spec.rb +84 -4
- data/spec/model/plugins_spec.rb +111 -0
- metadata +4 -2
@@ -99,13 +99,13 @@ describe Sequel::Model, "associate" do
|
|
99
99
|
class ::ParParent < Sequel::Model; end
|
100
100
|
klass = Class.new(Sequel::Model(:nodes))
|
101
101
|
|
102
|
-
klass.many_to_one(:par_parent, :order=>:a){1}
|
103
|
-
klass.one_to_many(:par_parent1s, :class=>'ParParent', :limit=>12){4}
|
104
|
-
klass.many_to_many(:par_parent2s, :class=>:ParParent, :uniq=>true){2}
|
102
|
+
klass.many_to_one(:par_parent, :order=>:a){|ds| 1}
|
103
|
+
klass.one_to_many(:par_parent1s, :class=>'ParParent', :limit=>12){|ds| 4}
|
104
|
+
klass.many_to_many(:par_parent2s, :class=>:ParParent, :uniq=>true){|ds| 2}
|
105
105
|
|
106
106
|
klass.many_to_one :par, :clone=>:par_parent, :select=>:b
|
107
107
|
klass.one_to_many :par1s, :clone=>:par_parent1s, :order=>:b, :limit=>10, :block=>nil
|
108
|
-
klass.many_to_many(:par2s, :clone=>:par_parent2s, :order=>:c){3}
|
108
|
+
klass.many_to_many(:par2s, :clone=>:par_parent2s, :order=>:c){|ds| 3}
|
109
109
|
klass.many_to_one :par3, :clone=>:par
|
110
110
|
|
111
111
|
klass.association_reflection(:par).associated_class.must_equal ParParent
|
@@ -861,6 +861,50 @@ describe Sequel::Model, "one_to_one" do
|
|
861
861
|
"UPDATE attributes SET y = 5, node_id = 1234 WHERE (id = 3)"]
|
862
862
|
end
|
863
863
|
|
864
|
+
it "should have setter method handle associations to models with joined datasets" do
|
865
|
+
db = Sequel.mock
|
866
|
+
c = Class.new(Sequel::Model(db)) do
|
867
|
+
set_dataset(db[:attributes].join(:foo, :attribute_id=>:id))
|
868
|
+
def _insert_dataset
|
869
|
+
db[:attributes]
|
870
|
+
end
|
871
|
+
def _update_dataset
|
872
|
+
db[:attributes].where(pk_hash)
|
873
|
+
end
|
874
|
+
@instance_dataset = dataset.limit(1).naked.skip_limit_check
|
875
|
+
unrestrict_primary_key
|
876
|
+
columns :id, :node_id, :y
|
877
|
+
end
|
878
|
+
|
879
|
+
@c2.one_to_one :attribute, :class => c
|
880
|
+
attrib = c.new(:id=>3)
|
881
|
+
|
882
|
+
db.fetch = [[], {:id=>3}]
|
883
|
+
@c2.load(:id => 1234).attribute = attrib
|
884
|
+
DB.sqls.must_equal []
|
885
|
+
db.sqls.must_equal [
|
886
|
+
"SELECT * FROM (SELECT * FROM attributes INNER JOIN foo ON (foo.attribute_id = attributes.id)) AS attributes LIMIT 1",
|
887
|
+
"SELECT * FROM (SELECT * FROM attributes INNER JOIN foo ON (foo.attribute_id = attributes.id)) AS attributes WHERE (node_id = 1234) LIMIT 1",
|
888
|
+
"INSERT INTO attributes (id, node_id) VALUES (3, 1234)",
|
889
|
+
"SELECT * FROM (SELECT * FROM attributes INNER JOIN foo ON (foo.attribute_id = attributes.id)) AS attributes WHERE (id = 3) LIMIT 1"]
|
890
|
+
|
891
|
+
db.fetch = [[{:id=>4}], {:id=>3, :node_id=>1234}]
|
892
|
+
db.numrows = 1
|
893
|
+
@c2.load(:id => 1234).attribute = c.load(:id=>3)
|
894
|
+
db.sqls.must_equal [
|
895
|
+
"SELECT * FROM (SELECT * FROM attributes INNER JOIN foo ON (foo.attribute_id = attributes.id)) AS attributes WHERE (node_id = 1234) LIMIT 1",
|
896
|
+
"UPDATE attributes SET node_id = NULL WHERE (id = 4)",
|
897
|
+
"UPDATE attributes SET node_id = 1234 WHERE (id = 3)"]
|
898
|
+
|
899
|
+
db.fetch = [[{:id=>4}], {:id=>3, :node_id=>1234}]
|
900
|
+
@c2.load(:id => 1234).attribute = c.new(:id=>3)
|
901
|
+
db.sqls.must_equal [
|
902
|
+
"SELECT * FROM (SELECT * FROM attributes INNER JOIN foo ON (foo.attribute_id = attributes.id)) AS attributes WHERE (node_id = 1234) LIMIT 1",
|
903
|
+
"UPDATE attributes SET node_id = NULL WHERE (id = 4)",
|
904
|
+
"INSERT INTO attributes (id, node_id) VALUES (3, 1234)",
|
905
|
+
"SELECT * FROM (SELECT * FROM attributes INNER JOIN foo ON (foo.attribute_id = attributes.id)) AS attributes WHERE (id = 3) LIMIT 1"]
|
906
|
+
end
|
907
|
+
|
864
908
|
it "should use implicit key if omitted" do
|
865
909
|
@c2.dataset = @c2.dataset.with_fetch({})
|
866
910
|
@c2.one_to_one :parent, :class => @c2
|
@@ -958,6 +1002,42 @@ describe Sequel::Model, "one_to_one" do
|
|
958
1002
|
DB.sqls.must_equal ["SELECT * FROM nodes WHERE ((parent_id = 100) AND (x > 1)) ORDER BY name LIMIT 1 OFFSET 20"]
|
959
1003
|
end
|
960
1004
|
|
1005
|
+
it "should support :dataset options with different types of arity" do
|
1006
|
+
@c2.one_to_one :child_20, :class => @c2, :key=>:id, :dataset=>proc{model.filter(:parent_id=>pk)}
|
1007
|
+
@c2.load(:id => 100).child_20
|
1008
|
+
DB.sqls.must_equal ["SELECT * FROM nodes WHERE (parent_id = 100) LIMIT 1"]
|
1009
|
+
|
1010
|
+
@c2.one_to_one :child_20, :class => @c2, :key=>:id, :dataset=>proc{|_| model.filter(:parent_id=>pk)}
|
1011
|
+
@c2.load(:id => 100).child_20
|
1012
|
+
DB.sqls.must_equal ["SELECT * FROM nodes WHERE (parent_id = 100) LIMIT 1"]
|
1013
|
+
|
1014
|
+
@c2.one_to_one :child_20, :class => @c2, :key=>:id, :dataset=>proc{|_, *| model.filter(:parent_id=>pk)}
|
1015
|
+
@c2.load(:id => 100).child_20
|
1016
|
+
DB.sqls.must_equal ["SELECT * FROM nodes WHERE (parent_id = 100) LIMIT 1"]
|
1017
|
+
|
1018
|
+
@c2.one_to_one :child_20, :class => @c2, :key=>:id, :dataset=>proc{|*| model.filter(:parent_id=>pk)}
|
1019
|
+
@c2.load(:id => 100).child_20
|
1020
|
+
DB.sqls.must_equal ["SELECT * FROM nodes WHERE (parent_id = 100) LIMIT 1"]
|
1021
|
+
end
|
1022
|
+
|
1023
|
+
deprecated "should support :dataset option that requires multiple arguments" do
|
1024
|
+
@c2.one_to_one :child_20, :class => @c2, :key=>:id, :dataset=>proc{|_, _| model.filter(:parent_id=>pk)}
|
1025
|
+
@c2.load(:id => 100).child_20
|
1026
|
+
DB.sqls.must_equal ["SELECT * FROM nodes WHERE (parent_id = 100) LIMIT 1"]
|
1027
|
+
end
|
1028
|
+
|
1029
|
+
deprecated "should support association block requires no arguments" do
|
1030
|
+
@c2.one_to_one :child_20, :class => @c2, :key=>:id do model.filter(:parent_id=>pk) end
|
1031
|
+
@c2.load(:id => 100).child_20
|
1032
|
+
DB.sqls.must_equal ["SELECT * FROM nodes WHERE (parent_id = 100)"]
|
1033
|
+
end
|
1034
|
+
|
1035
|
+
deprecated "should support association block requires multiple arguments" do
|
1036
|
+
@c2.one_to_one :child_20, :class => @c2, :key=>:id do |_, _| model.filter(:parent_id=>pk) end
|
1037
|
+
@c2.load(:id => 100).child_20
|
1038
|
+
DB.sqls.must_equal ["SELECT * FROM nodes WHERE (parent_id = 100)"]
|
1039
|
+
end
|
1040
|
+
|
961
1041
|
it "should return nil if primary_key value is nil" do
|
962
1042
|
@c2.one_to_one :parent, :class => @c2, :primary_key=>:node_id
|
963
1043
|
|
data/spec/model/plugins_spec.rb
CHANGED
@@ -316,3 +316,114 @@ describe "Sequel::Model.plugin" do
|
|
316
316
|
a.must_equal ['sequel/plugins/something_or_other']
|
317
317
|
end
|
318
318
|
end
|
319
|
+
|
320
|
+
describe "Sequel::Plugins.def_sequel_method" do
|
321
|
+
before do
|
322
|
+
@m = Class.new
|
323
|
+
@scope = @m.new
|
324
|
+
end
|
325
|
+
|
326
|
+
it "should define methods using block" do
|
327
|
+
m0 = Sequel::Plugins.def_sequel_method(@m, "x", 0){1}
|
328
|
+
m0.must_be_kind_of Symbol
|
329
|
+
m0.must_match /\A_sequel_x_\d+\z/
|
330
|
+
@scope.send(m0).must_equal 1
|
331
|
+
|
332
|
+
m1 = Sequel::Plugins.def_sequel_method(@m, "x", 1){|x| [x, 2]}
|
333
|
+
m1.must_be_kind_of Symbol
|
334
|
+
m1.must_match /\A_sequel_x_\d+\z/
|
335
|
+
@scope.send(m1, 3).must_equal [3, 2]
|
336
|
+
end
|
337
|
+
|
338
|
+
it "should define public methods" do
|
339
|
+
proc{@scope.public_send(Sequel::Plugins.def_sequel_method(@m, "x", 0){1})}.must_raise NoMethodError
|
340
|
+
end
|
341
|
+
|
342
|
+
it "should accept symbols as method name and return the same symbol" do
|
343
|
+
m0 = Sequel::Plugins.def_sequel_method(@m, :_roda_foo, 0){1}
|
344
|
+
m0.must_equal :_roda_foo
|
345
|
+
@scope.send(m0).must_equal 1
|
346
|
+
end
|
347
|
+
|
348
|
+
it "should handle optional arguments and splats for expected_arity 0" do
|
349
|
+
m2 = Sequel::Plugins.def_sequel_method(@m, "x", 0){|*x| [x, 3]}
|
350
|
+
@scope.send(m2).must_equal [[], 3]
|
351
|
+
|
352
|
+
m3 = Sequel::Plugins.def_sequel_method(@m, "x", 0){|x=5| [x, 4]}
|
353
|
+
@scope.send(m3).must_equal [5, 4]
|
354
|
+
|
355
|
+
m4 = Sequel::Plugins.def_sequel_method(@m, "x", 0){|x=6, *y| [x, y, 5]}
|
356
|
+
@scope.send(m4).must_equal [6, [], 5]
|
357
|
+
end
|
358
|
+
|
359
|
+
it "should should optional arguments and splats for expected_arity 1" do
|
360
|
+
m2 = Sequel::Plugins.def_sequel_method(@m, "x", 1){|y, *x| [y, x, 3]}
|
361
|
+
@scope.send(m2, :a).must_equal [:a, [], 3]
|
362
|
+
|
363
|
+
m3 = Sequel::Plugins.def_sequel_method(@m, "x", 1){|y, x=5| [y, x, 4]}
|
364
|
+
@scope.send(m3, :b).must_equal [:b, 5, 4]
|
365
|
+
|
366
|
+
m4 = Sequel::Plugins.def_sequel_method(@m, "x", 1){|y, x=6, *z| [y, x, z, 5]}
|
367
|
+
@scope.send(m4, :c).must_equal [:c, 6, [], 5]
|
368
|
+
end
|
369
|
+
|
370
|
+
deprecated "should handle differences in arity" do
|
371
|
+
m0 = Sequel::Plugins.def_sequel_method(@m, "x", 0){|x| [x, 1]}
|
372
|
+
@scope.send(m0).must_equal [nil, 1]
|
373
|
+
|
374
|
+
m1 = Sequel::Plugins.def_sequel_method(@m, "x", 1){2}
|
375
|
+
@scope.send(m1, 3).must_equal 2
|
376
|
+
|
377
|
+
m1 = Sequel::Plugins.def_sequel_method(@m, "x", 1){|x, y| [x, y]}
|
378
|
+
@scope.send(m1, 4).must_equal [4, nil]
|
379
|
+
end
|
380
|
+
|
381
|
+
it "should raise for unexpected expected_arity" do
|
382
|
+
proc{Sequel::Plugins.def_sequel_method(@m, "x", 2){|x|}}.must_raise Sequel::Error
|
383
|
+
end
|
384
|
+
|
385
|
+
it "should fail if a lambda with invalid arity is passed" do
|
386
|
+
m0 = Sequel::Plugins.def_sequel_method(@m, "x", 0, &lambda{|x| [x, 1]})
|
387
|
+
proc{@scope.send(m0)}.must_raise ArgumentError
|
388
|
+
|
389
|
+
m1 = Sequel::Plugins.def_sequel_method(@m, "x", 1, &lambda{2})
|
390
|
+
proc{@scope.send(m1, 1)}.must_raise ArgumentError
|
391
|
+
end
|
392
|
+
|
393
|
+
if RUBY_VERSION > '2.1'
|
394
|
+
it "should raise for required keyword arguments for expected_arity 0 or 1" do
|
395
|
+
proc{eval("Sequel::Plugins.def_sequel_method(@m, 'x', 0){|b:| [b, 1]}", binding)}.must_raise Sequel::Error
|
396
|
+
proc{eval("Sequel::Plugins.def_sequel_method(@m, 'x', 0){|c=1, b:| [c, b, 1]}", binding)}.must_raise Sequel::Error
|
397
|
+
proc{eval("Sequel::Plugins.def_sequel_method(@m, 'x', 1){|x, b:| [b, 1]}", binding)}.must_raise Sequel::Error
|
398
|
+
proc{eval("Sequel::Plugins.def_sequel_method(@m, 'x', 1){|x, c=1, b:| [c, b, 1]}", binding)}.must_raise Sequel::Error
|
399
|
+
end
|
400
|
+
|
401
|
+
it "should ignore keyword arguments for expected_arity 0" do
|
402
|
+
@scope.send(eval("Sequel::Plugins.def_sequel_method(@m, 'x', 0){|b:2| [b, 1]}", binding)).must_equal [2, 1]
|
403
|
+
@scope.send(eval("Sequel::Plugins.def_sequel_method(@m, 'x', 0){|**b| [b, 1]}", binding)).must_equal [{}, 1]
|
404
|
+
@scope.send(eval("Sequel::Plugins.def_sequel_method(@m, 'x', 0){|c=1, b:2| [c, b, 1]}", binding)).must_equal [1, 2, 1]
|
405
|
+
@scope.send(eval("Sequel::Plugins.def_sequel_method(@m, 'x', 0){|c=1, **b| [c, b, 1]}", binding)).must_equal [1, {}, 1]
|
406
|
+
end
|
407
|
+
|
408
|
+
deprecated "should ignore keyword arguments for expected_arity 0 with invalid arity" do
|
409
|
+
@scope.send(eval("Sequel::Plugins.def_sequel_method(@m, 'x', 0){|x, b:2| [x, b, 1]}", binding)).must_equal [nil, 2, 1]
|
410
|
+
@scope.send(eval("Sequel::Plugins.def_sequel_method(@m, 'x', 0){|x, **b| [x, b, 1]}", binding)).must_equal [nil, {}, 1]
|
411
|
+
@scope.send(eval("Sequel::Plugins.def_sequel_method(@m, 'x', 0){|x, c=1, b:2| [x, c, b, 1]}", binding)).must_equal [nil, 1, 2, 1]
|
412
|
+
@scope.send(eval("Sequel::Plugins.def_sequel_method(@m, 'x', 0){|x, c=1, **b| [x, c, b, 1]}", binding)).must_equal [nil, 1, {}, 1]
|
413
|
+
end
|
414
|
+
|
415
|
+
deprecated "should ignore keyword arguments for expected_arity 1 with invalid arity" do
|
416
|
+
@scope.send(eval("Sequel::Plugins.def_sequel_method(@m, 'x', 1){|b:2| [b, 1]}", binding), 3).must_equal [2, 1]
|
417
|
+
@scope.send(eval("Sequel::Plugins.def_sequel_method(@m, 'x', 1){|**b| [b, 1]}", binding), 3).must_equal [{}, 1]
|
418
|
+
end
|
419
|
+
|
420
|
+
it "should ignore keyword arguments for expected_arity 1" do
|
421
|
+
@scope.send(eval("Sequel::Plugins.def_sequel_method(@m, 'x', 1){|c=1, b:2| [c, b, 1]}", binding), 3).must_equal [3, 2, 1]
|
422
|
+
@scope.send(eval("Sequel::Plugins.def_sequel_method(@m, 'x', 1){|c=1, **b| [c, b, 1]}", binding), 3).must_equal [3, {}, 1]
|
423
|
+
@scope.send(eval("Sequel::Plugins.def_sequel_method(@m, 'x', 1){|x, b:2| [x, b, 1]}", binding), 3).must_equal [3, 2, 1]
|
424
|
+
@scope.send(eval("Sequel::Plugins.def_sequel_method(@m, 'x', 1){|x, **b| [x, b, 1]}", binding), 3).must_equal [3, {}, 1]
|
425
|
+
@scope.send(eval("Sequel::Plugins.def_sequel_method(@m, 'x', 1){|x, c=1, b:2| [x, c, b, 1]}", binding), 3).must_equal [3, 1, 2, 1]
|
426
|
+
@scope.send(eval("Sequel::Plugins.def_sequel_method(@m, 'x', 1){|x, c=1, **b| [x, c, b, 1]}", binding), 3).must_equal [3, 1, {}, 1]
|
427
|
+
end
|
428
|
+
end
|
429
|
+
end
|
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.20.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-
|
11
|
+
date: 2019-05-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|
@@ -203,6 +203,7 @@ extra_rdoc_files:
|
|
203
203
|
- doc/release_notes/5.17.0.txt
|
204
204
|
- doc/release_notes/5.18.0.txt
|
205
205
|
- doc/release_notes/5.19.0.txt
|
206
|
+
- doc/release_notes/5.20.0.txt
|
206
207
|
files:
|
207
208
|
- CHANGELOG
|
208
209
|
- MIT-LICENSE
|
@@ -293,6 +294,7 @@ files:
|
|
293
294
|
- doc/release_notes/5.18.0.txt
|
294
295
|
- doc/release_notes/5.19.0.txt
|
295
296
|
- doc/release_notes/5.2.0.txt
|
297
|
+
- doc/release_notes/5.20.0.txt
|
296
298
|
- doc/release_notes/5.3.0.txt
|
297
299
|
- doc/release_notes/5.4.0.txt
|
298
300
|
- doc/release_notes/5.5.0.txt
|