File Coverage

blib/lib/DDC/PP/CQFilter.pm
Criterion Covered Total %
statement 102 139 73.3
branch 17 32 53.1
condition 17 35 48.5
subroutine 44 73 60.2
pod 0 2 0.0
total 180 281 64.0


line stmt bran cond sub pod time code
1             ##-*- Mode: CPerl -*-
2              
3             ##======================================================================
4             ## top-level
5             package DDC::PP::CQFilter;
6 20     20   146 use DDC::PP::Object;
  20         44  
  20         603  
7 20     20   100 use DDC::PP::Constants;
  20         51  
  20         381  
8 20     20   94 use DDC::Utils qw();
  20         41  
  20         256  
9 20     20   87 use strict;
  20         41  
  20         499  
10              
11             ##======================================================================
12             ## CQFilter
13             package DDC::PP::CQFilter;
14 20     20   92 use strict;
  20         42  
  20         2122  
15             our @ISA = qw(DDC::PP::Object);
16              
17             sub new {
18 34     34 0 147 my ($that,%opts) = @_;
19 34         166 return $that->SUPER::new(%opts);
20             }
21              
22 0     0 0 0 sub toString { return "#FILTER[?]"; }
23              
24             ##======================================================================
25             package DDC::PP::CQFSort;
26 20     20   157 use strict;
  20         42  
  20         13236  
27             our @ISA = qw(DDC::PP::CQFilter);
28              
29             __PACKAGE__->defprop('Arg0');
30             __PACKAGE__->defprop('Arg1');
31             __PACKAGE__->defprop('Arg2');
32             __PACKAGE__->defprop('Type');
33              
34 0     0   0 sub defaultSort { return 'NoSort'; }
35             sub new {
36 34     34   124 my ($that,$sort,$arg0,$arg1,$arg2,%opts) = @_;
37 34 100       178 return $that->SUPER::new(Type=>(defined($sort) ? $sort : $DDC::PP::HitSortEnum{$that->defaultSort}),
38             Arg0=>$arg0,
39             Arg1=>$arg1,
40             Arg2=>$arg2,
41             %opts);
42             }
43             sub new_i {
44 0     0   0 my ($that,$sort,$arg0,$arg1,$arg2,%opts) = @_;
45 0         0 return $that->new($sort,$arg0,($arg1+0),($arg2+0),%opts);
46             }
47              
48             sub argString {
49 6 50 33 6   43 return !defined($_[1]) || $_[1] eq '' ? '' : DDC::Utils::escapeq($_[1]);
50             }
51             sub argStringE {
52 16 50   16   65 return DDC::Utils::escapeq(defined($_[1]) ? $_[1] : '');
53             }
54             sub toString {
55 6     6   19 my $f = shift;
56             my $args = join(',',
57             ($f->{Arg0} ? $f->{Arg0} : qw()),
58             ($f->{Arg1} || $f->{Arg2}
59             ? ((defined($f->{Arg1}) ? $f->{Arg1} : ''),
60 6 50 66     82 (defined($f->{Arg2}) ? $f->{Arg2} : ''))
    50          
    50          
    100          
61             : qw())
62             );
63 6 100       96 return '#'.uc($DDC::PP::HitSortEnumStrings[$f->{Type}]).($args ? "[$args]" : '');
64             }
65              
66 12     12   61 sub jsonType { return (FilterType=>$DDC::PP::HitSortEnumStrings[$_[0]{Type}]); }
67 12     12   95 sub jsonMinMax { return (Min=>$_[0]{Arg1}, Max=>$_[0]{Arg2}); }
68 12     12   39 sub jsonData { return ($_[0]->jsonType, $_[0]->jsonMinMax); }
69              
70             ##-- ddc-compatible hash-conversion (for toJson())
71             sub toHash {
72 16     16   41 my ($obj,%opts) = @_;
73 16 50       42 return $obj->SUPER::toHash(%opts) if (!$opts{json});
74 16         54 return { class=>$obj->jsonClass, $obj->jsonData };
75             }
76              
77             ##-- pseudo-accessors (for json)
78             __PACKAGE__->defalias('Min'=>'Arg1', 0,1);
79             __PACKAGE__->defalias('Max'=>'Arg2', 0,1);
80             #sub getFilterType { return $DDC::PP::HitSortEnumStrings[$_[0]{Type}]; }
81 0     0   0 sub setFilterType { return $_[0]{Type} = $DDC::PP::HitSortEnum{$_[1]}; }
82              
83              
84             ##======================================================================
85             ## CQFRankSort
86             package DDC::PP::CQFRankSort;
87 20     20   170 use strict;
  20         46  
  20         1766  
