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) ? '+' : '-';
=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
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
__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',
--
-- 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;
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;
sub run_tests {
- plan tests => 66;
+ plan tests => 321;
my $schema = shift;
my $employees = $schema->resultset('Employee');
hammer_rs( $employees );
- return;
+ #return;
DBICTest::Employee->grouping_column('group_id');
$employees->delete();
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' );