File Coverage

blib/lib/Storage/Abstract/Driver/Composite.pm
Criterion Covered Total %
statement 67 68 98.5
branch 21 28 75.0
condition n/a
subroutine 16 16 100.0
pod 5 6 83.3
total 109 118 92.3


line stmt bran cond sub pod time code
1             package Storage::Abstract::Driver::Composite;
2             $Storage::Abstract::Driver::Composite::VERSION = '0.008';
3 2     2   27 use v5.14;
  2         8  
4 2     2   10 use warnings;
  2         4  
  2         119  
5              
6 2     2   10 use Mooish::Base -standard;
  2         3  
  2         28  
7              
8 2     2   29609 use Scalar::Util qw(blessed);
  2         4  
  2         1962  
9              
10             extends 'Storage::Abstract::Driver';
11              
12             has field '_cache' => (
13             isa => HashRef,
14             clearer => 1,
15             lazy => sub { {} },
16             );
17              
18             with 'Storage::Abstract::Role::Driver::Meta';
19              
20             sub source_is_array
21             {
22 5     5 0 26 return !!1;
23             }
24              
25             sub refresh
26             {
27             my ($self) = @_;
28              
29             $self->_clear_cache;
30             }
31              
32             sub _run_on_sources
33             {
34 13     13   30 my ($self, $name, $callback) = @_;
35 13         26 my $finished = !!0;
36              
37             # run on one cached source
38 13 100       407 my $cached_source = defined $name ? $self->_cache->{$name} : undef;
39 13 100       158 if ($cached_source) {
40 6         44 $finished = $callback->($cached_source);
41             }
42              
43             # if there was no cached source or $callback did not return true, do it on
44             # all sources
45 13 100       39 if (!$finished) {
46 8         14 foreach my $source (@{$self->source}) {
  8         34  
47 13 100       95 if ($finished = $callback->($source)) {
48 4 50       176 $self->_cache->{$name} = $source
49             if defined $name;
50 4         50 last;
51             }
52             }
53             }
54              
55 13         36 return $finished;
56             }
57              
58             sub store_impl
59             {
60 1     1 1 4 my ($self, $name, $handle) = @_;
61              
62             my $stored = $self->_run_on_sources(
63             $name,
64             sub {
65 2     2   7 my $source = shift;
66 2 100       45 return !!0 if $source->readonly;
67              
68 1         95 $source->store($name, $handle);
69 1         6 return !!1;
70             }
71 1         8 );
72              
73 1 50       8 Storage::Abstract::X::StorageError->raise('could not store')
74             unless $stored;
75             }
76              
77             sub is_stored_impl
78             {
79 6     6 1 20 my ($self, $name, %opts) = @_;
80              
81             my $stored = $self->_run_on_sources(
82             $name,
83             sub {
84 9     9   16 my $source = shift;
85              
86 9         257 return $source->is_stored($name, %opts);
87             }
88 6         42 );
89              
90 6         74 return $stored;
91             }
92              
93             sub retrieve_impl
94             {
95 4     4 1 12 my ($self, $name, $properties) = @_;
96              
97 4         9 my $stored = !!0;
98             my $retrieved = $self->_run_on_sources(
99             $name,
100             sub {
101 5     5   11 my $source = shift;
102              
103 5 100       126 if ($source->is_stored($name)) {
104 3         7 $stored = !!1;
105 3         88 return $source->retrieve($name, $properties);
106             }
107              
108 2         11 return undef;
109             }
110 4         30 );
111              
112 4 100       62 Storage::Abstract::X::NotFound->raise('file was not found')
113             unless $stored;
114              
115 3 50       7 Storage::Abstract::X::StorageError->raise('could not retrieve')
116             unless defined $retrieved;
117              
118 3         22 return $retrieved;
119             }
120              
121             sub dispose_impl
122             {
123 1     1 1 3 my ($self, $name) = @_;
124              
125 1         2 my $stored = !!0;
126             my $disposed = $self->_run_on_sources(
127             $name,
128             sub {
129 1     1   2 my $source = shift;
130              
131 1 50       24 if ($source->is_stored($name)) {
132 1         4 $stored = !!1;
133 1 50       32 return !!0 if $source->readonly;
134              
135 1         116 $source->dispose($name);
136 1         4 return !!1;
137             }
138              
139 0         0 return !!0;
140             }
141 1         8 );
142              
143 1 50       9 Storage::Abstract::X::StorageError->raise('file was not found')
144             unless $stored;
145              
146 1 50       4 Storage::Abstract::X::StorageError->raise('could not dispose')
147             unless $disposed;
148             }
149              
150             sub list_impl
151             {
152 1     1 1 5 my ($self, @args) = @_;
153              
154 1         3 my %all_files;
155             $self->_run_on_sources(
156             undef,
157             sub {
158 2     2   5 my $source = shift;
159              
160 2         4 foreach my $filename (@{$source->list(@args)}) {
  2         68  
161 5         14 $all_files{$filename} = 1;
162             }
163              
164 2         11 return !!0;
165             }
166 1         8 );
167              
168 1         21 return [keys %all_files];
169             }
170              
171             1;
172              
173             __END__