sequel 4.2.0 → 4.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +28 -0
- data/doc/extensions.rdoc +84 -0
- data/doc/model_plugins.rdoc +270 -0
- data/doc/release_notes/4.3.0.txt +40 -0
- data/doc/testing.rdoc +3 -0
- data/lib/sequel/adapters/jdbc/as400.rb +4 -0
- data/lib/sequel/adapters/shared/mysql.rb +6 -1
- data/lib/sequel/adapters/shared/postgres.rb +2 -0
- data/lib/sequel/ast_transformer.rb +2 -0
- data/lib/sequel/extensions/error_sql.rb +71 -0
- data/lib/sequel/extensions/migration.rb +0 -1
- data/lib/sequel/extensions/pagination.rb +6 -2
- data/lib/sequel/extensions/pg_array.rb +12 -5
- data/lib/sequel/extensions/pg_hstore.rb +5 -3
- data/lib/sequel/extensions/pg_inet.rb +3 -3
- data/lib/sequel/extensions/pg_interval.rb +3 -3
- data/lib/sequel/extensions/pg_json.rb +3 -3
- data/lib/sequel/extensions/pg_range.rb +3 -3
- data/lib/sequel/extensions/pg_row.rb +3 -3
- data/lib/sequel/extensions/server_block.rb +11 -3
- data/lib/sequel/plugins/rcte_tree.rb +59 -39
- data/lib/sequel/plugins/tree.rb +13 -6
- data/lib/sequel/sql.rb +1 -1
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/postgres_spec.rb +17 -0
- data/spec/core/dataset_spec.rb +14 -0
- data/spec/core/schema_spec.rb +1 -0
- data/spec/extensions/error_sql_spec.rb +20 -0
- data/spec/extensions/migration_spec.rb +15 -0
- data/spec/extensions/pagination_spec.rb +19 -0
- data/spec/extensions/pg_array_spec.rb +3 -2
- data/spec/extensions/rcte_tree_spec.rb +135 -0
- data/spec/extensions/tree_spec.rb +130 -0
- data/spec/integration/database_test.rb +5 -0
- data/spec/integration/dataset_test.rb +4 -0
- data/spec/integration/plugin_test.rb +163 -177
- data/spec/integration/spec_helper.rb +4 -0
- metadata +10 -2
@@ -24,6 +24,11 @@ describe Sequel::Database do
|
|
24
24
|
proc{@db << "SELECT"}.should raise_error(Sequel::DatabaseError)
|
25
25
|
end
|
26
26
|
|
27
|
+
specify "should have Sequel::DatabaseError#sql give the SQL causing the error" do
|
28
|
+
(@db << "SELECT") rescue (e = $!)
|
29
|
+
e.sql.should == "SELECT"
|
30
|
+
end if ENV['SEQUEL_ERROR_SQL']
|
31
|
+
|
27
32
|
describe "constraint violations" do
|
28
33
|
before do
|
29
34
|
@db.drop_table?(:test2, :test)
|
@@ -371,6 +371,10 @@ describe Sequel::Database do
|
|
371
371
|
DB.get(Sequel.cast(Sequel.blob("\1\2\3"), File).as(:a)).should == "\1\2\3"
|
372
372
|
end
|
373
373
|
|
374
|
+
cspecify "should properly handle empty blobs", [:jdbc, :hsqldb], :oracle do
|
375
|
+
DB.get(Sequel.cast(Sequel.blob(""), File).as(:a)).should == ""
|
376
|
+
end
|
377
|
+
|
374
378
|
cspecify "should properly escape identifiers", :db2, :oracle do
|
375
379
|
DB.create_table(:"\\'\"[]"){Integer :id}
|
376
380
|
DB.drop_table(:"\\'\"[]")
|
@@ -705,43 +705,8 @@ describe "Composition plugin" do
|
|
705
705
|
end
|
706
706
|
end
|
707
707
|
|
708
|
-
|
709
|
-
|
710
|
-
describe "RcteTree Plugin" do
|
711
|
-
before(:all) do
|
712
|
-
@db = DB
|
713
|
-
@db.create_table!(:nodes) do
|
714
|
-
primary_key :id
|
715
|
-
Integer :parent_id
|
716
|
-
String :name
|
717
|
-
end
|
718
|
-
class ::Node < Sequel::Model(@db)
|
719
|
-
plugin :rcte_tree, :order=>:name
|
720
|
-
end
|
721
|
-
|
722
|
-
@nodes = []
|
723
|
-
@nodes << @a = Node.create(:name=>'a')
|
724
|
-
@nodes << @b = Node.create(:name=>'b')
|
725
|
-
@nodes << @aa = Node.create(:name=>'aa', :parent=>@a)
|
726
|
-
@nodes << @ab = Node.create(:name=>'ab', :parent=>@a)
|
727
|
-
@nodes << @ba = Node.create(:name=>'ba', :parent=>@b)
|
728
|
-
@nodes << @bb = Node.create(:name=>'bb', :parent=>@b)
|
729
|
-
@nodes << @aaa = Node.create(:name=>'aaa', :parent=>@aa)
|
730
|
-
@nodes << @aab = Node.create(:name=>'aab', :parent=>@aa)
|
731
|
-
@nodes << @aba = Node.create(:name=>'aba', :parent=>@ab)
|
732
|
-
@nodes << @abb = Node.create(:name=>'abb', :parent=>@ab)
|
733
|
-
@nodes << @aaaa = Node.create(:name=>'aaaa', :parent=>@aaa)
|
734
|
-
@nodes << @aaab = Node.create(:name=>'aaab', :parent=>@aaa)
|
735
|
-
@nodes << @aaaaa = Node.create(:name=>'aaaaa', :parent=>@aaaa)
|
736
|
-
end
|
737
|
-
before do
|
738
|
-
@nodes.each{|n| n.associations.clear}
|
739
|
-
end
|
740
|
-
after(:all) do
|
741
|
-
@db.drop_table? :nodes
|
742
|
-
Object.send(:remove_const, :Node)
|
743
|
-
end
|
744
|
-
|
708
|
+
describe "RcteTree Plugin" do
|
709
|
+
shared_examples_for "rcte tree plugin" do
|
745
710
|
specify "should load all standard (not-CTE) methods correctly" do
|
746
711
|
@a.children.should == [@aa, @ab]
|
747
712
|
@b.children.should == [@ba, @bb]
|
@@ -803,7 +768,7 @@ if DB.dataset.supports_cte? and !Sequel.guarded?(:db2)
|
|
803
768
|
end
|
804
769
|
|
805
770
|
specify "should eagerly load all ancestors and descendants for a dataset" do
|
806
|
-
nodes = Node.filter(
|
771
|
+
nodes = @Node.filter(@Node.primary_key=>[@a.pk, @b.pk, @aaa.pk]).order(:name).eager(:ancestors, :descendants).all
|
807
772
|
nodes.should == [@a, @aaa, @b]
|
808
773
|
nodes[0].descendants.should == [@aa, @aaa, @aaaa, @aaaaa, @aaab, @aab, @ab, @aba, @abb]
|
809
774
|
nodes[1].descendants.should == [@aaaa, @aaaaa, @aaab]
|
@@ -813,26 +778,14 @@ if DB.dataset.supports_cte? and !Sequel.guarded?(:db2)
|
|
813
778
|
nodes[2].ancestors.should == []
|
814
779
|
end
|
815
780
|
|
816
|
-
specify "should work correctly if not all columns are selected" do
|
817
|
-
c = Class.new(Sequel::Model(@db[:nodes]))
|
818
|
-
c.plugin :rcte_tree, :order=>:name
|
819
|
-
c.plugin :lazy_attributes, :name
|
820
|
-
c[:name=>'aaaa'].descendants.should == [c.load(:parent_id=>11, :id=>13)]
|
821
|
-
c[:name=>'aa'].ancestors.should == [c.load(:parent_id=>nil, :id=>1)]
|
822
|
-
nodes = c.filter(:id=>[@a.id, @b.id, @aaa.id]).order(:name).eager(:ancestors, :descendants).all
|
823
|
-
nodes.should == [{:parent_id=>nil, :id=>1}, {:parent_id=>3, :id=>7}, {:parent_id=>nil, :id=>2}].map{|x| c.load(x)}
|
824
|
-
nodes[2].descendants.should == [{:parent_id=>2, :id=>5}, {:parent_id=>2, :id=>6}].map{|x| c.load(x)}
|
825
|
-
nodes[1].ancestors.should == [{:parent_id=>nil, :id=>1}, {:parent_id=>1, :id=>3}].map{|x| c.load(x)}
|
826
|
-
end
|
827
|
-
|
828
781
|
specify "should eagerly load descendants to a given level" do
|
829
|
-
nodes = Node.filter(
|
782
|
+
nodes = @Node.filter(@Node.primary_key=>[@a.pk, @b.pk, @aaa.pk]).order(:name).eager(:descendants=>1).all
|
830
783
|
nodes.should == [@a, @aaa, @b]
|
831
784
|
nodes[0].descendants.should == [@aa, @ab]
|
832
785
|
nodes[1].descendants.should == [@aaaa, @aaab]
|
833
786
|
nodes[2].descendants.should == [@ba, @bb]
|
834
787
|
|
835
|
-
nodes = Node.filter(
|
788
|
+
nodes = @Node.filter(@Node.primary_key=>[@a.pk, @b.pk, @aaa.pk]).order(:name).eager(:descendants=>2).all
|
836
789
|
nodes.should == [@a, @aaa, @b]
|
837
790
|
nodes[0].descendants.should == [@aa, @aaa, @aab, @ab, @aba, @abb]
|
838
791
|
nodes[1].descendants.should == [@aaaa, @aaaaa, @aaab]
|
@@ -840,7 +793,7 @@ if DB.dataset.supports_cte? and !Sequel.guarded?(:db2)
|
|
840
793
|
end
|
841
794
|
|
842
795
|
specify "should populate all :children associations when eagerly loading descendants for a dataset" do
|
843
|
-
nodes = Node.filter(
|
796
|
+
nodes = @Node.filter(@Node.primary_key=>[@a.pk, @b.pk, @aaa.pk]).order(:name).eager(:descendants).all
|
844
797
|
nodes[0].associations[:children].should == [@aa, @ab]
|
845
798
|
nodes[1].associations[:children].should == [@aaaa, @aaab]
|
846
799
|
nodes[2].associations[:children].should == [@ba, @bb]
|
@@ -854,7 +807,7 @@ if DB.dataset.supports_cte? and !Sequel.guarded?(:db2)
|
|
854
807
|
end
|
855
808
|
|
856
809
|
specify "should not populate :children associations for final level when loading descendants to a given level" do
|
857
|
-
nodes = Node.filter(
|
810
|
+
nodes = @Node.filter(@Node.primary_key=>[@a.pk, @b.pk, @aaa.pk]).order(:name).eager(:descendants=>1).all
|
858
811
|
nodes[0].associations[:children].should == [@aa, @ab]
|
859
812
|
nodes[0].associations[:children].map{|c1| c1.associations[:children]}.should == [nil, nil]
|
860
813
|
nodes[1].associations[:children].should == [@aaaa, @aaab]
|
@@ -866,7 +819,7 @@ if DB.dataset.supports_cte? and !Sequel.guarded?(:db2)
|
|
866
819
|
nodes[1].associations[:children].map{|c1| c1.children}.should == [[@aaaaa], []]
|
867
820
|
nodes[2].associations[:children].map{|c1| c1.children}.should == [[], []]
|
868
821
|
|
869
|
-
nodes = Node.filter(
|
822
|
+
nodes = @Node.filter(@Node.primary_key=>[@a.pk, @b.pk, @aaa.pk]).order(:name).eager(:descendants=>2).all
|
870
823
|
nodes[0].associations[:children].should == [@aa, @ab]
|
871
824
|
nodes[0].associations[:children].map{|c1| c1.associations[:children]}.should == [[@aaa, @aab], [@aba, @abb]]
|
872
825
|
nodes[0].associations[:children].map{|c1| c1.associations[:children].map{|c2| c2.associations[:children]}}.should == [[[@aaaa, @aaab], nil], [nil, nil]]
|
@@ -904,7 +857,7 @@ if DB.dataset.supports_cte? and !Sequel.guarded?(:db2)
|
|
904
857
|
end
|
905
858
|
|
906
859
|
specify "should populate all :parent associations when eagerly loading ancestors for a dataset" do
|
907
|
-
nodes = Node.filter(
|
860
|
+
nodes = @Node.filter(@Node.primary_key=>[@a.pk, @ba.pk, @aaa.pk, @aaaaa.pk]).order(:name).eager(:ancestors).all
|
908
861
|
nodes[0].associations.fetch(:parent, 1).should == nil
|
909
862
|
nodes[1].associations[:parent].should == @aa
|
910
863
|
nodes[1].associations[:parent].associations[:parent].should == @a
|
@@ -937,7 +890,91 @@ if DB.dataset.supports_cte? and !Sequel.guarded?(:db2)
|
|
937
890
|
@aaaaa.associations[:parent].associations[:parent].associations[:parent].associations[:parent].associations.fetch(:parent, 1).should == nil
|
938
891
|
end
|
939
892
|
end
|
940
|
-
|
893
|
+
|
894
|
+
before do
|
895
|
+
@nodes.each{|n| n.associations.clear}
|
896
|
+
end
|
897
|
+
|
898
|
+
describe "with single key" do
|
899
|
+
before(:all) do
|
900
|
+
@db = DB
|
901
|
+
@db.create_table!(:nodes) do
|
902
|
+
primary_key :id
|
903
|
+
Integer :parent_id
|
904
|
+
String :name
|
905
|
+
end
|
906
|
+
@Node = Class.new(Sequel::Model(@db[:nodes]))
|
907
|
+
@Node.plugin :rcte_tree, :order=>:name
|
908
|
+
@nodes = []
|
909
|
+
@nodes << @a = @Node.create(:name=>'a')
|
910
|
+
@nodes << @b = @Node.create(:name=>'b')
|
911
|
+
@nodes << @aa = @Node.create(:name=>'aa', :parent=>@a)
|
912
|
+
@nodes << @ab = @Node.create(:name=>'ab', :parent=>@a)
|
913
|
+
@nodes << @ba = @Node.create(:name=>'ba', :parent=>@b)
|
914
|
+
@nodes << @bb = @Node.create(:name=>'bb', :parent=>@b)
|
915
|
+
@nodes << @aaa = @Node.create(:name=>'aaa', :parent=>@aa)
|
916
|
+
@nodes << @aab = @Node.create(:name=>'aab', :parent=>@aa)
|
917
|
+
@nodes << @aba = @Node.create(:name=>'aba', :parent=>@ab)
|
918
|
+
@nodes << @abb = @Node.create(:name=>'abb', :parent=>@ab)
|
919
|
+
@nodes << @aaaa = @Node.create(:name=>'aaaa', :parent=>@aaa)
|
920
|
+
@nodes << @aaab = @Node.create(:name=>'aaab', :parent=>@aaa)
|
921
|
+
@nodes << @aaaaa = @Node.create(:name=>'aaaaa', :parent=>@aaaa)
|
922
|
+
end
|
923
|
+
after(:all) do
|
924
|
+
@db.drop_table? :nodes
|
925
|
+
end
|
926
|
+
|
927
|
+
it_should_behave_like "rcte tree plugin"
|
928
|
+
|
929
|
+
specify "should work correctly if not all columns are selected" do
|
930
|
+
c = Class.new(Sequel::Model(@db[:nodes]))
|
931
|
+
c.plugin :rcte_tree, :order=>:name
|
932
|
+
c.plugin :lazy_attributes, :name
|
933
|
+
c[:name=>'aaaa'].descendants.should == [c.load(:parent_id=>11, :id=>13)]
|
934
|
+
c[:name=>'aa'].ancestors.should == [c.load(:parent_id=>nil, :id=>1)]
|
935
|
+
nodes = c.filter(:id=>[@a.id, @b.id, @aaa.id]).order(:name).eager(:ancestors, :descendants).all
|
936
|
+
nodes.should == [{:parent_id=>nil, :id=>1}, {:parent_id=>3, :id=>7}, {:parent_id=>nil, :id=>2}].map{|x| c.load(x)}
|
937
|
+
nodes[2].descendants.should == [{:parent_id=>2, :id=>5}, {:parent_id=>2, :id=>6}].map{|x| c.load(x)}
|
938
|
+
nodes[1].ancestors.should == [{:parent_id=>nil, :id=>1}, {:parent_id=>1, :id=>3}].map{|x| c.load(x)}
|
939
|
+
end
|
940
|
+
end
|
941
|
+
|
942
|
+
describe "with composite keys" do
|
943
|
+
before(:all) do
|
944
|
+
@db = DB
|
945
|
+
@db.create_table!(:nodes) do
|
946
|
+
Integer :id
|
947
|
+
Integer :id2
|
948
|
+
Integer :parent_id
|
949
|
+
Integer :parent_id2
|
950
|
+
String :name
|
951
|
+
primary_key [:id, :id2]
|
952
|
+
end
|
953
|
+
@Node = Class.new(Sequel::Model(@db[:nodes]))
|
954
|
+
@Node.plugin :rcte_tree, :order=>:name, :key=>[:parent_id, :parent_id2]
|
955
|
+
@Node.unrestrict_primary_key
|
956
|
+
@nodes = []
|
957
|
+
@nodes << @a = @Node.create(:id=>1, :id2=>1, :name=>'a')
|
958
|
+
@nodes << @b = @Node.create(:id=>1, :id2=>2, :name=>'b')
|
959
|
+
@nodes << @aa = @Node.create(:id=>2, :id2=>1, :name=>'aa', :parent=>@a)
|
960
|
+
@nodes << @ab = @Node.create(:id=>2, :id2=>2, :name=>'ab', :parent=>@a)
|
961
|
+
@nodes << @ba = @Node.create(:id=>3, :id2=>1, :name=>'ba', :parent=>@b)
|
962
|
+
@nodes << @bb = @Node.create(:id=>3, :id2=>2, :name=>'bb', :parent=>@b)
|
963
|
+
@nodes << @aaa = @Node.create(:id=>3, :id2=>3, :name=>'aaa', :parent=>@aa)
|
964
|
+
@nodes << @aab = @Node.create(:id=>1, :id2=>3, :name=>'aab', :parent=>@aa)
|
965
|
+
@nodes << @aba = @Node.create(:id=>2, :id2=>3, :name=>'aba', :parent=>@ab)
|
966
|
+
@nodes << @abb = @Node.create(:id=>4, :id2=>1, :name=>'abb', :parent=>@ab)
|
967
|
+
@nodes << @aaaa = @Node.create(:id=>1, :id2=>4, :name=>'aaaa', :parent=>@aaa)
|
968
|
+
@nodes << @aaab = @Node.create(:id=>2, :id2=>4, :name=>'aaab', :parent=>@aaa)
|
969
|
+
@nodes << @aaaaa = @Node.create(:id=>3, :id2=>4, :name=>'aaaaa', :parent=>@aaaa)
|
970
|
+
end
|
971
|
+
after(:all) do
|
972
|
+
@db.drop_table? :nodes
|
973
|
+
end
|
974
|
+
|
975
|
+
it_should_behave_like "rcte tree plugin"
|
976
|
+
end
|
977
|
+
end if DB.dataset.supports_cte? and !Sequel.guarded?(:db2)
|
941
978
|
|
942
979
|
describe "Instance Filters plugin" do
|
943
980
|
before(:all) do
|
@@ -1538,167 +1575,116 @@ describe "List plugin with a scope" do
|
|
1538
1575
|
end
|
1539
1576
|
|
1540
1577
|
describe "Sequel::Plugins::Tree" do
|
1541
|
-
|
1542
|
-
@db = DB
|
1543
|
-
end
|
1544
|
-
|
1545
|
-
describe "with natural database order" do
|
1546
|
-
before(:all) do
|
1547
|
-
@db.create_table!(:nodes) do
|
1548
|
-
Integer :id, :primary_key=>true
|
1549
|
-
String :name
|
1550
|
-
Integer :parent_id
|
1551
|
-
Integer :position
|
1552
|
-
end
|
1553
|
-
|
1554
|
-
@nodes = [{:id => 1, :name => 'one', :parent_id => nil, :position => 1},
|
1555
|
-
{:id => 2, :name => 'two', :parent_id => nil, :position => 2},
|
1556
|
-
{:id => 3, :name => 'three', :parent_id => nil, :position => 3},
|
1557
|
-
{:id => 4, :name => "two.one", :parent_id => 2, :position => 1},
|
1558
|
-
{:id => 5, :name => "two.two", :parent_id => 2, :position => 2},
|
1559
|
-
{:id => 6, :name => "two.two.one", :parent_id => 5, :position => 1},
|
1560
|
-
{:id => 7, :name => "one.two", :parent_id => 1, :position => 2},
|
1561
|
-
{:id => 8, :name => "one.one", :parent_id => 1, :position => 1},
|
1562
|
-
{:id => 9, :name => "five", :parent_id => nil, :position => 5},
|
1563
|
-
{:id => 10, :name => "four", :parent_id => nil, :position => 4},
|
1564
|
-
{:id => 11, :name => "five.one", :parent_id => 9, :position => 1},
|
1565
|
-
{:id => 12, :name => "two.three", :parent_id => 2, :position => 3}]
|
1566
|
-
@nodes.each{|node| @db[:nodes].insert(node)}
|
1567
|
-
|
1568
|
-
class ::Node < Sequel::Model
|
1569
|
-
plugin :tree
|
1570
|
-
end
|
1571
|
-
end
|
1572
|
-
after(:all) do
|
1573
|
-
@db.drop_table?(:nodes)
|
1574
|
-
Object.send(:remove_const, :Node)
|
1575
|
-
end
|
1576
|
-
|
1578
|
+
shared_examples_for "tree plugin" do
|
1577
1579
|
it "should instantiate" do
|
1578
|
-
Node.all.size.should == 12
|
1579
|
-
end
|
1580
|
-
|
1581
|
-
it "should find top level nodes" do
|
1582
|
-
Node.roots_dataset.count.should == 5
|
1580
|
+
@Node.all.size.should == 12
|
1583
1581
|
end
|
1584
1582
|
|
1585
1583
|
it "should find all descendants of a node" do
|
1586
|
-
|
1587
|
-
two.name.should == "two"
|
1588
|
-
two.descendants.map{|m| m[:id]}.should == [4, 5, 12, 6]
|
1584
|
+
@Node.find(:name => 'two').descendants.map{|m| m.name}.should == %w'two.one two.two two.three two.two.one'
|
1589
1585
|
end
|
1590
1586
|
|
1591
1587
|
it "should find all ancestors of a node" do
|
1592
|
-
|
1593
|
-
twotwoone.name.should == "two.two.one"
|
1594
|
-
twotwoone.ancestors.map{|m| m[:id]}.should == [5, 2]
|
1588
|
+
@Node.find(:name => "two.two.one").ancestors.map{|m| m.name}.should == %w'two.two two'
|
1595
1589
|
end
|
1596
1590
|
|
1597
1591
|
it "should find all siblings of a node, excepting self" do
|
1598
|
-
|
1599
|
-
twoone.name.should == "two.one"
|
1600
|
-
twoone.siblings.map{|m| m[:id]}.should == [5, 12]
|
1592
|
+
@Node.find(:name=>"two.one").siblings.map{|m| m.name}.should == %w'two.two two.three'
|
1601
1593
|
end
|
1602
1594
|
|
1603
1595
|
it "should find all siblings of a node, including self" do
|
1604
|
-
|
1605
|
-
twoone.name.should == "two.one"
|
1606
|
-
twoone.self_and_siblings.map{|m| m[:id]}.should == [4, 5, 12]
|
1596
|
+
@Node.find(:name=>"two.one").self_and_siblings.map{|m| m.name}.should == %w'two.one two.two two.three'
|
1607
1597
|
end
|
1608
1598
|
|
1609
1599
|
it "should find siblings for root nodes" do
|
1610
|
-
|
1611
|
-
three.name.should == "three"
|
1612
|
-
three.self_and_siblings.map{|m| m[:id]}.should == [1, 2, 3, 9, 10]
|
1600
|
+
@Node.find(:name=>'three').self_and_siblings.map{|m| m.name}.should == %w'one two three four five'
|
1613
1601
|
end
|
1614
1602
|
|
1615
1603
|
it "should find correct root for a node" do
|
1616
|
-
|
1617
|
-
|
1618
|
-
|
1619
|
-
|
1620
|
-
three = Node.find(:id => 3)
|
1621
|
-
three.name.should == "three"
|
1622
|
-
three.root[:id].should == 3
|
1623
|
-
|
1624
|
-
fiveone = Node.find(:id => 11)
|
1625
|
-
fiveone.name.should == "five.one"
|
1626
|
-
fiveone.root[:id].should == 9
|
1604
|
+
@Node.find(:name=>"two.two.one").root.name.should == 'two'
|
1605
|
+
@Node.find(:name=>"three").root.name.should == 'three'
|
1606
|
+
@Node.find(:name=>"five.one").root.name.should == 'five'
|
1627
1607
|
end
|
1628
1608
|
|
1629
|
-
it "iterate top-level nodes in
|
1630
|
-
Node.roots_dataset.count.should == 5
|
1631
|
-
Node.roots.
|
1609
|
+
it "iterate top-level nodes in order" do
|
1610
|
+
@Node.roots_dataset.count.should == 5
|
1611
|
+
@Node.roots.map{|p| p.name}.should == %w'one two three four five'
|
1632
1612
|
end
|
1633
1613
|
|
1634
1614
|
it "should have children" do
|
1635
|
-
|
1636
|
-
one.name.should == "one"
|
1637
|
-
one.children.size.should == 2
|
1638
|
-
end
|
1639
|
-
|
1640
|
-
it "children should be natural database order" do
|
1641
|
-
one = Node.find(:id => 1)
|
1642
|
-
one.name.should == "one"
|
1643
|
-
one.children.map{|m| m[:position]}.should == [2, 1]
|
1615
|
+
@Node.find(:name=>'one').children.map{|m| m.name}.should == %w'one.one one.two'
|
1644
1616
|
end
|
1617
|
+
end
|
1645
1618
|
|
1646
|
-
|
1647
|
-
|
1648
|
-
|
1649
|
-
|
1650
|
-
|
1651
|
-
|
1652
|
-
|
1653
|
-
|
1619
|
+
describe "with simple key" do
|
1620
|
+
before(:all) do
|
1621
|
+
@db = DB
|
1622
|
+
@db.create_table!(:nodes) do
|
1623
|
+
Integer :id, :primary_key=>true
|
1624
|
+
String :name
|
1625
|
+
Integer :parent_id
|
1626
|
+
Integer :position
|
1654
1627
|
end
|
1655
1628
|
|
1656
|
-
|
1657
|
-
|
1658
|
-
|
1659
|
-
|
1629
|
+
@nodes = [{:id => 1, :name => 'one', :parent_id => nil, :position => 1},
|
1630
|
+
{:id => 2, :name => 'two', :parent_id => nil, :position => 2},
|
1631
|
+
{:id => 3, :name => 'three', :parent_id => nil, :position => 3},
|
1632
|
+
{:id => 4, :name => "two.one", :parent_id => 2, :position => 1},
|
1633
|
+
{:id => 5, :name => "two.two", :parent_id => 2, :position => 2},
|
1634
|
+
{:id => 6, :name => "two.two.one", :parent_id => 5, :position => 1},
|
1635
|
+
{:id => 7, :name => "one.two", :parent_id => 1, :position => 2},
|
1636
|
+
{:id => 8, :name => "one.one", :parent_id => 1, :position => 1},
|
1637
|
+
{:id => 9, :name => "five", :parent_id => nil, :position => 5},
|
1638
|
+
{:id => 10, :name => "four", :parent_id => nil, :position => 4},
|
1639
|
+
{:id => 11, :name => "five.one", :parent_id => 9, :position => 1},
|
1640
|
+
{:id => 12, :name => "two.three", :parent_id => 2, :position => 3}]
|
1641
|
+
@nodes.each{|node| @db[:nodes].insert(node)}
|
1660
1642
|
|
1661
|
-
|
1662
|
-
|
1663
|
-
|
1664
|
-
|
1665
|
-
|
1643
|
+
@Node = Class.new(Sequel::Model(:nodes))
|
1644
|
+
@Node.plugin :tree, :order=>:position
|
1645
|
+
end
|
1646
|
+
after(:all) do
|
1647
|
+
@db.drop_table?(:nodes)
|
1666
1648
|
end
|
1649
|
+
|
1650
|
+
it_should_behave_like "tree plugin"
|
1667
1651
|
end
|
1668
1652
|
|
1669
|
-
describe "
|
1653
|
+
describe "with composite key" do
|
1670
1654
|
before(:all) do
|
1671
|
-
@db
|
1672
|
-
|
1655
|
+
@db = DB
|
1656
|
+
@db.create_table!(:nodes) do
|
1657
|
+
Integer :id
|
1658
|
+
Integer :id2
|
1673
1659
|
String :name
|
1674
|
-
Integer :
|
1675
|
-
Integer :
|
1660
|
+
Integer :parent_id
|
1661
|
+
Integer :parent_id2
|
1662
|
+
Integer :position
|
1663
|
+
primary_key [:id, :id2]
|
1676
1664
|
end
|
1677
1665
|
|
1678
|
-
@
|
1679
|
-
{:id => 2, :name => '
|
1680
|
-
{:id =>
|
1681
|
-
{:id =>
|
1682
|
-
|
1666
|
+
@nodes = [{:id => 1, :id2=> 1, :name => 'one', :parent_id => nil, :parent_id2 => nil, :position => 1},
|
1667
|
+
{:id => 2, :id2=> 1, :name => 'two', :parent_id => nil, :parent_id2 => nil, :position => 2},
|
1668
|
+
{:id => 1, :id2=> 2, :name => 'three', :parent_id => nil, :parent_id2 => nil, :position => 3},
|
1669
|
+
{:id => 2, :id2=> 2, :name => "two.one", :parent_id => 2, :parent_id2 => 1, :position => 1},
|
1670
|
+
{:id => 3, :id2=> 1, :name => "two.two", :parent_id => 2, :parent_id2 => 1, :position => 2},
|
1671
|
+
{:id => 3, :id2=> 2, :name => "two.two.one", :parent_id => 3, :parent_id2 => 1, :position => 1},
|
1672
|
+
{:id => 3, :id2=> 3, :name => "one.two", :parent_id => 1, :parent_id2 => 1, :position => 2},
|
1673
|
+
{:id => 1, :id2=> 3, :name => "one.one", :parent_id => 1, :parent_id2 => 1, :position => 1},
|
1674
|
+
{:id => 2, :id2=> 3, :name => "five", :parent_id => nil, :parent_id2 => nil, :position => 5},
|
1675
|
+
{:id => 4, :id2=> 1, :name => "four", :parent_id => nil, :parent_id2 => nil, :position => 4},
|
1676
|
+
{:id => 1, :id2=> 4, :name => "five.one", :parent_id => 2, :parent_id2 => 3, :position => 1},
|
1677
|
+
{:id => 2, :id2=> 4, :name => "two.three", :parent_id => 2, :parent_id2 => 1, :position => 3}]
|
1678
|
+
@nodes.each{|node| @db[:nodes].insert(node)}
|
1683
1679
|
|
1684
|
-
|
1685
|
-
|
1686
|
-
end
|
1680
|
+
@Node = Class.new(Sequel::Model(:nodes))
|
1681
|
+
@Node.plugin :tree, :order=>:position, :key=>[:parent_id, :parent_id2]
|
1687
1682
|
end
|
1688
1683
|
after(:all) do
|
1689
|
-
@db.drop_table?(:
|
1690
|
-
Object.send(:remove_const, :Lorem)
|
1691
|
-
end
|
1692
|
-
|
1693
|
-
it "iterate top-level nodes in order by position" do
|
1694
|
-
Lorem.roots_dataset.count.should == 2
|
1695
|
-
Lorem.roots.inject([]){|ids, p| ids << p.neque}.should == [3, 4]
|
1684
|
+
@db.drop_table?(:nodes)
|
1696
1685
|
end
|
1697
1686
|
|
1698
|
-
|
1699
|
-
one = Lorem.find(:id => 2)
|
1700
|
-
one.children.map{|m| m[:neque]}.should == [1, 2]
|
1701
|
-
end
|
1687
|
+
it_should_behave_like "tree plugin"
|
1702
1688
|
end
|
1703
1689
|
end
|
1704
1690
|
|