File Coverage

blib/lib/Class/DBI/Sweet/Pie.pm
Criterion Covered Total %
statement 68 69 98.5
branch 19 24 79.1
condition 8 13 61.5
subroutine 8 8 100.0
pod 0 1 0.0
total 103 115 89.5


line stmt bran cond sub pod time code
1             package Class::DBI::Sweet::Pie;
2 3     3   319421 use strict;
  3         7  
  3         255  
3 3     3   19 use vars qw/$VERSION/;
  3         6  
  3         257  
4             $VERSION = '0.04';
5              
6             sub import {
7 2     2   20 my $class = shift;
8 2         6 my $pkg = caller(0);
9              
10 3     3   15 no strict 'refs';
  3         9  
  3         439  
11 2         5 *{"$pkg\::mk_aggregate_function"} = \&mk_aggregate_function;
  2         66  
12             }
13              
14             sub mk_aggregate_function {
15 24     24 0 1187864 my $class = shift;
16 24         49 my ($aggregate_func, $alias) = @_;
17 24   66     119 $alias ||= $aggregate_func;
18              
19             ## create aggregate function
20 24         59 my $sql_aggregate = "sql_Join_AggregateFunction_$alias";
21 24         166 $class->set_sql( "Join_AggregateFunction_$alias" => <<__SQL__ );
22             SELECT $aggregate_func( %s )
23             FROM %s
24             WHERE %s
25             __SQL__
26              
27 3     3   58 no strict 'refs';
  3         7  
  3         3330  
28 24         351 *{"$class\::$alias"} = sub {
29 44     44   525484 my $self = shift;
30 44         69 my $aggregate_column = shift;
31 44 100       160 return $self->_attr( $alias ) unless defined $aggregate_column;
32              
33 35   66     147 my $class = ref $self || $self;
34 35         276 my ($criteria, $attributes) = $class->_search_args(@_);
35              
36 35         770 $aggregate_column =~ s/^ (distinct) \s+ //ix;
37 35   100     178 my $distinct = $1 || '';
38              
39 35 100       208 if ($aggregate_column eq "*") {
    100          
40             ;
41             }
42             elsif ($aggregate_column =~ /^(\w+)\.(.+)$/) {
43 23         50 my $join = $1;
44 23 100       73 $aggregate_column = "*" if $2 eq '*';
45              
46 23 100       45 if (ref $self) {
47 13         47 $attributes->{prefetch} = [ $join ];
48 13         41 foreach my $pcol ($self->primary_column) {
49 13         301 $criteria->{ $pcol } = $self->$pcol;
50             }
51             }
52             else {
53 10 50       67 $criteria->{ $join } = \"IS NOT NULL"
54             unless exists $criteria->{ $join };
55             }
56             }
57             else {
58 10         29 $aggregate_column = "me.$aggregate_column";
59             }
60              
61 35 100       1010 $aggregate_column = "$distinct $aggregate_column" if $distinct;
62              
63             # make sure we take copy of $attribues since it can be reused
64 35         43 my $agfunc_attr = { %{$attributes} };
  35         95  
65            
66             # no need for LIMIT/OFFSET and ORDER BY in AGGREGATE_FUNC()
67 35         57 delete @{$agfunc_attr}{qw( rows offset order_by )};
  35         87  
68            
69 35         141 my ($sql_parts, $classes, $columns, $values) = $class->_search( $criteria, $agfunc_attr );
70            
71 35         14241 my $sth = $class->$sql_aggregate( $aggregate_column, @{$sql_parts}{qw/ from where /} );
  35         192  
72            
73 35         18979 $class->_bind_param( $sth, $columns );
74 35         798 return $sth->select_val(@$values);
75 24         3634 };
76              
77             ## create search with aggregate function
78 24         153 my $sql_with_aggregate = "sql_Join_Retrieve_$alias";
79 24         137 $class->set_sql( "Join_Retrieve_$alias" => <<__SQL__ );
80             SELECT __ESSENTIAL(me)__, $aggregate_func( %s ) AS $alias
81             FROM %s
82             WHERE %s
83             GROUP BY __ESSENTIAL(me)__
84             %s %s
85             __SQL__
86              
87 24         168 *{"$class\::search_with_$alias"} = sub {
88 4     4   2615 my $self = shift;
89 4   33     27 my $class = ref($self) || $self;
90 4         10 my $aggregate_column = shift;
91 4         38 my ($criteria, $attributes) = $class->_search_args(@_);
92              
93 4         95 $aggregate_column =~ s/^ (distinct) \s+ //ix;
94 4   50     26 my $distinct = $1 || '';
95              
96 4 50       43 if ($aggregate_column eq "*") {
    50          
97             ;
98             }
99             elsif ($aggregate_column =~ /^(\w+)\.(.+)$/) {
100 4         11 my $join = $1;
101 4 100       17 $aggregate_column = "*" if $2 eq '*';
102              
103 4 50       19 $criteria->{ $join } = \"IS NOT NULL"
104             unless exists $criteria->{ $join };
105             }
106             else {
107 0         0 $aggregate_column = "me.$aggregate_column";
108             }
109              
110 4 50       11 $aggregate_column = "$distinct $aggregate_column" if $distinct;
111              
112 4         17 my ($sql_parts, $classes, $columns, $values) = $class->_search( $criteria, $attributes );
113            
114 4         3491 my $sth = $class->$sql_with_aggregate( $aggregate_column, @{$sql_parts}{qw/ from where order_by limit /} );
  4         27  
115              
116 4         1955 $self->sth_to_objects( $sth, $values );
117 24         1960 };
118             }
119              
120             1;
121             __END__