DBICx-MaterializedPath
view release on metacpan or search on metacpan
lib/DBICx/MaterializedPath.pm view on Meta::CPAN
my $self = shift;
my $path_column = $self->path_column || "";
my $separator = quotemeta( $self->path_separator );
split($separator, $self->$path_column || "");
}
sub root_node :method {
my $self = shift;
my ( $root_id ) = $self->_nodelist;
$self->result_source->resultset->find($root_id);
}
# Note caveat, instructions about children method.
# How can order_by get into this mix?
sub grandchildren {
my $self = shift;
my $path_separator = $self->path_separator;
my $path_column = $self->path_column;
my $id = $self->id;
# Example: 1/2/3
# to find descendants of 1, use LIKE "1/%"
# to find descendants of 2, use LIKE "%/2/%"
my $like_if_root = "${id}${path_separator}\%";
my $like_not_root = "\%${path_separator}${id}${path_separator}\%";
my @grandkids = $self->result_source->resultset->search(
{
-or => [
$path_column => { 'like', $like_if_root },
$path_column => { 'like', $like_not_root },
]
},
{
order_by => \"LENGTH($path_column)"
},
);
return @grandkids;
}
sub set_materialized_path :method {
my $self = shift;
my $parent_column = $self->parent_column;
my $path_column = $self->path_column;
my @path_parts = map { $_->id } $self->_compute_ancestors;
push @path_parts, $self->id;
my $materialized_path = join( $self->path_separator, @path_parts );
$self->$path_column( $materialized_path );
return $materialized_path; # For good measure.
}
sub insert :method {
my $self = shift;
$self->next::method(@_);
$self->set_materialized_path;
$self->update;
}
sub update :method {
my $self = shift;
my %to_update = $self->get_dirty_columns;
my $parent_column = $self->parent_column;
$self->next::method(@_);
return $self unless $to_update{$parent_column};
# This should be configurable as a transaction I think. 321
$self->set_materialized_path;
for my $descendant ( $self->grandchildren )
{
$descendant->set_materialized_path;
$descendant->update;
}
return $self;
}
# Previous and next support here.
sub siblings :method {
my $self = shift;
my $parent_column = $self->parent_column;
my $sort = [ $self->_sibling_order || $self->primary_columns ];
$self->result_source
->resultset
->search({ $parent_column => $self->$parent_column },
{ order_by => $sort });
}
1;
__END__
=pod
=head1 NAME
DBICx::MaterializedPath - L<DBIx::Class> plugin for automatically tracking lineage paths in simple data trees.
=head1 PREFER
Please see L<DBIx::Class::Tree::Mobius>, L<DBIx::Class::Graph>, and L<DBIx::Class::Tree> instead of this experimental package.
=head1 SYNOPSIS
We need a table, or tables, which represents a tree.
CREATE TABLE tree_data (
id INTEGER PRIMARY KEY NOT NULL,
parent INT(10),
content TEXT NOT NULL,
path VARCHAR(255),
created DATETIME(19) NOT NULL
);
CREATE INDEX tree_data_idx_parent ON tree_data (parent);
In your L<DBIx::Class> add this to your componentsE<ndash>
use warnings;
use strict;
use parent qw( DBIx::Class );
( run in 0.887 second using v1.01-cache-2.11-cpan-39bf76dae61 )