Multicol tests done. Also tweaked the pods and took out my debugger breakpoints.
Neil de Carteret [Sat, 25 Nov 2006 15:42:36 +0000 (15:42 +0000)]
lib/DBIx/Class/Ordered.pm
t/87ordered.t
t/lib/DBICTest/Schema/Employee.pm
t/lib/sqlite.sql

index b6ad5dc..d5a7a00 100644 (file)
@@ -17,7 +17,26 @@ Create a table for your ordered data.
     name TEXT NOT NULL,
     position INTEGER NOT NULL
   );
-  # Optional: group_id INTEGER NOT NULL
+
+Optionally, add one or more columns to specify groupings, allowing you 
+to maintain independent ordered lists within one table:
+
+  CREATE TABLE items (
+    item_id INTEGER PRIMARY KEY AUTOINCREMENT,
+    name TEXT NOT NULL,
+    position INTEGER NOT NULL,
+    group_id INTEGER NOT NULL
+  );
+
+Or even
+
+  CREATE TABLE items (
+    item_id INTEGER PRIMARY KEY AUTOINCREMENT,
+    name TEXT NOT NULL,
+    position INTEGER NOT NULL,
+    group_id INTEGER NOT NULL,
+    other_group_id INTEGER NOT NULL
+  );
 
 In your Schema or DB class add Ordered to the top 
 of the component list.
@@ -29,7 +48,14 @@ each row.
 
   package My::Item;
   __PACKAGE__->position_column('position');
-  __PACKAGE__->grouping_column('group_id'); # optional
+
+If you are using one grouping column, specify it as follows:
+
+  __PACKAGE__->grouping_column('group_id');
+
+Or if you have multiple grouping columns:
+
+  __PACKAGE__->grouping_column(['group_id', 'other_group_id']);
 
 Thats it, now you can change the position of your objects.
 
@@ -54,6 +80,10 @@ Thats it, now you can change the position of your objects.
   $item->move_first();
   $item->move_last();
   $item->move_to( $position );
