The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

DBIx::Tree::MaterializedPath::Node - node objects for "materialized path" trees

VERSION

Version 0.06

SYNOPSIS

    my $node = DBIx::Tree::MaterializedPath::Node->new( $root );

DESCRIPTION

This module implements nodes for a "materialized path" parent/child tree.

Note: Normally nodes would not be created independently - create a tree first using DBIx::Tree::MaterializedPath and then create/manipulate its children.

METHODS

new

    my $node = DBIx::Tree::MaterializedPath::Node->new( $root );

new() initializes a node in the tree.

new() expects a single argument, which must be a DBIx::Tree::MaterializedPath object representing the root of the tree that this node belongs to.

is_root

Returns true if this node is the root of the tree

get_root

Returns root of the tree

is_same_node_as

    $node->is_same_node_as( $other_node )

Returns true if this node is the same as the specified node, based on whether the two nodes have the same path.

is_ancestor_of

    $node->is_ancestor_of( $other_node )

Returns true if this node is an ancestor of the specified node.

Returns false if this node is the same as the specified node.

is_descendant_of

    $node->is_descendant_of( $other_node )

Returns true if this node is a descendant of the specified node.

Returns false if this node is the same as the specified node.

depth

Returns the depth of this node in the tree.

The root node is at depth zero.

table_name

Returns the name of the database table in which this tree data is stored. Useful when creating JOIN-type queries across multiple tables for use with find().

data

    $node->data( $optional_data_hashref )

(Optionally sets and) returns a hashref of metadata stored with the node. Setting data will update the row in the database. Getting data will return the data stored in the node, or will query the database using the node ID if the node data has not yet been loaded.

If setting data, note that each key of the hash must correspond to a column of the same name that already exists in the database table.

Will croak if data is not a HASHREF or is an empty hash.

Will croak if the data hash contains keys which match either the id_column_name or the path_column_name as specified in the DBIx::Tree::MaterializedPath constructor.

refresh_data

Queries the database using the node ID to refresh the in-memory copy of the node data. Returns a hashref of data stored with the node.

Note: Setting node metadata via data() will keep the database and in-memory copies of the node metadata in sync. Only use the refresh_data() method if you think this node's metadata in the database may have changed out from under you.

add_children

    $node->add_children( @children )

Add one or more child nodes below this node. Returns a reference to a list of the newly-created node objects. New nodes will be created to the right of any existing children (i.e. ordered after any existing children).

@children should be a list (or listref) of hashrefs, where each hashref contains the metadata for a child to be added.

Note: Children with no metadata can be added by passing empty hashrefs, e.g.:

    $node->add_children({}, {}, {})

add_child

    $node->add_child( $child )

Add a child node below this node. Returns the newly-created node object.

$child should be a hashref representing the child to add.

This is just a wrapper for add_children().

add_children_at_left

    $node->add_children_at_left( @children )

Add one or more child nodes below this node, as the left-most children (i.e. ordered before any existing children). Returns a reference to a list of the newly-created node objects.

Note that this requires more work than adding children at the end of the list (via add_children()), since in this case the paths for any existing children (and all of their descendants) will need to be updated.

@children should be a list (or listref) of hashrefs, where each hashref contains the metadata for a child to be added.

Note: Children with no metadata can be added by passing empty hashrefs, e.g.:

    $node->add_children_at_left({}, {}, {})

get_parent

Returns this node's parent node, or undef if this node is the root.

get_children

    $node->get_children( $options_hashref )

Returns a reference to a (possibly empty) ordered list of direct child nodes.

By default, any node metadata stored in the database is retrieved by the database SELECT and is populated in each of the corresponding node objects.

If the optional parameters hashref contains a true value for "delay_load", then the metadata will not be retrieved from the database until the data() method is called on a given node.

get_siblings

    $node->get_siblings( $options_hashref )

Returns a reference to an ordered list of sibling nodes.

Note: The list will always contain at least one node, i.e. the current node on which the method is being called.

By default, any node metadata stored in the database is retrieved by the database SELECT and is populated in each of the corresponding node objects.

If the optional parameters hashref contains a true value for "delay_load", then the metadata will not be retrieved from the database until the data() method is called on a given node.

get_siblings_to_the_right

    $node->get_siblings_to_the_right( $options_hashref )

Returns a reference to an ordered list of any sibling nodes to the right of this node.

Note: The list will not contain the current node.

By default, any node metadata stored in the database is retrieved by the database SELECT and is populated in each of the corresponding node objects.

If the optional parameters hashref contains a true value for "delay_load", then the metadata will not be retrieved from the database until the data() method is called on a given node.

get_siblings_to_the_left

    $node->get_siblings_to_the_left( $options_hashref )

Returns a reference to an ordered list of any sibling nodes to the left of this node.

Note: The list will not contain the current node.

By default, any node metadata stored in the database is retrieved by the database SELECT and is populated in each of the corresponding node objects.

If the optional parameters hashref contains a true value for "delay_load", then the metadata will not be retrieved from the database until the data() method is called on a given node.

get_descendants

    $node->get_descendants( $options_hashref )

Returns a DBIx::Tree::MaterializedPath::TreeRepresentation object, which in turn can be used to traverse() this node's descendants.

