sequel 4.2.0 → 4.3.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 +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
|
|