+  $item->move_to_group( 'groupname' );
+  $item->move_to_group( 'groupname', $position );
+  $item->move_to_group( {group_id=>'groupname', 'other_group_id=>'othergroupname'} );
+  $item->move_to_group( {group_id=>'groupname', 'other_group_id=>'othergroupname'}, $position );
 
 =head1 DESCRIPTION
 
@@ -307,9 +337,9 @@ group, or to the end of the group if $position is undef.
 1 is returned on success, and 0 is returned if the object is
 already at the specified position of the specified group.
 
-$group should be supplied as a hashref of column => value pairs,
-e.g. if the grouping columns were 'user' and 'list',
-{ user => 'fred', list => 'work' }.
+$group may be specified as a single scalar if only one 
+grouping column is in use, or as a hashref of column => value pairs
+if multiple grouping columns are in use.
 
 =cut
 
@@ -396,9 +426,7 @@ sub update {
 
     my $pos_col = $self->position_column;
 
-    # is there a chance in hell of this working?
     # if any of our grouping columns have been changed
-$DB::single=1;
     if (grep {$_} map {exists $changes{$_}} $self->_grouping_columns ) {
 
         # create new_group by taking the current group and inserting changes
@@ -457,8 +485,8 @@ sub _grouping_clause {
 =head2 _get_grouping_columns
 
 Returns a list of the column names used for grouping, regardless of whether
-they were specified as an arrayref or a single string, and even returns ()
-if we're not grouping.
+they were specified as an arrayref or a single string, and returns ()
+if there is no grouping.
 
 =cut
 sub _grouping_columns {
@@ -493,8 +521,6 @@ sub _is_in_group {
 }
 
 
-
-
 1;
 __END__
 
index 7843eee..7bc1bed 100644 (file)
@@ -6,9 +6,11 @@ use Test::More;
 use lib qw(t/lib);
 use DBICTest;
 
+use POSIX qw(ceil);
+
 my $schema = DBICTest->init_schema();
 
-plan tests => 417;
+plan tests => 879;
 
 my $employees = $schema->resultset('Employee');
 $employees->delete();
@@ -94,6 +96,97 @@ ok(
        "overloaded update 7"
 );
 
+# multicol tests begin here
+DBICTest::Employee->grouping_column(['group_id', 'group_id_2']);
+$employees->delete();
+foreach my $group_id (1..4) {
+    foreach my $group_id_2 (1..4) {
+        foreach (1..4) {
+            $employees->create({ name=>'temp', group_id=>$group_id, group_id_2=>$group_id_2 });
+        }
+    }
+}
+$employees = $employees->search(undef,{order_by=>'group_id,group_id_2,position'});
+
+foreach my $group_id (1..3) {
+    foreach my $group_id_2 (1..3) {
+        my $group_employees = $employees->search({group_id=>$group_id, group_id_2=>$group_id_2});
+        $group_employees->all();
+        ok( check_rs($group_employees), "group intial positions" );
+        hammer_rs( $group_employees );
+    }
+}
+
+# move_to_group, specifying group by hash
+my $group_4 = $employees->search({group_id=>4});
+$to_group = 1;
+my $to_group_2_base = 7;
+my $to_group_2 = 1;
+$to_pos = undef;
+while (my $employee = $group_4->next) {
+       $employee->move_to_group({group_id=>$to_group, group_id_2=>$to_group_2}, $to_pos);
+       $to_pos++;
+    $to_group = ($to_group % 3) + 1;
+    $to_group_2_base++;
+    $to_group_2 = (ceil($to_group_2_base/3.0) %3) +1
+}
+foreach my $group_id (1..4) {
+    foreach my $group_id_2 (1..4) {
+        my $group_employees = $employees->search({group_id=>$group_id,group_id_2=>$group_id_2});
+        $group_employees->all();
+        ok( check_rs($group_employees), "group positions after move_to_group" );
+    }
+}
+
+$employees->delete();
+foreach my $group_id (1..4) {
+    foreach my $group_id_2 (1..4) {
+        foreach (1..4) {
+            $employees->create({ name=>'temp', group_id=>$group_id, group_id_2=>$group_id_2 });
+        }
+    }
+}
+$employees = $employees->search(undef,{order_by=>'group_id,group_id_2,position'});
+
+$employee = $employees->search({group_id=>4, group_id_2=>1})->first;
+$employee->group_id(1);
+$employee->update;
+ok( 
+    check_rs($employees->search_rs({group_id=>4, group_id_2=>1}))
+    && check_rs($employees->search_rs({group_id=>1, group_id_2=>1})), 
+    "overloaded multicol update 1" 
+);
+
+$employee = $employees->search({group_id=>4, group_id_2=>1})->first;
+$employee->update({group_id=>2});
+ok( check_rs($employees->search_rs({group_id=>4, group_id_2=>1}))
+    && check_rs($employees->search_rs({group_id=>2, group_id_2=>1})), 
+    "overloaded multicol update 2" 
+);
+
+$employee = $employees->search({group_id=>3, group_id_2=>1})->first;
+$employee->group_id(1);
+$employee->group_id_2(3);
+$employee->update();
+ok( check_rs($employees->search_rs({group_id=>3, group_id_2=>1}))
+    && check_rs($employees->search_rs({group_id=>1, group_id_2=>3})),
+    "overloaded multicol update 3" 
+);
+
+$employee = $employees->search({group_id=>3, group_id_2=>1})->first;
+$employee->update({group_id=>2, group_id_2=>3});
+ok( check_rs($employees->search_rs({group_id=>3, group_id_2=>1}))
+    && check_rs($employees->search_rs({group_id=>2, group_id_2=>3})), 
+    "overloaded multicol update 4" 
+);
+
+$employee = $employees->search({group_id=>3, group_id_2=>2})->first;
+$employee->update({group_id=>2, group_id_2=>4, position=>2});
+ok( check_rs($employees->search_rs({group_id=>3, group_id_2=>2}))
+    && check_rs($employees->search_rs({group_id=>2, group_id_2=>4})), 
+    "overloaded multicol update 5" 
+);
+
 sub hammer_rs {
     my $rs = shift;
     my $employee;
index 78b3d16..7beb833 100644 (file)
@@ -19,6 +19,10 @@ __PACKAGE__->add_columns(
         data_type => 'integer',
         is_nullable => 1,
     },
+    group_id_2 => {
+        data_type => 'integer',
+        is_nullable => 1,
+    },
     name => {
         data_type => 'varchar',
         size      => 100,
index 2ce5dad..a5f4084 100644 (file)
@@ -11,6 +11,7 @@ CREATE TABLE employee (
   employee_id INTEGER PRIMARY KEY NOT NULL,
   position integer NOT NULL,
   group_id integer,
+  group_id_2 integer,  
   name varchar(100)
 );