File Coverage

blib/lib/Connector/Builtin/Memory.pm
Criterion Covered Total %
statement 105 114 92.1
branch 40 54 74.0
condition 2 6 33.3
subroutine 16 16 100.0
pod 8 8 100.0
total 171 198 86.3


line stmt bran cond sub pod time code
1             # Connector::Builtin::Memory
2             #
3             # Proxy class for reading YAML configuration
4             #
5             # Written by Scott Hardin, Martin Bartosch and Oliver Welter
6             # for the OpenXPKI project 2012
7             #
8             # THIS IS NOT WORKING IN A FORKING ENVIRONMENT!
9              
10              
11              
12             use strict;
13 9     9   305080 use warnings;
  9         40  
  9         264  
14 9     9   47 use English;
  9         40  
  9         207  
15 9     9   38 use Data::Dumper;
  9         15  
  9         62  
16 9     9   3677  
  9         5880  
  9         425  
17             use Moose;
18 9     9   918 extends 'Connector::Builtin';
  9         775499  
  9         56  
19              
20             has '+LOCATION' => ( required => 0 );
21              
22             has 'primary_attribute' => (
23             is => 'ro',
24             isa => 'Str',
25             predicate => 'has_primary_attribute',
26             );
27              
28             my $self = shift;
29             $self->_config( {} );
30 3     3   11 }
31 3         62  
32              
33             my $self = shift;
34             my @path = $self->_build_path_with_prefix( shift );
35              
36 321     321   428 $self->log()->trace('get node for path'. Dumper \@path);
37 321         844  
38             my $ptr = $self->_config();
39 321         6614  
40             # Top Level Node requested
41 321         19630 if (!@path) {
42             return $ptr;
43             }
44 321 100       726  
45 12         31 while ( scalar @path > 1 ) {
46             my $entry = shift @path;
47             if ( exists $ptr->{$entry} ) {
48 309         655 if ( ref $ptr->{$entry} eq 'HASH' ) {
49 528         779 $ptr = $ptr->{$entry};
50 528 100       1048 }
51 524 100       1388 else {
52 520         1073 return $self->_node_not_exists( ref $ptr->{$entry} );
53             }
54             } else {
55 4         11 return $self->_node_not_exists($entry);
56             }
57             }
58 4         20  
59             return $ptr->{ shift @path };
60              
61             }
62 301         788  
63              
64             my $self = shift;
65             my $value = $self->_get_node( shift );
66              
67             return $self->_node_not_exists() unless (defined $value);
68 69     69 1 3520  
69 69         193 if (ref $value ne '') {
70             die "requested value is not a scalar"
71 69 100       197 unless ($self->has_primary_attribute() && ref $value eq 'HASH');
72              
73 63 100       175 return $self->_node_not_exists()
74 1 50 33     34 unless (defined $value->{$self->primary_attribute});
75              
76             die "primary_attribute is not a scalar"
77             unless (ref $value->{$self->primary_attribute} eq '');
78 1 50       27  
79             return $value->{$self->primary_attribute};
80             }
81 1 50       23  
82             return $value;
83 1         24  
84             }
85              
86 62         486  
87             my $self = shift;
88             my $node = $self->_get_node( shift );
89              
90             return 0 unless(defined $node);
91              
92 2     2 1 14 if ( ref $node ne 'ARRAY' ) {
93 2         6 die "requested value is not a list"
94             }
95 2 50       6  
96             return scalar @{$node};
97 2 50       8 }
98 0         0  
99              
100             my $self = shift;
101 2         4 my $path = shift;
  2         8  
102              
103             my $node = $self->_get_node( $path );
104              
105             return $self->_node_not_exists( $path ) unless(defined $node);
106 6     6 1 15  
107 6         11 if ( ref $node ne 'ARRAY' ) {
108             die "requested value is not a list"
109 6         18 }
110              
111 6 100       21 return @{$node};
112             }
113 5 50       18  
114 0         0  
115             my $self = shift;
116             my $path = shift;
117 5         8  
  5         30  
118             my $node = $self->_get_node( $path );
119              
120             return @{[]} unless(defined $node);
121              
122 14     14 1 41 if ( ref $node ne 'HASH' ) {
123 14         24 die "requested value is not a hash"
124             }
125 14         41  
126             return keys %{$node};
127 14 50       54 }
  0         0  
