File Coverage

lib/Ubic/Persistent.pm
Criterion Covered Total %
statement 44 47 93.6
branch 4 6 66.6
condition n/a
subroutine 12 12 100.0
pod 3 3 100.0
total 63 68 92.6


line stmt bran cond sub pod time code
1             package Ubic::Persistent;
2             $Ubic::Persistent::VERSION = '1.58_01'; # TRIAL
3 25     25   117 use strict;
  25         40  
  25         808  
4 25     25   121 use warnings;
  25         38  
  25         892  
5              
6             # ABSTRACT: simple hash-to-file persistence object
7              
8              
9 25     25   15268 use JSON;
  25         169345  
  25         209  
10 25     25   13600 use Ubic::Lockf;
  25         56  
  25         1435  
11 25     25   8005 use Ubic::AtomicFile;
  25         38  
  25         799  
12              
13             {
14             # support the compatibility with JSON.pm v1 just because we can
15             # see also: Ubic::ServiceLoader::Ext::json
16 25     25   137 no strict;
  25         37  
  25         559  
17 25     25   94 no warnings;
  25         40  
  25         11679  
18             sub jsonToObj; *jsonToObj = (*{JSON::from_json}{CODE}) ? \&JSON::from_json : \&JSON::jsonToObj;
19             sub objToJson; *objToJson = (*{JSON::to_json}{CODE}) ? \&JSON::to_json : \&JSON::objToJson;
20             }
21              
22             my $meta = {};
23              
24             sub _load {
25 28     28   61 my ($fname) = @_;
26              
27 28 50       952 open my $fh, '<', $fname or die "Can't open $fname: $!";
28 28         39 my $data;
29 28         186 local $/;
30 28         614 my $str = <$fh>;
31 28 50       149 if ($str =~ /^\$data/) {
32             # old Data::Dumper format, parsing with regexes
33 0         0 my ($status) = $str =~ m{'status' => '(\w+)'};
34 0         0 my ($enabled) = $str =~ m{'enabled' => (\d+)};
35 0         0 $data = { status => $status, enabled => $enabled };
36             }
37             else {
38 28         244 $data = jsonToObj($str);
39             }
40              
41 28         1561 return $data;
42             }
43              
44             sub load {
45 14     14 1 41 my ($class, $fname) = @_;
46 14         68 return _load($fname);
47             }
48              
49             sub new {
50 27     27 1 65 my ($class, $fname) = @_;
51 27         196 my $lock = lockf("$fname.lock", { blocking => 1 });
52              
53 27         89 my $self = {};
54 27 100       460 $self = _load($fname) if -e $fname;
55              
56 27         276 bless $self => $class;
57 27         313 $meta->{$self} = { lock => $lock, fname => $fname };
58 27         159 return $self;
59             }
60              
61             sub commit {
62 27     27 1 52 my $self = shift;
63 27         81 my $fname = $meta->{$self}{fname};
64              
65 27         273 Ubic::AtomicFile::store(objToJson({ %$self }) => $fname);
66             }
67              
68             sub DESTROY {
69 27     27   74 my $self = shift;
70 27         68 local $@;
71 27         412 delete $meta->{$self};
72             }
73              
74              
75             1;
76              
77             __END__