X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=lib%2FWebPAC%2FStore.pm;h=91ca503128ff65f0c54e16a543984e26a05ce4eb;hb=cec67015c5f0421f4fa71348a1b9eff91604c729;hp=2a86689880cd9aa77a66a3502451dbb2600b7e65;hpb=9480d415f5c2ac8de9c7a67a4968b18e032a11a8;p=webpac2 diff --git a/lib/WebPAC/Store.pm b/lib/WebPAC/Store.pm index 2a86689..91ca503 100644 --- a/lib/WebPAC/Store.pm +++ b/lib/WebPAC/Store.pm @@ -3,7 +3,10 @@ package WebPAC::Store; use warnings; use strict; -use base 'WebPAC::Common'; +use WebPAC::Common; +use base qw/WebPAC::Common Class::Accessor/; +__PACKAGE__->mk_accessors(qw/database/); + use Storable; use File::Path; use Data::Dump qw/dump/; @@ -14,11 +17,11 @@ WebPAC::Store - Store WebPAC data on disk =head1 VERSION -Version 0.13 +Version 0.15 =cut -our $VERSION = '0.13'; +our $VERSION = '0.15'; =head1 SYNOPSIS @@ -34,109 +37,29 @@ databases just yet :-) This has additional advantage. I can create single place to plugin other file formats which provide better performance for particular type of data. -For now, this is a prototype version. - - use WebPAC::Store; - - my $foo = WebPAC::Store->new(); - ... - =head1 FUNCTIONS =head2 new Create new normalised database object - my $db = new WebPAC::Store( - path => '/path/to/cache/ds/', + my $store = new WebPAC::Store({ database => 'name', - read_only => 1, - ); + }); Optional parameter C defines path to directory in which cache file for C call will be created. -If called with C it will not disable caching if -called without write permission (but will die on C). - Optional parametar C will be used used as subdirectory in path if no database in specified when calling other functions. =cut -sub new { - my $class = shift; - my $self = {@_}; - bless($self, $class); - - my $log = $self->_get_logger(); - - foreach my $p (qw/path/) { - $log->logconfess("need $p") unless ($self->{$p}); - } - - $self->path( $self->{'path'} ); - - $self ? return $self : return undef; -} - -=head2 path - -Check if specified cache directory exist, and if not, disable caching. - - $db->path('./cache/ds/'); - -If you pass false or zero value to this function, it will disable -cacheing. - -You can also call this function to get current cache path. - - my $cache_path = $db->path; - -=cut - -sub path { - my $self = shift; - - my $dir = shift; - - return $self->{path} unless defined($dir); - - my $log = $self->_get_logger(); - - if ($dir) { - my $msg; - if (! -e $dir) { - if ($self->{'read_only'}) { - $msg = "doesn't exist"; - } else { - $log->info("creating $dir"); - mkpath $dir; - } - } elsif (! -d $dir) { - $msg = "is not directory"; - } elsif (! -w $dir) { - $msg = "not writable" unless ($self->{'read_only'}); - } - - if ($msg) { - $log->warn("cache path $dir $msg, disabling..."); - undef $self->{'path'}; - } else { - $log->debug("using cache dir $dir"); - $self->{'path'} = $dir; - } - } else { - $log->debug("disabling cache"); - undef $self->{'path'}; - } -} - =head2 load_ds Retrive from disk one data_structure records usually using field 000 as key - my $ds = $db->load_ds( + my $ds = $store->load_ds( database => 'ps', input => 'name', id => 42, @@ -161,13 +84,6 @@ sub load_ds { my $log = $self->_get_logger; - my $cache_path = $self->{'path'}; - - if (! $cache_path) { - $log->warn("path not set, ignoring load_ds"); - return; - } - $log->logconfess("arguments for load_ds must be HASH") unless (ref(\@_) eq 'ARRAY' && ($#_ % 2 == 1)); my $args = {@_}; @@ -176,12 +92,11 @@ sub load_ds { $log->logconfess("got hash, but without id") unless (defined($id)); $log->logconfess("got hash, but id [$id] isn't number") unless ($id =~ /^\d+$/); - my $database = $args->{database} || $self->{database} || $log->logconfess("no database?"); + my $database = $args->{database} || $self->database || $log->logconfess("no database?"); my $input = $args->{input} || ''; - my $cache_file = "$cache_path/ds/$database/$input/$id"; - $cache_file =~ s#//#/#go; + my $cache_file = $self->var_path( 'ds', $database, $input, $id ); $log->debug("using cache_file $cache_file"); @@ -192,8 +107,7 @@ sub load_ds { if ($ds_ref->{'ds'}) { return $ds_ref->{'ds'}; } else { - $log->warn("cache entry $cache_file corrupt. Use rm $cache_path/* to re-create it on next run!"); - undef $self->{'path'}; + $log->warn("cache entry $cache_file corrupt. Use rm $cache_file to re-create it on next run!"); } } } else { @@ -208,7 +122,7 @@ sub load_ds { Store data_structure on disk. - $db->save_ds( + $store->save_ds( database => 'name', input => 'name', id => $ds->{000}->[0], @@ -222,14 +136,10 @@ C and C are optional. sub save_ds { my $self = shift; - die "can't write to database in read_only mode!" if ($self->{'read_only'}); - - return unless($self->{'path'}); - my $args = {@_}; my $log = $self->_get_logger; - $log->debug("save_ds arguments:", dump( \@_ )); + $log->debug("save_ds arguments:", sub { dump( \@_ ) }); foreach my $f (qw/id ds/) { $log->logconfess("need $f") unless (defined($args->{$f})); @@ -240,12 +150,11 @@ sub save_ds { my $input = $args->{input} || ''; - my $cache_file = $self->{path} . "/ds/$database/$input/"; - $cache_file =~ s#//#/#go; + my $cache_file = $self->var_path( 'ds', $database, $input ); mkpath($cache_file) unless (-d $cache_file); - $cache_file .= $args->{id}; + $cache_file = $self->var_path( 'ds', $database, $input, $args->{id} ); $log->debug("creating storable cache file $cache_file"); @@ -260,7 +169,7 @@ sub save_ds { Loads lookup hash from file - $data = $db->load_lookup( + $data = $store->load_lookup( database => $database, input => $input, key => $key, @@ -282,15 +191,15 @@ sub load_lookup { my $database = $args->{database} || $self->{database} || $log->logconfess("no database?"); - my $path = $self->{path} . "/lookup/$database/" . $args->{input} . '/' . $args->{key}; + my $path = $self->var_path( 'lookup', $database, $args->{input}, $args->{key} ); if (! -e $path) { - $log->warn("lookup $path doesn't exist, skipping"); + $log->error("lookup $path doesn't exist, lookups will be disabled. Try re-indexing $database/", $args->{input}); return; } if (my $data = retrieve($path)) { - $log->info("loaded lookup $path"); + $log->info("loaded lookup $path ", -s $path, " bytes"); return $data; } else { $log->logwarn("can't load lookup $database/", $args->{input}, "/", $args->{key}, " from $path: $!"); @@ -302,7 +211,7 @@ sub load_lookup { Save lookup data to file. - $db->save_lookup( + $store->save_lookup( database => $database, input => $input, key => $key, @@ -325,17 +234,103 @@ sub save_lookup { my $database = $args->{database} || $self->{database} || $log->logconfess("no database?"); - my $path = $self->{path} . "/lookup/$database/" . $args->{input}; + my $path = $self->var_path( 'lookup', $database, $args->{input} ); mkpath($path) unless (-d $path); $path .= "/" . $args->{key}; + my $t = time(); + if (store $args->{data}, $path) { - $log->info("saved lookup $path"); + $log->info(sprintf("saved lookup %s %d bytes in %.2fs", $path, -s $path, time() - $t)); + return 1; + } else { + $log->logwarn("can't save lookup to $path: $!"); + return undef; + } +} + +=head2 load_row + +Loads row from input database cache (used for lookups) + + $row = $store->load_row( + database => $database, + input => $input, + id => 42, + ); + +C is optional. + +=cut + +sub load_row { + my $self = shift; + my $args = {@_}; + + my $log = $self->_get_logger; + + foreach my $r (qw/input id/) { + $log->logconfess("need '$r'") unless defined($args->{$r}); + } + + my $database = $args->{database} || $self->{database} || $log->logconfess("no database?"); + + my $path = $self->var_path( 'row', $database, $args->{input}, $args->{id} ); + + if (! -e $path) { + $log->warn("input row $path doesn't exist, skipping"); + return; + } + + if (my $data = retrieve($path)) { + $log->debug("loaded row $path"); + return $data; + } else { + $log->logwarn("can't load row from $path: $!"); + return undef; + } +} + +=head2 save_row + +Save row data to file. + + $store->save_row( + database => $database, + input => $input, + id => $mfn, + row => $lookup, + ); + +C is optional. + +=cut + +sub save_row { + my $self = shift; + my $args = {@_}; + + my $log = $self->_get_logger; + + foreach my $r (qw/input id row/) { + $log->logconfess("need '$r'") unless defined($args->{$r}); + } + + my $database = $args->{database} || $self->{database} || $log->logconfess("no database?"); + + my $path = $self->var_path( 'row', $database, $args->{input} ); + + mkpath($path) unless (-d $path); + + $path .= "/" . $args->{id}; + + if (store $args->{row}, $path) { + $log->debug("saved row $path"); return 1; } else { - $log->logwarn("can't save lookup $database/", $args->{input}, "/", $args->{key}, " in $path: $!"); + $log->logwarn("can't save row to $path: $!"); return undef; } }