128              
129 14 50       59  
130 0         0 my $self = shift;
131             my $path = shift;
132              
133 14         21 my $node = $self->_get_node( $path );
  14         109  
134              
135             return $self->_node_not_exists( $path ) unless(defined $node);
136              
137             if ( ref $node ne 'HASH' ) {
138 6     6 1 1156 die "requested value is not a hash"
139 6         12 }
140              
141 6         14 return { %$node };
142             }
143 6 100       18  
144              
145 5 50       16 my $self = shift;
146 0         0  
147             my $node = $self->_get_node( shift );
148              
149 5         34 $self->log()->trace('get_node returned '. Dumper $node);
150              
151             if (!defined $node) {
152             # die_on_undef already handled by get_node
153             return;
154 203     203 1 273 }
155              
156 203         390 my $meta = {};
157              
158 203         3669 if (ref $node eq '') {
159             $meta = {TYPE => "scalar", VALUE => $node };
160 203 100       8817 } elsif (ref $node eq "SCALAR") {
161             $meta = {TYPE => "reference", VALUE => $$node };
162 100         308 } elsif (ref $node eq "ARRAY") {
163             $meta = {TYPE => "list", VALUE => $node };
164             } elsif (ref $node eq "HASH") {
165 103         181 my @keys = keys(%{$node});
166             $meta = {TYPE => "hash", VALUE => \@keys };
167 103 100 33     384 } elsif (blessed($node) && $node->isa('Connector')) {
    100          
    100          
    100          
    50          
168 36         119 $meta = {TYPE => "connector", VALUE => $node };
169             } else {
170 23         107 die "Unsupported node type: " . ref $node;
171             }
172 5         18 return $meta;
173             }
174 36         57  
  36         104  
175 36         171  
176             my $self = shift;
177 3         12  
178             my $value = 0;
179 0         0 eval {
180             $value = defined $self->_get_node( shift );
181 103         278 };
182             return $value;
183              
184             }
185              
186 21     21 1 644  
187             my $self = shift;
188 21         36 my @path = $self->_build_path_with_prefix( shift );
189 21         31  
190 21         69 my $value = shift;
191              
192 21         127 my $ptr = $self->_config();
193              
194             while (scalar @path > 1) {
195             my $entry = shift @path;
196             if (!exists $ptr->{$entry}) {
197             $ptr->{$entry} = {};
198 9     9 1 41 } elsif (ref $ptr->{$entry} ne "HASH") {
199 9         33 confess('Try to step over a value node at ' . $entry);
200             }
201 9         20 $ptr = $ptr->{$entry};
202             }
203 9         216  
204             my $entry = shift @path;
205 9         24  
206 5         10 if (!defined $value) {
207 5 100       17 delete $ptr->{$entry};
    50          
208 4         11 return;
209             }
210 0         0  
211             if (exists $ptr->{$entry}) {
212 5         12 if (ref $ptr->{$entry} ne ref $value) {
213             confess('Try to override data type at node ' . $entry);
214             }
215 9         16 }
216             $ptr->{$entry} = $value;
217 9 100       20 return 1;
218 1         3 }
219 1         3  
220              
221             no Moose;
222 8 50       16 __PACKAGE__->meta->make_immutable;
223 0 0       0  
224 0         0 1;
225              
226             =head1 Name
227 8         26  
228 8         19 Connector::Builtin::Memory
229              
230             =head1 Description
231              
232 9     9   59992 A connector implementation to allow memory based caching
  9         20  
  9         51  
233              
234             =head1 Parameters
235              
236             =over
237              
238             =item LOCATION
239              
240             Not used
241              
242             =item primary_attribute
243              
244             If your data consists of hashes as leaf nodes, set this to the name of
245             the node that is considered the primary attribute, e.g. the name of a
246             person. If you now access the key on the penultimate level using I<get>
247             you will receive the value of this attribute back.
248              
249             user1234:
250             name: John Doe
251             email: john.doe@acme.com
252              
253             When you call I<get(user1234)> on this structure, the connector will
254             usually die with a "not a scalar" error. With I<primary_attribute = name>
255             you will get back I<John Doe>.
256              
257             =back