Fixes to Tree::AdjacencyList, and working tests.
Aran Deltac [Fri, 24 Mar 2006 03:43:16 +0000 (03:43 +0000)]
lib/DBIx/Class/Positioned.pm
lib/DBIx/Class/Tree/AdjacencyList.pm
t/helperrels/27adjacency_list.t [new file with mode: 0644]
t/lib/DBICTest/Schema.pm
t/lib/DBICTest/Schema/Employee/AdjacencyList.pm
t/lib/DBICTest/Schema/Employee/PositionedAdjacencyList.pm [deleted file]
t/lib/sqlite.sql
t/run/27adjacency_list.tl [new file with mode: 0644]

index 03d4156..5266f9d 100644 (file)
@@ -308,7 +308,7 @@ sub insert {
     my $position_column = $self->position_column;
     $self->set_column( $position_column => $self->result_source->resultset->search( {$self->_collection_clause()} )->count()+1 ) 
         if (!$self->get_column($position_column));
-    $self->next::method( @_ );
+    return $self->next::method( @_ );
 }
 
 =head2 delete
@@ -322,7 +322,7 @@ integrity of the positions.
 sub delete {
     my $self = shift;
     $self->move_last;
-    $self->next::method( @_ );
+    return $self->next::method( @_ );
 }
 
 =head1 PRIVATE METHODS
index 381b039..c0175d6 100644 (file)
@@ -63,6 +63,9 @@ 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 Positioned component then this parent_column 
+will automatically be used as the collection_column.
+
 =cut
 
 __PACKAGE__->mk_classdata( 'parent_column' => 'parent_id' );
@@ -94,12 +97,12 @@ sub parent {
             $new_parent = $new_parent->id() || 0;
         }
         return 0 if ($new_parent == ($self->get_column($parent_column)||0));
-        my $positioned = $self->can('position_column');
-        $self->move_last if ($positioned);
+        my $is_positioned = $self->isa('DBIx::Class::Positioned');
+        $self->move_last() if ($is_positioned);
         $self->set_column( $parent_column => $new_parent );
