File Coverage

blib/lib/Query/Abstract/Driver/ArrayOfHashes.pm
Criterion Covered Total %
statement 47 48 97.9
branch 2 4 50.0
condition 1 2 50.0
subroutine 13 14 92.8
pod 0 3 0.0
total 63 71 88.7


line stmt bran cond sub pod time code
1             package Query::Abstract::Driver::ArrayOfHashes;
2              
3             our $VERSION = '0.01';
4              
5 1     1   706 use v5.10;
  1         3  
  1         39  
6 1     1   4 use strict;
  1         2  
  1         28  
7 1     1   5 use warnings;
  1         1  
  1         27  
8              
9 1     1   3 use Data::Dumper;
  1         1  
  1         58  
10              
11 1     1   5 use base 'Query::Abstract::Driver::Base';
  1         1  
  1         385  
12              
13             my %TESTERS = (
14             'eq' => sub { lc($_[0]) eq lc($_[1]) },
15             'ne' => sub { lc($_[0]) ne lc($_[1]) },
16             'lt' => sub { lc($_[0]) lt lc($_[1]) },
17             'le' => sub { lc($_[0]) le lc($_[1]) },
18             'gt' => sub { lc($_[0]) gt lc($_[1]) },
19             'ge' => sub { lc($_[0]) ge lc($_[1]) },
20             '<' => sub { $_[0] < $_[1] },
21             '>' => sub { $_[0] > $_[1] },
22             '<=' => sub { $_[0] <= $_[1] },
23             '>=' => sub { $_[0] >= $_[1] },
24             'in' => sub { scalar( grep { lc($_[0]) eq lc($_)} @{$_[1]} ) },
25             'like' => sub {
26             my ($value, $pattern) = @_;
27             $pattern = join( '%', map { quotemeta($_) } split('\%', $pattern, -1 ) );
28             $pattern =~ s/\%/.*/;
29             return $value =~ m/^$pattern$/i;
30             },
31              
32             );
33              
34             sub convert_query {
35 4     4 0 5 my ($self, %query) = @_;
36              
37 4         8 my $tester_sub = $self->convert_filter( $query{where} );
38 4         7 my $sort_sub = $self->convert_sort( $query{sort_by} );
39              
40             return sub {
41 4     4   1163 my $array = shift;
42 4         8 return [ sort $sort_sub grep {$tester_sub->($_)} @$array];
  20         23  
43             }
44 4         19 }
45              
46              
47             sub convert_filter {
48 4     4 0 4 my ( $self, $where ) = @_;
49              
50 4         3 my @field_testers;
51 4         8 for ( my $i = 0; $i < @$where; $i += 2 ) {
52 6         8 my $field = $where->[$i];
53 6         7 my $condition = $where->[$i+1];
54 6         9 my ($oper, $restriction) = %$condition;
55              
56 30     30   45 push @field_testers, sub { $TESTERS{$oper}->( $_[0]->{$field}, $restriction ) }
57 6         27 }
58              
59             return sub {
60 20     20   17 my $hash = shift;
61 20         19 @field_testers == grep { $_->($hash) } @field_testers
  30         33  
62 4         12 };
63             }
64              
65             sub convert_sort {
66 4     4 0 4 my ( $self, $sort_by ) = @_;
67 4         4 my @comparators;
68 4         8 foreach my $sort_rule ( @$sort_by ) {
69 1         3 my ($field, $order) = split(/\s+/, $sort_rule, 2);
70 1   50     3 $order ||='ASC';
71              
72             my $field_comparator = uc($order) eq 'DESC'
73 1     1   5 ? sub { $_[1]->{$field} cmp $_[0]->{$field} }
74 1 50   0   6 : sub { $_[0]->{$field} cmp $_[1]->{$field} };
  0         0  
75              
76 1         2 push @comparators, $field_comparator;
77             }
78              
79             return sub {
80 2     2   5 foreach my $compar (@comparators) {
81 1         2 my $res = $compar->($a, $b);
82 1 50       6 return $res if $res != 0;
83             }
84 1         4 return 0;
85             }
86 4         10 }
87              
88             1;