File Coverage

blib/lib/DBIx/Class/Helper/WindowFunctions.pm
Criterion Covered Total %
statement 53 53 100.0
branch 16 22 72.7
condition 4 9 44.4
subroutine 6 6 100.0
pod n/a
total 79 90 87.7


line stmt bran cond sub pod time code
1             package DBIx::Class::Helper::WindowFunctions;
2              
3             # ABSTRACT: Add support for window functions and aggregate filters to DBIx::Class
4              
5 1     1   1149110 use v5.14;
  1         5  
6 1     1   6 use warnings;
  1         1  
  1         58  
7              
8 1     1   17 use parent 'DBIx::Class::ResultSet';
  1         1  
  1         7  
9              
10 1     1   78 use Ref::Util qw/ is_plain_arrayref is_plain_hashref /;
  1         1  
  1         54  
11              
12             # RECOMMEND PREREQ: Ref::Util::XS
13              
14 1     1   4 use namespace::clean;
  1         2  
  1         6  
15              
16             our $VERSION = 'v0.6.0';
17              
18              
19             sub _resolved_attrs {
20 7     7   753630 my $rs = $_[0];
21 7         24 my $attrs = $rs->{attrs};
22              
23 7         54 my $sqla = $rs->result_source->storage->sql_maker;
24              
25 7         700 foreach my $attr (qw/ select +select /) {
26              
27 14 100       95 my $sel = $attrs->{$attr} or next;
28 7         16 my @sel;
29              
30 7 50       17 foreach my $col ( @{ is_plain_arrayref($sel) ? $sel : [$sel] } ) {
  7         42  
31              
32 7         22 push @sel, $col;
33              
34 7 50       35 next unless is_plain_hashref($col);
35              
36 7         21 my $as = delete $col->{'-as'};
37 7         20 my $over = delete $col->{'-over'};
38 7         19 my $filter = delete $col->{'-filter'};
39              
40 7 50 66     32 next unless $over || $filter;
41              
42 7         72 my ( $sql, @bind ) = $sqla->_recurse_fields($col);
43              
44 7 100       746 if ($over) {
45              
46 5 50       16 $rs->throw_exception('-over must be a hashref')
47             unless is_plain_hashref($over);
48              
49             my ( $part_sql, @part_bind ) =
50 5         20 $sqla->_recurse_fields( $over->{partition_by} );
51 5 100       1744 if ($part_sql) {
52 4         13 $part_sql = $sqla->_sqlcase('partition by ') . $part_sql;
53             }
54              
55 5         30 my @filter_bind;
56 5 100       17 if ( defined $filter ) {
57 1 50 33     10 $rs->throw_exception('-filter must be an arrayref or hashref')
58             unless is_plain_arrayref($filter)
59             or is_plain_hashref($filter);
60 1         6 @filter_bind = $sqla->_recurse_where($filter);
61 1         483 my $clause = shift @filter_bind;
62 1         11 $sql .= $sqla->_sqlcase(' filter (where ') . $clause . ')';
63             }
64              
65             my ( $order_sql, @order_bind ) =
66 5         49 $sqla->_order_by( $over->{order_by} );
67              
68 5         1347 $sql .= $sqla->_sqlcase(' over (') . $part_sql . $order_sql . ')';
69 5 100       35 if ($as) {
70 2         19 $sql .= $sqla->_sqlcase(' as ') . $sqla->_quote($as);
71             }
72              
73 5         88 push @bind, @part_bind, @filter_bind, @order_bind;
74              
75             }
76             else {
77              
78 2 50 33     18 $rs->throw_exception('-filter must be an arrayref or hashref')
79             unless is_plain_arrayref($filter)
80             or is_plain_hashref($filter);
81 2         12 my @filter_bind = $sqla->_recurse_where($filter);
82 2         1070 my $clause = shift @filter_bind;
83 2         9 $sql .= $sqla->_sqlcase(' filter (where ') . $clause . ')';
84              
85 2         15 push @bind, @filter_bind;
86              
87             }
88              
89 7         42 $sel[-1] = \[ $sql, @bind ];
90              
91             }
92              
93 7         34 $attrs->{$attr} = \@sel;
94              
95             }
96              
97 7         26 return $rs->next::method;
98             }
99              
100              
101             1;
102              
103             __END__