line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Hey::Cache; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
our $VERSION = '0.01'; |
4
|
|
|
|
|
|
|
|
5
|
1
|
|
|
1
|
|
41198
|
use Data::DumpXML qw(dump_xml); |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
=cut |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
=head1 NAME |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
Hey::Cache - Cache data multiple data structures |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
=head1 SYNOPSIS |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
use Hey::Cache; |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
my $cache = Hey::Cache->new( |
18
|
|
|
|
|
|
|
Namespace => 'WeatherApp2000', # string (optional, default='default') |
19
|
|
|
|
|
|
|
CacheFile => 'fun_cache_file.xml', # file path and name (optional, default='cache.xml') |
20
|
|
|
|
|
|
|
AutoSync => 1, # boolean (optional, default=1) |
21
|
|
|
|
|
|
|
Expires => 300, # seconds (optional, default=86400) |
22
|
|
|
|
|
|
|
); |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
$cache->set( |
25
|
|
|
|
|
|
|
Name => '98501', # sets the name/key of the piece of data |
26
|
|
|
|
|
|
|
Value => { Temperature => 17, # sets the data that you wish to cache |
27
|
|
|
|
|
|
|
Condition => 'Rain', |
28
|
|
|
|
|
|
|
High => 19, |
29
|
|
|
|
|
|
|
Low => 7 }, |
30
|
|
|
|
|
|
|
Expires => 600, # optional, defaults to what was set in the constructor above |
31
|
|
|
|
|
|
|
); |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
$value = $cache->get( Name => '98501' ); # returns what you had set |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
... enough time passes (at least 10 minutes, according to the "Expires" value) ... |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
$value = $cache->get( Name => '98501' ); # returns undef because it has expired |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
$value = $cache->get( Name => '98501', Expires => 86400 ); # returns what you had set |
40
|
|
|
|
|
|
|
# because it is newer than a day |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
=head1 DESCRIPTION |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
Helps with regular data caching. It's targetted for items that are in hash references, primarly. |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
=head2 new |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
my $cache = Hey::Cache->new( |
49
|
|
|
|
|
|
|
Namespace => 'WeatherApp2000', # string (optional, default='default') |
50
|
|
|
|
|
|
|
CacheFile => 'fun_cache_file.xml', # file path and name (optional, default='cache.xml') |
51
|
|
|
|
|
|
|
AutoSync => 1, # boolean (optional, default=1) |
52
|
|
|
|
|
|
|
Expires => 300, # seconds (optional, default=86400) |
53
|
|
|
|
|
|
|
); |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
=head3 Namespace [optional] |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
Default value is "default". |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
=head3 CacheFile [optional] |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
Default value is "cache.xml". |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
=head3 AutoSync [optional] |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
Default value is 1. |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
=head3 Expires [optional] |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
Default value is 86400 (24 hours). |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
=cut |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
sub new { |
74
|
|
|
|
|
|
|
my $class = shift; |
75
|
|
|
|
|
|
|
my %options = @_; |
76
|
|
|
|
|
|
|
my $self = {}; |
77
|
|
|
|
|
|
|
bless($self, $class); # class-ify it. |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
$self->{cacheFile} = $options{CacheFile} || 'cache.xml'; # define location of cache file |
80
|
|
|
|
|
|
|
$self->{autoSync} = (!defined($options{AutoSync}) ? 1 : ($options{AutoSync} ? 1 : 0)); # default to true |
81
|
|
|
|
|
|
|
$self->{expires} = int($options{Expires}) || 86400; # default to 24 hours |
82
|
|
|
|
|
|
|
$self->{namespace} = $options{Namespace} || $options{NameSpace} || 'default'; # which namespace to read/write |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
use Data::DumpXML::Parser; |
85
|
|
|
|
|
|
|
my $parser = Data::DumpXML::Parser->new( Blesser => sub {} ); |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
$self->{cache} = {}; # preset to emptiness |
88
|
|
|
|
|
|
|
eval { $self->{cache} = $parser->parsefile($self->{cacheFile})->[0] }; # try to load cache file |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
return $self; |
91
|
|
|
|
|
|
|
} |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
=cut |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
=head2 sync |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
$cache->sync; |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
Sends the data out to file. If AutoSync is disabled (per call or in the constructor), this will manually save out |
100
|
|
|
|
|
|
|
your data to the cache file. If AutoSync is enabled, this will happen automatically. |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
=cut |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
sub sync { |
105
|
|
|
|
|
|
|
my $self = shift || return undef; |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
my $cacheOut = dump_xml($self->{cache}); # convert hashref data into XML structure |
108
|
|
|
|
|
|
|
if ($cacheOut) { # only if cacheOut is valid/existing (wouldn't want to wipe out our only cache with null) |
109
|
|
|
|
|
|
|
if (open(CACHEFH, '>'.$self->{cacheFile})) { # overwrite old cache file with new cache file |
110
|
|
|
|
|
|
|
print CACHEFH $cacheOut; |
111
|
|
|
|
|
|
|
close(CACHEFH); |
112
|
|
|
|
|
|
|
return 1; |
113
|
|
|
|
|
|
|
} |
114
|
|
|
|
|
|
|
} |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
return undef; |
117
|
|
|
|
|
|
|
} |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
=cut |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
=head2 get |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
$weather = $cache->get( Name => '98501' ); |
124
|
|
|
|
|
|
|
$weather = $cache->get( Name => '98501', Expires => 600 ); # override the expiration of the item |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
Gets the named data from the cache. |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
=head3 Name [required] |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
The name of the item to return. This name was specified in the $cache->set function. |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
=head3 Expires [optional] |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
Age in number of seconds that would be acceptable. If the cached item is newer than this value, it will return the item. If the cached item is |
135
|
|
|
|
|
|
|
older than the value, it will return undef. |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
=cut |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
sub get { |
140
|
|
|
|
|
|
|
my $self = shift || return undef; |
141
|
|
|
|
|
|
|
my %options = @_; |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
my $var = $options{Name} || return undef; |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
(defined($self->{cache}->{$self->{namespace}})) || ($self->{cache}->{$self->{namespace}} = {}); # make sure this object exists |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
my $obj = $self->{cache}->{$self->{namespace}}->{$var}; # get object |
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
return undef unless $obj; # no obj? no problem. your job is your credit! |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
my $expires = int($options{Expires}) || $obj->{expires}; |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
if ($obj->{timestamp} + $expires <= time()) { # if expired |
154
|
|
|
|
|
|
|
return undef; |
155
|
|
|
|
|
|
|
} |
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
return $obj->{value}; # return object's value |
158
|
|
|
|
|
|
|
} |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
=cut |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
=head2 set |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
$value = { Temperature => 14, High => 15, Low => 12 }; |
165
|
|
|
|
|
|
|
$cache->get( Name => '98501', Value => $value ); |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
Set a value (scalar, hash, etc) by name into the cache. |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
=head3 Name [required] |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
The name. Name of the item. Use this as a key to get it later with the $cache->get function. |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
=head3 Value [required] |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
The value. It works best if it's a reference to something, especially a hash. |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
=head3 Sync [optional] |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
Boolean. Defaults to the value specified in the constructor, which defaults to true. |
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
=head3 Timestamp [optional] |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
Defaults to the current time. If it is useful to set a different timestamp, you can do it here. This value is in epoch seconds. |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
=head3 Expires [optional] |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
Defaults to the value specified in the constructor. Sets the expiration time for this item. Expiration is stored with each item separately, so you |
188
|
|
|
|
|
|
|
can assign different expirations for different items. |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
=cut |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
sub set { |
193
|
|
|
|
|
|
|
my $self = shift || return undef; |
194
|
|
|
|
|
|
|
my %options = @_; |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
my $var = $options{Name} || return undef; |
197
|
|
|
|
|
|
|
my $value = $options{Value}; |
198
|
|
|
|
|
|
|
my $doSync = (defined($options{Sync}) ? $options{Sync} : $self->{autoSync}); |
199
|
|
|
|
|
|
|
my $timestamp = $options{Timestamp} || $options{TimeStamp} || time(); |
200
|
|
|
|
|
|
|
my $expires = int($options{Expires}) || $self->{expires}; |
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
$self->{cache}->{$self->{namespace}}->{$var} = { # set the object in the cache |
203
|
|
|
|
|
|
|
timestamp => $timestamp, |
204
|
|
|
|
|
|
|
expires => $expires, |
205
|
|
|
|
|
|
|
value => $value, |
206
|
|
|
|
|
|
|
}; |
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
$self->sync if $doSync; # write it out to file |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
return 1; |
211
|
|
|
|
|
|
|
} |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
=cut |
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
=head1 AUTHOR |
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
Dusty Wilson, Ehey-cache-module@dusty.hey.nuE |
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
Copyright (C) 2006 by Dusty Wilson Ehttp://dusty.hey.nu/E |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or modify |
224
|
|
|
|
|
|
|
it under the same terms as Perl itself, either Perl version 5.8.8 or, |
225
|
|
|
|
|
|
|
at your option, any later version of Perl 5 you may have available. |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
=cut |
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
1; |