File Coverage

blib/lib/Catmandu/Store/Solr/Bag.pm
Criterion Covered Total %
statement 21 57 36.8
branch 0 10 0.0
condition 0 9 0.0
subroutine 7 15 46.6
pod 0 7 0.0
total 28 98 28.5


line stmt bran cond sub pod time code
1             package Catmandu::Store::Solr::Bag;
2              
3 1     1   2413 use Catmandu::Sane;
  1         1  
  1         6  
4 1     1   1075 use Catmandu::Util qw(:is);
  1         34357  
  1         400  
5 1     1   8 use Carp qw(confess);
  1         3  
  1         45  
6 1     1   754 use Catmandu::Hits;
  1         20986  
  1         31  
7 1     1   564 use Catmandu::Store::Solr::Searcher;
  1         3  
  1         26  
8 1     1   554 use Catmandu::Store::Solr::CQL;
  1         4  
  1         44  
9 1     1   11 use Moo;
  1         3  
  1         12  
10              
11             with 'Catmandu::Bag';
12             with 'Catmandu::Searchable';
13             with 'Catmandu::Buffer';
14              
15             sub generator {
16 0     0 0   my ($self) = @_;
17 0           my $store = $self->store;
18 0           my $name = $self->name;
19 0           my $limit = $self->buffer_size;
20 0           my $query = qq/_bag:"$name"/;
21             sub {
22 0     0     state $start = 0;
23 0           state $hits;
24 0 0 0       unless ($hits && @$hits) {
25 0           $hits =
26             $store->solr->search($query, {start => $start, rows => $limit})
27             ->content->{response}{docs};
28 0           $start += $limit;
29             }
30 0   0       my $hit = shift(@$hits) || return;
31 0           delete $hit->{_bag};
32 0           $hit;
33 0           };
34             }
35              
36             sub count {
37 0     0 0   my ($self) = @_;
38 0           my $name = $self->name;
39 0           my $res = $self->store->solr->search(
40             qq/_bag:"$name"/,
41             {
42             rows => 0,
43             facet => "false",
44             spellcheck => "false",
45             defType => "lucene",
46             }
47             );
48 0           $res->content->{response}{numFound};
49             }
50              
51             sub get {
52             my ($self, $id) = @_;
53             my $name = $self->name;
54             my $res = $self->store->solr->search(
55             qq/_bag:"$name" AND _id:"$id"/,
56             {
57             rows => 1,
58             facet => "false",
59             spellcheck => "false",
60             defType => "lucene",
61             }
62             );
63             my $hit = $res->content->{response}{docs}->[0] || return;
64             delete $hit->{_bag};
65             $hit;
66             }
67              
68             sub add {
69             my ($self, $data) = @_;
70              
71             my @fields = (WebService::Solr::Field->new(_bag => $self->name));
72              
73             for my $key (keys %$data) {
74             next if $key eq '_bag';
75             my $val = $data->{$key};
76             if (is_array_ref($val)) {
77             is_value($_) && push @fields,
78             WebService::Solr::Field->new($key => $_)
79             foreach @$val;
80             }
81             elsif (is_value($val)) {
82             push @fields, WebService::Solr::Field->new($key => $val);
83             }
84             }
85              
86             $self->buffer_add(WebService::Solr::Document->new(@fields));
87              
88             if ($self->buffer_is_full) {
89             $self->commit;
90             }
91             }
92              
93             sub delete {
94             my ($self, $id) = @_;
95             my $name = $self->name;
96             $self->store->solr->delete_by_query(qq/_bag:"$name" AND _id:"$id"/);
97             }
98              
99             sub delete_all {
100 0     0 0   my ($self) = @_;
101 0           my $name = $self->name;
102 0           $self->store->solr->delete_by_query(qq/_bag:"$name"/);
103             }
104              
105             sub delete_by_query {
106             my ($self, %args) = @_;
107             my $name = $self->name;
108             $self->store->solr->delete_by_query(qq/_bag:"$name" AND ($args{query})/);
109             }
110              
111             sub commit { # TODO better error handling
112 0     0 0   my ($self) = @_;
113 0           my $solr = $self->store->solr;
114 0           my $err;
115 0 0         if ($self->buffer_used) {
116 0 0 0       eval { $solr->add($self->buffer) } or push @{ $err ||= [] }, $@;
  0            
  0            
117 0           $self->clear_buffer;
118             }
119 0 0 0       eval { $solr->commit } or push @{ $err ||= [] }, $@;
  0            
  0            
120 0           !defined $err, $err;
121             }
122              
123             sub search {
124             my ($self, %args) = @_;
125              
126             my $query = delete $args{query};
127             my $start = delete $args{start};
128             my $limit = delete $args{limit};
129             my $bag = delete $args{reify};
130              
131             my $name = $self->name;
132              
133             my $bag_fq = qq/_bag:"$name"/;
134              
135             if ( $args{fq} ) {
136             if (is_array_ref( $args{fq})) {
137             unshift @{ $args{fq} }, $bag_fq;
138             }
139             else {
140             $args{fq} = [$bag_fq, $args{fq}];
141             }
142             } else {
143             $args{fq} = $bag_fq;
144             }
145              
146             my $res = $self->store->solr->search($query, {%args, start => $start, rows => $limit});
147              
148             my $set = $res->content->{response}{docs};
149              
150             if ($bag) {
151             $set = [map { $bag->get($_->{_id}) } @$set];
152             } else {
153             delete $_->{_bag} for @$set;
154             }
155              
156             my $hits = Catmandu::Hits->new({
157             limit => $limit,
158             start => $start,
159             total => $res->content->{response}{numFound},
160             hits => $set,
161             });
162              
163             if ($res->facet_counts) {
164             $hits->{facets} = $res->facet_counts;
165             }
166              
167             if ($res->spellcheck) {
168             $hits->{spellcheck} = $res->spellcheck;
169             }
170              
171             $hits;
172             }
173              
174             sub searcher {
175             my ($self, %args) = @_;
176             Catmandu::Store::Solr::Searcher->new(%args, bag => $self);
177             }
178              
179             sub translate_sru_sortkeys {
180 0     0 0   confess 'TODO';
181             }
182              
183             sub translate_cql_query {
184 0     0 0   Catmandu::Store::Solr::CQL->parse($_[1]);
185             }
186              
187             sub normalize_query {
188 0 0   0 0   $_[1] || "*:*";
189             }
190              
191             =head1 SEE ALSO
192              
193             L, L
194              
195             =cut
196              
197             1;