File Coverage

blib/lib/DBICx/Shortcuts.pm
Criterion Covered Total %
statement 42 54 77.7
branch 11 20 55.0
condition 3 9 33.3
subroutine 8 10 80.0
pod 3 3 100.0
total 67 96 69.7


line stmt bran cond sub pod time code
1             package DBICx::Shortcuts;
2             our $VERSION = '0.007';
3              
4 4     4   116268 use strict;
  4         11  
  4         135  
5 4     4   21 use warnings;
  4         9  
  4         127  
6 4     4   35 use Carp qw( croak );
  4         7  
  4         1372  
7              
8             my %schemas;
9              
10             sub setup {
11 4     4 1 31091 my ($class, $schema_class, @methods) = @_;
12              
13 4         274 eval "require $schema_class";
14 4 100       660866 die if $@;
15 3         42 local $ENV{DBIC_NO_VERSION_CHECK} = 1;
16 3         27 my $schema = $schema_class->connect;
17              
18 3         260065 SOURCE: for my $source ($schema->sources) {
19 12         229 my $info = $schema->source($source)->source_info;
20 12 100 100     628 next SOURCE if exists $info->{skip_shortcut} && $info->{skip_shortcut};
21              
22 9         38 my $method;
23 9 100       30 if (exists $info->{shortcut}) {
24 6         15 $method = $info->{shortcut};
25 6 100       25 next SOURCE unless defined $method;
26             }
27             else {
28 3         9 $method = $source;
29 3         9 $method =~ s/.+::(.+)$/$1/; ## deal with nested sources
30 3         37 $method =~ s/([a-z])([A-Z])/${1}_$2/g;
31 3         12 $method = lc($method);
32             }
33              
34 6 100       112 croak("Shortcut failed, '$method' already defined in '$class', ")
35             if $class->can($method);
36              
37 4     4   23 no strict 'refs';
  4         8  
  4         876  
38 5         50 *{__PACKAGE__ . "::$method"} = sub {
39 0     0   0 my $rs = shift->schema->resultset($source);
40              
41             ## No arguments, return empty result set;
42 0 0       0 return $rs unless @_;
43              
44             ## first argument not a reference, assume find by PK
45 0 0 0     0 return $rs->find(@_) if defined($_[0]) && !ref($_[0]);
46              
47             ## first argument is a scalar ref, assume unique constraint name,
48             ## use find
49 0 0 0     0 return $rs->find(@_[1 .. $#_], {key => ${$_[0]}})
  0         0  
50             if defined($_[0]) && ref($_[0]) eq 'SCALAR';
51              
52             ## otherwise, its a search
53 0         0 return $rs->search(@_);
54 5         28 };
55             }
56              
57             ## Enable set of schema shortcuts
58 2         7 for my $meth (@methods) {
59 4     4   25 no strict 'refs';
  4         5  
  4         1106  
60 2     0   7 *{__PACKAGE__ . "::$meth"} = sub { return shift->schema->$meth(@_) };
  2         14  
  0         0  
61             }
62              
63 2         10 $schemas{$class} = {class => $schema_class};
64              
65 2         23 return;
66             }
67              
68             sub schema {
69 1     1 1 63 my ($class) = @_;
70              
71 1 50       37 croak("Class '$class' did not call 'setup()'")
72             unless exists $schemas{$class};
73              
74 0         0 my $info = $schemas{$class};
75 0         0 my $schema = $info->{schema};
76 0 0       0 return $schema if $schema;
77              
78 0         0 my @connect_args = $class->connect_info();
79 0         0 return $info->{schema} = $info->{class}->connect(@connect_args);
80             }
81              
82             sub connect_info {
83 1     1 1 1623 croak("Class '$_[0]' needs to override 'connect_info()', ");
84             }
85              
86             1;
87              
88             __END__