/[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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 710 - (show annotations)
Mon Sep 25 18:58:43 2006 UTC (17 years, 7 months ago) by dpavlin
File size: 6038 byte(s)
 r1014@llin:  dpavlin | 2006-09-25 20:56:33 +0200
 save lookups using WebPAC::Store

1 package WebPAC::Store;
2
3 use warnings;
4 use strict;
5
6 use base 'WebPAC::Common';
7 use Storable;
8 use File::Path;
9 use Data::Dumper;
10
11 =head1 NAME
12
13 WebPAC::Store - Store WebPAC data on disk
14
15 =head1 VERSION
16
17 Version 0.10
18
19 =cut
20
21 our $VERSION = '0.10';
22
23 =head1 SYNOPSIS
24
25 This module provides disk storage for normalised data and lookups.
26
27 It is one of newer components of WebPAC, so it will change from time to
28 time.
29
30 I will try to keep backward compatiblity by providing multiple back-ends,
31 but this can't be garanteed. In other words, don't delete your input
32 databases just yet :-)
33
34 This has additional advantage. I can create single place to plugin other
35 file formats which provide better performance for particular type of data.
36
37 For now, this is a prototype version.
38
39 use WebPAC::Store;
40
41 my $foo = WebPAC::Store->new();
42 ...
43
44 =head1 FUNCTIONS
45
46 =head2 new
47
48 Create new normalised database object
49
50 my $db = new WebPAC::Store(
51 path => '/path/to/cache/ds/',
52 database => 'name',
53 read_only => 1,
54 );
55
56 Optional parameter C<path> defines path to directory
57 in which cache file for C<data_structure> call will be created.
58
59 If called with C<read_only> it will not disable caching if
60 called without write permission (but will die on C<save_ds>).
61
62 Mandatory parametar C<database> is used as subdirectory in database directory.
63
64 =cut
65
66 sub new {
67 my $class = shift;
68 my $self = {@_};
69 bless($self, $class);
70
71 my $log = $self->_get_logger();
72
73 foreach my $p (qw/path database/) {
74 $log->logconfess("need $p") unless ($self->{$p});
75 }
76
77 $self->path( $self->{'path'} );
78
79 $self ? return $self : return undef;
80 }
81
82 =head2 path
83
84 Check if specified cache directory exist, and if not, disable caching.
85
86 $db->path('./cache/ds/');
87
88 If you pass false or zero value to this function, it will disable
89 cacheing.
90
91 You can also example C<< $db->{path} >> to get current cache path.
92
93 =cut
94
95 sub path {
96 my $self = shift;
97
98 my $dir = shift;
99
100 my $log = $self->_get_logger();
101
102 if ($dir) {
103 my $msg;
104 if (! -e $dir) {
105 if ($self->{'read_only'}) {
106 $msg = "doesn't exist";
107 } else {
108 $log->info("creating $dir");
109 mkpath $dir;
110 }
111 } elsif (! -d $dir) {
112 $msg = "is not directory";
113 } elsif (! -w $dir) {
114 $msg = "not writable" unless ($self->{'read_only'});
115 }
116
117 if ($msg) {
118 $log->warn("cache path $dir $msg, disabling...");
119 undef $self->{'path'};
120 } else {
121 $log->debug("using cache dir $dir");
122 $self->{'path'} = $dir;
123 }
124 } else {
125 $log->debug("disabling cache");
126 undef $self->{'path'};
127 }
128 }
129
130 =head2 load_ds
131
132 Retrive from disk one data_structure records usually using field 000 as key
133
134 my $ds = $db->load_ds( id => 42, prefix => 'name', database => 'ps' );
135
136 This function will also perform basic sanity checking on returned
137 data and disable caching if data is corrupted (or changed since last
138 update).
139
140 C<prefix> is used to differenciate different source input databases
141 which are indexed in same database.
142
143 C<database> if B<optional> argument which will override database name used when creating
144 C<WebPAC::Store> object (for simple retrival from multiple databases).
145
146 Returns hash or undef if cacheing is disabled or unavailable.
147
148 =cut
149
150 sub load_ds {
151 my $self = shift;
152
153 my $log = $self->_get_logger;
154
155 my $cache_path = $self->{'path'};
156
157 if (! $cache_path) {
158 $log->warn("path not set, ignoring load_ds");
159 return;
160 }
161
162 $log->logconfess("arguments for load_ds must be HASH") unless (ref(\@_) eq 'ARRAY' && ($#_ % 2 == 1));
163
164 my $args = {@_};
165 my $id = $args->{id};
166
167 $log->logconfess("got hash, but without id") unless (defined($id));
168 $log->logconfess("got hash, but id [$id] isn't number") unless ($id =~ /^\d+$/);
169
170 my $database = $args->{database} || $self->{database};
171 my $prefix = $args->{prefix} || '';
172
173 $log->logconfess("can't find database name") unless ($database);
174
175 my $cache_file = "$cache_path/$database/$prefix/$id";
176 $cache_file =~ s#//#/#go;
177
178 $log->debug("using cache_file $cache_file");
179
180 if (-r $cache_file) {
181 my $ds_ref = retrieve($cache_file);
182 if ($ds_ref) {
183 $log->debug("cache hit: $cache_file");
184 if ($ds_ref->{'ds'}) {
185 return $ds_ref->{'ds'};
186 } else {
187 $log->warn("cache entry $cache_file corrupt. Use rm $cache_path/* to re-create it on next run!");
188 undef $self->{'path'};
189 }
190 }
191 } else {
192 #$log->warn("cache entry $cache_file doesn't exist");
193 return undef;
194 }
195
196 return undef;
197 }
198
199 =head2 save_ds
200
201 Store data_structure on disk.
202
203 $db->save_ds(
204 id => $ds->{000}->[0],
205 prefix => 'name',
206 ds => $ds,
207 );
208
209 B<Totally broken, but fast.>
210
211 Depends on filename generated by C<load_ds>.
212
213 =cut
214
215 sub save_ds {
216 my $self = shift;
217
218 die "can't write to database in read_only mode!" if ($self->{'read_only'});
219
220 return unless($self->{'path'});
221
222 my $arg = {@_};
223
224 my $log = $self->_get_logger;
225
226 foreach my $f (qw/id ds/) {
227 $log->logconfess("need $f") unless ($arg->{$f});
228 }
229
230 my $database = $self->{database};
231 $log->logconfess("can't find database name") unless ($database);
232
233 my $prefix = $arg->{prefix} || '';
234
235 my $cache_file = $self->{path} . '/' . $prefix . '/';
236 $cache_file =~ s#//#/#go;
237
238 mkpath($cache_file) unless (-d $cache_file);
239
240 $cache_file .= $arg->{id};
241
242 $log->debug("creating storable cache file $cache_file");
243
244 return store {
245 ds => $arg->{ds},
246 id => $arg->{id},
247 }, $cache_file;
248
249 }
250
251 =head2 save_lookup
252
253 $db->save_lookup( $database, $input, $key, $lookup );
254
255 =cut
256
257 sub save_lookup {
258 my $self = shift;
259 my ($database, $input, $key, $lookup) = @_;
260
261 my $log = $self->_get_logger;
262
263 my $path = $self->{'path'} . "/lookup/$input";
264
265 mkpath($path) unless (-d $path);
266
267 $path .= "/$key";
268
269 if (store $lookup, $path) {
270 $log->info("saved lookup $path");
271 } else {
272 $log->logwarn("can't store lookup $database/$input/$key in $path: $!");
273 }
274
275
276 }
277
278
279 =head1 AUTHOR
280
281 Dobrica Pavlinusic, C<< <dpavlin@rot13.org> >>
282
283 =head1 COPYRIGHT & LICENSE
284
285 Copyright 2005 Dobrica Pavlinusic, All Rights Reserved.
286
287 This program is free software; you can redistribute it and/or modify it
288 under the same terms as Perl itself.
289
290 =cut
291
292 1; # End of WebPAC::Store

  ViewVC Help
Powered by ViewVC 1.1.26