Renamed Positional to Ordered and added tests for Ordered.
Aran Deltac [Fri, 31 Mar 2006 22:28:15 +0000 (22:28 +0000)]
Changes
lib/DBIx/Class/Tree/AdjacencyList/Ordered.pm [moved from lib/DBIx/Class/Tree/AdjacencyList/Positional.pm with 72% similarity]
t/11_adjacencylist_ordered.t [new file with mode: 0644]
t/lib/TreeTest.pm

diff --git a/Changes b/Changes
index 100c94c..934f4aa 100644 (file)
--- a/Changes
+++ b/Changes
@@ -2,6 +2,9 @@
 Revision history for DBIx::Class::Tree
 
 0.01000
+    - Added tests for Ordered.
+    - Renamed Positional as Ordered.
+    - Added tests for AdjacencyList.
     - Moved Positional functionality out of AdjacencyList
       and in to AdjacencyList::Positional.
     - AdjacencyList module created.
@@ -1,5 +1,5 @@
 # vim: ts=8:sw=4:sts=4:et
-package DBIx::Class::Tree::AdjacencyList::Positional;
+package DBIx::Class::Tree::AdjacencyList::Ordered;
 use strict;
 use warnings;
 use base qw( DBIx::Class );
@@ -7,45 +7,45 @@ use Carp qw( croak );
 
 __PACKAGE__->load_components(qw(
     Tree::AdjacencyList
-    Positional
+    Ordered
 ));
 
 =head1 NAME
 
-DBIx::Class::Tree::AdjacencyList::Positional - Glue DBIx::Class::Positional and DBIx::Class::Tree::AdjacencyList together. (EXPERIMENTAL)
+DBIx::Class::Tree::AdjacencyList::Ordered - Glue DBIx::Class::Ordered and DBIx::Class::Tree::AdjacencyList together. (EXPERIMENTAL)
 
 =head1 SYNOPSIS
 
 Create a table for your tree data.
 