By default, any node metadata stored in the database is retrieved by the database SELECT and is populated in each of the corresponding node objects.

If the optional parameters hashref contains a true value for "delay_load", then the metadata will not be retrieved from the database until the data() method is called on a given node.

See for information on traverse().

delete_descendants

Delete any descendant nodes below this node.

delete

Delete this node and any descendant nodes below it.

If this node has any siblings to the right, the paths for those siblings (and for all of their descendants, if any) will be updated.

Don't try to use the node object after you have deleted it!

Note: The root node of the tree cannot be deleted.

find

    $node->find( $options_hashref )

Given an SQL::Abstract-style where clause, returns a reference to a (possibly empty) ordered list of descendant nodes that match.

find() accepts a hashref of arguments:

where

Required.

An SQL::Abstract-style where clause

extra_tables

An arrayref of additional table names to include in the SELECT statement, if the WHERE clause queries across any tables other than the main table in which the tree resides.

Note: If querying across additional tables, make sure that the column names referenced in the WHERE clause are correctly prefixed by the table in which they live.

order_by

An arrayref of column names to order the results by. If specified, this will override the default ordering by path (i.e. the order the node's descendants would be traversed).

delay_load

By default, any node metadata stored in the database is retrieved by the database SELECT and is populated in each of the corresponding node objects.

If the options hashref contains a true value for "delay_load", then the metadata will not be retrieved from the database until the data() method is called on a given node.

For example, if you have metadata columns in your tree table named "name" and "title", you could do queries like so:

    # name = ?
    #
    $nodes = $node->find(where => {
                                    name => 'exact text',
                                  });

    # name like ?
    #
    $nodes = $node->find(where => {
                                    name => {-like => '%text'},
                                  });

    # (name = ?) OR (name = ?)
    #
    $nodes = $node->find(where => {
                                    name => ['this', 'that'],
                                  });

    # (name = ?) AND (title = ?)
    #
    $nodes = $node->find(where => {
                                    name  => 'this',
                                    title => 'that',
                                  });

    # (name = ?) OR (title = ?)
    #
    # Note: "where" is an arrayref, not a hashref!
    #
    $nodes = $node->find(where => [
                                    {name  => 'this'},
                                    {title => 'that'},
                                  ]);

    # (name like ?) AND (name != ?)
    #
    $nodes = $node->find(where => {
                                    name => [
                                              -and =>
                                              {-like => '%text'},
                                              {'!='  => 'bad text},
                                            ],
                                  });

You can also do JOIN queries across tables using the extra_tables parameter. Suppose you have a "movies" table with columns for "id" and "title", and that your tree table has a metadata column named "movie_id" which corresponds to the "id" column in the "movies" table. You could do queries like so:

    my $table = $node->table_name;    # the table the tree lives in

    # (movies.title like ?) AND (movies.id = my_tree.movie_id)
    #
    # Note the literal backslash before "= $table.movie_id"...
    #
    $nodes = $node->find(extra_tables => ['movies'],
                         where => {
                                    'movies.title' => {-like => 'text%'},
                                    'movies.id'    => \"= $table.movie_id",
                                  });

swap_node

    $node->swap_node( $other_node )

Swap locations (i.e. paths) between this node and the specified node. The nodes being swapped can be at different depths in the tree.

Any children of the nodes being swapped will remain in place. E.g. swapping "B" and "E" in the tree below:

              A
           ___|_____
          |         |
          B         E
         _|_     ___|___
        |   |   |   |   |
        C   D   F   I   J
               _|_
              |   |
              G   H

results in:

              A
           ___|_____
          |         |
          E         B
         _|_     ___|___
        |   |   |   |   |
        C   D   F   I   J
               _|_
              |   |
              G   H

Note: The root node of the tree cannot be swapped with another node.

swap_subtree

    $node->swap_subtree( $other_node )

Swap this node (and all of its children) with the specified node (and all of its children). The nodes being swapped can be at different depths in the tree.

Any children of the nodes being swapped will move with them. E.g. swapping "B" and "E" in the tree below:

              A
           ___|_____
          |         |
          B         E
         _|_     ___|___
        |   |   |   |   |
        C   D   F   I   J
               _|_
              |   |
              G   H

results in:

              A
           ___|_____
          |         |
          E         B
       ___|___     _|_
      |   |   |   |   |
      F   I   J   C   D
     _|_
    |   |
    G   H

Note: Because subtrees are being swapped, a node cannot be swapped with one of its own ancestors or descendants.

Note: The root node of the tree cannot be swapped with another node.

clone

    $new_node = $node->clone

Create a clone of an existing node object.

SEE ALSO

DBIx::Tree::MaterializedPath

DBIx::Tree::MaterializedPath::PathMapper

DBIx::Tree::MaterializedPath::TreeRepresentation

SQL::Abstract

BUGS

Please report any bugs or feature requests to bug-dbix-tree-materializedpath at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=DBIx-Tree-MaterializedPath. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

SUPPORT

You can find documentation for this module with the perldoc command.

    perldoc DBIx::Tree::MaterializedPath

You can also look for information at:

AUTHOR

Larry Leszczynski, <larryl at cpan.org>

COPYRIGHT & LICENSE

Copyright 2008 Larry Leszczynski, all rights reserved.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.