move search in Search::Estraier
[BackupPC.git] / lib / BackupPC / Search / Estraier.pm
1 package BackupPC::Search::Estraier;
2 use warnings;
3 use strict;
4
5 use Search::Estraier 0.04;
6
7 my $debug = $ENV{DEBUG} || 0;
8
9 sub new {
10         my ( $class, $index_node_url ) = @_;
11
12         warn "# using $index_node_url";
13
14         my $self = bless {
15                 node => Search::Estraier::Node->new(
16                         url => $index_node_url,
17                         user => 'admin',
18                         passwd => 'admin',
19                         croak_on_error => 1,
20                 ),
21         }, $class;
22         return $self;
23 }
24
25 sub node { $_[0]->{node} };
26
27 sub exists {
28         my ( $self, $row ) = @_;
29
30         my $uri = $row->{hname} . ':' . $row->{sname} . '#' . $row->{backupnum} . ' ' . $row->{filepath};
31         my $id = $self->node->uri_to_id($uri);
32         return $id && $id != -1;
33 }
34
35 sub add_doc {
36         my ( $self, $row ) = @_;
37
38         # create a document object 
39         my $doc = Search::Estraier::Document->new;
40
41         my $uri = $row->{hname} . ':' . $row->{sname} . '#' . $row->{backupnum} . ' ' . $row->{filepath};
42         # add attributes to the document object 
43         $doc->add_attr('@uri', $uri);
44
45         foreach my $c (keys %$row) {
46                 print STDERR "attr $c = $row->{$c}\n" if ($debug > 2);
47                 $doc->add_attr($c, $row->{$c}) if defined($row->{$c});
48         }
49
50         #$doc->add_attr('@cdate', fmt_date($row->{'date'}));
51
52         # add the body text to the document object 
53         my $path = $row->{'filepath'};
54         $doc->add_text($path);
55         $path =~ s/(.)/$1 /g;
56         $doc->add_hidden_text($path);
57
58         print STDERR $doc->dump_draft,"\n" if ($debug > 1);
59
60         # register the document object to the database
61         $self->node->put_doc($doc);
62
63 }
64
65 sub commit {
66         my $self = shift;
67         warn "# commit not needed";
68 }
69
70 my $sort_mapping = {
71         share_d => 'sname STRD',
72         share_a => 'sname STRA',
73         path_d => 'filepath STRD',
74         path_a => 'filepath STRA',
75         num_d => 'backupnum NUMD',
76         num_a => 'backupnum NUMA',
77         size_d => 'size NUMD',
78         size_a => 'size NUMA',
79         date_d => 'date NUMD',
80         date_a => 'date NUMA',
81 };
82
83 sub search {
84         my ( $self, $offset, $on_page, $sort, $q, $shareid, $backup_from, $backup_to, $files_from, $files_to ) = @_;
85
86         warn "# search $offset/$on_page [$q] shareid: $shareid backup: $backup_from - $backup_to files: $files_from - $files_to";
87
88         # create a search condition object
89         my $cond = Search::Estraier::Condition->new();
90
91         if (length($q) > 0) {
92                 # exact match
93                 $cond->add_attr("filepath ISTRINC $q");
94
95                 $q =~ s/(.)/$1 /g;
96                 # set the search phrase to the search condition object
97                 $cond->set_phrase($q);
98         }
99
100         $cond->add_attr("backup_date NUMGE $backup_from") if ($backup_from);
101         $cond->add_attr("backup_date NUMLE $backup_to") if ($backup_to);
102
103         $cond->add_attr("date NUMGE $files_from") if ($files_from);
104         $cond->add_attr("date NUMLE $files_to") if ($files_to);
105
106         $cond->add_attr("shareid NUMEQ $shareid") if ($shareid);
107
108         $cond->set_max( $offset + $on_page );
109         $cond->set_options( 'SURE' );
110         $cond->set_order( $sort_mapping->{$sort} );
111
112         # get the result of search
113         my @res;
114         my ($result, $hits);
115
116         $result = $self->node->search($cond, 0);
117         if ($result) {
118                 $hits = $result->hits;
119         } else {
120                 return (0,[]);
121         }
122
123         # for each document in result
124         for my $i ($offset .. ($offset + $on_page - 1)) {
125                 last if ($i >= $result->doc_num);
126
127                 my $doc = $result->get_doc($i);
128
129                 my $row;
130                 foreach my $c (qw/fid hname sname backupnum filepath date type size/) {
131                         $row->{$c} = $doc->attr($c);
132                 }
133                 push @res, $row;
134         }
135
136         warn "# $hits hits";
137
138         return ($hits, \@res);
139
140 }
141
142 1;