KSx-IndexManager

 view release on metacpan or  search on metacpan

lib/KSx/IndexManager.pm  view on Meta::CPAN

use base qw(Class::Accessor::Grouped);

__PACKAGE__->mk_group_accessors(simple    => qw(root schema context _lock_fh));
__PACKAGE__->mk_group_accessors(inherited => qw(_plugins));
__PACKAGE__->mk_group_accessors(
  component_class => qw(invindexer_class searcher_class schema_class),
);
__PACKAGE__->invindexer_class('KinoSearch::InvIndexer');
__PACKAGE__->searcher_class('KinoSearch::Searcher');

use KinoSearch::Searcher;
use KinoSearch::InvIndexer;
use KinoSearch::Schema;

use Data::OptList;
use Carp ();
use Scalar::Util ();
use Fcntl qw(:DEFAULT :flock);

sub plugins { @{ $_[0]->_plugins || $_[0]->_plugins([]) } }

sub add_plugins {
  my $class = shift;
  if (Scalar::Util::blessed $class) { 
    Carp::croak "add_plugins is a class method, do not call it on $class";
  }
  my @plugins = $class->plugins;
  for my $opt (@{ Data::OptList::mkopt([@_]) }) {
    my ($plugin, $arg) = @$opt;
    $plugin = "KSx::IndexManager::Plugin::$plugin" 
      unless $plugin =~ s/^\+//;
    eval "require $plugin; 1" or die $@;
    push @plugins, $plugin->new($arg);
  }
  $class->_plugins(\@plugins);
}

sub call_plugins {
  my ($self, $event, $arg, @rest) = @_;
  for my $plugin ($self->plugins) {
    #use Data::Dumper; warn Dumper($plugin);
    $plugin->$event($arg, @rest);
  }
}

sub call_self_plugins {
  my ($self, $event, $arg, @rest) = @_;
  $arg ||= {};
  for my $plugin ($self->plugins) {
    $plugin->$event($self, $arg, @rest);
  }
}

sub new {
  my ($class, $arg) = @_;
  $arg ||= {};
  $class->call_plugins(before_new => $arg);
  unless ($arg->{schema} ||= $class->schema_class) {
    Carp::croak "schema is mandatory for $class->new";
  }
  my $self = bless $arg => $class;
  $self->call_self_plugins('after_new');
  return $self;
}

sub path {
  my $self = shift;
  my $path = $self->root;
  $self->call_self_plugins(alter_path => \$path);
  return $path;
}

sub open    { shift->invindexer({ mode => 'open'    }) }
sub clobber { shift->invindexer({ mode => 'clobber' }) }

sub invindexer {
  my ($self, $opt) = @_;
  Carp::croak "'mode' argument is mandatory for $self->invindexer"
    unless $opt->{mode};
  my $meth = $opt->{mode};
  return $self->invindexer_class->new(
    invindex => $self->schema->$meth($self->path),
  );
}

sub _load {
  my ($self, $i, $opt) = @_;
  $i->{$self->path} ||= $self->invindexer($opt);
}

sub to_doc {
  my ($self, $obj) = @_;
  return $obj;
}

sub _add_one_doc {
  my ($self, $i, $obj, $opt) = @_;
  my $inv = $self->_load($i, $opt);
  $self->call_self_plugins(before_add_doc => $obj);
  for my $doc ($self->to_doc($obj)) {
    $inv->add_doc($doc);
  }
  # wish we could call it with the new document or something
  $self->call_self_plugins(after_add_doc => $obj);
}

sub add_docs {
  my ($self, $opt, $docs) = @_;
  my $created = 0;
  my $i = {}; # invindex cache by path
  if (ref $docs eq 'ARRAY') {
    $created = @$docs;
    for my $obj (@$docs) {
      $self->_add_one_doc($i, $obj, $opt);
    }
  } elsif (eval { $docs->can('next') }) {
    while (my $obj = $docs->next) {
      $self->_add_one_doc($i, $obj, $opt);
      $created++;
    }
  } else {

 view all matches for this distribution
 view release on metacpan -  search on metacpan

( run in 0.446 second using v1.00-cache-2.02-grep-82fe00e-cpan-9e6bc14194b )