File Coverage

blib/lib/Net/Clacks/ClacksCache.pm
Criterion Covered Total %
statement 41 150 27.3
branch 0 36 0.0
condition 0 15 0.0
subroutine 14 31 45.1
pod 16 16 100.0
total 71 248 28.6


line stmt bran cond sub pod time code
1             package Net::Clacks::ClacksCache;
2             #---AUTOPRAGMASTART---
3 1     1   17 use 5.020;
  1         3  
4 1     1   5 use strict;
  1         1  
  1         21  
5 1     1   5 use warnings;
  1         1  
  1         21  
6 1     1   4 use diagnostics;
  1         3  
  1         6  
7 1     1   26 use mro 'c3';
  1         1  
  1         15  
8 1     1   26 use English;
  1         9  
  1         8  
9 1     1   350 use Carp;
  1         2  
  1         64  
10             our $VERSION = 22;
11 1     1   6 use autodie qw( close );
  1         2  
  1         7  
12 1     1   270 use Array::Contains;
  1         2  
  1         68  
13 1     1   6 use utf8;
  1         1  
  1         5  
14 1     1   21 use Encode qw(is_utf8 encode_utf8 decode_utf8);
  1         2  
  1         49  
15             #---AUTOPRAGMAEND---
16              
17 1     1   7 use Net::Clacks::Client;
  1         1  
  1         19  
18 1     1   4 use YAML::Syck;
  1         2  
  1         54  
19 1     1   6 use MIME::Base64;
  1         1  
  1         1466  
