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 )