From: Aran Deltac Date: Fri, 24 Mar 2006 03:43:16 +0000 (+0000) Subject: Fixes to Tree::AdjacencyList, and working tests. X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=0a298c734198290789bf9cbacb76893fb087af60;p=dbsrgits%2FDBIx-Class-Historic.git Fixes to Tree::AdjacencyList, and working tests. --- diff --git a/lib/DBIx/Class/Positioned.pm b/lib/DBIx/Class/Positioned.pm index 03d4156..5266f9d 100644 --- a/lib/DBIx/Class/Positioned.pm +++ b/lib/DBIx/Class/Positioned.pm @@ -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 diff --git a/lib/DBIx/Class/Tree/AdjacencyList.pm b/lib/DBIx/Class/Tree/AdjacencyList.pm index 381b039..c0175d6 100644 --- a/lib/DBIx/Class/Tree/AdjacencyList.pm +++ b/lib/DBIx/Class/Tree/AdjacencyList.pm @@ -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 +Aran Clary Deltac =head1 LICENSE diff --git a/t/helperrels/27adjacency_list.t b/t/helperrels/27adjacency_list.t new file mode 100644 index 0000000..dbc5992 --- /dev/null +++ b/t/helperrels/27adjacency_list.t @@ -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); diff --git a/t/lib/DBICTest/Schema.pm b/t/lib/DBICTest/Schema.pm index c0ef724..e43c898 100644 --- a/t/lib/DBICTest/Schema.pm +++ b/t/lib/DBICTest/Schema.pm @@ -9,7 +9,6 @@ __PACKAGE__->load_classes(qw/ Artist Employee::Positioned Employee::AdjacencyList - Employee::PositionedAdjacencyList CD #dummy Track diff --git a/t/lib/DBICTest/Schema/Employee/AdjacencyList.pm b/t/lib/DBICTest/Schema/Employee/AdjacencyList.pm index c0e4407..5af4532 100644 --- a/t/lib/DBICTest/Schema/Employee/AdjacencyList.pm +++ b/t/lib/DBICTest/Schema/Employee/AdjacencyList.pm @@ -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 index 86a2e58..0000000 --- a/t/lib/DBICTest/Schema/Employee/PositionedAdjacencyList.pm +++ /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; diff --git a/t/lib/sqlite.sql b/t/lib/sqlite.sql index c7190e9..1e8f83e 100644 --- a/t/lib/sqlite.sql +++ b/t/lib/sqlite.sql @@ -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 index 0000000..6c2f46a --- /dev/null +++ b/t/run/27adjacency_list.tl @@ -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;