File Coverage

blib/lib/True/Truth.pm
Criterion Covered Total %
statement 39 84 46.4
branch 6 24 25.0
condition 3 3 100.0
subroutine 10 16 62.5
pod 6 6 100.0
total 64 133 48.1


line stmt bran cond sub pod time code
1             package True::Truth;
2              
3 3     3   144458 use 5.010;
  3         12  
  3         167  
4 3     3   3563 use Cache::KyotoTycoon;
  3         125018  
  3         96  
5 3     3   2607 use Any::Moose;
  3         118718  
  3         22  
6 3     3   1935 use MIME::Base64 qw(encode_base64 decode_base64);
  3         6  
  3         243  
7 3     3   7038 use Storable qw/nfreeze thaw/;
  3         18336  
  3         286  
8 3     3   3087 use Data::Dump qw/dump/;
  3         19837  
  3         4625  
9              
10             # ABSTRACT: merge multiple versions of truth into one
11             #
12             our $VERSION = '1.1'; # VERSION
13              
14             has 'debug' => (
15             is => 'rw',
16             isa => 'Bool',
17             default => sub { 0 },
18             lazy => 1,
19             );
20              
21             has 'kt_server' => (
22             is => 'rw',
23             isa => 'Str',
24             default => '127.0.0.1',
25             );
26              
27             has 'kt_port' => (
28             is => 'rw',
29             isa => 'Int',
30             lazy => 1,
31             default => sub { 1978 },
32             );
33              
34             has 'kt_db' => (
35             is => 'rw',
36             isa => 'Str',
37             lazy => 1,
38             default => sub { 0 },
39             );
40              
41             has 'kt_timeout' => (
42             is => 'rw',
43             isa => 'Int',
44             lazy => 1,
45             default => sub { 5 },
46             );
47              
48             has 'kt' => (
49             is => 'rw',
50             isa => 'Cache::KyotoTycoon',
51             builder => '_connect_kt',
52             lazy => 1,
53             );
54              
55             has 'expire' => (
56             is => 'rw',
57             isa => 'Int',
58             default => '3600',
59             );
60              
61              
62             sub add_true_truth {
63 1     1 1 364 my ($self, $key, $truth) = @_;
64              
65 1         5 return int $self->_add($key, $truth);
66             }
67              
68              
69             sub add_pending_truth {
70 0     0 1 0 my ($self, $key, $truth) = @_;
71              
72 0 0       0 return unless ref $truth eq 'HASH';
73              
74 0         0 foreach my $ky (keys %$truth) {
75 0 0       0 if (ref($truth->{$ky}) eq 'HASH') {
76 0         0 $truth->{$ky}->{_locked} = 1;
77             }
78             else {
79 0         0 $truth->{_locked} = 1;
80             }
81             }
82 0         0 return int $self->_add($key, $truth);
83             }
84              
85              
86             sub persist_pending_truth {
87 0     0 1 0 my ($self, $key, $index) = @_;
88              
89 0         0 my $truth = $self->_get($key, $index);
90              
91 0 0       0 return unless ref $truth eq 'HASH';
92              
93 0         0 foreach my $k (keys %$truth) {
94 0 0       0 if (ref($truth->{$k}) eq 'HASH') {
95 0         0 delete $truth->{$k}->{_locked};
96             }
97             else {
98 0         0 delete $truth->{_locked};
99             }
100             }
101 0         0 $self->_add($key, $truth, $index);
102 0         0 return;
103             }
104              
105              
106             sub remove_pending_truth {
107 0     0 1 0 my ($self, $key, $index) = @_;
108              
109 0         0 $self->_del($key, $index);
110 0         0 return;
111             }
112              
113              
114             sub get_true_truth {
115 0     0 1 0 my ($self, $key) = @_;
116              
117 0         0 my $all_truth = $self->_get($key);
118 0         0 my $truth = merge(@$all_truth);
119 0         0 return $truth;
120             }
121              
122              
123             # This was stolen from Catalyst::Utils... thanks guys!
124             sub merge (@);
125              
126             sub merge (@) {
127             shift
128 14 50   14 1 36559 unless ref $_[0]
129             ; # Take care of the case we're called like Hash::Merge::Simple->merge(...)
130 14         41 my ($left, @right) = @_;
131              
132 14 50       39 return $left unless @right;
133              
134 14 50       35 return merge($left, merge(@right)) if @right > 1;
135              
136 14         38 my ($right) = @right;
137              
138 14         63 my %merge = %$left;
139              
140 14         45 for my $key (keys %$right) {
141              
142 21         40 my ($hr, $hl) = map { ref $_->{$key} eq 'HASH' } $right, $left;
  42         138  
143              
144 21 100 100     101 if ($hr and $hl) {
145 7         31 $merge{$key} = merge($left->{$key}, $right->{$key});
146             }
147             else {
148 14         53 $merge{$key} = $right->{$key};
149             }
150             }
151              
152 14         58 return \%merge;
153             }
154              
155             #### internal stuff ####
156              
157             sub _add {
158 1     1   3 my ($self, $key, $val, $index) = @_;
159              
160 1         1 my $idx;
161 1 50       4 if ($index) {
162 0         0 $idx = $index;
163             }
164             else {
165 1         10 $idx = scalar keys $self->kt->match_prefix("$key.");
166             }
167 0         0 $self->kt->set("$key.$idx", encode_base64(nfreeze($val)), $self->expire);
168 0         0 return $idx;
169             }
170              
171             sub _get {
172 0     0   0 my ($self, $key, $index) = @_;
173              
174 0 0       0 if ($index) {
175 0         0 my $val = $self->kt->get("$key.$index");
176 0 0       0 return thaw(decode_base64($val))
177             if $val;
178             }
179             else {
180 0         0 my $data = $self->kt->match_prefix($key);
181 0         0 my @res;
182 0         0 foreach my $val (sort keys %{$data}) {
  0         0  
183 0         0 push(@res, thaw(decode_base64($self->kt->get($val))));
184             }
185 0         0 return \@res;
186             }
187 0         0 return;
188             }
189              
190             sub _del {
191 0     0   0 my ($self, $key, $index) = @_;
192              
193 0 0       0 if ($index) {
194 0         0 $self->kt->remove("$key.$index");
195             }
196             else {
197 0         0 my $data = $self->kt->match_prefix($key);
198 0         0 foreach my $val (sort keys %{$data}) {
  0         0  
199 0         0 $self->kt->remove($val);
200             }
201             }
202 0         0 return;
203             }
204              
205             sub _connect_kt {
206 2     2   1014 my ($self) = @_;
207 2         18 return Cache::KyotoTycoon->new(
208             host => $self->kt_server,
209             port => $self->kt_port,
210             timeout => $self->kt_timeout,
211             db => $self->kt_db,
212             );
213             }
214              
215              
216             1; # This is the end of True::Truth
217              
218             __END__