88             our @ISA = qw(DDC::PP::CQFSort);
89              
90 0     0   0 sub defaultSort { return 'GreaterByRank'; }
91 0     0   0 sub jsonMinMax { return qw(); }
92              
93             ##======================================================================
94             ## CQFDateSort
95             package DDC::PP::CQFDateSort;
96 20     20   157 use strict;
  20         45  
  20         2336  
97             our @ISA = qw(DDC::PP::CQFSort);
98              
99 0     0   0 sub defaultSort { return 'LessByDate' };
100             sub new {
101 16     16   55 my ($that,$ftype,$lb,$ub,%opts) = @_;
102 16         97 return $that->SUPER::new($ftype,'',$lb,$ub,%opts);
103             }
104              
105             ##======================================================================
106             ## CQFSizeSort
107             package DDC::PP::CQFSizeSort;
108 20     20   162 use strict;
  20         55  
  20         2166  
109             our @ISA = qw(DDC::PP::CQFSort);
110              
111 0     0   0 sub defaultSort { return 'LessBySize'; }
112             sub new {
113 0     0   0 my ($that,$ftype,$lb,$ub,%opts) = @_;
114 0         0 return $that->SUPER::new($ftype,'',$lb,$ub,%opts);
115             }
116              
117             ##======================================================================
118             ## CQFRandomSort
119             package DDC::PP::CQFRandomSort;
120 20     20   144 use strict;
  20         45  
  20         3517  
121             our @ISA = qw(DDC::PP::CQFSort);
122              
123 0     0   0 sub defaultSort { return 'RandomSort'; }
124             sub new {
125 0     0   0 my ($that,$seed,%opts) = @_;
126 0         0 return $that->SUPER::new(undef,'',$seed,'',%opts);
127             }
128             *new_i = \&new;
129              
130             ##-- ddc-json compat
131             __PACKAGE__->defalias('Seed'=>'Arg1', 0,1);
132 0     0   0 sub jsonMinMax { return (Seed=>$_[0]{Arg1}); }
133              
134             ##======================================================================
135             ## CQFBiblSort
136             package DDC::PP::CQFBiblSort;
137 20     20   160 use strict;
  20         42  
  20         5013  
138             our @ISA = qw(DDC::PP::CQFSort);
139              
140 0     0   0 sub defaultSort { return 'LessByFreeBiblField'; }
141             sub new {
142 0     0   0 my ($that,$ftype,$field,$lb,$ub,%opts) = @_;
143 0         0 return $that->SUPER::new($ftype,$field,$lb,$ub,%opts);
144             }
145              
146             sub toString {
147 0     0   0 my $f = shift;
148             return ('#'.uc($DDC::PP::HitSortEnumStrings[$f->{Type}])
149             .'['.join(',',
150             $f->argString($f->{Arg0}),
151             (defined($f->{Arg1}) || defined($f->{Arg2})
152 0 0 0     0 ? ($f->argString($f->{Arg1}),$f->argString($f->{Arg2}))
153             : qw()),
154             )
155             .']');
156             }
157              
158             ##-- ddc-json compat
159             __PACKAGE__->defalias('Field'=>'Arg0', 0,1);
160 0     0   0 sub jsonData { return (Field=>$_[0]{Arg0}, $_[0]->SUPER::jsonData); }
161              
162              
163             ##======================================================================
164             ## CQFContextSort
165             package DDC::PP::CQFContextSort;
166 20     20   151 use strict;
  20         56  
  20         6028  
