throw error when doing parameterized join twice on same relation
[dbsrgits/DBIx-Class-ParameterizedJoinHack.git] / lib / DBIx / Class / ResultSet / ParameterizedJoinHack.pm
CommitLineData
638c1533 1package DBIx::Class::ResultSet::ParameterizedJoinHack;
2
3use strict;
4use warnings;
5use DBIx::Class::ParameterizedJoinHack;
6use base qw(DBIx::Class::ResultSet);
7
8sub _parameterized_join_store {
9 $_[0]->result_source->result_class
10 ->$DBIx::Class::ParameterizedJoinHack::STORE
11}
12
13sub with_parameterized_join {
14 my ($self, $rel, $params) = @_;
598b28ef 15 die "Missing relation name in with_parameterized_join"
16 unless defined $rel;
93b74da6 17
598b28ef 18 {
19 my $params_ref = ref($params);
20 $params_ref = 'non-reference-value'
21 unless $params_ref;
22 die "Parameters value must be a hash ref, not ${params_ref}"
23 unless $params_ref eq 'HASH';
24 }
93b74da6 25
6d37bc62 26 die "Parameterized join can only be used once per relation"
27 if exists(($self->{attrs}{join_parameters} || {})->{$rel});
28
638c1533 29 $self->search_rs(
30 {},
31 { join => $rel,
32 join_parameters => {
33 %{$self->{attrs}{join_parameters}||{}},
34 $rel => $params
35 }
36 },
37 );
38}
39
ddc15dd9 40sub _localize_parameters {
41 my ($self, $final, $params, $store, $first, @rest) = @_;
42 return $final->() unless $first;
43 local $store->{$first}{params} = $params->{$first};
44 $self->_localize_parameters($final, $params, $store, @rest);
45}
46
638c1533 47sub call_with_parameters {
48 my ($self, $method, @args) = @_;
49 my %params = %{$self->{attrs}{join_parameters}||{}};
50 my $store = $self->_parameterized_join_store;
ddc15dd9 51 return $self->_localize_parameters(
52 sub { $self->$method(@args) },
53 \%params, $store,
54 keys %params
55 );
638c1533 56}
57
58sub _resolved_attrs { my $self = shift; $self->call_with_parameters($self->next::can, @_) }
59sub related_resultset { my $self = shift; $self->call_with_parameters($self->next::can, @_) }
60
611;
62
63=head1 NAME
64
65DBIx::Class::ResultSet::ParameterizedJoinHack
66
67=head1 SYNOPSIS
68
69 package MySchema::ResultSet::Person;
70 use base qw(DBIx::Class::ResultSet);
71
72 __PACKAGE__->load_components(qw(ResultSet::ParameterizedJoinHack));
73
74 1;
75
76=head1 DESCRIPTION
77
78This is a ResultSet component allowing you to access the dynamically
79parameterized relations declared with
80L<DBIx::Class::ParameterizedJoinHack>.
81
82Enable the component as usual with:
83
84 __PACKAGE__->load_components(qw( ResultSet::ParameterizedJoinHack ));
85
86in your ResultSet class.
87
88See L<DBIx::Class::ParameterizedJoinHack> for declaration documentation,
89a general overview, and examples.
90
91=head1 METHODS
92
93=head2 with_parameterized_join
94
95 my $joined_rs = $resultset->with_parameterized_join(
96 $relation_name,
97 $parameters,
98 );
99
100This method constructs a ResultSet joined with the given C<$relation_name>
101by the passed C<$parameters>. The C<$relation_name> is the name as
102declared on the Result, C<$parameters> is a hash reference with the keys
103being the parameter names, and the values being the arguments to the join
104builder.
105
106=head1 SPONSORS
107
108Development of this module was sponsored by
109
110=over
111
112=item * Ctrl O L<http://ctrlo.com>
113
114=back
115
116=head1 AUTHOR
117
118 Matt S. Trout <mst@shadowcat.co.uk>
119
120=head1 CONTRIBUTORS
121
122None yet.
123
124=head1 COPYRIGHT
125
126Copyright (c) 2015 the DBIx::Class::ParameterizedJoinHack L</AUTHOR> and L</CONTRIBUTORS>
127as listed above.
128
129=head1 LICENSE
130
131This library is free software and may be distributed under the same terms
132as perl itself.
133
134=cut