autogenerated makefile.pl == bad
[dbsrgits/DBIx-Class-Tree.git] / lib / DBIx / Class / Tree / AdjacencyList / Positional.pm
CommitLineData
57f04bd5 1# vim: ts=8:sw=4:sts=4:et
2package DBIx::Class::Tree::AdjacencyList::Positional;
3use strict;
4use warnings;
5use base qw( DBIx::Class );
6use Carp qw( croak );
7
8__PACKAGE__->load_components(qw(
9 Tree::AdjacencyList
10 Positional
11));
12
13=head1 NAME
14
15DBIx::Class::Tree::AdjacencyList::Positional - Glue DBIx::Class::Positional and DBIx::Class::Tree::AdjacencyList together. (EXPERIMENTAL)
16
17=head1 SYNOPSIS
18
19Create a table for your tree data.
20
21 CREATE TABLE employees (
22 employee_id INTEGER PRIMARY KEY AUTOINCREMENT,
23 parent_id INTEGER NOT NULL,
24 position INTEGER NOT NULL,
25 name TEXT NOT NULL
26 );
27
28In your Schema or DB class add Tree::AdjacencyList::Positional
29to the top of the component list.
30
31 __PACKAGE__->load_components(qw( Tree::AdjacencyList::Positional ... ));
32
33Specify the column that contains the parent ID and position of each row.
34
35 package My::Employee;
36 __PACKAGE__->parent_column('parent_id');
37 __PACAKGE__->position_column('position');
38
39This module provides a few extra methods beyond what
40L<DBIx::Class::Positional> and L<DBIx::Class::Tree::AdjacencyList>
41already provide.
42
43 my $parent = $employee->parent();
44 $employee->parent( $parent_obj );
45 $employee->parent( $parent_id );
46
47 my $children_rs = $employee->children();
48 my @children = $employee->children();
49
50 $parent->append_child( $child );
51 $parent->prepend_child( $child );
52
53 $this->attach_before( $that );
54 $this->attach_after( $that );
55
56=head1 DESCRIPTION
57
58This module provides methods for working with adjacency lists and positional
59rows. All of the methods that L<DBIx::Class::Positional> and
60L<DBIx::Class::Tree::AdjacencyList> provide are available with this module.
61If you
62
63=head1 METHODS
64
65=head2 parent
66
67 my $parent = $employee->parent();
68 $employee->parent( $parent_obj );
69 $employee->parent( $parent_id );
70
71 my $children_rs = $employee->children();
72 my @children = $employee->children();
73
74This method works exactly like it does in the
75DBIx::Class::Tree::AdjacencyList module except that it will
76first move the object to the last position of the list, change
77the parent ID, then move the object to the last position of
78the new list. This ensures the intergrity of the positions.
79
80=cut
81
82sub parent {
83 my( $self, $new_parent ) = @_;
84 if ($new_parent) {
85 if (ref($new_parent)) {
86 $new_parent = $new_parent->id() || 0;
87 }
88 return 0 if ($new_parent == ($self->get_column($self->parent_column())||0));
89 $self->move_last();
90 return 0 if (!$self->next::method( $new_parent ));
91 $self->set_column(
92 $self->position_column() => $self->search( {$self->_collection_clause()} )->count() + 1
93 );
94 $self->update();
95 return 1;
96 }
97 else {
98 return $self->next::method();
99 }
100}
101
102=head2 children
103
104 my $children_rs = $employee->children();
105 my @children = $employee->children();
106
107This method works just like it does in the
108DBIx::Class::Tree::AdjacencyList module except it
109orders the children by there position.
110
111=cut
112
113sub children {
114 my( $self ) = @_;
115 my $rs = $self->search(
116 { $self->parent_column() => $self->id() },
117 { order_by => $self->position_column() }
118 );
119 return $rs->all() if (wantarray());
120 return $rs;
121}
122
123=head2 append_child
124
125 $parent->append_child( $child );
126
127Sets the child to have the specified parent and moves the
128child to the last position.
129
130=cut
131
132sub append_child {
133 my( $self, $child ) = @_;
134 $child->parent( $self );
135}
136
137=head2 prepend_child
138
139 $parent->prepend_child( $child );
140
141Sets the child to have the specified parent and moves the
142child to the first position.
143
144=cut
145
146sub prepend_child {
147 my( $self, $child ) = @_;
148 $child->parent( $self );
149 $child->move_first();
150}
151
152=head2 attach_before
153
154 $this->attach_before( $that );
155
156Attaches the object at the position just before the
157calling object's position.
158
159=cut
160
161sub attach_before {
162 my( $self, $sibling ) = @_;
163 $sibling->parent( $self->parent() );
164 $sibling->move_to( $self->get_column($self->position_column()) );
165}
166
167=head2 attach_after
168
169 $this->attach_after( $that );
170
171Attaches the object at the position just after the
172calling object's position.
173
174=cut
175
176sub attach_after {
177 my( $self, $sibling ) = @_;
178 $sibling->parent( $self->parent() );
179 $sibling->move_to( $self->get_column($self->position_column()) + 1 );
180}
181
182=head1 PRIVATE METHODS
183
184These methods are used internally. You should never have the
185need to use them.
186
187=head2 _collection_clause
188
189This method is provided as an override of the method in
190L<DBIx::Class::Positional>. This method is what provides the
191glue between AdjacencyList and Positional.
192
193=cut
194
195sub _collection_clause {
196 my( $self ) = @_;
197 return (
198 $self->parent_column() =>
199 $self->get_column($self->parent_column())
200 );
201}
202
2031;
204__END__
205
206=head1 AUTHOR
207
208Aran Clary Deltac <bluefeet@cpan.org>
209
210=head1 LICENSE
211
212You may distribute this code under the same terms as Perl itself.
213