167             our @ISA = qw(DDC::PP::CQFSort);
168              
169 0     0   0 sub defaultSort { return 'LessByMiddleContext'; }
170             sub new {
171 2     2   11 my ($that,$ftype,$field,$matchid,$offset,$lb,$ub,%opts) = @_;
172 2   50     28 return $that->SUPER::new($ftype,$field,$lb,$ub, MatchId=>($matchid||0), Offset=>($offset||0), %opts);
      50        
173             }
174              
175             sub toString {
176 2     2   7 my $f = shift;
177             return ('#'.uc($DDC::PP::HitSortEnumStrings[$f->{Type}])
178             .'['.$f->argString($f->{Arg0})
179             .($f->{MatchId} ? " =$f->{MatchId}" : '')
180             .sprintf(" %+d", ($f->{Offset}||0))
181             .(defined($f->{Arg1}) || defined($f->{Arg2})
182 2 50 50     23 ? join(',', '', $f->argString($f->{Arg1}), $f->argString($f->{Arg2}))
    50 33        
183             : '')
184             .']');
185             }
186              
187 0     0   0 sub jsonData { return (Field=>$_[0]{Arg0}, MatchId=>$_[0]{MatchId}, Offset=>$_[0]{Offset}, $_[0]->SUPER::jsonData); }
188             __PACKAGE__->defalias('Field'=>'Arg0', 0,1);
189              
190             ##======================================================================
191             ## CQFHasField
192             package DDC::PP::CQFHasField;
193 20     20   153 use strict;
  20         45  
  20         6732  
194             our @ISA = qw(DDC::PP::CQFSort);
195              
196             __PACKAGE__->defprop('Negated');
197 8     8   61 sub defaultSort { return 'NoSort'; }
198             sub new {
199 8     8   31 my ($that,$field,$val,$negated,%opts) = @_;
200 8   100     83 return $that->SUPER::new(undef,$field,$val,'',Negated=>($negated||0),%opts);
201             }
202              
203 0 0   0   0 sub Negate { $_[0]{Negated} = $_[0]{Negated} ? 0 : 1; }
204              
205             sub toString {
206 8     8   637 my $f = shift;
207             return (($f->{Negated} ? '!' : '')
208 8 100       91 ."#HAS[".$f->argStringE($f->{Arg0}).','.$f->valueString.']'
209             );
210             }
211 4     4   17 sub valueString { return $_[0]->argStringE($_[0]{Arg1}); }
212              
213 0 0   0   0 sub jsonMinMax { return (Field=>$_[0]{Arg0}, Value=>$_[0]->jsonFieldValue, Negated=>($_[0]{Negated} ? 1 : 0)); }
214 0     0   0 sub jsonFieldValue { return $_[0]{Arg1}; }
215             __PACKAGE__->defalias('Field'=>'Arg0', 0,1);
216             __PACKAGE__->defalias('Value'=>'Arg1', 0,1);
217              
218             ##======================================================================
219             ## CQFHasFieldValue
220             package DDC::PP::CQFHasFieldValue;
221 20     20   172 use strict;
  20         65  
  20         1105  
222             our @ISA = qw(DDC::PP::CQFHasField);
223              
224             ##======================================================================
225             ## CQFHasFieldRegex
226             package DDC::PP::CQFHasFieldRegex;
227 20     20   138 use strict;
  20         76  
  20         3214  
228             our @ISA = qw(DDC::PP::CQFHasField);
229              
230             __PACKAGE__->defprop('Regex');
231             sub new {
232 2     2   10 my ($that,$field,$val,$negated,%opts) = @_;
233 2         21 return $that->SUPER::new($field,$val,$negated,Regex=>$val,%opts);
234             }
235              
236 2     2   17 sub valueString { return "/$_[0]{Regex}/"; }
237              
238             ##======================================================================
239             ## CQFHasFieldPrefix
240             package DDC::PP::CQFHasFieldPrefix;
241 20     20   135 use strict;
  20         92  
  20         2780  
242             our @ISA = qw(DDC::PP::CQFHasFieldRegex);
243              
244             sub new {
245 0     0   0 my ($that,$field,$val,$negated,%opts) = @_;
246 0         0 return $that->SUPER::new($field,$val,$negated,Regex=>"^\\Q${val}\\E",%opts);
247             }
248              
249 0     0   0 sub valueString { return $_[0]->argStringE($_[0]{Arg1}).'*'; }
250              
251             ##======================================================================
252             ## CQFHasFieldSuffix
253             package DDC::PP::CQFHasFieldSuffix;
254 20     20   155 use strict;
  20         44  
  20         2931  
