Commit | Line | Data |
c11aa533 |
1 | package DBIx::Class::Tree::AdjacencyList::Ordered; |
bb17efa0 |
2 | # vim: ts=8:sw=4:sts=4:et |
3 | |
57f04bd5 |
4 | use strict; |
5 | use warnings; |
bb17efa0 |
6 | |
57f04bd5 |
7 | use base qw( DBIx::Class ); |
8 | use Carp qw( croak ); |
9 | |
10 | __PACKAGE__->load_components(qw( |
c11aa533 |
11 | Ordered |
9717d3ca |
12 | Tree::AdjacencyList |
57f04bd5 |
13 | )); |
14 | |
15 | =head1 NAME |
16 | |
c11aa533 |
17 | DBIx::Class::Tree::AdjacencyList::Ordered - Glue DBIx::Class::Ordered and DBIx::Class::Tree::AdjacencyList together. (EXPERIMENTAL) |
57f04bd5 |
18 | |
19 | =head1 SYNOPSIS |
20 | |
21 | Create a table for your tree data. |
22 | |
c11aa533 |
23 | CREATE TABLE items ( |
24 | item_id INTEGER PRIMARY KEY AUTOINCREMENT, |
82958127 |
25 | parent_id INTEGER NOT NULL DEFAULT 0, |
57f04bd5 |
26 | position INTEGER NOT NULL, |
27 | name TEXT NOT NULL |
28 | ); |
29 | |
c11aa533 |
30 | In your Schema or DB class add Tree::AdjacencyList::Ordered |
9717d3ca |
31 | to the front of the component list. |
57f04bd5 |
32 | |
c11aa533 |
33 | __PACKAGE__->load_components(qw( Tree::AdjacencyList::Ordered ... )); |
57f04bd5 |
34 | |
35 | Specify the column that contains the parent ID and position of each row. |
36 | |
37 | package My::Employee; |
82958127 |
38 | __PACKAGE__->position_column('position'); |
c11aa533 |
39 | __PACKAGE__->parent_column('parent_id'); |
57f04bd5 |
40 | |
41 | This module provides a few extra methods beyond what |
c11aa533 |
42 | L<DBIx::Class::Ordered> and L<DBIx::Class::Tree::AdjacencyList> |
57f04bd5 |
43 | already provide. |
44 | |
c11aa533 |
45 | my $parent = $item->parent(); |
46 | $item->parent( $parent_obj ); |
47 | $item->parent( $parent_id ); |
57f04bd5 |
48 | |
c11aa533 |
49 | my $children_rs = $item->children(); |
50 | my @children = $item->children(); |
57f04bd5 |
51 | |
52 | $parent->append_child( $child ); |
53 | $parent->prepend_child( $child ); |
54 | |
55 | $this->attach_before( $that ); |
56 | $this->attach_after( $that ); |
57 | |
58 | =head1 DESCRIPTION |
59 | |
c11aa533 |
60 | This module provides methods for working with adjacency lists and ordered |
61 | rows. All of the methods that L<DBIx::Class::Ordered> and |
62 | L<DBIx::Class::Tree::AdjacencyList> provide are available with this module. |
57f04bd5 |
63 | |
64 | =head1 METHODS |
65 | |
82958127 |
66 | =head2 parent_column |
67 | |
68 | __PACKAGE__->parent_column('parent_id'); |
69 | |
70 | Works the same as AdjacencyList's parent_column() method, but it |
71 | declares the children() has many relationship to be ordered by the |
72 | position column. |
73 | |
74 | =cut |
75 | |
76 | sub parent_column { |
77 | my $class = shift; |
9717d3ca |
78 | my $position_col = $class->position_column() || croak('You must call position_column() before calling parent_column()'); |
82958127 |
79 | if (@_) { |
9717d3ca |
80 | $class->grouping_column( @_ ); |
81 | $class->next::method( @_ ); |
82 | $class->relationship_info('children')->{attrs}->{order_by} = $position_col; |
82958127 |
83 | return 1; |
84 | } |
9717d3ca |
85 | return $class->grouping_column; |
82958127 |
86 | } |
87 | |
57f04bd5 |
88 | =head2 parent |
89 | |
c11aa533 |
90 | my $parent = $item->parent(); |
91 | $item->parent( $parent_obj ); |
92 | $item->parent( $parent_id ); |
57f04bd5 |
93 | |
82958127 |
94 | This method overrides AdjacencyList's parent() method but |
95 | modifies it so that the object is moved to the last position, |
96 | then the parent is changed, and then it is moved to the last |
c11aa533 |
97 | position of the new list, thus maintaining the intergrity of |
98 | the ordered lists. |
57f04bd5 |
99 | |
100 | =cut |
101 | |
102 | sub parent { |
82958127 |
103 | my $self = shift; |
104 | if (@_) { |
105 | my $new_parent = shift; |
106 | my $parent_col = $self->_parent_column(); |
57f04bd5 |
107 | if (ref($new_parent)) { |
82958127 |
108 | $new_parent = $new_parent->id() || croak('Parent object does not have an ID');; |
57f04bd5 |
109 | } |
82958127 |
110 | return 0 if ($new_parent == ($self->get_column($parent_col)||0)); |
111 | $self->move_last; |
112 | $self->set_column( $parent_col => $new_parent ); |
57f04bd5 |
113 | $self->set_column( |
e338251b |
114 | $self->position_column() => |
115 | $self->result_source->resultset->search( |
c11aa533 |
116 | {$self->_grouping_clause()} |
e338251b |
117 | )->count() + 1 |
57f04bd5 |
118 | ); |
119 | $self->update(); |
120 | return 1; |
121 | } |
82958127 |
122 | return $self->_parent(); |
57f04bd5 |
123 | } |
124 | |
125 | =head2 children |
126 | |
c11aa533 |
127 | my $children_rs = $item->children(); |
128 | my @children = $item->children(); |
57f04bd5 |
129 | |
130 | This method works just like it does in the |
131 | DBIx::Class::Tree::AdjacencyList module except it |
132 | orders the children by there position. |
133 | |
57f04bd5 |
134 | =head2 append_child |
135 | |
136 | $parent->append_child( $child ); |
137 | |
138 | Sets the child to have the specified parent and moves the |
139 | child to the last position. |
140 | |
141 | =cut |
142 | |
143 | sub append_child { |
144 | my( $self, $child ) = @_; |
145 | $child->parent( $self ); |
146 | } |
147 | |
148 | =head2 prepend_child |
149 | |
150 | $parent->prepend_child( $child ); |
151 | |
152 | Sets the child to have the specified parent and moves the |
153 | child to the first position. |
154 | |
155 | =cut |
156 | |
157 | sub prepend_child { |
158 | my( $self, $child ) = @_; |
159 | $child->parent( $self ); |
160 | $child->move_first(); |
161 | } |
162 | |
163 | =head2 attach_before |
164 | |
165 | $this->attach_before( $that ); |
166 | |
167 | Attaches the object at the position just before the |
168 | calling object's position. |
169 | |
170 | =cut |
171 | |
172 | sub attach_before { |
173 | my( $self, $sibling ) = @_; |
174 | $sibling->parent( $self->parent() ); |
175 | $sibling->move_to( $self->get_column($self->position_column()) ); |
176 | } |
177 | |
178 | =head2 attach_after |
179 | |
180 | $this->attach_after( $that ); |
181 | |
182 | Attaches the object at the position just after the |
183 | calling object's position. |
184 | |
185 | =cut |
186 | |
187 | sub attach_after { |
188 | my( $self, $sibling ) = @_; |
189 | $sibling->parent( $self->parent() ); |
190 | $sibling->move_to( $self->get_column($self->position_column()) + 1 ); |
191 | } |
192 | |
9717d3ca |
193 | 1; |
194 | __END__ |
e338251b |
195 | |
9717d3ca |
196 | =head1 INHERITED METHODS |
57f04bd5 |
197 | |
4b44af23 |
198 | =head2 DBIx::Class::Ordered |
199 | |
200 | =over 4 |
201 | |
202 | =item * |
203 | |
204 | L<siblings|DBIx::Class::Ordered/siblings> |
205 | |
206 | =item * |
207 | |
208 | L<first_sibling|DBIx::Class::Ordered/first_sibling> |
209 | |
210 | =item * |
211 | |
212 | L<last_sibling|DBIx::Class::Ordered/last_sibling> |
213 | |
214 | =item * |
215 | |
216 | L<previous_sibling|DBIx::Class::Ordered/previous_sibling> |
217 | |
218 | =item * |
219 | |
220 | L<next_sibling|DBIx::Class::Ordered/next_sibling> |
221 | |
222 | =item * |
223 | |
224 | L<move_previous|DBIx::Class::Ordered/move_previous> |
225 | |
226 | =item * |
227 | |
228 | L<move_next|DBIx::Class::Ordered/move_next> |
229 | |
230 | =item * |
231 | |
232 | L<move_first|DBIx::Class::Ordered/move_first> |
233 | |
234 | =item * |
235 | |
236 | L<move_last|DBIx::Class::Ordered/move_last> |
237 | |
238 | =item * |
239 | |
240 | L<move_to|DBIx::Class::Ordered/move_to> |
241 | |
242 | =item * |
243 | |
244 | L<insert|DBIx::Class::Ordered/insert> |
245 | |
246 | =item * |
247 | |
248 | L<delete|DBIx::Class::Ordered/delete> |
249 | |
250 | =back |
251 | |
252 | =head2 DBIx::Class::Tree::AdjacencyList |
253 | |
254 | =over 4 |
255 | |
256 | =item * |
257 | |
258 | L<parent_column|DBIx::Class::Tree::AdjacencyList/parent_column> |
259 | |
260 | =item * |
261 | |
262 | L<parent|DBIx::Class::Tree::AdjacencyList/parent> |
263 | |
264 | =item * |
265 | |
266 | L<attach_child|DBIx::Class::Tree::AdjacencyList/attach_child> |
267 | |
268 | =item * |
269 | |
270 | L<siblings|DBIx::Class::Tree::AdjacencyList/siblings> |
271 | |
272 | =item * |
273 | |
274 | L<attach_sibling|DBIx::Class::Tree::AdjacencyList/attach_sibling> |
275 | |
276 | =back |
277 | |
278 | =head2 DBIx::Class |
279 | |
280 | =over 4 |
281 | |
282 | =item * |
283 | |
284 | L<mk_classdata|DBIx::Class/mk_classdata> |
285 | |
286 | =item * |
287 | |
288 | L<component_base_class|DBIx::Class/component_base_class> |
289 | |
290 | =back |
291 | |
292 | =head2 DBIx::Class::Componentised |
293 | |
294 | =over 4 |
295 | |
296 | =item * |
297 | |
298 | L<inject_base|DBIx::Class::Componentised/inject_base> |
299 | |
300 | =item * |
301 | |
302 | L<load_components|DBIx::Class::Componentised/load_components> |
303 | |
304 | =item * |
305 | |
306 | L<load_own_components|DBIx::Class::Componentised/load_own_components> |
307 | |
308 | =back |
309 | |
310 | =head2 Class::Data::Accessor |
311 | |
312 | =over 4 |
313 | |
314 | =item * |
315 | |
316 | L<mk_classaccessor|Class::Data::Accessor/mk_classaccessor> |
317 | |
318 | =back |
57f04bd5 |
319 | |
320 | =head1 AUTHOR |
321 | |
322 | Aran Clary Deltac <bluefeet@cpan.org> |
323 | |
324 | =head1 LICENSE |
325 | |
326 | You may distribute this code under the same terms as Perl itself. |
327 | |