diff options
Diffstat (limited to 'lib/Devscripts/JSONCache.pm')
-rw-r--r-- | lib/Devscripts/JSONCache.pm | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/lib/Devscripts/JSONCache.pm b/lib/Devscripts/JSONCache.pm new file mode 100644 index 0000000..cf056c0 --- /dev/null +++ b/lib/Devscripts/JSONCache.pm @@ -0,0 +1,99 @@ +package Devscripts::JSONCache; + +use strict; +use JSON; +use Moo; + +has file => (is => 'rw', required => 1); + +has saved => (is => 'rw'); + +has _data => (is => 'rw'); + +sub save_sec { + my ($self, $obj) = @_; + my $tmp = umask; + umask 0177; + open(my $fh, '>', $self->file) or ($self->saved(1) and die $!); + print $fh JSON::to_json($obj); + close $fh; + umask $tmp; +} + +sub data { + my ($self) = @_; + return $self->_data if $self->_data; + my $res; + if (-r $self->file) { + open(F, $self->file) or ($self->saved(1) and die $!); + $res = JSON::from_json(join('', <F>) || "{}"); + close F; + } else { + $self->save_sec({}); + $self->saved(0); + } + return $self->_data($res); +} + +sub TIEHASH { + my $r = shift->new({ + file => shift, + @_, + }); + # build data + $r->data; + return $r; +} + +sub FETCH { + return $_[0]->data->{ $_[1] }; +} + +sub STORE { + $_[0]->data->{ $_[1] } = $_[2]; +} + +sub DELETE { + delete $_[0]->data->{ $_[1] }; +} + +sub CLEAR { + $_[0]->save({}); +} + +sub EXISTS { + return exists $_[0]->data->{ $_[1] }; +} + +sub FIRSTKEY { + my ($k) = sort { $a cmp $b } keys %{ $_[0]->data }; + return $k; +} + +sub NEXTKEY { + my ($self, $last) = @_; + my $i = 0; + my @keys = map { + return $_ if ($i); + $i++ if ($_ eq $last); + return () + } + sort { + $a cmp $b + } keys %{ $_[0]->data }; + return @keys ? $keys[0] : (); +} + +sub SCALAR { + return scalar %{ $_[0]->data }; +} + +sub save { + return if ($_[0]->saved); + eval { $_[0]->save_sec($_[0]->data); }; + $_[0]->saved(1); +} + +*DESTROY = *UNTIE = *save; + +1; |