255             our @ISA = qw(DDC::PP::CQFHasFieldRegex);
256              
257             sub new {
258 0     0   0 my ($that,$field,$val,$negated,%opts) = @_;
259 0         0 return $that->SUPER::new($field,$val,$negated,Regex=>"\\Q${val}\\E\$",%opts);
260             }
261              
262 0     0   0 sub valueString { return '*'.$_[0]->argStringE($_[0]{Arg1}); }
263              
264             ##======================================================================
265             ## CQFHasFieldInfix
266             package DDC::PP::CQFHasFieldInfix;
267 20     20   153 use strict;
  20         48  
  20         2853  
268             our @ISA = qw(DDC::PP::CQFHasFieldRegex);
269              
270             sub new {
271 0     0   0 my ($that,$field,$val,$negated,%opts) = @_;
272 0         0 return $that->SUPER::new($field,$val,$negated,Regex=>"\\Q${val}\\E",%opts);
273             }
274              
275 0     0   0 sub valueString { return '*'.$_[0]->argStringE($_[0]{Arg1}).'*'; }
276              
277             ##======================================================================
278             ## CQFHasFieldSet
279             package DDC::PP::CQFHasFieldSet;
280 20     20   152 use strict;
  20         48  
  20         4992  
281             our @ISA = qw(DDC::PP::CQFHasField);
282              
283             __PACKAGE__->defprop('Values');
284             sub new {
285 2     2   9 my ($that,$field,$vals,$negated,%opts) = @_;
286 2   50     21 return $that->SUPER::new($field,"{}",$negated,Values=>($vals||[]),%opts);
287             }
288              
289             sub SetValueString {
290 2     2   9 my ($f,$vals) = @_;
291 2   50     18 $vals ||= ($f->{Values}||[]);
      33        
292 2         7 return join(',', map {$f->argStringE($_)} @$vals);
  4         10  
293             }
294 2     2   11 sub valueString { return '{' . $_[0]->SetValueString . '}'; }
295              
296 0     0   0 sub jsonFieldValue { return $_[0]{Values}; }
297              
298              
299             ##======================================================================
300             ## CQFPrune
301              
302             package DDC::PP::CQFPrune;
303 20     20   174 use strict;
  20         40  
  20         5797  
304             our @ISA = qw(DDC::PP::CQFSort);
305              
306             __PACKAGE__->defprop('Limit');
307             __PACKAGE__->defprop('Keys');
308             sub new {
309 6     6   25 my ($that,$sort,$limit,$keys,%opts) = @_;
310 6   50     65 return $that->SUPER::new($sort,undef,undef,undef,Limit=>($limit//0), Keys=>($keys//[]), %opts);
      100        
311             }
312              
313 0     0   0 sub defaultSort { return 'LessByPruneKey'; }
314              
315             sub toString {
316 2     2   7 my $f = shift;
317             my $s = ('#'.uc($DDC::PP::HitSortEnumStrings[$f->{Type}])
318             .'['.join(',',
319             ($f->{Limit}//0),
320 2 50 50     35 (UNIVERSAL::can($f->{Keys},'toString') ? $f->{Keys}->toString() : qw()),
321             )
322             .']');
323             }
324              
325             sub jsonData {
326 4   50 4   57 return ('Limit'=>($_[0]{Limit}//0), Keys=>$_[0]{Keys});
327             }
328              
329              
330             1; ##-- be happy
331              
332             =pod
333              
334             =head1 NAME
335              
336             DDC::PP::CQFilter - pure-perl implementation of DDC::XS::CQFilter
337              
338             =head1 SYNOPSIS
339              
340             use DDC::PP::CQFilter;
341             #... stuff happens ...
342              
343              
344             =head1 DESCRIPTION
345              
346             The DDC::PP::CQFilter class is a pure-perl fork of the L class,
347             which see for details.
348              
349             =head1 SEE ALSO
350              
351             perl(1),
352             DDC::PP(3perl),
353             DDC::XS::CQFilter(3perl).
354              
355             =head1 AUTHOR
356              
357             Bryan Jurish Emoocow@cpan.orgE
358              
359             =head1 COPYRIGHT AND LICENSE
360              
361             Copyright (C) 2016-2020 by Bryan Jurish
362              
363             This library is free software; you can redistribute it and/or modify
364             it under the same terms as Perl itself, either Perl version 5.14.2 or,
365             at your option, any later version of Perl 5 you may have available.
366              
367             =cut
368