DBIx-Class
view release on metacpan or search on metacpan
lib/DBIx/Class/Ordered.pm view on Meta::CPAN
my $new_group_last_position = $self->_position_from_value (
$new_group_last_posval
);
if ( not defined($to_position) or $to_position > $new_group_last_position) {
$self->set_column(
$position_column => $new_group_last_position
? $self->_next_position_value ( $new_group_last_posval )
: $self->_initial_position_value
);
}
else {
my $bumped_pos_val = $self->_position_value ($to_position);
my @between = map { $self->_position_value ($_) } ($to_position, $new_group_last_position);
$self->_shift_siblings (1, @between); #shift right
$self->set_column( $position_column => $bumped_pos_val );
}
$self->_ordered_internal_update;
$guard->commit;
return 1;
}
=head2 insert
Overrides the DBIC insert() method by providing a default
position number. The default will be the number of rows in
the table +1, thus positioning the new record at the last position.
=cut
sub insert {
my $self = shift;
my $position_column = $self->position_column;
unless ($self->get_column($position_column)) {
my $lsib_posval = $self->_last_sibling_posval;
$self->set_column(
$position_column => (defined $lsib_posval
? $self->_next_position_value ( $lsib_posval )
: $self->_initial_position_value
)
);
}
return $self->next::method( @_ );
}
=head2 update
Overrides the DBIC update() method by checking for a change
to the position and/or group columns. Movement within a
group or to another group is handled by repositioning
the appropriate siblings. Position defaults to the end
of a new group if it has been changed to undef.
=cut
sub update {
my $self = shift;
# this is set by _ordered_internal_update()
return $self->next::method(@_) if $self->result_source->schema->{_ORDERED_INTERNAL_UPDATE};
my $upd = shift;
$self->set_inflated_columns($upd) if $upd;
my $position_column = $self->position_column;
my @group_columns = $self->_grouping_columns;
# see if the order is already changed
my $changed_ordering_cols = { map { $_ => $self->get_column($_) } grep { $self->is_column_changed($_) } ($position_column, @group_columns) };
# nothing changed - short circuit
if (! keys %$changed_ordering_cols) {
return $self->next::method( undef, @_ );
}
elsif (grep { exists $changed_ordering_cols->{$_} } @group_columns ) {
$self->move_to_group(
# since the columns are already re-set the _grouping_clause is correct
# move_to_group() knows how to get the original storage values
{ $self->_grouping_clause },
# The FIXME bit contradicts the documentation: POD states that
# when changing groups without supplying explicit positions in
# move_to_group(), we push the item to the end of the group.
# However when I was rewriting this, the position from the old
# group was clearly passed to the new one
# Probably needs to go away (by ribasushi)
(exists $changed_ordering_cols->{$position_column}
? $changed_ordering_cols->{$position_column} # means there was a position change supplied with the update too
: $self->_position # FIXME! (replace with undef)
),
);
}
else {
$self->move_to($changed_ordering_cols->{$position_column});
}
return $self;
}
=head2 delete
Overrides the DBIC delete() method by first moving the object
to the last position, then deleting it, thus ensuring the
integrity of the positions.
=cut
sub delete {
my $self = shift;
my $guard = $self->result_source->schema->txn_scope_guard;
$self->move_last;
$self->next::method( @_ );
( run in 0.854 second using v1.01-cache-2.11-cpan-39bf76dae61 )