Moved Positional code to a separate module.
Aran Deltac [Mon, 27 Mar 2006 21:12:07 +0000 (21:12 +0000)]
Build.PL
Changes
lib/DBIx/Class/Tree/AdjacencyList.pm
lib/DBIx/Class/Tree/AdjacencyList/Positional.pm [new file with mode: 0644]
t/01_pod.t [moved from t/01pod.t with 100% similarity]

index de8c300..27dabe7 100644 (file)
--- a/Build.PL
+++ b/Build.PL
@@ -6,7 +6,7 @@ my %arguments = (
     license            => 'perl',
     module_name        => 'DBIx::Class::Tree',
     requires           => {
-        'DBIx::Class'               => 0.07,
+        'DBIx::Class'               => 0.05,
     },
     build_requires      => {
         'DBD::SQLite'               => 1.11,
diff --git a/Changes b/Changes
index 8909281..100c94c 100644 (file)
--- a/Changes
+++ b/Changes
@@ -2,6 +2,8 @@
 Revision history for DBIx::Class::Tree
 
 0.01000
+    - Moved Positional functionality out of AdjacencyList
+      and in to AdjacencyList::Positional.
     - AdjacencyList module created.
     - First version.
 
index 93ccb16..4ceada2 100644 (file)
@@ -23,11 +23,8 @@ In your Schema or DB class add Tree::AdjacencyList to the top
 of the component list.
 
   __PACKAGE__->load_components(qw( Tree::AdjacencyList ... ));
-  # If you want positionable data make sure this 
-  # module comes first, as in:
-  __PACKAGE__->load_components(qw( Tree::AdjacencyList Positional ... ));
 
-Specify the column that contains the parent ID each row.
+Specify the column that contains the parent ID of each row.
 
   package My::Employee;
   __PACKAGE__->parent_column('parent_id');
@@ -64,9 +61,6 @@ other rows.
 Declares the name of the column that contains the self-referential 
 ID which defines the parent row.  Defaults to "parent_id".
 
-If you are useing the L<DBIx::Class::Positional> component then this 
-parent_column will automatically be used as the collection_column.
-
 =cut
 
 __PACKAGE__->mk_classdata( 'parent_column' => 'parent_id' );
@@ -82,12 +76,6 @@ parent ID.  If setting the parent ID then 0 will be returned
 if the object already has the specified parent, and 1 on 
 success.
 
-If you are using the L<DBIx::Class::Positional> component this 
-module will first move the object to the last position of 
-the list, change the parent ID, then move the object to the 
-last position of the new list.  This ensures the intergrity 
-of the positions.
-
 =cut
 
 sub parent {
@@ -98,13 +86,7 @@ sub parent {
             $new_parent = $new_parent->id() || 0;
         }
         return 0 if ($new_parent == ($self->get_column($parent_column)||0));
-        $self->move_last() if ($self->positional());
         $self->set_column( $parent_column => $new_parent );
-        if ($self->positional()) {
-            $self->set_column(
-                $self->position_column() => $self->search( {$self->_collection_clause()} )->count() + 1
-            );
-        }
         $self->update();
         return 1;
     }
@@ -121,16 +103,12 @@ sub parent {
 Returns a list or record set, depending on context, of all 
 the objects one level below the current one.
 
-If you are using the L<DBIx::Class::Positional> component then this method 
-will return the children sorted by the position column.
-
 =cut
 
 sub children {
     my( $self ) = @_;
     my $rs = $self->search(
-        { $self->parent_column()=>$self->id() },
-        ( $self->isa('DBIx::Class::Position') ? {order_by=>$self->position_column()} : () )
+        { $self->parent_column()=>$self->id() }
     );
     return $rs->all() if (wantarray());
     return $rs;
@@ -163,112 +141,6 @@ sub attach_sibling {
     $child->parent( $self->parent() );
 }
 
-=head1 POSITIONAL METHODS
-
-If you are useing the L<DBIx::Class::Postional> component 
-in conjunction with this module then you will also have 
-these methods available to you.
-
-=head2 append_child
-
-  $parent->append_child( $child );
-
-Sets the child to have the specified parent and moves the 
-child to the last position.
-
-=cut
-
-sub append_child {
-    my( $self, $child ) = @_;
-    croak('This method may only be used with the Positional component') if (!$self->positional());
-    $child->parent( $self );
-}
-
-=head2 prepend_child
-
-  $parent->prepend_child( $child );
-
-Sets the child to have the specified parent and moves the 
-child to the first position.
-
-=cut
-
-sub prepend_child {
-    my( $self, $child ) = @_;
-    croak('This method may only be used with the Positional component') if (!$self->positional());
-    $child->parent( $self );
-    $child->move_first();
-}
-
-=head2 attach_before
-
-  $this->attach_before( $that );
-
-Attaches the object at the position just before the 
-calling object's position.
-
-=cut
-
-sub attach_before {
-    my( $self, $sibling ) = @_;
-    croak('This method may only be used with the Positional component') if (!$self->positional());
-    $sibling->parent( $self->parent() );
-    $sibling->move_to( $self->get_column($self->position_column()) );
-}
-
-=head2 attach_after
-
-  $this->attach_after( $that );
-
-Attaches the object at the position just after the 
-calling object's position.
-
-=cut
-
-sub attach_after {
-    my( $self, $sibling ) = @_;
-    croak('This method may only be used with the Positional component') if (!$self->positional());
-    $sibling->parent( $self->parent() );
-    $sibling->move_to( $self->get_column($self->position_column()) + 1 );
-}
-
-=head2 positional
-
-  if ($object->positional()) { ... }
-
-Returns true if the object is a DBIx::Class::Positional 
-object.
-
-=cut
-
-sub positional {
-    my( $self ) = @_;
-    return $self->isa('DBIx::Class::Positional');
-}
-
-=head1 PRIVATE METHODS
-
-These methods are used internally.  You should never have the 
-need to use them.
-
-=head2 _collection_clause
-
-This method is provided as an override of the method in 
-L<DBIx::Class::Positional>.  This way Positional and Tree::AdjacencyList 
-may be used together without conflict.  Make sure that in 
-your component list that you load Tree::AdjacencyList before you 
-load Positional.
-
-=cut
-
-sub _collection_clause {
-    my( $self ) = @_;
-    return (
-        $self->parent_column() =>
-        $self->get_column($self->parent_column())
-    );
-}
-
 1;
 __END__
 
diff --git a/lib/DBIx/Class/Tree/AdjacencyList/Positional.pm b/lib/DBIx/Class/Tree/AdjacencyList/Positional.pm
new file mode 100644 (file)
index 0000000..97e4149
--- /dev/null
@@ -0,0 +1,213 @@
+# vim: ts=8:sw=4:sts=4:et
+package DBIx::Class::Tree::AdjacencyList::Positional;
+use strict;
+use warnings;
+use base qw( DBIx::Class );
+use Carp qw( croak );
+
+__PACKAGE__->load_components(qw(
+    Tree::AdjacencyList
+    Positional
+));
+
+=head1 NAME
+
+DBIx::Class::Tree::AdjacencyList::Positional - Glue DBIx::Class::Positional 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,
+    parent_id INTEGER NOT NULL,
+    position INTEGER NOT NULL,
+    name TEXT NOT NULL
+  );
+
+In your Schema or DB class add Tree::AdjacencyList::Positional 
+to the top of the component list.
+
+  __PACKAGE__->load_components(qw( Tree::AdjacencyList::Positional ... ));
+
+Specify the column that contains the parent ID and position of each row.
+
+  package My::Employee;
+  __PACKAGE__->parent_column('parent_id');
+  __PACAKGE__->position_column('position');
+
+This module provides a few extra methods beyond what 
+L<DBIx::Class::Positional> and L<DBIx::Class::Tree::AdjacencyList> 
+already provide.
+
+  my $parent = $employee->parent();
+  $employee->parent( $parent_obj );
+  $employee->parent( $parent_id );
+  
+  my $children_rs = $employee->children();
+  my @children = $employee->children();
+  
+  $parent->append_child( $child );
+  $parent->prepend_child( $child );
+  
+  $this->attach_before( $that );
+  $this->attach_after( $that );
+
+=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 
+
+=head1 METHODS
+
+=head2 parent
+
+  my $parent = $employee->parent();
+  $employee->parent( $parent_obj );
+  $employee->parent( $parent_id );
+  
+  my $children_rs = $employee->children();
+  my @children = $employee->children();
+
+This method works exactly like it does in the 
+DBIx::Class::Tree::AdjacencyList module except that it will 
+first move the object to the last position of the list, change 
+the parent ID, then move the object to the last position of 
+the new list.  This ensures the intergrity of the positions.
+
+=cut
+
+sub parent {
+    my( $self, $new_parent ) = @_;
+    if ($new_parent) {
+        if (ref($new_parent)) {
+            $new_parent = $new_parent->id() || 0;
+        }
+        return 0 if ($new_parent == ($self->get_column($self->parent_column())||0));
+        $self->move_last();
+        return 0 if (!$self->next::method( $new_parent ));
+        $self->set_column(
+            $self->position_column() => $self->search( {$self->_collection_clause()} )->count() + 1
+        );
+        $self->update();
+        return 1;
+    }
+    else {
+        return $self->next::method();
+    }
+}
+
+=head2 children
+
+  my $children_rs = $employee->children();
+  my @children = $employee->children();
+
+This method works just like it does in the 
+DBIx::Class::Tree::AdjacencyList module except it 
+orders the children by there position.
+
+=cut
+
+sub children {
+    my( $self ) = @_;
+    my $rs = $self->search(
+        { $self->parent_column() => $self->id() },
+        { order_by => $self->position_column() }
+    );
+    return $rs->all() if (wantarray());
+    return $rs;
+}
+
+=head2 append_child
+
+  $parent->append_child( $child );
+
+Sets the child to have the specified parent and moves the 
+child to the last position.
+
+=cut
+
+sub append_child {
+    my( $self, $child ) = @_;
+    $child->parent( $self );
+}
+
+=head2 prepend_child
+
+  $parent->prepend_child( $child );
+
+Sets the child to have the specified parent and moves the 
+child to the first position.
+
+=cut
+
+sub prepend_child {
+    my( $self, $child ) = @_;
+    $child->parent( $self );
+    $child->move_first();
+}
+
+=head2 attach_before
+
+  $this->attach_before( $that );
+
+Attaches the object at the position just before the 
+calling object's position.
+
+=cut
+
+sub attach_before {
+    my( $self, $sibling ) = @_;
+    $sibling->parent( $self->parent() );
+    $sibling->move_to( $self->get_column($self->position_column()) );
+}
+
+=head2 attach_after
+
+  $this->attach_after( $that );
+
+Attaches the object at the position just after the 
+calling object's position.
+
+=cut
+
+sub attach_after {
+    my( $self, $sibling ) = @_;
+    $sibling->parent( $self->parent() );
+    $sibling->move_to( $self->get_column($self->position_column()) + 1 );
+}
+
+=head1 PRIVATE METHODS
+
+These methods are used internally.  You should never have the 
+need to use them.
+
+=head2 _collection_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.
+
+=cut
+
+sub _collection_clause {
+    my( $self ) = @_;
+    return (
+        $self->parent_column() =>
+        $self->get_column($self->parent_column())
+    );
+}
+
+1;
+__END__
+
+=head1 AUTHOR
+
+Aran Clary Deltac <bluefeet@cpan.org>
+
+=head1 LICENSE
+
+You may distribute this code under the same terms as Perl itself.
+
similarity index 100%
rename from t/01pod.t
rename to t/01_pod.t