File Coverage

blib/lib/Net/Clacks/ClacksCache.pm
Criterion Covered Total %
statement 47 210 22.3
branch 0 36 0.0
condition 0 21 0.0
subroutine 16 34 47.0
pod 17 17 100.0
total 80 318 25.1


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