Apache-Wyrd
view release on metacpan or search on metacpan
Wyrd/Services/Index.pm view on Meta::CPAN
$self->process_html($id, $entry->index_data);
$self->update_key("\x06\%$id", $entry->index_title) if ($entry->can('index_title'));
$self->update_key("\x07\%$id", $entry->index_keywords) if ($entry->can('index_keywords'));
$self->update_key("\x08\%$id", $entry->index_description) if ($entry->can('index_description'));
if ($self->extended) {
my @attributes = @{$self->attribute_list};
splice(@attributes, 0, 8);
foreach my $attribute (@attributes) {
my $value = undef;
if ($entry->can("index_$attribute")) {
eval('$value = $entry->index_' . $attribute);
$self->set_error($@) if ($@);
$self->check_error;
} elsif (exists($entry->{$attribute})) {
$value = $entry->{$attribute};
}
if ($entry->can("handle_$attribute")) {
eval('$entry->handle_' . $attribute . '($id, $value)');
$self->set_error($@) if ($@);
$self->check_error;
} else {
if ($self->maps->{$attribute}) {
$self->index_map($attribute, $id, [token_parse(lc($value))]);
} else {
$self->update_key($self->attributes->{$attribute} . "\%$id", $value);
}
}
}
}
$self->update_key($id, $name);
$self->update_key("\x00%" . $name, $id);
my $result = 0;
$self->db->db_get("\xff%greatest_id", my $greatest_id);
$self->update_key("\xff%greatest_id", $id) if ($id > $greatest_id);
if ($result) {
$self->set_error("Failed to store greatest ID: $id");
$self->check_error;
}
if ($self->current_transaction) {
if ($self->error) {
unless ($self->quiet) {
warn join ("\n", "Errors occurred in update of $name => $id:", $self->error, "Aborting transaction...");
}
$self->current_transaction->txn_abort;
} else {
$self->current_transaction->txn_commit;
}
$self->{'current_transaction'} = undef;
}
$self->close_db;
return "Update of entry $id " . ($self->error ? "unsuccessful." : "successful.");
}
sub purge_entry {
my ($self, $entry) = @_;
my $id = undef;
my $found_entry = undef;
my $not_entry = $self->db->db_get("\x00%$entry", $found_entry);
if ($not_entry) {
$id = $entry;
$self->db->db_get($entry, $found_entry);
$entry = $found_entry;
} else {
$id = $found_entry;
}
#warn "$id and $entry";
unless ($id and $entry) {
return "Entry not found to purge: $entry";
return 1;
}
$self->set_error("purge_entry called without write access") unless ($self->status eq 'RW');
foreach my $attribute (@{$self->attribute_list}) {
next if ($attribute eq 'reverse');
#warn "purging $attribute";
if ($self->maps->{$attribute}) {
$self->purge_map($attribute, $id) unless ($self->dirty) && $self->set_error("failed to purge map $attribute");
} else {
$self->delete_key($self->attributes->{$attribute} . "%$id") && $self->set_error("failed to purge key $attribute");
}
}
$self->db->db_del($id) && $self->set_error("failed to purge ID $id");
$self->db->db_del("\x00%$entry") && $self->set_error("failed to purge entry $entry");
my $errors = $self->error;
return "Entry (BerkeleyDB ID# $id) successfully purged" unless ($errors);
return "Entry (BerkeleyDB ID# $id) failed to be purged: " . join("\n", $self->error) . "\n";
}
=pod
=item (hashref) C<entry_by_name> (scalar)
Given the value of an B<name> attribute, returns a hashref of all the regular
attributes stored for a given entry.
=cut
sub entry_by_name {
my ($self, $name) = @_;
my $id = $self->get_id($name);
return $self->get_entry($id);
}
sub get_entry {
#note - Call get_entry with an ID ONLY. No names
my ($self, $id, $params) = @_;
$params = {} unless (ref($params) eq 'HASH');
my $failed = $self->db->db_get($id, my $name);
return {} if ($failed);
my %entry = (id => $id, name => $name);
my @attributes = @{$self->attribute_list};
my %skip = map {$_ => 1} (@{$params->{'skip'} || []}, @{$self->map_list}, 'name', 'id');
@attributes = grep {!$skip{$_}} @attributes;
if ($params->{'limit'}) {
my %limit = map {$_ => 1} @{$params->{'limit'}};
@attributes = grep {$limit{$_}} @attributes;
}
if ($params->{'require'}) {
my %unique = ();
@attributes = grep {$unique{$_}++ == 0} (@attributes, @{$params->{'require'}});
Wyrd/Services/Index.pm view on Meta::CPAN
#indexed object
if ($self->bigfile and length($data) >= 2048) {
$self->db->db_get("\x03\%$id", my $old_key);
$old_key =~ s/^\x00://;
my $current_key = sha1_hex($data);
if ($current_key ne $old_key) {
$self->db_big->db_put($current_key, $data);
my $wordcount = $self->index_words($id, $data);
$self->update_key("\x03\%$id", "\x00:$current_key");
$self->update_key("\x05\%$id", $wordcount);
}
return;
}
$self->update_key("\x03\%$id", $data);
my $wordcount = $self->index_words($id, $data);
$self->update_key("\x05\%$id", $wordcount);
#warn "\x03\%$id updated to $data";
return;
}
sub extract_html {
my ($self, $id) = @_;
$self->db->db_get("\x03\%$id", my $data);
if ($data =~ s/^\x00:(.+)//) {
$self->db_big->db_get($1, $data);
}
return $data;
}
sub index_map {
my ($self, $attribute_name, $id, $data) = @_;
use Encode qw(_utf8_off);
_utf8_off($data);
#warn "mapping $id - $attribute : " . join (':', @$data);
my $attribute = $self->attributes->{$attribute_name};
my (%unique, $item, @items) = (); # for unique-ifying word list
#remove duplicates if necessary
if (ref($data) eq 'ARRAY') {
@items = grep { $unique{$_}++ == 0 } @$data;
} elsif (ref($data) eq 'HASH') {
%unique = %$data;
@items = keys(%unique);
} else {
#not sure why you'd want to do this, but hey.
@items = ($data);
}
if ($attribute_name eq 'word') {
@items = grep {length($_) >= $self->wordmin} @items;
}
# For each item, add id to map
foreach my $item (sort @items) {
#This actually does happen, strangely enough.
unless ($item or ($item =~ /^0+$/o)) {
warn 'null item here';
warn 'but defined' if (defined($item));
}
my $value = undef;
my $not_found = $self->db->db_get("$attribute\%$item", my $data);
my(%entries) = ();
%entries = unpack("n*", $data) unless ($not_found);
$entries{$id} = $unique{$item};
foreach my $item (keys %entries) {
$value .= pack "n", $item;
$value .= pack "n", $entries{$item};
}
#warn($self->translate_packed($attribute) . "\%$item: " . $self->translate_packed($value));
$self->update_key("$attribute\%$item", $value);
}
if ($self->reversemaps) {
my $rev_attribute = $self->attributes->{"_$attribute_name"};
$self->update_key("$rev_attribute\%$id", join("\x00", @items));
}
return;
}
sub purge_map {
my ($self, $attribute_name, $id) = @_;
my $debug = $self->debug;
$debug = 1 if ($self->{'runtime_flags'}->{'debug'});
my $attribute = $self->attributes->{$attribute_name};
my $rev_attribute = $self->attributes->{"_$attribute_name"};
my $reverse_index = '';
my $reversemap_notfound = 1;#by default, don't search for a reversemap unless it's supposed to have one.
$reversemap_notfound = $self->db->db_get("$rev_attribute\%$id", $reverse_index) if ($self->reversemaps);
my @updates = ();
if (not($reversemap_notfound)) {
$debug && warn ("Found reverse index for map $attribute_name. Will purge based on that value.");
foreach my $entry (split "\x00", $reverse_index) {
#warn "purging $id from $entry";
my $result = $self->db->db_get("$attribute\%$entry", my $current);
if ($result) {
$debug && warn "Reverse index for $attribute_name has a corrupt entry: $entry. Will do a complete purge.";
$reversemap_notfound = 1;
$reversemap_notfound = 0 if ($attribute_name) eq 'word';
last;
}
my(%entries) = unpack("n*", $current);
#warn "$entry has " . scalar(keys(%entries)) . " documents";
my $value = undef;
foreach my $item (keys %entries) {
#warn "$entry has doc $item";
next if ($item eq $id);
$value .= pack "n", $item;
$value .= pack "n", $entries{$item};
}
push (@updates, "$attribute\%$entry", $value);
}
$self->db->db_del("$rev_attribute\%$id") && $self->set_error("Could not remove reversemap for $attribute_name on id $id");
}
if ($reversemap_notfound) {
$debug && $self->reversemaps && warn ("No reverse index for map $attribute_name. Doing a full purge of $id from the map.");
my ($key, $current, $removed) = ();
my $cursor = $self->db->db_cursor;
unless ($cursor) {
$self->read_db;
$cursor = $self->db->db_cursor;
unless ($cursor) {
warn 'Failed to obtain DB Cursor. Aborting purge_map()';
return 1;
}
( run in 2.496 seconds using v1.01-cache-2.11-cpan-98e64b0badf )