File Coverage

blib/lib/Plucene/Search/DateFilter.pm
Criterion Covered Total %
statement 41 41 100.0
branch 5 10 50.0
condition 2 6 33.3
subroutine 10 10 100.0
pod 2 2 100.0
total 60 69 86.9


line stmt bran cond sub pod time code
1             package Plucene::Search::DateFilter;
2 1     1   597 use base 'Plucene::Search::Filter';
  1         2  
  1         476  
3 1     1   6 use Carp;
  1         4  
  1         60  
4 1     1   6 use strict;
  1         3  
  1         25  
5 1     1   6 use warnings;
  1         1  
  1         402  
6              
7 1     1   8 use Plucene::Document::DateSerializer;
  1         3  
  1         54  
8 1     1   5 use Time::Piece;
  1         2  
  1         8  
9 1     1   69 use Bit::Vector::Minimal;
  1         3  
  1         153  
10              
11             =head1 NAME
12              
13             Plucene::Search::DateFilter - Restrict searches to given time periods
14              
15             =head1 SYNOPSIS
16              
17             my $filter = Plucene::Search::DateFilter->new({
18             field => "date",
19             from => Time::Piece $from,
20             to => Time::Piece $to
21             })
22             my $hits = $searcher->search($query, $filter);
23              
24             =head1 DESCRIPTION
25              
26             This class can restrict the results of a search to a set of dates. This
27             requires a field to have been indexed using
28             L. See the documentation for that module
29             for how to do this.
30              
31             =head1 METHODS
32              
33             =head2 new
34              
35             my $filter = Plucene::Search::DateFilter->new({
36             field => "date",
37             from => Time::Piece $from,
38             to => Time::Piece $to
39             })
40              
41             This creates a new filter. Either of C or C are optional.
42              
43             =cut
44              
45             sub new {
46 1     1 1 155 my ($self, $args) = @_;
47 1         5 for my $arg (qw(from to)) {
48 2 50       7 next unless exists $args->{$arg};
49 2 50       12 croak "$arg argument was not a Time::Piece object"
50             unless UNIVERSAL::isa($args->{$arg}, "Time::Piece");
51             }
52 1 50       6 croak "Need to pass a field" unless exists $args->{field};
53 1     1   5 no warnings 'uninitialized';
  1         2  
  1         339  
54 1   33     9 bless {
      33        
55             field => $args->{field},
56             from => freeze_date($args->{from} || Time::Piece->new(0)),
57             to => freeze_date($args->{to} || Time::Piece->new(~0)),
58             }, $self;
59             }
60              
61             =head2 bits
62              
63             This is used by the searcher to iterate over the documents and return
64             a bitfield specifying which documents are included in the range.
65              
66             =cut
67              
68             sub bits {
69 1     1 1 2 my ($self, $reader) = @_;
70 1         5 my $bits = Bit::Vector::Minimal->new(size => $reader->max_doc);
71 1         41 my $enum = $reader->terms(
72             Plucene::Index::Term->new({
73             field => $self->{field},
74             text => $self->{from} }));
75 1 50       9 return $bits unless $enum->term;
76 1         10 my $termdocs = $reader->term_docs;
77              
78 1         11 my $stop = Plucene::Index::Term->new({
79             field => $self->{field},
80             text => $self->{to} });
81 1         15 while ($enum->term->le($stop)) {
82 2         9 $termdocs->seek($enum->term);
83 2         16 $bits->set($termdocs->doc) while $termdocs->next;
84 2 50       18 last unless $enum->next;
85             }
86 1         26 return $bits;
87             }
88              
89             1;