20              
21             sub new {
22 0     0 1   my ($proto, %config) = @_;
23 0   0       my $class = ref($proto) || $proto;
24              
25 0           my $self = bless \%config, $class;
26              
27 0           $self->reconnect();
28              
29 0           $self->{initfromhandle} = 0;
30              
31 0 0         if(!defined($self->{user})) {
32 0           croak("User not defined!");
33             }
34              
35 0 0         if(!defined($self->{password})) {
36 0           croak("Password not defined!");
37             }
38              
39              
40 0           return $self;
41             }
42              
43             sub newFromHandle {
44 0     0 1   my ($proto, $clacks) = @_;
45 0   0       my $class = ref($proto) || $proto;
46              
47 0           my $self = bless {}, $class;
48              
49 0           $self->{initfromhandle} = 1;
50 0           $self->{clacks} = $clacks;
51              
52 0           $self->extraInits(); # Hook for application specific inits
53              
54 0           return $self;
55             }
56              
57             sub reconnect {
58 0     0 1   my ($self) = @_;
59              
60 0 0         return if($self->{initfromhandle});
61 0 0         return if(defined($self->{clacks}));
62              
63 0           my $clacks;
64 0 0 0       if(defined($self->{host}) && defined($self->{port})) {
    0          
65             $clacks = Net::Clacks::Client->new($self->{host}, $self->{port},
66             $self->{user}, $self->{password},
67 0 0         $self->{APPNAME} . '/' . $VERSION, 0)
68             or croak("Can't connect to Clacks server");
69             } elsif(defined($self->{socketpath})) {
70             $clacks = Net::Clacks::Client->newSocket($self->{socketpath},
71             $self->{user}, $self->{password},
72 0 0         $self->{APPNAME} . '/' . $VERSION, 0)
73             or croak("Can't connect to Clacks server");
74             } else {
75 0           croak("No valid connection configured. Don't know where to connect to!");
76             }
77 0           $self->{clacks} = $clacks;
78              
79 0           $self->{clacks}->disablePing(); # Webclient doesn't know when it is called again
80              
81 0           $self->set("VERSION::" . $self->{APPNAME}, $VERSION);
82              
83 0           $self->{clacks}->activate_memcached_compat;
84 0           $self->{clacks}->disablePing();
85              
86 0           $self->extraInits(); # Hook for application specific inits
87              
88 0           return;
89             }
90              
91             sub extraInits {
92 0     0 1   my ($self) = @_;
93              
94             # Hook for application specific inits
95 0           return;
96             }
97              
98             sub extraDestroys {
99 0     0 1   my ($self) = @_;
100              
101             # Hook for application specific destroys
102 0           return;
103             }
104              
105             sub disconnect {
106 0     0 1   my ($self) = @_;
107              
108 0           eval {
109 0           $self->{clacks}->disconnect();
110             };
111              
112 0           return;
113             }
114              
115             DESTROY {
116 0     0     my ($self) = @_;
117              
118 0           eval {
119 0           $self->{clacks}->disconnect();
120             };
121              
122 0           $self->extraDestroys();
123 0           return;
124             };
125              
126             sub get {
127 0     0 1   my ($self, $key) = @_;
128              
129 0           $self->reconnect(); # Make sure we are connected
130              
131 0           $key = $self->sanitize_key($key);
132              
133 0           my $value = $self->{clacks}->retrieve($key);
134 0 0         return if(!defined($value));
135              
136 0 0         if($value =~ /^PAGECAMELCLACKSYAMLB64\:(.+)/o) {
    0          
137 0           $value = decode_base64($1);
138 0           $value = Load($value);
139 0           $value = $self->deref($value);
140             } elsif($value =~ /^PAGECAMELCLACKSB64\:(.+)/o) {
141 0           $value = decode_base64($1);
142             }
143 0           return $value;
144             }
145              
146             sub set { ## no critic (NamingConventions::ProhibitAmbiguousNames)
147 0     0 1   my ($self, $key, $data) = @_;
148              
149 0           $self->reconnect(); # Make sure we are connected
150              
151 0           $key = $self->sanitize_key($key);
152              
153 0 0 0       if(ref $data ne '') {
    0          
    0          
154             #$data = 'PAGECAMELCLACKSYAMLB64: ' . encode_base64(Dump($data), '');
155 0           $data = Dump($data);
156 0           $data = 'PAGECAMELCLACKSYAMLB64: ' . encode_base64($data, '');
157             } elsif($data =~ /^PAGECAMELCLACKSB64/o) {
158             # Already encoded? Clacks injection alert? Just don't store the thing...
159 0           return 0;
160             } elsif($data =~ /\n/o || $data =~ /\r/o) {
161 0           $data = 'PAGECAMELCLACKSB64:' . encode_base64($data, '');
162             }
163              
164 0           $self->{clacks}->store($key, $data);
165              
166 0           return 1;
167             }
168              
169             sub delete { ## no critic(BuiltinHomonyms)
170 0     0 1   my ($self, $key) = @_;
171              
172 0           $self->reconnect(); # Make sure we are connected
173              
174 0           $key = $self->sanitize_key($key);
175              
176 0           $self->{clacks}->remove($key);
177 0           return 1;
178             }
179              
180             sub incr {
181 0     0 1   my ($self, $key, $stepsize) = @_;
182              
183 0           $self->reconnect(); # Make sure we are connected
184              
185 0           $key = $self->sanitize_key($key);
186              
187 0 0         if(!defined($stepsize)) {
188 0           $self->{clacks}->increment($key);
189             } else {
190 0           $self->{clacks}->increment($key, $stepsize);
191             }
192 0           return 1;
193             }
194              
195             sub decr {
196 0     0 1   my ($self, $key, $stepsize) = @_;
197              
198 0           $self->reconnect(); # Make sure we are connected
199              
200 0           $key = $self->sanitize_key($key);
201              
202 0 0         if(!defined($stepsize)) {
203 0           $self->{clacks}->decrement($key);
204             } else {
205 0           $self->{clacks}->decrement($key, $stepsize);
206             }
207 0           return 1;
208             }
209              
210             sub clacks_set {
211 0     0 1   my ($self, $key, $data) = @_;
212              
213 0           $self->reconnect(); # Make sure we are connected
214              
215 0           $key = $self->sanitize_key($key);
216              
217 0           $self->{clacks}->set($key, $data);
218              
219 0           return 1;
220             }
221              
222             sub clacks_notify {
223 0     0 1   my ($self, $key) = @_;
224              
225 0           $self->reconnect(); # Make sure we are connected
226              
227 0           $key = $self->sanitize_key($key);
228              
229 0           $self->{clacks}->set($key);
230              
231 0           return 1;
232             }
233              
234             sub clacks_keylist {
235 0     0 1   my ($self) = @_;
236              
237 0           $self->reconnect(); # Make sure we are connected
238              
239 0           return $self->{clacks}->keylist();
240             }
241              
242              
243             sub sanitize_key {
244 0     0 1   my ($self, $key) = @_;
245              
246             # Certain chars are not allowed in keys for protocol reason.
247             # We handle this by substituting them with a tripple underline
248              
249 0           $key =~ s/\ /___/go;
250 0           $key =~ s/\=/___/go;
251              
252 0           return $key;
253             }
254              
255             sub deref {
256 0     0 1   my ($self, $val) = @_;
257              
258 0 0         return if(!defined($val));
259              
260 0   0       while(ref($val) eq "SCALAR" || ref($val) eq "REF") {
261 0           $val = ${$val};
  0            
262 0 0         last if(!defined($val));
263             }
264              
265 0           return $val;
266             }
267              
268             1;
269             __END__