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 | |
9 | =attribute_public parent is: ro, isa: 'Catalyst::Controller::DBIC::API::JoinBuilder' |
10 | |
11 | parent stores the direct ascendant in the datastructure that represents the join |
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 | |
23 | =attribute_public children is: ro, isa: ArrayRef['Catalyst::Controller::DBIC::API::JoinBuilder'], traits => ['Array'] |
24 | |
25 | children stores the immediate descendants in the datastructure that represents the join. |
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 | |
47 | =attribute_public joins is: ro, isa: HashRef, lazy_build: true |
48 | |
49 | joins holds the cached generated join datastructure. |
50 | |
51 | =cut |
52 | |
8ea592cb |
53 | has joins => ( |
54 | is => 'ro', |
55 | isa => HashRef, |
d2739840 |
56 | lazy_build => 1, |
57 | ); |
58 | |
59 | =attribute_public name is: ro, isa: Str, required: 1 |
60 | |
61 | Sets the key for this level in the generated hash |
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 | |
73 | _build_joins finds the top parent in the structure and then recursively iterates the children building out the join datastructure |
74 | |
75 | =cut |
76 | |
8ea592cb |
77 | sub _build_joins { |
d2739840 |
78 | my ($self) = @_; |
406086f3 |
79 | |
d2739840 |
80 | my $parent; |
8ea592cb |
81 | while ( my $found = $self->parent ) { |
82 | if ( $found->has_parent ) { |
d2739840 |
83 | $self = $found; |
84 | next; |
85 | } |
86 | $parent = $found; |
87 | } |
88 | |
89 | my $builder; |
8ea592cb |
90 | $builder = sub { |
d2739840 |
91 | my ($node) = @_; |
92 | my $foo = {}; |
8ea592cb |
93 | map { $foo->{ $_->name } = $builder->($_) } $node->all_children; |
d2739840 |
94 | return $foo; |
95 | }; |
96 | |
8ea592cb |
97 | return $builder->( $parent || $self ); |
d2739840 |
98 | } |
99 | |
100 | =head1 DESCRIPTION |
101 | |
102 | JoinBuilder is used to keep track of joins automgically for complex searches. It accomplishes this by building a simple tree of parents and children and then recursively drilling into the tree to produce a useable join attribute for ->search. |
103 | |
104 | =cut |
105 | |
106 | 1; |