-        if ($positioned) {
+        if ($is_positioned) {
             $self->set_column(
-                $self->position_column() => $self->search( {$self->_parent_clause()} )->count() + 1
+                $self->position_column() => $self->search( {$self->_collection_clause()} )->count() + 1
             );
         }
         $self->update();
@@ -127,41 +130,28 @@ sub children {
     my( $self ) = @_;
     my $rs = $self->search(
         { $self->parent_column()=>$self->id() },
-        ( $self->can('position_column') ? {order_by=>$self->position_column()} : () )
+        ( $self->isa('DBIx::Class::Position') ? {order_by=>$self->position_column()} : () )
     );
     return $rs->all() if (wantarray());
     return $rs;
 }
 
-=head2 descendents
-
-Same as children.  Declared so that this module is 
-compatible with the Tree::NestedSet module.
-
-=cut
-
-#*descendants = \&children;
-
 =head1 PRIVATE METHODS
 
 These methods are used internally.  You should never have the 
 need to use them.
 
-=head2 _parent_clause
+=head2 _collection_clause
 
 This method is provided as an override of the method in 
-DBIC::Positioned.  This way Positioned and Tree::AdjacencyList 
+DBIx::Class::Positioned.  This way Positioned and Tree::AdjacencyList 
 may be used together without conflict.  Make sure that in 
-you component list that you load Tree::AdjacencyList before you 
+your component list that you load Tree::AdjacencyList before you 
 load Positioned.
 
-This method assumes a parent ID of 0 if none is defined.  This 
-usually comes in to play if you are just createing the object 
-and it has not yet been assigned a parent.
-
 =cut
 
-sub _parent_clause {
+sub _collection_clause {
     my( $self ) = @_;
     return (
         $self->parent_column() =>
@@ -174,7 +164,7 @@ __END__
 
 =head1 AUTHOR
 
-Aran Deltac <bluefeet@cpan.org>
+Aran Clary Deltac <bluefeet@cpan.org>
 
 =head1 LICENSE
 
diff --git a/t/helperrels/27adjacency_list.t b/t/helperrels/27adjacency_list.t
new file mode 100644 (file)
index 0000000..dbc5992
--- /dev/null
@@ -0,0 +1,7 @@
+use Test::More;
+use lib qw(t/lib);
+use DBICTest;
+use DBICTest::HelperRels;
+
+require "t/run/27adjacency_list.tl";
+run_tests(DBICTest->schema);
index c0ef724..e43c898 100644 (file)
@@ -9,7 +9,6 @@ __PACKAGE__->load_classes(qw/
   Artist
   Employee::Positioned
   Employee::AdjacencyList
-  Employee::PositionedAdjacencyList
   CD
   #dummy
   Track
index c0e4407..5af4532 100644 (file)
@@ -5,6 +5,7 @@ use base 'DBIx::Class';
 
 __PACKAGE__->load_components(qw(
     Tree::AdjacencyList
+    Positioned
     PK::Auto
     Core
 ));
@@ -18,6 +19,9 @@ __PACKAGE__->add_columns(
     },
     parent_id => {
         data_type => 'integer',
+    },
+    position => {
+        data_type => 'integer',
         is_nullable => 1,
     },
     name => {
@@ -29,10 +33,12 @@ __PACKAGE__->add_columns(
 
 __PACKAGE__->set_primary_key('employee_id');
 __PACKAGE__->parent_column('parent_id');
+__PACKAGE__->position_column('position');
 
 __PACKAGE__->mk_classdata('field_name_for', {
     employee_id => 'primary key',
     parent_id   => 'parent id',
+    position    => 'list order',
     name        => 'employee name',
 });
 
diff --git a/t/lib/DBICTest/Schema/Employee/PositionedAdjacencyList.pm b/t/lib/DBICTest/Schema/Employee/PositionedAdjacencyList.pm
deleted file mode 100644 (file)
index 86a2e58..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-package # hide from PAUSE 
-    DBICTest::Schema::Employee::PositionedAdjacencyList;
-
-use base 'DBIx::Class';
-
-__PACKAGE__->load_components(qw(
-    Tree::AdjacencyList
-    Positioned
-    PK::Auto
-    Core
-));
-
-__PACKAGE__->table('employees_positioned_adjacencylist');
-
-__PACKAGE__->add_columns(
-    employee_id => {
-        data_type => 'integer',
-        is_auto_increment => 1
-    },
-    parent_id => {
-        data_type => 'integer',
-        is_nullable => 1,
-    },
-    position => {
-        data_type => 'integer',
-    },
-    name => {
-        data_type => 'varchar',
-        size      => 100,
-        is_nullable => 1,
-    },
-);
-
-__PACKAGE__->set_primary_key('employee_id');
-__PACKAGE__->position_column('position');
-__PACKAGE__->parent_column('parent_id');
-
-__PACKAGE__->mk_classdata('field_name_for', {
-    employee_id => 'primary key',
-    parent_id   => 'parent id',
-    position    => 'list position',
-    name        => 'employee name',
-});
-
-1;
index c7190e9..1e8f83e 100644 (file)
@@ -1,10 +1,18 @@
 -- 
 -- Created by SQL::Translator::Producer::SQLite
--- Created on Thu Mar 23 11:13:18 2006
+-- Created on Thu Mar 23 19:41:26 2006
 -- 
 BEGIN TRANSACTION;
 
 --
+-- Table: serialized
+--
+CREATE TABLE serialized (
+  id INTEGER PRIMARY KEY NOT NULL,
+  serialized text NOT NULL
+);
+
+--
 -- Table: employees_positioned
 --
 CREATE TABLE employees_positioned (
@@ -15,20 +23,13 @@ CREATE TABLE employees_positioned (
 );
 
 --
--- Table: serialized
---
-CREATE TABLE serialized (
-  id INTEGER PRIMARY KEY NOT NULL,
-  serialized text NOT NULL
-);
-
---
--- Table: cd_to_producer
+-- Table: employees_adjacencylist
 --
-CREATE TABLE cd_to_producer (
-  cd integer NOT NULL,
-  producer integer NOT NULL,
-  PRIMARY KEY (cd, producer)
+CREATE TABLE employees_adjacencylist (
+  employee_id INTEGER PRIMARY KEY NOT NULL,
+  parent_id integer NOT NULL,
+  position integer,
+  name varchar(100)
 );
 
 --
@@ -40,12 +41,12 @@ CREATE TABLE liner_notes (
 );
 
 --
--- Table: employees_adjacencylist
+-- Table: cd_to_producer
 --
-CREATE TABLE employees_adjacencylist (
-  employee_id INTEGER PRIMARY KEY NOT NULL,
-  parent_id integer,
-  name varchar(100)
+CREATE TABLE cd_to_producer (
+  cd integer NOT NULL,
+  producer integer NOT NULL,
+  PRIMARY KEY (cd, producer)
 );
 
 --
@@ -57,16 +58,6 @@ CREATE TABLE artist (
 );
 
 --
--- Table: employees_positioned_adjacencylist
---
-CREATE TABLE employees_positioned_adjacencylist (
-  employee_id INTEGER PRIMARY KEY NOT NULL,
-  parent_id integer,
-  position integer NOT NULL,
-  name varchar(100)
-);
-
---
 -- Table: self_ref_alias
 --
 CREATE TABLE self_ref_alias (
@@ -96,11 +87,10 @@ CREATE TABLE track (
 );
 
 --
--- Table: treelike
+-- Table: self_ref
 --
-CREATE TABLE treelike (
+CREATE TABLE self_ref (
   id INTEGER PRIMARY KEY NOT NULL,
-  parent integer NOT NULL,
   name varchar(100) NOT NULL
 );
 
@@ -114,10 +104,11 @@ CREATE TABLE tags (
 );
 
 --
--- Table: self_ref
+-- Table: treelike
 --
-CREATE TABLE self_ref (
+CREATE TABLE treelike (
   id INTEGER PRIMARY KEY NOT NULL,
+  parent integer NOT NULL,
   name varchar(100) NOT NULL
 );
 
@@ -151,6 +142,14 @@ CREATE TABLE artist_undirected_map (
 );
 
 --
+-- Table: producer
+--
+CREATE TABLE producer (
+  producerid INTEGER PRIMARY KEY NOT NULL,
+  name varchar(100) NOT NULL
+);
+
+--
 -- Table: onekey
 --
 CREATE TABLE onekey (
@@ -159,12 +158,4 @@ CREATE TABLE onekey (
   cd integer NOT NULL
 );
 
---
--- Table: producer
---
-CREATE TABLE producer (
-  producerid INTEGER PRIMARY KEY NOT NULL,
-  name varchar(100) NOT NULL
-);
-
 COMMIT;
diff --git a/t/run/27adjacency_list.tl b/t/run/27adjacency_list.tl
new file mode 100644 (file)
index 0000000..6c2f46a
--- /dev/null
@@ -0,0 +1,52 @@
+# vim: filetype=perl
+
+sub run_tests {
+
+    plan tests => 5;
+    my $schema = shift;
+
+    my $employees = $schema->resultset('Employee::AdjacencyList');
+    $employees->delete();
+
+    my $grandma = $employees->create({ name=>'grandma', parent_id=>0 });
+    foreach (1..15) {
+        $employees->create({ name=>'temp', parent_id=>$grandma->id() });
+    }
+    ok( ($grandma->children->count()==15), 'grandma children' );
+
+    my $mom = ($grandma->children->search(undef,{rows=>1})->all())[0];
+    foreach (1..5) {
+        ($grandma->children->search(undef,{rows=>1})->all())[0]->parent( $mom );
+    }
+    ok( ($mom->children->count()==5), 'mom children' );
+    ok( ($grandma->children->count()==10), 'grandma children' );
+
+    $mom = ($grandma->children->search(undef,{rows=>2})->all())[0];
+    foreach (1..4) {
+        ($grandma->children->search(undef,{rows=>1})->all())[0]->parent( $mom );
+    }
+    ok( ($mom->children->count()==4), 'mom children' );
+    ok( ($grandma->children->count()==6), 'grandma children' );
+
+    ok( check_rs( scalar $grandma->children() ), 'correct positions' );
+}
+
+sub check_rs {
+    my( $rs ) = @_;
+    $rs->reset();
+    my $position_column = $rs->result_class->position_column();
+    my $expected_position = 0;
+    while (my $row = $rs->next()) {
+        $expected_position ++;
+        if ($row->get_column($position_column)!=$expected_position) {
+            return 0;
+        }
+        my $children = $row->children();
+        while (my $child = $children->next()) {
+            return 0 if (!check_rs( scalar $child->children() ));
+        }
+    }
+    return 1;
+}
+
+1;