sequel 5.19.0 → 5.20.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|