Commit | Line | Data |
d2739840 |
1 | package Catalyst::Controller::DBIC::API::JoinBuilder; |
2 | |
3 | #ABSTRACT: Provides a helper class to automatically keep track of joins in complex searches |
4 | use Moose; |
5 | use MooseX::Types::Moose(':all'); |
6 | use Catalyst::Controller::DBIC::API::Types(':all'); |
7 | use namespace::autoclean; |
8 | |
c0c8e1c6 |
9 | =attribute_public parent |
d2739840 |
10 | |
c0c8e1c6 |
11 | Stores the direct ascendant in the datastructure that represents the join. |
d2739840 |
12 | |
13 | =cut |
14 | |
8ea592cb |
15 | has parent => ( |
16 | is => 'ro', |
17 | isa => JoinBuilder, |
d2739840 |
18 | predicate => 'has_parent', |
8ea592cb |
19 | weak_ref => 1, |
20 | trigger => sub { my ( $self, $new ) = @_; $new->add_child($self); }, |
d2739840 |
21 | ); |
22 | |
c0c8e1c6 |
23 | =attribute_public children |
d2739840 |
24 | |
c0c8e1c6 |
25 | Stores the immediate descendants in the datastructure that represents the join. |
d2739840 |
26 | |
27 | Handles the following methods: |
28 | |
29 | all_children => 'elements' |
30 | has_children => 'count' |
8ea592cb |
31 | add_child => 'push' |
d2739840 |
32 | |
33 | =cut |
34 | |
8ea592cb |
35 | has children => ( |
36 | is => 'ro', |
37 | isa => ArrayRef [JoinBuilder], |
38 | traits => ['Array'], |
d2739840 |
39 | default => sub { [] }, |
8ea592cb |
40 | handles => { |
d2739840 |
41 | all_children => 'elements', |
42 | has_children => 'count', |
8ea592cb |
43 | add_child => 'push', |
d2739840 |
44 | } |
45 | ); |
46 | |
c0c8e1c6 |
47 | =attribute_public joins |
d2739840 |
48 | |
c0c8e1c6 |
49 | Holds the cached, generated join datastructure. |
d2739840 |
50 | |
51 | =cut |
52 | |
8ea592cb |
53 | has joins => ( |
54 | is => 'ro', |
55 | isa => HashRef, |
d2739840 |
56 | lazy_build => 1, |
57 | ); |
58 | |
c0c8e1c6 |
59 | =attribute_public name |
d2739840 |
60 | |
c0c8e1c6 |
61 | Sets the key for this level in the generated hash. |
d2739840 |
62 | |
63 | =cut |
64 | |
8ea592cb |
65 | has name => ( |
66 | is => 'ro', |
67 | isa => Str, |
d2739840 |
68 | required => 1, |
69 | ); |
70 | |
71 | =method_private _build_joins |
72 | |
c0c8e1c6 |
73 | Finds the top parent in the structure and then recursively iterates the children |
74 | building out the join datastructure. |
d2739840 |
75 | |
76 | =cut |
77 | |
8ea592cb |
78 | sub _build_joins { |
d2739840 |
79 | my ($self) = @_; |
406086f3 |
80 | |
d2739840 |
81 | my $parent; |
8ea592cb |
82 | while ( my $found = $self->parent ) { |
83 | if ( $found->has_parent ) { |
d2739840 |
84 | $self = $found; |
85 | next; |
86 | } |
87 | $parent = $found; |
88 | } |
89 | |
90 | my $builder; |
8ea592cb |
91 | $builder = sub { |
d2739840 |
92 | my ($node) = @_; |
93 | my $foo = {}; |
8ea592cb |
94 | map { $foo->{ $_->name } = $builder->($_) } $node->all_children; |
d2739840 |
95 | return $foo; |
96 | }; |
97 | |
8ea592cb |
98 | return $builder->( $parent || $self ); |
d2739840 |
99 | } |
100 | |
101 | =head1 DESCRIPTION |
102 | |
c0c8e1c6 |
103 | JoinBuilder is used to keep track of joins automagically for complex searches. |
104 | It accomplishes this by building a simple tree of parents and children and then |
105 | recursively drilling into the tree to produce a useable join attribute for |
106 | search. |
d2739840 |
107 | |
108 | =cut |
109 | |
110 | 1; |