/[webpac2]/trunk/lib/WebPAC/Store.pm
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/lib/WebPAC/Store.pm

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 714 by dpavlin, Tue Sep 26 12:47:52 2006 UTC revision 1083 by dpavlin, Sun Dec 23 19:41:10 2007 UTC
# Line 3  package WebPAC::Store; Line 3  package WebPAC::Store;
3  use warnings;  use warnings;
4  use strict;  use strict;
5    
6  use base 'WebPAC::Common';  use WebPAC::Common;
7    use base qw/WebPAC::Common Class::Accessor/;
8    __PACKAGE__->mk_accessors(qw/database/);
9    
10  use Storable;  use Storable;
11  use File::Path;  use File::Path;
12  use Data::Dump qw/dump/;  use Data::Dump qw/dump/;
# Line 14  WebPAC::Store - Store WebPAC data on dis Line 17  WebPAC::Store - Store WebPAC data on dis
17    
18  =head1 VERSION  =head1 VERSION
19    
20  Version 0.11  Version 0.15
21    
22  =cut  =cut
23    
24  our $VERSION = '0.11';  our $VERSION = '0.15';
25    
26  =head1 SYNOPSIS  =head1 SYNOPSIS
27    
# Line 34  databases just yet :-) Line 37  databases just yet :-)
37  This has additional advantage. I can create single place to plugin other  This has additional advantage. I can create single place to plugin other
38  file formats which provide better performance for particular type of data.  file formats which provide better performance for particular type of data.
39    
 For now, this is a prototype version.  
   
     use WebPAC::Store;  
   
     my $foo = WebPAC::Store->new();  
     ...  
   
40  =head1 FUNCTIONS  =head1 FUNCTIONS
41    
42  =head2 new  =head2 new
43    
44  Create new normalised database object  Create new normalised database object
45    
46    my $db = new WebPAC::Store(    my $store = new WebPAC::Store({
         path => '/path/to/cache/ds/',  
47          database => 'name',          database => 'name',
48          read_only => 1,    });
   );  
49    
50  Optional parameter C<path> defines path to directory  Optional parameter C<path> defines path to directory
51  in which cache file for C<data_structure> call will be created.  in which cache file for C<data_structure> call will be created.
52    
 If called with C<read_only> it will not disable caching if  
 called without write permission (but will die on C<save_ds>).  
   
53  Optional parametar C<database> will be used used as subdirectory in path if no  Optional parametar C<database> will be used used as subdirectory in path if no
54  database in specified when calling other functions.  database in specified when calling other functions.
55    
56  =cut  =cut
57    
 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'};  
         }  
 }  
   
