File Coverage

blib/lib/Criteria/DateTime.pm
Criterion Covered Total %
statement 87 88 98.8
branch 34 70 48.5
condition 9 27 33.3
subroutine 29 29 100.0
pod 0 2 0.0
total 159 216 73.6


line stmt bran cond sub pod time code
1             # You may distribute under the terms of either the GNU General Public License
2             # or the Artistic License (the same terms as Perl itself)
3             #
4             # Copyright (C) 2011 - Anthony J. Lucas - kaoyoriketsu@ansoni.com
5              
6              
7              
8             package Criteria::DateTime;
9 1     1   25483 use parent qw( Criteria::Compile );
  1         301  
  1         5  
10              
11              
12 1     1   37 use strict;
  1         2  
  1         37  
13 1     1   5 use warnings;
  1         1  
  1         48  
14              
15              
16              
17             our $VERSION = '0.04__7';
18              
19              
20              
21 1     1   1588 use DateTime ( );
  1         222428  
  1         41  
22 1     1   12 use DateTime::Duration ( );
  1         2  
  1         16  
23 1     1   5 use Criteria::Compile ( );
  1         1  
  1         23  
24              
25              
26              
27             #INIT CONFIG / VARS
28              
29              
30 1     1   6 use constant DATETIME_CLASS => 'DateTime';
  1         2  
  1         81  
31 1     1   6 use constant DURATION_CLASS => 'DateTime::Duration';
  1         2  
  1         1968  
