Commit | Line | Data |
db57afbb |
1 | package DBIx::Class::ResultSetManager; |
ed28f830 |
2 | use strict; |
bf5ecff9 |
3 | use warnings; |
ed28f830 |
4 | use base 'DBIx::Class'; |
5 | use Class::Inspector; |
6 | |
75d07914 |
7 | =head1 NAME |
bc0c9800 |
8 | |
9b83fccd |
9 | DBIx::Class::ResultSetManager - helpful methods for managing resultset |
10 | classes (EXPERIMENTAL) |
bc0c9800 |
11 | |
12 | =head1 SYNOPSIS |
13 | |
14 | # in a table class |
15 | __PACKAGE__->load_components(qw/ResultSetManager Core/); # note order! |
9b83fccd |
16 | |
bc0c9800 |
17 | # will be removed from the table class and inserted into a |
18 | # table-specific resultset class |
19 | sub search_by_year_desc : ResultSet { |
20 | my $self = shift; |
21 | my $cond = shift; |
22 | my $attrs = shift || {}; |
23 | $attrs->{order_by} = 'year DESC'; |
63e9e431 |
24 | $self->search($cond, $attrs); |
bc0c9800 |
25 | } |
26 | |
27 | $rs = $schema->resultset('CD')->search_by_year_desc({ artist => 'Tool' }); |
28 | |
29 | =head1 DESCRIPTION |
30 | |
31 | This package implements two useful features for customizing resultset |
32 | classes. C<load_resultset_components> loads components in addition to |
33 | C<DBIx::Class::ResultSet> (or whatever you set as |
34 | C<base_resultset_class>). Any methods tagged with the C<ResultSet> |
35 | attribute will be moved into a table-specific resultset class (by |
36 | default called C<Class::_resultset>, but configurable via |
37 | C<table_resultset_class_suffix>). Most of the magic is done when you |
38 | call C<< __PACKAGE__->table >>. |
39 | |
40 | =cut |
41 | |
24d67825 |
42 | __PACKAGE__->mk_classdata($_) |
43 | for qw/ base_resultset_class table_resultset_class_suffix /; |
570783b1 |
44 | __PACKAGE__->base_resultset_class('DBIx::Class::ResultSet'); |
f0750722 |
45 | __PACKAGE__->table_resultset_class_suffix('::_resultset'); |
ed28f830 |
46 | |
9b83fccd |
47 | =head2 table |
48 | |
49 | Stacks on top of the normal L<DBIx::Class> C<table> method. Any |
50 | methods tagged with the C<ResultSet> attribute will be moved into a |
51 | table-specific resultset class (by default called |
52 | C<Class::_resultset>, but configurable via |
53 | C<table_resultset_class_suffix>). The magic for this is done within |
54 | this C<< __PACKAGE__->table >> call. |
55 | |
56 | =cut |
57 | |
ed28f830 |
58 | sub table { |
59 | my ($self,@rest) = @_; |
e8861f71 |
60 | my $ret = $self->next::method(@rest); |
61 | if (@rest) { |
62 | $self->_register_attributes; |
75d07914 |
63 | $self->_register_resultset_class; |
e8861f71 |
64 | } |
65 | return $ret; |
ed28f830 |
66 | } |
67 | |
9b83fccd |
68 | =head2 load_resultset_components |
69 | |
9b83fccd |
70 | C<load_resultset_components> loads components in addition to |
71 | C<DBIx::Class::ResultSet> (or whatever you set as |
72 | C<base_resultset_class>). |
73 | |
74 | =cut |
75 | |
ed28f830 |
76 | sub load_resultset_components { |
77 | my ($self,@comp) = @_; |
78 | my $resultset_class = $self->_setup_resultset_class; |
79 | $resultset_class->load_components(@comp); |
80 | } |
81 | |
ed28f830 |
82 | sub _register_attributes { |
83 | my $self = shift; |
84 | my $cache = $self->_attr_cache; |
da95b45f |
85 | return if keys %$cache == 0; |
9b83fccd |
86 | |
ed28f830 |
87 | foreach my $meth (@{Class::Inspector->methods($self) || []}) { |
88 | my $attrs = $cache->{$self->can($meth)}; |
89 | next unless $attrs; |
a39e84a3 |
90 | if ($attrs->[0] eq 'ResultSet') { |
ed28f830 |
91 | no strict 'refs'; |
92 | my $resultset_class = $self->_setup_resultset_class; |
e250c046 |
93 | *{"$resultset_class\::$meth"} = $self->can($meth); |
f8d97a01 |
94 | delete ${"${self}::"}{$meth}; |
ed28f830 |
95 | } |
96 | } |
ed28f830 |
97 | } |
98 | |
99 | sub _setup_resultset_class { |
100 | my $self = shift; |
f0750722 |
101 | my $resultset_class = $self . $self->table_resultset_class_suffix; |
ed28f830 |
102 | no strict 'refs'; |
103 | unless (@{"$resultset_class\::ISA"}) { |
570783b1 |
104 | @{"$resultset_class\::ISA"} = ($self->base_resultset_class); |
ed28f830 |
105 | } |
106 | return $resultset_class; |
107 | } |
108 | |
570783b1 |
109 | sub _register_resultset_class { |
110 | my $self = shift; |
f0750722 |
111 | my $resultset_class = $self . $self->table_resultset_class_suffix; |
570783b1 |
112 | no strict 'refs'; |
113 | if (@{"$resultset_class\::ISA"}) { |
24d67825 |
114 | $self->result_source_instance->resultset_class($resultset_class); |
570783b1 |
115 | } else { |
24d67825 |
116 | $self->result_source_instance->resultset_class |
75d07914 |
117 | ($self->base_resultset_class); |
570783b1 |
118 | } |
119 | } |
120 | |
19345968 |
121 | 1; |
122 | |
19345968 |
123 | =head1 AUTHORS |
124 | |
125 | David Kamholz <dkamholz@cpan.org> |
126 | |
127 | =head1 LICENSE |
128 | |
129 | You may distribute this code under the same terms as Perl itself. |
130 | |
131 | =cut |