58  =head2 load_ds  =head2 load_ds
59    
60  Retrive from disk one data_structure records usually using field 000 as key  Retrive from disk one data_structure records usually using field 000 as key
61    
62    my $ds = $db->load_ds(    my $ds = $store->load_ds(
63                  database => 'ps',                  database => 'ps',
64                  input => 'name',                  input => 'name',
65                  id => 42,                  id => 42,
# Line 161  sub load_ds { Line 84  sub load_ds {
84    
85          my $log = $self->_get_logger;          my $log = $self->_get_logger;
86    
         my $cache_path = $self->{'path'};  
   
         if (! $cache_path) {  
                 $log->warn("path not set, ignoring load_ds");  
                 return;  
         }  
   
87          $log->logconfess("arguments for load_ds must be HASH") unless (ref(\@_) eq 'ARRAY' && ($#_ % 2 == 1));          $log->logconfess("arguments for load_ds must be HASH") unless (ref(\@_) eq 'ARRAY' && ($#_ % 2 == 1));
88    
89          my $args = {@_};          my $args = {@_};
# Line 176  sub load_ds { Line 92  sub load_ds {
92          $log->logconfess("got hash, but without id") unless (defined($id));          $log->logconfess("got hash, but without id") unless (defined($id));
93          $log->logconfess("got hash, but id [$id] isn't number") unless ($id =~ /^\d+$/);          $log->logconfess("got hash, but id [$id] isn't number") unless ($id =~ /^\d+$/);
94    
95          my $database = $args->{database} || $self->{database} || $log->logconfess("no database?");          my $database = $args->{database} || $self->database || $log->logconfess("no database?");
96    
97          my $input = $args->{input} || '';          my $input = $args->{input} || '';
98    
99          my $cache_file = "$cache_path/$database/$input/$id";          my $cache_file = $self->var_path( 'ds', $database, $input, $id );
         $cache_file =~ s#//#/#go;  
100    
101          $log->debug("using cache_file $cache_file");          $log->debug("using cache_file $cache_file");
102    
# Line 192  sub load_ds { Line 107  sub load_ds {
107                          if ($ds_ref->{'ds'}) {                          if ($ds_ref->{'ds'}) {
108                                  return $ds_ref->{'ds'};                                  return $ds_ref->{'ds'};
109                          } else {                          } else {
110                                  $log->warn("cache entry $cache_file corrupt. Use rm $cache_path/* to re-create it on next run!");                                  $log->warn("cache entry $cache_file corrupt. Use rm $cache_file to re-create it on next run!");
                                 undef $self->{'path'};  
111                          }                          }
112                  }                  }
113          } else {          } else {
# Line 208  sub load_ds { Line 122  sub load_ds {
122    
123  Store data_structure on disk.  Store data_structure on disk.
124    
125    $db->save_ds(    $store->save_ds(
126          database => 'name',          database => 'name',
127          input => 'name',          input => 'name',
128          id => $ds->{000}->[0],          id => $ds->{000}->[0],
129          ds => $ds,          ds => $ds,
130    );    );
131    
132  B<Totally broken, but fast.>  C<database> and C<input> are optional.
   
 Depends on filename generated by C<load_ds>.  
133    
134  =cut  =cut
135    
136  sub save_ds {  sub save_ds {
137          my $self = shift;          my $self = shift;
138    
         die "can't write to database in read_only mode!" if ($self->{'read_only'});  
   
         return unless($self->{'path'});  
   
139          my $args = {@_};          my $args = {@_};
140    
141          my $log = $self->_get_logger;          my $log = $self->_get_logger;
142          $log->debug("save_ds arguments:", dump( \@_ ));          $log->debug("save_ds arguments:", sub { dump( \@_ ) });
143    
144          foreach my $f (qw/id ds/) {          foreach my $f (qw/id ds/) {
145                  $log->logconfess("need $f") unless (defined($args->{$f}));                  $log->logconfess("need $f") unless (defined($args->{$f}));
# Line 242  sub save_ds { Line 150  sub save_ds {
150    
151          my $input = $args->{input} || '';          my $input = $args->{input} || '';
152    
153          my $cache_file = $self->{path} . "/$database/$input/";          my $cache_file = $self->var_path( 'ds', $database, $input );
         $cache_file =~ s#//#/#go;  
154    
155          mkpath($cache_file) unless (-d $cache_file);          mkpath($cache_file) unless (-d $cache_file);
156    
157          $cache_file .= $args->{id};          $cache_file = $self->var_path( 'ds', $database, $input, $args->{id} );
158    
159          $log->debug("creating storable cache file $cache_file");          $log->debug("creating storable cache file $cache_file");
160    
# Line 258  sub save_ds { Line 165  sub save_ds {
165    
166  }  }
167    
168    =head2 load_lookup
169    
170    Loads lookup hash from file
171    
172      $data = $store->load_lookup(
173            database => $database,
174            input => $input,
175            key => $key,
176      );
177    
178    C<database> is optional.
179    
180    =cut
181    
182    sub load_lookup {
183            my $self = shift;
184            my $args = {@_};
185    
186            my $log = $self->_get_logger;
187    
188            foreach my $r (qw/input key/) {
189                    $log->logconfess("need '$r'") unless defined($args->{$r});
190            }
191    
192            my $database = $args->{database} || $self->{database} || $log->logconfess("no database?");
193    
194            my $path = $self->var_path( 'lookup', $database, $args->{input}, $args->{key} );
195    
196            if (! -e $path) {
197                    $log->error("lookup $path doesn't exist, lookups will be disabled. Try re-indexing $database/", $args->{input});
198                    return;
199            }
200    
201            if (my $data = retrieve($path)) {
202                    $log->info("loaded lookup $path ", -s $path, " bytes");
203                    return $data;
204            } else {
205                    $log->logwarn("can't load lookup $database/", $args->{input}, "/", $args->{key}, " from $path: $!");
206                    return undef;
207            }
208    }
209    
210  =head2 save_lookup  =head2 save_lookup
211    
212    $db->save_lookup(  Save lookup data to file.
213    
214      $store->save_lookup(
215          database => $database,          database => $database,
216          input => $input,          input => $input,
217          key => $key,          key => $key,
218          data => $lookup,          data => $lookup,
219    );    );
220    
221    C<database> is optional.
222    
223  =cut  =cut
224    
225  sub save_lookup {  sub save_lookup {
# Line 281  sub save_lookup { Line 234  sub save_lookup {
234    
235          my $database = $args->{database} || $self->{database} || $log->logconfess("no database?");          my $database = $args->{database} || $self->{database} || $log->logconfess("no database?");
236    
237          my $path = $self->{path} . "/lookup/$database/" . $args->{input};          my $path = $self->var_path( 'lookup', $database, $args->{input} );
238    
239          mkpath($path) unless (-d $path);          mkpath($path) unless (-d $path);
240    
241          $path .= "/" . $args->{key};          $path .= "/" . $args->{key};
242    
243            my $t = time();
244    
245          if (store $args->{data}, $path) {          if (store $args->{data}, $path) {
246                  $log->info("saved lookup $path");                  $log->info(sprintf("saved lookup %s %d bytes in %.2fs", $path, -s $path, time() - $t));
247                    return 1;
248            } else {
249                    $log->logwarn("can't save lookup to $path: $!");
250                    return undef;
251            }
252    }
253    
254    =head2 load_row
255    
256    Loads row from input database cache (used for lookups)
257    
258      $row = $store->load_row(
259            database => $database,
260            input => $input,
261            id => 42,
262      );
263    
264    C<database> is optional.
265    
266    =cut
267    
268    sub load_row {
269            my $self = shift;
270            my $args = {@_};
271    
272            my $log = $self->_get_logger;
273    
274            foreach my $r (qw/input id/) {
275                    $log->logconfess("need '$r'") unless defined($args->{$r});
276            }
277    
278            my $database = $args->{database} || $self->{database} || $log->logconfess("no database?");
279    
280            my $path = $self->var_path( 'row', $database, $args->{input}, $args->{id} );
281    
282            if (! -e $path) {
283                    $log->warn("input row $path doesn't exist, skipping");
284                    return;
285            }
286    
287            if (my $data = retrieve($path)) {
288                    $log->debug("loaded row $path");
289                    return $data;
290            } else {
291                    $log->logwarn("can't load row from $path: $!");
292                    return undef;
293            }
294    }
295    
296    =head2 save_row
297    
298    Save row data to file.
299    
300      $store->save_row(
301            database => $database,
302            input => $input,
303            id => $mfn,
304            row => $lookup,
305      );
306    
307    C<database> is optional.
308    
309    =cut
310    
311    sub save_row {
312            my $self = shift;
313            my $args = {@_};
314    
315            my $log = $self->_get_logger;
316    
317            foreach my $r (qw/input id row/) {
318                    $log->logconfess("need '$r'") unless defined($args->{$r});
319            }
320    
321            my $database = $args->{database} || $self->{database} || $log->logconfess("no database?");
322    
323            my $path = $self->var_path( 'row', $database, $args->{input} );
324    
325            mkpath($path) unless (-d $path);
326    
327            $path .= "/" . $args->{id};
328    
329            if (store $args->{row}, $path) {
330                    $log->debug("saved row $path");
331                  return 1;                  return 1;
332          } else {          } else {
333                  $log->logwarn("can't store lookup $database/", $args->{input}, "/", $args->{key}, " in $path: $!");                  $log->logwarn("can't save row to $path: $!");
334                  return undef;                  return undef;
335          }          }
336  }  }
# Line 303  Dobrica Pavlinusic, C<< <dpavlin@rot13.o Line 342  Dobrica Pavlinusic, C<< <dpavlin@rot13.o
342    
343  =head1 COPYRIGHT & LICENSE  =head1 COPYRIGHT & LICENSE
344    
345  Copyright 2005 Dobrica Pavlinusic, All Rights Reserved.  Copyright 2005-2006 Dobrica Pavlinusic, All Rights Reserved.
346    
347  This program is free software; you can redistribute it and/or modify it  This program is free software; you can redistribute it and/or modify it
348  under the same terms as Perl itself.  under the same terms as Perl itself.

Legend:
Removed from v.714  
changed lines
  Added in v.1083

  ViewVC Help
Powered by ViewVC 1.1.26