No longer support unique constraints in Ordered.
Aran Deltac [Sun, 30 Apr 2006 14:41:53 +0000 (14:41 +0000)]
lib/DBIx/Class/Ordered.pm
t/lib/DBICTest/Schema/Employee.pm
t/lib/sqlite.sql
t/run/27ordered.tl

index eaf78f7..8e2c74d 100644 (file)
@@ -277,17 +277,15 @@ sub move_to {
     my( $self, $to_position ) = @_;
     my $position_column = $self->position_column;
     my $from_position = $self->get_column( $position_column );
-#print "# from:$from_position to:$to_position\n";
     return 0 if ( $to_position < 1 );
     return 0 if ( $from_position==$to_position );
-    $self->update({
-        $position_column => 
-            1 + $self->result_source->resultset->search({ $self->_grouping_clause() })->count()
-    });
+    my @between = (
+        ( $from_position < $to_position )
+        ? ( $from_position+1, $to_position )
+        : ( $to_position, $from_position-1 )
+    );
     my $rs = $self->result_source->resultset->search({
-        $position_column => { -between => [ 
-            ( ($from_position < $to_position) ? ($from_position, $to_position) : ($to_position, $from_position) )
-        ] },
+        $position_column => { -between => [ @between ] },
         $self->_grouping_clause(),
     });
     my $op = ($from_position>$to_position) ? '+' : '-';
@@ -353,6 +351,15 @@ __END__
 
 =head1 BUGS
 
+=head2 Unique Constraints
+
+Unique indexes and constraints on the position column are not 
+supported at this time.  It would be make sense to support them, 
+but there are some unexpected database issues that make this 
+hard to do.  The main problem from the author's view is that 
+SQLite (the DB engine that we use for testing) does not support 
+ORDER BY on updates.
+
 =head2 Race Condition on Insert
 
 If a position is not specified for an insert than a position 
@@ -369,7 +376,7 @@ you've pre-loaded the objects then when you move one of the objects
 the position of the other object will not reflect their new value 
 until you reload them from the database.
 
-The are times when you will want to move objects as groups, such 
+There are times when you will want to move objects as groups, such 
 as changeing the parent of several objects at once - this directly 
 conflicts with this problem.  One solution is for us to write a 
 ResultSet class that supports a parent() method, for example.  Another 
index 4ebeffd..e91f872 100644 (file)
@@ -29,7 +29,7 @@ __PACKAGE__->add_columns(
 __PACKAGE__->set_primary_key('employee_id');
 __PACKAGE__->position_column('position');
 
-__PACKAGE__->add_unique_constraint(position_group => [ qw/position group_id/ ]);
+#__PACKAGE__->add_unique_constraint(position_group => [ qw/position group_id/ ]);
 
 __PACKAGE__->mk_classdata('field_name_for', {
     employee_id => 'primary key',
index 826805a..4c89d2e 100644 (file)
@@ -1,6 +1,6 @@
 -- 
 -- Created by SQL::Translator::Producer::SQLite
--- Created on Wed Apr 19 18:32:39 2006
+-- Created on Sun Apr 30 07:37:44 2006
 -- 
 BEGIN TRANSACTION;
 
@@ -160,7 +160,6 @@ CREATE TABLE producer (
   name varchar(100) NOT NULL
 );
 
-CREATE UNIQUE INDEX position_group_employee on employee (position, group_id);
 CREATE UNIQUE INDEX tktlnameunique_twokeytreelike on twokeytreelike (name);
 CREATE UNIQUE INDEX artist_title_cd on cd (artist, title);
 COMMIT;
index 3883c05..3a53951 100644 (file)
@@ -2,7 +2,7 @@
 
 sub run_tests {
 
-    plan tests => 66;
+    plan tests => 321;
     my $schema = shift;
 
     my $employees = $schema->resultset('Employee');
@@ -16,7 +16,7 @@ sub run_tests {
 
     hammer_rs( $employees );
 
-    return;
+    #return;
 
     DBICTest::Employee->grouping_column('group_id');
     $employees->delete();
@@ -44,29 +44,29 @@ sub hammer_rs {
 
     foreach my $position (1..$count) {
 
-        $row = $rs->find({ $position_column=>$position });
+        ($row) = $rs->search({ $position_column=>$position })->all();
         $row->move_previous();
         ok( check_rs($rs), "move_previous( $position )" );
 
-        $row = $rs->find({ $position_column=>$position });
+        ($row) = $rs->search({ $position_column=>$position })->all();
         $row->move_next();
         ok( check_rs($rs), "move_next( $position )" );
 
-        $row = $rs->find({ $position_column=>$position });
+        ($row) = $rs->search({ $position_column=>$position })->all();
         $row->move_first();
         ok( check_rs($rs), "move_first( $position )" );
 
-        $row = $rs->find({ $position_column=>$position });
+        ($row) = $rs->search({ $position_column=>$position })->all();
         $row->move_last();
         ok( check_rs($rs), "move_last( $position )" );
 
         foreach my $to_position (1..$count) {
-            $row = $rs->find({ $position_column=>$position });
+            ($row) = $rs->search({ $position_column=>$position })->all();
             $row->move_to($to_position);
             ok( check_rs($rs), "move_to( $position => $to_position )" );
         }
 
-        $row = $rs->find({ position=>$position });
+        ($row) = $rs->search({ position=>$position })->all();
         if ($position==1) {
             ok( !$row->previous_sibling(), 'no previous sibling' );
             ok( !$row->first_sibling(), 'no first sibling' );