package Catmandu::Fix::search_in_store;
use Catmandu::Sane;
use Catmandu;
use Moo;
use Catmandu::Fix::Has;
with 'Catmandu::Fix::Base';
#options/arguments
has path => (fix_arg => 1);
has store_name => (fix_opt => 1, init_arg => 'store');
has bag_name => (fix_opt => 1, init_arg => 'bag');
has limit => (fix_opt => 1, init_arg => undef, default => sub {20});
has start => (fix_opt => 1, init_arg => undef, default => sub {0});
has sort => (fix_opt => 1, init_arg => undef);
has store_args => (fix_opt => 'collect');
#internal
has store => (is => 'lazy', init_arg => undef, builder => '_build_store');
has bag => (is => 'lazy', init_arg => undef, builder => '_build_bag');
sub _build_store {
my $self = $_[0];
Catmandu->store($self->store_name, %{$self->store_args});
}
sub _build_bag {
my ($self) = @_;
defined $self->bag_name
? $self->store->bag($self->bag_name)
: $self->store->bag;
}
sub emit {
my ($self, $fixer) = @_;
my $path = $fixer->split_path($self->path);
my $key = pop @$path;
my $bag_var = $fixer->capture($self->bag);
my $limit = $self->limit;
my $start = $self->start;
my $sort = $self->sort || "";
$fixer->emit_walk_path(
$fixer->var,
$path,
sub {
my $var = shift;
$fixer->emit_get_key(
$var, $key,
sub {
my $val_var = shift;
my $perl = <<EOF;
${val_var} = ${bag_var}->search( query => $val_var, start => ${start}, limit => ${limit}, sort => '${sort}' );
${val_var} = { start => ${start}, limit => ${limit}, total => ${val_var}->total(), hits => ${val_var}->to_array() };
EOF
$perl;
}
);
}
);
}
=head1 NAME
Catmandu::Fix::search_in_store - use the value as query, and replace it by a search object
=head1 SYNTAX
search_in_store(path)
search_in_store(path,store: 'store', bag: 'bag', limit: 0, start: 0, sort: 'title desc')
=head1 RETURN VALUE
{
start: 0,
limit: 0,
hits: [],
total: 1000
}
cf. L<Catmandu::Hits>
=head1 PARAMETERS
=head2 path
The location in the perl hash where the query is stored.
See L<Catmandu::Fix/"PATHS"> for more information about paths.
=head2 store
The name of the store.
This store MUST be an implementation of L<Catmandu::Searchable>.
There are several ways to refer to a store:
* by full package name ( e.g. 'Catmandu::Store::Solr' )
* by short package name ( e.g. 'Solr' )
* by name defined in the Catmandu configuration
See L<Catmandu/store-NAME> for more information.
Default is 'default'.
=head2 bag
Name of bag.
Default is 'data'.
=head2 limit
only return $limit number of records.
=head2 start
offset of records to return
=head2 sort
sort records before slicing them.
This parameter is store specific.
=head1 OTHER PARAMETERS
other parameters are given to the contructor of the L<Catmandu::Store>
e.g. catmandu.yml:
store:
catalog:
package: "Catmandu::Store::Solr"
e.g. fix:
search_in_store('foo.query', store:'catalog', bag: 'data', url: 'http://localhost:8983/solr/catalog')
=head1 EXAMPLES
#search in Catmandu->store->bag, and store first 20 results in the foo.query.hits
search_in_store('foo.query')
#search in Catmandu->store->bag, and store first 20 results in the foo.query.hits
search_in_store('foo.query', store:'default')
#search in Catmandu->store->bag; limit number of results to 10
search_in_store('foo.query', store:'default', limit: 10)
#search in Catmandu->store->bag; limit number of result to 10, starting from 15
search_in_store('foo.query', store:'default', limit: 10, start: 15)
#search in Catmandu->store->bag('persons'); sort by year descending, and by title ascending
search_in_store('foo.query', store:'default', bag:'persons', sort: 'year desc,title asc')
=head1 AUTHORS
Nicolas Franck C<< <nicolas.franck at ugent.be> >>
=head1 SEE ALSO
L<Catmandu::Fix>
L<Catmandu::Store>
=cut
1;