File Coverage

blib/lib/DBIx/Class/Candy/ResultSet.pm
Criterion Covered Total %
statement 77 85 90.5
branch 9 18 50.0
condition 2 5 40.0
subroutine 16 16 100.0
pod 0 7 0.0
total 104 131 79.3


line stmt bran cond sub pod time code
1             package DBIx::Class::Candy::ResultSet;
2             $DBIx::Class::Candy::ResultSet::VERSION = '0.005002';
3 2     2   4442 use strict;
  2         3  
  2         49  
4 2     2   5 use warnings;
  2         3  
  2         36  
5              
6 2     2   7 use MRO::Compat;
  2         3  
  2         35  
7 2     2   7 use Sub::Exporter 'build_exporter';
  2         2  
  2         14  
8 2     2   306 use Carp 'croak';
  2         3  
  2         958  
9              
10             # ABSTRACT: Sugar for your resultsets
11              
12 4   50 4 0 10 sub base { return $_[1] || 'DBIx::Class::ResultSet' }
13              
14 2     2 0 22 sub perl_version { return $_[1] }
15              
16 2     2 0 1 sub experimental { $_[1] }
17              
18             sub import {
19 4     4   1745 my $self = shift;
20              
21 4         7 my $inheritor = caller(0);
22 4         14 my $args = $self->parse_arguments(\@_);
23 4         11 my $perl_version = $self->perl_version($args->{perl_version});
24 4         12 my $experimental = $self->experimental($args->{experimental});
25 4         8 my @rest = @{$args->{rest}};
  4         6  
26              
27 4         12 $self->set_base($inheritor, $args->{base});
28 4         4 $inheritor->load_components(@{$args->{components}});
  4         41  
29              
30 4         32 @_ = ($self, @rest);
31 4         19 my $import = build_exporter({
32             installer => $self->installer,
33             collectors => [ INIT => $self->gen_INIT($perl_version, $inheritor, $experimental) ],
34             });
35              
36 4         377 goto $import
37             }
38              
39             sub parse_arguments {
40 4     4 0 3 my $self = shift;
41 4         4 my @args = @{shift @_};
  4         8  
42              
43 4         5 my $skipnext;
44             my $base;
45 0         0 my @rest;
46 4         4 my $perl_version = undef;
47 4         3 my $components = [];
48 4         4 my $experimental;
49              
50 4         9 for my $idx ( 0 .. $#args ) {
51 4         6 my $val = $args[$idx];
52              
53 4 50       9 next unless defined $val;
54 4 100       6 if ($skipnext) {
55 2         3 $skipnext--;
56 2         4 next;
57             }
58              
59 2 50       6 if ( $val eq '-base' ) {
    0          
    0          
    0          
60 2         2 $base = $args[$idx + 1];
61 2         3 $skipnext = 1;
62             } elsif ( $val eq '-perl5' ) {
63 0         0 $perl_version = ord $args[$idx + 1];
64 0         0 $skipnext = 1;
65             } elsif ( $val eq '-experimental' ) {
66 0         0 $experimental = $args[$idx + 1];
67 0         0 $skipnext = 1;
68             } elsif ( $val eq '-components' ) {
69 0         0 $components = $args[$idx + 1];
70 0         0 $skipnext = 1;
71             } else {
72 0         0 push @rest, $val;
73             }
74             }
75              
76             return {
77 4         13 base => $base,
78             perl_version => $perl_version,
79             components => $components,
80             rest => \@rest,
81             experimental => $experimental,
82             };
83             }
84              
85             sub installer {
86 4     4 0 4 my ($self) = @_;
87             sub {
88 4     4   242 Sub::Exporter::default_installer @_;
89             }
90 4         16 }
91              
92             sub set_base {
93 4     4 0 4 my ($self, $inheritor, $base) = @_;
94              
95             # inlined from parent.pm
96 4         7 for ( my @useless = $self->base($base) ) {
97 4         32 s{::|'}{/}g;
98 4         19 require "$_.pm"; # dies if the file is not found
99             }
100              
101             {
102 2     2   11 no strict 'refs';
  2         3  
  2         446  
  4         22  
103             # This is more efficient than push for the new MRO
104             # at least until the new MRO is fixed
105 4         5 @{"$inheritor\::ISA"} = (@{"$inheritor\::ISA"} , $self->base($base));
  4         52  
  4         14  
106             }
107             }
108              
109             sub gen_INIT {
110 4     4 0 4 my ($self, $perl_version, $inheritor, $experimental) = @_;
111             sub {
112 4     4   158 my $orig = $_[1]->{import_args};
113 4         4 $_[1]->{import_args} = [];
114              
115 4         17 strict->import;
116 4         22 warnings->import;
117              
118 4 100       8 if ($perl_version) {
119 2         8 require feature;
120 2         98 feature->import(":5.$perl_version")
121             }
122              
123 4 100       8 if ($experimental) {
124 2         6 require experimental;
125 2 50 33     14 die 'experimental arg must be an arrayref!'
126             unless ref $experimental && ref $experimental eq 'ARRAY';
127             # to avoid experimental referring to the method
128 2         8 experimental::->import(@$experimental)
129             }
130              
131 4         72 mro::set_mro($inheritor, 'c3');
132              
133 4         7 1;
134             }
135 4         20 }
136              
137             1;
138              
139             __END__
140              
141             =pod
142              
143             =head1 NAME
144              
145             DBIx::Class::Candy::ResultSet - Sugar for your resultsets
146              
147             =head1 SYNOPSIS
148              
149             package MyApp::Schema::ResultSet::Artist;
150              
151             use DBIx::Class::Candy::ResultSet
152             -components => ['Helper::ResultSet::Me'];
153              
154             use experimental 'signatures';
155              
156             sub by_name ($self, $name) { $self->search({ $self->me . 'name' => $name }) }
157              
158             1;
159              
160             =head1 DESCRIPTION
161              
162             C<DBIx::Class::Candy::ResultSet> is an initial sugar layer in the spirit of
163             L<DBIx::Class::Candy>. Unlike the original it does not define a DSL, though I
164             do have plans for that in the future. For now all it does is set some imports:
165              
166             =over
167              
168             =item *
169              
170             turns on strict and warnings
171              
172             =item *
173              
174             sets your parent class
175              
176             =item *
177              
178             sets your mro to C<c3>
179              
180             =back
181              
182             =head1 IMPORT OPTIONS
183              
184             See L</SETTING DEFAULT IMPORT OPTIONS> for information on setting these schema wide.
185              
186             =head2 -base
187              
188             use DBIx::Class::Candy::ResultSet -base => 'MyApp::Schema::ResultSet';
189              
190             The first thing you can do to customize your usage of C<DBIx::Class::Candy::ResultSet>
191             is change the parent class. Do that by using the C<-base> import option.
192              
193             =head2 -components
194              
195             use DBIx::Class::Candy::ResultSet -components => ['Helper::ResultSet::Me'];
196              
197             C<DBIx::Class::Candy::ResultSet> allows you to set which components you are using at
198             import time.
199              
200             =head2 -perl5
201              
202             use DBIx::Class::Candy::ResultSet -perl5 => v20;
203              
204             I love the new features in Perl 5.20, so I felt that it would be
205             nice to remove the boiler plate of doing C<< use feature ':5.20' >> and
206             add it to my sugar importer. Feel free not to use this.
207              
208             =head1 SETTING DEFAULT IMPORT OPTIONS
209              
210             Eventually you will get tired of writing the following in every single one of
211             your resultsets:
212              
213             use DBIx::Class::Candy::ResultSet
214             -base => 'MyApp::Schema::ResultSet',
215             -perl5 => v20,
216             -experimental => ['signatures'];
217              
218             You can set all of these for your whole schema if you define your own C<Candy::ResultSet>
219             subclass as follows:
220              
221             package MyApp::Schema::Candy::ResultSet;
222              
223             use base 'DBIx::Class::Candy::ResultSet';
224              
225             sub base { $_[1] || 'MyApp::Schema::ResultSEt' }
226             sub perl_version { 20 }
227             sub experimental { ['signatures'] }
228              
229             Note the C<< $_[1] || >> in C<base>. All of these methods are passed the
230             values passed in from the arguments to the subclass, so you can either throw
231             them away, honor them, die on usage, or whatever. To be clear, if you define
232             your subclass, and someone uses it as follows:
233              
234             use MyApp::Schema::Candy::ResultSet
235             -base => 'MyApp::Schema::ResultSet',
236             -perl5 => v18,
237             -experimental => ['postderef'];
238              
239             Your C<base> method will get C<MyApp::Schema::ResultSet>, your C<experimental>
240             will get C<['postderef']>, and your C<perl_version> will get C<18>.
241              
242             =head1 AUTHOR
243              
244             Arthur Axel "fREW" Schmidt <frioux+cpan@gmail.com>
245              
246             =head1 COPYRIGHT AND LICENSE
247              
248             This software is copyright (c) 2016 by Arthur Axel "fREW" Schmidt.
249              
250             This is free software; you can redistribute it and/or modify it under
251             the same terms as the Perl 5 programming language system itself.
252              
253             =cut