File Coverage

blib/lib/XAS/Service/Search.pm
Criterion Covered Total %
statement 15 112 13.3
branch 0 50 0.0
condition 0 5 0.0
subroutine 5 12 41.6
pod 2 2 100.0
total 22 181 12.1


line stmt bran cond sub pod time code
1             package XAS::Service::Search;
2              
3             our $VERSION = '0.01';
4              
5 1     1   1435 use XAS::Service::Profiles;
  1         2  
  1         32  
6 1     1   388 use XAS::Service::Profiles::Search;
  1         1  
  1         24  
7 1     1   5 use XAS::Constants 'HASHREF ARRAYREF';
  1         1  
  1         5  
8              
9             use XAS::Class
10 1         10 version => $VERSION,
11             base => 'XAS::Base',
12             mixin => 'XAS::Service::CheckParameters',
13             accessors => 'profile',
14             utils => ':validation',
15             codec => 'JSON',
16             vars => {
17             PARAMS => {
18             -columns => { type => ARRAYREF },
19             }
20             }
21 1     1   110 ;
  1         2  
22              
23 1     1   769 use Data::Dumper;
  1         1  
  1         795  
24              
25             # ----------------------------------------------------------------------
26             # Public Methods
27             # ----------------------------------------------------------------------
28              
29             sub build {
30 0     0 1   my $self = shift;
31 0           my ($multi) = validate_params(\@_, [
32             { isa => 'Hash::MultiValue' },
33             ]);
34              
35 0           my $opts;
36 0           my $options = {};
37 0           my $criteria = {};
38 0           my $params = $multi->as_hashref;
39              
40             # internal routines
41              
42             my $comparison = sub {
43 0     0     my $filter = shift;
44              
45 0 0         if ($filter->{'comparison'} eq 'lt') {
    0          
    0          
    0          
    0          
    0          
    0          
46              
47 0           $criteria->{$filter->{'field'}} = {'<', $filter->{'value'}};
48              
49             } elsif ($filter->{'comparison'} eq 'le') {
50              
51 0           $criteria->{$filter->{'field'}} = {'<=', $filter->{'value'}};
52              
53             } elsif ($filter->{'comparison'} eq 'gt') {
54              
55 0           $criteria->{$filter->{'field'}} = {'>', $filter->{'value'}};
56              
57             } elsif ($filter->{'comparison'} eq 'ge') {
58              
59 0           $criteria->{$filter->{'field'}} = {'>=', $filter->{'value'}};
60              
61             } elsif ($filter->{'comparison'} eq 'lk') {
62              
63 0           $criteria->{$filter->{'field'}} = {-like => [$filter->{'value'} . '%']};
64              
65             } elsif ($filter->{'comparison'} eq 'eq') {
66              
67 0           $criteria->{$filter->{'field'}} = $filter->{'value'};
68              
69             } elsif ($filter->{'comparison'} eq 'be') {
70              
71 0           my $begin = shift(@{$filter->{'value'}});
  0            
72 0           my $end = shift(@{$filter->{'value'}});
  0            
73              
74 0           $criteria->{$filter->{'field'}} = {-between => [$begin, $end]};
75              
76             }
77              
78 0           };
79              
80             # build the options
81              
82 0 0 0       if (defined($params->{'start'}) && defined($params->{'limit'})) {
83              
84 0           my $pager = $self->_dbpage($params->{'start'}, $params->{'limit'});
85              
86 0           $options->{'page'} = $pager->{'page'};
87 0           $options->{'rows'} = $pager->{'rows'};
88              
89 0           delete $params->{'start'};
90 0           delete $params->{'limit'};
91              
92             }
93              
94 0 0         if (defined($params->{'sort'})) {
95              
96 0           $params->{'sort'} = decode($params->{'sort'});
97 0           $options->{'order_by'} = $self->_order_by($params->{'sort'});
98              
99 0           delete $params->{'sort'};
100              
101             }
102              
103 0 0         if (defined($params->{'group'})) {
104              
105 0           $params->{'group'} = decode($params->{'group'});
106 0           $options->{'group_by'} = $self->_group_by($params->{'group'});
107              
108 0           delete $params->{'group'};
109              
110             }
111              
112             # user defined options
113              
114 0 0         if (defined($params->{'options'})) {
115              
116 0           my $hash = $params->{'options'};
117              
118 0           while (my ($key, $value) = each(%$hash)) {
119              
120 0           $options->{$key} = $value;
121              
122             }
123              
124             }
125              
126             # build the criteria
127              
128 0 0         if (defined($params->{'filter'})) {
129              
130 0           my $filters = decode($params->{'filter'});
131              
132 0           while (my $filter = shift(@$filters)) {
133              
134 0           $self->check_parameters($filter, 'filter');
135              
136 0 0         if ($filter->{'type'} eq 'string') {
    0          
    0          
    0          
    0          
137              
138 0 0         if (defined($filter->{'comparison'})) {
139              
140 0           $comparison->($filter);
141              
142             } else {
143              
144 0           $criteria->{$filter->{'field'}} = $filter->{'value'};
145              
146             }
147              
148             } elsif ($filter->{'type'} eq 'number') {
149              
150 0 0         if (defined($filter->{'comparison'})) {
151              
152 0           $comparison->($filter);
153              
154             } else {
155              
156 0           $criteria->{$filter->{'field'}} = $filter->{'value'};
157              
158             }
159              
160             } elsif ($filter->{'type'} eq 'list') {
161              
162 0           while (my $x = shift(@{$filter->{'value'}})) {
  0            
163              
164 0           push(@{$criteria->{$filter->{'field'}}}, $x);
  0            
165              
166             }
167              
168             } elsif ($filter->{'type'} eq 'boolean') {
169              
170 0           my $b = sprintf("%s", $filter->{'value'});
171              
172 0 0         $criteria->{$filter->{'field'}} = 'f' if ($b eq '0');
173 0 0         $criteria->{$filter->{'field'}} = 't' if ($b eq '1');
174              
175             } elsif ($filter->{'type'} eq 'date') {
176              
177 0 0         if (defined($filter->{'comparison'})) {
178              
179 0           $comparison->($filter);
180              
181             } else {
182              
183 0           $criteria->{$filter->{'field'}} = $filter->{'value'};
184              
185             }
186              
187             }
188              
189             }
190              
191             }
192              
193 0           return $criteria, $options;
194              
195             }
196              
197             # ----------------------------------------------------------------------
198             # Private Methods
199             # ----------------------------------------------------------------------
200              
201             sub init {
202 0     0 1   my $class = shift;
203              
204 0           my $self = $class->SUPER::init(@_);
205              
206 0           my $fields = $self->columns->[0];
207 0           my $search = XAS::Service::Profiles::Search->new($fields);
208              
209 0           $self->{'profile'} = XAS::Service::Profiles->new($search);
210              
211 0           return $self;
212              
213             }
214              
215             #
216             # General purpose rounding function.
217             #
218             # To round a number to the nearest integer, use round($x). To round it to
219             # the nearest 10, use round($x, 1). Nearest 100 is round($x, 2) and so on.
220             # You can also round to the nearest tenth, hundredth, etc., by using a
221             # negative second argument: round(5.28, -1) == 5.3.
222             #
223             sub _roundup {
224 0     0     my $self = shift;
225 0           my $n = shift;
226 0           my $places = shift;
227              
228 0   0       my $factor = 10 ** ($places || 0);
229 0 0         return (int(($n * $factor) + ($n < 0 ? -1 : 1) * 0.5) / $factor);
230              
231             }
232              
233             #
234             # Find the "page" in a "paged" db retrieval
235             #
236             sub _dbpage {
237 0     0     my $self = shift;
238 0           my $start = shift;
239 0           my $limit = shift;
240              
241 0           my $params = {
242             start => $start,
243             limit => $limit
244             };
245              
246 0           $self->check_parameters($params, 'pager');
247              
248             return {
249 0           page => $self->_roundup(($start / $limit) + 1),
250             rows => $limit
251             }
252              
253             }
254              
255             sub _order_by {
256 0     0     my $self = shift;
257 0           my $ob = shift;
258              
259 0           my @d;
260              
261 0           foreach my $x (@$ob) {
262              
263 0           my $y;
264 0           my $z = $self->check_parameters($x, 'sort');
265              
266 0 0         $y->{'-asc'} = $z->{'field'} if ($z->{'direction'} eq 'ASC');
267 0 0         $y->{'-desc'} = $z->{'field'} if ($z->{'direction'} eq 'DESC');
268              
269 0           push(@d, $y);
270              
271             }
272              
273 0           return \@d;
274              
275             }
276              
277             sub _group_by {
278 0     0     my ($self, $ob) = @_;
279              
280 0           my @d;
281 0           my $columns = $self->columns->[0];
282              
283 0           foreach my $x (@$ob) {
284              
285 0           my $y = $self->check_parameters($x, 'group');
286 0           my $z = $y->{'field'};
287              
288 0           push(@d, $z);
289              
290             }
291              
292 0           foreach my $x (@$columns) {
293              
294 0           push(@d, 'me.' . $x);
295              
296             };
297              
298 0           return \@d;
299              
300             }
301              
302             1;
303              
304             __END__