-  CREATE TABLE employees (
-    employee_id INTEGER PRIMARY KEY AUTOINCREMENT,
+  CREATE TABLE items (
+    item_id INTEGER PRIMARY KEY AUTOINCREMENT,
     parent_id INTEGER NOT NULL DEFAULT 0,
     position INTEGER NOT NULL,
     name TEXT NOT NULL
   );
 
-In your Schema or DB class add Tree::AdjacencyList::Positional 
+In your Schema or DB class add Tree::AdjacencyList::Ordered 
 to the top of the component list.
 
-  __PACKAGE__->load_components(qw( Tree::AdjacencyList::Positional ... ));
+  __PACKAGE__->load_components(qw( Tree::AdjacencyList::Ordered ... ));
 
 Specify the column that contains the parent ID and position of each row.
 
   package My::Employee;
-  __PACKAGE__->parent_column('parent_id');
   __PACKAGE__->position_column('position');
+  __PACKAGE__->parent_column('parent_id');
 
 This module provides a few extra methods beyond what 
-L<DBIx::Class::Positional> and L<DBIx::Class::Tree::AdjacencyList> 
+L<DBIx::Class::Ordered> and L<DBIx::Class::Tree::AdjacencyList> 
 already provide.
 
-  my $parent = $employee->parent();
-  $employee->set_parent( $parent_obj );
-  $employee->set_parent( $parent_id );
+  my $parent = $item->parent();
+  $item->parent( $parent_obj );
+  $item->parent( $parent_id );
   
-  my $children_rs = $employee->children();
-  my @children = $employee->children();
+  my $children_rs = $item->children();
+  my @children = $item->children();
   
   $parent->append_child( $child );
   $parent->prepend_child( $child );
@@ -55,10 +55,9 @@ already provide.
 
 =head1 DESCRIPTION
 
-This module provides methods for working with adjacency lists and positional 
-rows.  All of the methods that L<DBIx::Class::Positional> and 
-L<DBIx::Class::Tree::AdjacencyList> provide are available with this module.  
-If you 
+This module provides methods for working with adjacency lists and ordered 
+rows.  All of the methods that L<DBIx::Class::Ordered> and 
+L<DBIx::Class::Tree::AdjacencyList> provide are available with this module.
 
 =head1 METHODS
 
@@ -77,8 +76,9 @@ sub parent_column {
     if (@_) {
         my $parent_col = shift;
         my $primary_col = ($class->primary_columns())[0];
+        my $position_col = $class->position_column() || croak('You must call position_column() before calling parent_column()');
         $class->belongs_to( '_parent' => $class => { "foreign.$primary_col" => "self.$parent_col" } );
-        $class->has_many( 'children' => $class => { "foreign.$parent_col" => "self.$primary_col" }, { order_by=>$self->position_column() } );
+        $class->has_many( 'children' => $class => { "foreign.$parent_col" => "self.$primary_col" }, { order_by=>$position_col } );
         $class->_parent_column( $parent_col );
         return 1;
     }
@@ -87,14 +87,15 @@ sub parent_column {
 
 =head2 parent
 
-  my $parent = $employee->parent();
-  $employee->parent( $parent_obj );
-  $employee->parent( $parent_id );
+  my $parent = $item->parent();
+  $item->parent( $parent_obj );
+  $item->parent( $parent_id );
 
 This method overrides AdjacencyList's parent() method but 
 modifies it so that the object is moved to the last position, 
 then the parent is changed, and then it is moved to the last 
-position of the new list.
+position of the new list, thus maintaining the intergrity of 
+the ordered lists.
 
 =cut
 
@@ -112,7 +113,7 @@ sub parent {
         $self->set_column(
             $self->position_column() => 
                 $self->result_source->resultset->search(
-                    {$self->_collection_clause()}
+                    {$self->_grouping_clause()}
                 )->count() + 1
         );
         $self->update();
@@ -123,8 +124,8 @@ sub parent {
 
 =head2 children
 
-  my $children_rs = $employee->children();
-  my @children = $employee->children();
+  my $children_rs = $item->children();
+  my @children = $item->children();
 
 This method works just like it does in the 
 DBIx::Class::Tree::AdjacencyList module except it 
@@ -194,31 +195,31 @@ sub attach_after {
 These methods are used internally.  You should never have the 
 need to use them.
 
-=head2 collection_column
+=head2 grouping_column
 
-Postional's collection_column method does not, and should not, be 
+Postional's grouping_column method does not, and should not, be 
 defined when using this module.  This method just throws out an 
 error if you try to use it.
 
 =cut
 
-sub collection_column {
-    croak('Use parent_column() instead of collection_column()');
+sub grouping_column {
+    croak('Use parent_column() instead of grouping_column()');
 }
 
-=head2 _collection_clause
+=head2 _grouping_clause
 
 This method is provided as an override of the method in 
-L<DBIx::Class::Positional>.  This method is what provides the 
-glue between AdjacencyList and Positional.
+L<DBIx::Class::Ordered>.  This method is what provides the 
+glue between AdjacencyList and Ordered.
 
 =cut
 
-sub _collection_clause {
+sub _grouping_clause {
     my( $self ) = @_;
+    my $col = $self->_parent_column();
     return (
-        $self->_parent_column() =>
-        $self->get_column($self->_parent_column())
+        $col => $self->get_column( $col )
     );
 }
 
diff --git a/t/11_adjacencylist_ordered.t b/t/11_adjacencylist_ordered.t
new file mode 100644 (file)
index 0000000..6c1419e
--- /dev/null
@@ -0,0 +1,20 @@
+# vim: filetype=perl:ts=8:sw=4:sts=4:et
+use strict;
+use warnings;
+use lib 't/lib';
+
+use Test::More;
+use TreeTest;
+
+TreeTest::Schema::Node->load_components(qw(
+    Tree::AdjacencyList::Ordered
+));
+
+TreeTest::Schema::Node->position_column( 'position' );
+TreeTest::Schema::Node->parent_column( 'parent_id' );
+
+my $tests = TreeTest::count_tests();
+plan tests => $tests;
+TreeTest::run_tests();
+
+1;
index 95a0dec..137ea17 100644 (file)
@@ -8,7 +8,11 @@ use TreeTest::Schema;
 our $NODE_COUNT = 80;
 
 sub count_tests {
-    return 11;
+    my $count = 11;
+    if( TreeTest::Schema::Node->can('position_column') ){
+        $count ++;
+    }
+    return $count;
 }
 
 sub run_tests {
@@ -41,6 +45,21 @@ sub run_tests {
     $nodes->find(22)->attach_sibling( $nodes->find(3) );
     ok( ($nodes->find(22)->children->count()==2), 'node 22 has correct number of children' );
     ok( ($nodes->find(22)->siblings->count()==3), 'node 22 has correct number of siblings' );
+
+    if( TreeTest::Schema::Node->can('position_column') ){
+        ok( check_positions(scalar $root->children()), 'positions are correct' );
+    }
+}
+
+sub check_positions {
+    my $nodes = shift;
+    my $position = 0;
+    while (my $node = $nodes->next()) {
+        $position ++;
+        return 0 if ($node->position() != $position);
+        return 0 if ( !check_positions(scalar $node->children()) );
+    }
+    return 1;
 }
 
 1;