#-*- perl -*- # # Copyright (C) 2002,2003 Ken'ichi Fukamachi # All rights reserved. This program is free software; you can # redistribute it and/or modify it under the same terms as Perl itself. # # $FML: Cache.pm,v 1.10 2003/05/28 13:14:05 fukachan Exp $ # package FML::Error::Cache; use strict; use vars qw(@ISA @EXPORT @EXPORT_OK $AUTOLOAD); use Carp; use FML::Log qw(Log LogWarn LogError); =head1 NAME FML::Error::Cache - manipulate error/bounce information database. =head1 SYNOPSIS use FML::Error::Cache; my $db = new FML::Error::Cache $curproc; $db->add( $bounce_info ); where C<$bounce_info) follows: $bounce_info = [ { address => 'rudo@nuinui.net', status => '5.x.y', reason => '... reason ... ', }, ... ]; =head1 DESCRIPTION =head1 METHODS =head2 C =cut # Descriptions: standard constructor # Arguments: OBJ($self) HASH_REF($curproc) # Side Effects: none # Return Value: OBJ sub new { my ($self, $curproc) = @_; my ($type) = ref($self) || $self; my $me = { _curproc => $curproc }; my $config = $curproc->config(); my $db_dir = $config->{ error_analyzer_cache_dir }; unless (-d $db_dir) { $curproc->mkdir($db_dir, "mode=private"); } return bless $me, $type; } =head2 open() dummy. =head2 close() dummy. =head2 touch() dummy. =cut # Descriptions: none # Arguments: none # Side Effects: none # Return Value: none sub open { 1;} # Descriptions: none # Arguments: none # Side Effects: none # Return Value: none sub close { 1;} # Descriptions: none # Arguments: none # Side Effects: none # Return Value: none sub touch { 1;} =head2 add($address, $argv) add data given as hash reference $argv. $argv = { address => STR, reason => STR, status => STR, }; C is a simple hash, so $argv is converted to the following a set of key ($address) and value. $address => "$unixtime status=$status reason=$reason" =cut # Descriptions: add bounce info into cache. # Arguments: OBJ($self) STR($address) HASH_REF($argv) # Side Effects: update cache # Return Value: none sub add { my ($self, $address, $argv) = @_; $self->_open_cache(); my $db = $self->{ _db }; if (defined $db) { my ($reason, $status); my $unixtime = time; if (ref($argv) eq 'HASH') { $reason = $argv->{ reason } || 'unknown'; $status = $argv->{ status } || 'unknown'; $status =~ s/\s+/_/g; $reason =~ s/\s+/_/g; } else { LogError("FML::Error::Cache: add: not implemented \$argv type"); return undef; } if ($address) { $db->{ $address } = "$unixtime status=$status reason=$reason"; } else { LogWarn("FML::Error::Cache: add: invalid data"); } $self->_close_cache(); } else { croak("FML::Error::Cache: add: unknown data input type"); } } =head2 delete($address) delete entry for $address. =cut # Descriptions: delete entry for $address. # Arguments: OBJ($self) STR($address) # Side Effects: update cache # Return Value: none sub delete { my ($self, $address) = @_; $self->_open_cache(); my $db = $self->{ _db }; if (defined $db) { if ($address) { delete $db->{ $address }; } else { LogWarn("FML::Error::Cache: delete: invalid data"); } $self->_close_cache(); } else { croak("FML::Error::Cache: delete: unknown data input type"); } } =head1 CACHE IO MANIPULATION You need to use primitive methods this class provides for IO into/from error data cache. C is a simple hash, so $argv is converted to the following a set of key ($address) and value. $address => "$unixtime status=$status reason=$reason" =cut # Descriptions: open the cache database for File::CacheDir. # Arguments: OBJ($self) # Side Effects: none # Return Value: OBJ sub _open_cache { my ($self) = @_; my $curproc = $self->{ _curproc }; my $config = $curproc->{ config }; my $type = $config->{ error_analyzer_cache_type }; my $dir = $config->{ error_analyzer_cache_dir }; my $mode = $config->{ error_analyzer_cache_mode } || 'temporal'; my $days = $config->{ error_analyzer_cache_size } || 14; use Tie::JournaledDir; # tie style my %db = (); tie %db, 'Tie::JournaledDir', { dir => $dir }; $self->{ _db } = \%db; } # Descriptions: destruct tied hash. # Arguments: OBJ($self) # Side Effects: none # Return Value: none sub _close_cache { my ($self) = @_; my $db = $self->{ _db }; if (defined $db) { untie %$db; } } =head1 UTILITY FUNCTIONS =head2 get_primary_keys() return primary keys in cache as ARRAY_REF. =cut # Descriptions: return (primary) key list in cache database. # Arguments: OBJ($self) # Side Effects: none # Return Value: ARRAY_REF sub get_primary_keys { my ($self) = @_; $self->_open_cache(); my $db = $self->{ _db }; my @addr = keys %$db; $self->_close_cache(); return \@addr; } # Descriptions: get all values as HASH_REF. # Arguments: OBJ($self) # Side Effects: none # Return Value: HASH_REF sub get_all_values_as_hash_ref { my ($self) = @_; my $curproc = $self->{ _curproc }; my $config = $curproc->config(); my $dir = $config->{ error_analyzer_cache_dir }; use Tie::JournaledDir; my $obj = new Tie::JournaledDir { dir => $dir }; return $obj->get_all_values_as_hash_ref(); } =head1 CODING STYLE See C on fml coding style guide. =head1 AUTHOR Ken'ichi Fukamachi =head1 COPYRIGHT Copyright (C) 2002,2003 Ken'ichi Fukamachi All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =head1 HISTORY FML::Error::Cache first appeared in fml8 mailing list driver package. See C for more details. =cut 1;