File Coverage

blib/lib/Data/Seek/Search.pm
Criterion Covered Total %
statement 44 44 100.0
branch 7 8 87.5
condition 3 6 50.0
subroutine 6 6 100.0
pod 3 3 100.0
total 63 67 94.0


line stmt bran cond sub pod time code
1             # ABSTRACT: Data::Seek Search Execution Class
2             package Data::Seek::Search;
3              
4 3     3   1603 use Data::Seek::Exception;
  3         9  
  3         200  
5 3     3   1291 use Data::Seek::Search::Result;
  3         6  
  3         95  
6              
7 3     3   16 use Data::Object::Class;
  3         6  
  3         11  
8              
9             our $VERSION = '0.08'; # VERSION
10              
11             has 'cache' => (
12             is => 'rw',
13             default => 0
14             );
15              
16             has 'criteria' => (
17             is => 'rw',
18             default => sub {{}}
19             );
20              
21             has 'data' => (
22             is => 'ro',
23             default => sub {{}}
24             );
25              
26             has 'data_cache' => (
27             is => 'ro',
28             default => sub { shift->data->encode },
29             lazy => 1
30             );
31              
32             has 'ignore' => (
33             is => 'rw',
34             default => 0
35             );
36              
37             sub criterion {
38 51     51 1 104 my $self = shift;
39 51         88 my $expr = shift;
40              
41 51 50 33     406 Data::Seek::Exception->throw(message => 'Invalid Criterion Provided')
42             unless $expr && $expr =~ /^[\*\@\%\w\:\.]+$/;
43              
44 51         76 $self->criteria->{$expr} = keys %{$self->criteria};
  51         346  
45              
46 51         172 return $self;
47             }
48              
49             sub perform {
50 48     48 1 882 my $self = shift;
51              
52 48         111 my $criteria = $self->criteria;
53 48         215 $criteria = { reverse %$criteria };
54              
55 48 100       498 my $dataset = $self->cache ? $self->data_cache : $self->data->encode;
56              
57 47         209672 my @orders = sort keys %$criteria;
58 47         149 my @criteria = @$criteria{@orders};
59              
60 47         55 my @results;
61 47         96 for my $criterion (@criteria) {
62 48         103 my $regexp = quotemeta $criterion;
63              
64             # array selector
65 48         122 $regexp =~ s/\\\.\\\@\\\./\:\\d+\./g;
66              
67             # trailing tail array selector
68 48         430 $regexp =~ s/([\w\\\*]*(?:\w|\*))\\[\@\%]\B/$1:\\d+/g;
69             # trailing step array selector
70 48         237 $regexp =~ s/([\w\\\*]*(?:\w|\*))\\[\@\%]\\\./$1:\\d+\\\./g;
71              
72             # leading head array selector
73 48         84 $regexp =~ s/\A\\[\@\%]([\w\\\*]*(?:\w|\*))/$1:\\d+/g;
74             # leading step array selector
75 48         145 $regexp =~ s/\\\.\\[\@\%]([\w\\\*]*(?:\w|\*))/\\\.$1:\\d+/g;
76              
77             # greedy wildcard selector
78 48         109 $regexp =~ s/\\\*\\\*/[\\w\\:\\.]+/g;
79             # wildcard selector
80 48         110 $regexp =~ s/\\\*/\\w+/g;
81              
82 48         8055 my @nodes = grep /^$regexp$/, sort keys %$dataset;
83 48 100 66     541 Data::Seek::Exception->throw(message => "No Data Matched ($criterion)")
84             if not @nodes and not $self->ignore;
85              
86 37 100       99 next unless @nodes;
87              
88 25         173 my $result = {nodes => [sort @nodes], criterion => $criterion};
89 25         89 push @results, $result;
90             }
91              
92 36         63 my $output = [];
93 36         88 for my $result (@results) {
94 25         37 $$result{dataset} = {map { $_ => $$dataset{$_} } @{$$result{nodes}}};
  460         658  
  25         73  
95 25         87 push @$output, $result;
96             }
97              
98 36         924 return $output;
99             }
100              
101             sub result {
102 47     47 1 1133 return Data::Seek::Search::Result->new(
103             search => shift
104             );
105             }
106              
107             1;
108              
109             __END__