File Coverage

blib/lib/BeePack.pm
Criterion Covered Total %
statement 8 10 80.0
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 12 14 85.7


line stmt bran cond sub pod time code
1             package BeePack;
2             BEGIN {
3 3     3   75867 $BeePack::AUTHORITY = 'cpan:GETTY';
4             }
5             # ABSTRACT: Primitive MsgPack based key value storage
6             $BeePack::VERSION = '0.100';
7 3     3   1744 use Moo;
  3         41249  
  3         15  
8 3     3   4984 use bytes;
  3         23  
  3         20  
9 3     3   2257 use CDB::TinyCDB;
  0            
  0            
10             use Data::MessagePack;
11             use Carp qw( croak );
12              
13             sub true { Data::MessagePack::true() }
14             sub false { Data::MessagePack::false() }
15              
16             # currently workaround to be reset
17             has cdb => (
18             is => 'rw',
19             lazy => 1,
20             builder => 1,
21             init_arg => undef,
22             handles => [qw(
23             keys
24             )],
25             );
26              
27             sub _build_cdb {
28             my ( $self ) = @_;
29             return -f $self->filename
30             ? CDB::TinyCDB->open($self->filename, $self->has_tempfile ? (
31             for_update => $self->tempfile
32             ) : ())
33             : $self->readonly
34             ? croak("Can't open non-existing readonly database ".$self->filename)
35             : CDB::TinyCDB->create($self->filename,$self->tempfile);
36             }
37              
38             has filename => (
39             is => 'ro',
40             required => 1,
41             );
42              
43             has tempfile => (
44             is => 'ro',
45             predicate => 1,
46             );
47              
48             has nil_exists => (
49             is => 'lazy',
50             );
51              
52             sub _build_nil_exists { 1 }
53              
54             has readonly => (
55             is => 'lazy',
56             );
57              
58             sub _build_readonly {
59             my ( $self ) = @_;
60             return $self->has_tempfile ? 0 : 1;
61             }
62              
63             has data_messagepack => (
64             is => 'lazy',
65             init_arg => undef,
66             );
67              
68             sub _build_data_messagepack {
69             Data::MessagePack->new->canonical->utf8->prefer_integer
70             }
71              
72             sub BUILD {
73             my ( $self ) = @_;
74             croak("Read/Write opening requires tempfile") if !$self->readonly && !$self->has_tempfile;
75             $self->cdb;
76             $self->data_messagepack;
77             }
78              
79             sub open {
80             my ( $class, $filename, $tempfile, %attr ) = @_;
81             return $class->new(
82             filename => $filename,
83             defined $tempfile ? ( tempfile => $tempfile ) : (),
84             %attr,
85             );
86             }
87              
88             sub set {
89             my ( $self, $key, $value ) = @_;
90             croak("Trying to set on readonly BeePack ".$self->filename) if $self->readonly;
91             $self->cdb->put_replace($key,$self->data_messagepack->pack($value));
92             }
93              
94             sub set_integer {
95             my ( $self, $key, $value ) = @_;
96             $self->set($key, 0 + $value);
97             }
98              
99             sub set_bool {
100             my ( $self, $key, $value ) = @_;
101             $self->set($key, $value
102             ? Data::MessagePack::true()
103             : Data::MessagePack::false()
104             );
105             }
106              
107             sub set_string {
108             my ( $self, $key, $value ) = @_;
109             $self->set($key, "$value");
110             }
111              
112             sub set_nil {
113             my ( $self, $key ) = @_;
114             $self->set($key, undef);
115             }
116              
117             sub exists {
118             my ( $self, $key ) = @_;
119             return 0 unless $self->cdb->exists($key);
120             my $msgpack = $self->cdb->get($key);
121             my $value = $self->data_messagepack->unpack($msgpack);
122             return defined $value ? 1 : 0;
123             }
124              
125             sub get {
126             my ( $self, $key ) = @_;
127             return undef unless $self->exists($key);
128             return $self->data_messagepack->unpack(scalar $self->cdb->get($key));
129             }
130              
131             sub get_raw {
132             my ( $self, $key ) = @_;
133             return scalar $self->cdb->get($key);
134             }
135              
136             sub save {
137             my ( $self ) = @_;
138             croak("Trying to save readonly CDB ".$self->filename) if $self->readonly;
139             $self->cdb->finish( save_changes => 1, reopen => 0 );
140             # Bug in CDB::TinyCDB? reopen => 1 is not reopening
141             $self->cdb(undef);
142             $self->cdb($self->_build_cdb);
143             return 1;
144             }
145              
146             1;
147              
148             __END__