32              
33              
34             my $DATETIME_GRAMMAR = {
35             Criteria::Compile::TYPE_DYNAMIC() => {
36             qw/^(.*)_before$/ => qw/_gen_before_sub/,
37             qw/^(.*)_after$/ => qw/_gen_after_sub/,
38             qw/^(.*)_sooner_than$/ => qw/_gen_sooner_than_sub/,
39             qw/^(.*)_later_than$/ => qw/_gen_later_than_sub/,
40             qw/^(.*)_newer_than$/ => qw/_gen_newer_than_sub/,
41             qw/^(.*)_older_than$/ => qw/_gen_older_than_sub/
42             }
43             };
44             my $DURATION_GRAMMAR = {
45             Criteria::Compile::TYPE_DYNAMIC() => {
46             qw/^(.*)_longer_than$/ => qw/_gen_longer_than_sub/,
47             qw/^(.*)_shorter_than$/ => qw/_gen_shorter_than_sub/
48             }
49             };
50              
51              
52             #INITIALISATION ROUTINES
53              
54              
55             sub _init {
56              
57 6     6   13 my ($self, $crit, $nocomp) = @_;
58 6         99 $self->SUPER::_init($crit, 1);
59              
60             #define datetime grammara
61 6         19 $self->define_datetime_grammar();
62 6         18 $self->define_duration_grammar();
63              
64             #validate any criteria supplied
65 6 50 33     34 if ($crit and !$nocomp) {
66 6 50       20 die('Error: Failed to compile criteria.')
67             unless ($self->compile());
68             }
69 6         14 return 1;
70             }
71              
72              
73             sub define_datetime_grammar {
74 6     6 0 26 Criteria::Compile::_define_grammar_dtbl($_[0], $DATETIME_GRAMMAR);
75             }
76              
77              
78             sub define_duration_grammar {
79 6     6 0 22 Criteria::Compile::_define_grammar_dtbl($_[0], $DURATION_GRAMMAR);
80             }
81              
82              
83              
84              
85             #GRAMMAR HANDLER ROUTINES
86              
87              
88             *getter = \&Criteria::Compile::getter;
89              
90             sub _dt_to_unix {
91            
92 8     8   12 my $dt = $_[0];
93             #convert datetime to unixtime
94 8 50       43 $dt = $dt->epoch()
95             if (ref($dt) eq 'DateTime');
96             #return unixtime or undef
97 8 50       166 return ($dt =~ /^\d+$/)
98             ? $dt
99             : undef;
100             }
101              
102              
103             sub _del_to_dur {
104              
105 24     24   29 my $del = $_[0];
106             #convert delta to duration
107 24 50       111 return $del
108             if (ref($del) eq DURATION_CLASS());
109 0 0       0 return DURATION_CLASS()->new(%$del)
110             if (ref($del) eq 'HASH');
111             }
112              
113              
114             sub _gen_before_sub {
115              
116 4     4   11 my ($context, $val, $attr) = @_;
117              
118             #check arguments
119 4 50       11 die sprintf(Criteria::Compile::HANDLER_DIE_MSG(), 'before',
120             'No attribute supplied.')
121             unless ($attr);
122              
123             #check value is usable for comparison
124 4 50       14 die sprintf(Criteria::Compile::HANDLER_DIE_MSG(), 'before',
125             'Value not a valid datetime or unixtime value')
126             unless (($val = _dt_to_unix($val)) ne '');
127              
128             #return handler sub
129 4         10 my $getter = $context->{getter};
130             return sub {
131 4 50 33 4   25 return (ref($_[0])
132             and (local $_ = $getter->($_[0], $attr)))
133             ? ($_->epoch() < $val)
134             : 0;
135 4         26 };
136             }
137              
138              
139             sub _gen_after_sub {
140              
141 4     4   8 my ($context, $val, $attr) = @_;
142              
143             #check arguments
144 4 50       10 die sprintf(Criteria::Compile::HANDLER_DIE_MSG(), 'after',
145             'No attribute supplied.')
146             unless ($attr);
147              
148             #check value is usable for comparison
149 4 50       24 die sprintf(Criteria::Compile::HANDLER_DIE_MSG(), 'after',
150             'Value not a valid datetime or unixtime value')
151             unless (($val = _dt_to_unix($val)) ne '');
152              
153             #return handler sub
154 4         10 my $getter = $context->{getter};
155             return sub {
156 4 50 33 4   27 return (ref($_[0])
157             and (local $_ = $getter->($_[0], $attr)))
158             ? ($_->epoch() > $val)
159             : 0;
160 4         30 };
161             }
162              
163              
164             sub _gen_sooner_than_sub {
165              
166 4     4   9 my ($context, $val, $attr) = @_;
167              
168             #check arguments
169 4 50       13 die sprintf(Criteria::Compile::HANDLER_DIE_MSG(), 'sooner_than',
170             'No attribute supplied.')
171             unless ($attr);
172              
173             #check value is usable for comparison
174 4 50       9 die sprintf(Criteria::Compile::HANDLER_DIE_MSG(), 'sooner_than',
175             'Value not a valid duration value')
176             unless (ref($val = _del_to_dur($val)));
177              
178             #return handler sub
179 4         8 my $getter = $context->{getter};
180 4 50       53 Carp::croak('Getter not defined!') unless ($getter);
181             return sub {
182 4 50 33 4   23 return (ref($_[0])
183             and (local $_ = $getter->($_[0], $attr)))
184             ? ($_->epoch() < DATETIME_CLASS()->now()->add_duration($val)->epoch())
185             : 0;
186 4         27 };
187             }
188              
189              
190             sub _gen_later_than_sub {
191              
192 4     4   9 my ($context, $val, $attr) = @_;
193              
194             #check arguments
195 4 50       11 die sprintf(Criteria::Compile::HANDLER_DIE_MSG(), 'later_than',
196             'No attribute supplied.')
197             unless ($attr);
198              
199             #check value is usable for comparison
200 4 50       9 die sprintf(Criteria::Compile::HANDLER_DIE_MSG(), 'later_than',
201             'Value not a valid duration value')
202             unless (ref($val = _del_to_dur($val)));
203              
204             #return handler sub
205 4         10 my $getter = $context->{getter};
206             return sub {
207 4 50 33 4   24 return (ref($_[0])
208             and (local $_ = $getter->($_[0], $attr)))
209             ? ($_->epoch() > DATETIME_CLASS()->now()->add_duration($val)->epoch())
210             : 0;
211 4         29 };
212             }
213              
214              
215             sub _gen_shorter_than_sub {
216              
217 4     4   7 my ($context, $val, $attr) = @_;
218              
219             #check arguments
220 4 50       13 die sprintf(Criteria::Compile::HANDLER_DIE_MSG(), 'shorter_than',
221             'No attribute supplied.')
222             unless ($attr);
223              
224             #check value is usable for comparison
225 4 50       17 die sprintf(Criteria::Compile::HANDLER_DIE_MSG(), 'shorter_than',
226             'Value not a valid duration value')
227             unless (ref($val = _del_to_dur($val)));
228              
229             #return handler sub
230 4         8 my $getter = $context->{getter};
231             return sub {
232 4 50 33 4   63 return (ref($_[0])
    50          
233             and (local $_ = $getter->($_[0], $attr)))
234             ? (DURATION_CLASS()->compare($val, $_) > 0 ? 1 : 0)
235             : 0;
236 4         25 };
237             }
238              
239              
240             sub _gen_longer_than_sub {
241              
242 4     4   8 my ($context, $val, $attr) = @_;
243              
244             #check arguments
245 4 50       12 die sprintf(Criteria::Compile::HANDLER_DIE_MSG(), 'longer_than',
246             'No attribute supplied.')
247             unless ($attr);
248              
249             #check value is usable for comparison
250 4 50       10 die sprintf(Criteria::Compile::HANDLER_DIE_MSG(), 'longer_than',
251             'Value not a valid duration value')
252             unless (ref($val = _del_to_dur($val)));
253              
254             #return handler sub
255 4         9 my $getter = $context->{getter};
256             return sub {
257 4 50 33 4   27 return (ref($_[0])
    50          
258             and (local $_ = $getter->($_[0], $attr)))
259             ? (DURATION_CLASS()->compare($val, $_) < 0 ? 1 : 0)
260             : 0;
261 4         26 };
262             }
263              
264              
265              
266             sub _gen_newer_than_sub {
267              
268 4     4   10 my ($context, $val, $attr) = @_;
269              
270             #check arguments
271 4 50       12 die sprintf(Criteria::Compile::HANDLER_DIE_MSG(), 'newer_than',
272             'No attribute supplied.')
273             unless ($attr);
274              
275             #check value is usable for comparison
276 4 50       11 die sprintf(Criteria::Compile::HANDLER_DIE_MSG(), 'newer_than',
277             'Value not a valid duration value')
278             unless (ref($val = _del_to_dur($val)));
279              
280             #return handler sub
281 4         8 my $getter = $context->{getter};
282             return sub {
283 4 50 33 4   32 return (ref($_[0])
    50          
284             and (local $_ = $getter->($_[0], $attr)))
285             ? (DURATION_CLASS()->compare(
286             DATETIME_CLASS()->now->subtract_datetime($_),
287             $val) < 0 ? 1 : 0)
288             : 0;
289 4         29 };
290             }
291              
292              
293             sub _gen_older_than_sub {
294              
295 4     4   8 my ($context, $val, $attr) = @_;
296              
297             #check arguments
298 4 50       9 die sprintf(Criteria::Compile::HANDLER_DIE_MSG(), 'older_than',
299             'No attribute supplied.')
300             unless ($attr);
301              
302             #check value is usable for comparison
303 4 50       11 die sprintf(Criteria::Compile::HANDLER_DIE_MSG(), 'older_than',
304             'Value not a valid duration value')
305             unless (ref($val = _del_to_dur($val)));
306              
307             #return handler sub
308 4         10 my $getter = $context->{getter};
309             return sub {
310 4 50 33 4   24 return (ref($_[0])
    50          
311             and (local $_ = $getter->($_[0], $attr)))
312             ? (DURATION_CLASS()->compare(
313             DATETIME_CLASS()->now->subtract_datetime($_),
314             $val) > 0 ? 1 : 0)
315             : 0;
316 4         27 };
317             }
318              
319              
320              
321              
322              
323             1;