Apache-Wyrd
view release on metacpan or search on metacpan
Wyrd/Services/MySQLIndex.pm view on Meta::CPAN
} else {
#not sure why you'd want to do this, but hey.
@items = ($data);
}
if ($attribute_name eq 'data') {
@items = grep {length($_) >= $self->wordmin} @items;
}
#make an array of data items to be assembled into an efficient insert query.
my @entries = ();
# For each item, add id to map
foreach my $item (@items) {
#N.B. Do not skip over undefined here.
my $count = $unique{$item} || 1;
push @entries, "('$item', $id, $count)";
}
if (@entries) {
my $query = "insert into $table (item, id, tally) values " . join(", ", @entries);
my $sh = $self->db->prepare($query);
$sh->execute;
if ($sh->err) {
$self->set_error($sh->errstr);
}
}
return;
}
sub purge_map {
my ($self, $attribute_name, $id) = @_;
my $debug = $self->debug;
$debug = 1 if ($self->{'runtime_flags'}->{'debug'});
my $table = '_wyrd_index_' . $attribute_name;
my $sh = $self->db->prepare("delete from $table where id=?");
$sh->execute($id);
if ($sh->err) {
$self->set_error($sh->errstr);
}
return;
}
sub word_search { #accepts a search string, returns an arrayref of entry matches
my ($self, $string, $attribute, $params) = @_;
if ($attribute) {
$self->_raise_exception("You cannot perform a word search on the attribute $attribute; It doesn't exist or isn't a map")
unless ($self->maps->{$attribute});
} else {
$attribute = 'data';
}
my $table = '_wyrd_index_' . $attribute;
my $index = $self->read_db;
my (@out, %match, %must, %mustnot, @match, @add, @remove, $restrict, @entries)=();
$string =~ s/(\+|\-)\s+/$1/g;
if ($string =~ /"/) {#first deal with exact word matches
while ($string =~ m/(([\+-]?)"([^"]+?)")/) { #whole=1, modifier=2, phrase=3
my $phrase = $self->clean_searchstring($3);
my $modifier = $2;
my $substring = $1;
#escape out phrase and substring since they will be used in regexps
#later in this subroutine.
$substring =~ s/([\\\+\?\:\\*\&\@\$\!])/\\$1/g;
$phrase =~ s/([\\\+\?\:\\*\&\@\$\!])/\\$1/g;
$string =~ s/$substring//; #remove the phrase from the string;
if ($modifier eq '+') {
push (@add, "_$phrase");
$restrict = 1;
} elsif ($modifier eq '-') {
push (@remove, "_$phrase");
} else {
push (@match, "_$phrase");
}
}
}
my @word=split(/\s+/, $string); #then deal with single words
foreach my $word (@word){
my ($modifier) = $word =~ /^([\+\-])/;
$word = $self->clean_searchstring($word);
if ($modifier eq '+') {
push (@add, $word);
$restrict = 1;
} elsif ($modifier eq '-') {
push (@remove, $word);
} else {
push (@match, $word);
}
}
#warn "searching for:";
#warn map {"\nmatch - $_"} @match;
#warn map {"\nadd - $_"} @add;
#warn map {"\nremove - $_"} @remove;
#if this is a 100% negative search, all entries match
unless (scalar(@match) or scalar(@add)) {
@entries = $self->get_all_entries;
foreach my $key (@entries) {
$match{$key}=1;
}
}
foreach my $word (@match){
if ($word =~ s/^_//) {
my $sh = $self->db->prepare(qq{select id, $attribute from _wyrd_index where $attribute like '\%$word\%'});
$sh->execute;
if ($sh->err) {
$self->set_error($sh->errstr);
}
while (my $data_ref = $sh->fetchrow_arrayref) {
my $entry = $data_ref->[0];
my $data = $data_ref->[1];
my @count = $data =~ m/$word/g;
my $count = @count;
$match{$entry} += $count;
}
} else {
my $sh = $self->db->prepare(qq{select id, tally from $table where item=?});
$sh->execute($word);
if ($sh->err) {
$self->set_error($sh->errstr);
}
while (my $data_ref = $sh->fetchrow_arrayref) {
my $entry = $data_ref->[0];
( run in 2.560 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )