File Coverage

blib/lib/Catmandu/Store/File/BagIt/Index.pm
Criterion Covered Total %
statement 54 59 91.5
branch 8 12 66.6
condition n/a
subroutine 12 14 85.7
pod 0 3 0.0
total 74 88 84.0


line stmt bran cond sub pod time code
1             package Catmandu::Store::File::BagIt::Index;
2              
3             our $VERSION = '0.260';
4              
5 3     3   30 use Catmandu::Sane;
  3         9  
  3         30  
6 3     3   709 use Moo;
  3         8  
  3         16  
7 3     3   1099 use Path::Tiny;
  3         7  
  3         166  
8 3     3   29 use Carp;
  3         8  
  3         199  
9 3     3   20 use POSIX qw(ceil);
  3         17  
  3         28  
10 3     3   7399 use Path::Iterator::Rule;
  3         29447  
  3         96  
11 3     3   21 use File::Spec;
  3         5  
  3         63  
12 3     3   17 use namespace::clean;
  3         6  
  3         18  
13              
14 3     3   1084 use Data::Dumper;
  3         7  
  3         3852  
15              
16             with 'Catmandu::Bag';
17             with 'Catmandu::FileBag::Index';
18             with 'Catmandu::Droppable';
19              
20             sub generator {
21 2     2 0 3863 my ($self) = @_;
22              
23 2         11 my $root = $self->store->root;
24 2         8 my $keysize = $self->store->keysize;
25 2         24 my @root_split = File::Spec->splitdir($root);
26              
27 2         20 my $mindepth = ceil($keysize / 3);
28              
29 2 50       57 unless (-d $root) {
30 0         0 $self->log->error("no root $root found");
31 0     0   0 return sub {undef};
  0         0  
32             }
33              
34 2         58 $self->log->debug("creating generator for root: $root");
35              
36 2         2266 my $rule = Path::Iterator::Rule->new;
37 2         26 $rule->min_depth($mindepth);
38 2         88 $rule->max_depth($mindepth);
39 2         62 $rule->directory;
40              
41             return sub {
42 5     5   37 state $iter = $rule->iter($root, {depthfirst => 1});
43              
44 5         268 my $path = $iter->();
45              
46 5 100       2645 return undef unless defined($path);
47              
48             # Strip of the root part and translate the path to an identifier
49 3         24 my @split_path = File::Spec->splitdir($path);
50 3         11 my $id = join("", splice(@split_path, int(@root_split)));
51              
52 3 50       29 unless ($self->store->uuid) {
53 3         17 $id =~ s/^0+//;
54             }
55              
56 3 50       14 if ($self->store->default_case eq 'upper') {
57 3         8 $id = uc($id);
58             }
59             else {
60 0         0 $id = lc($id);
61             }
62            
63 3         78 $self->get($id);
64 2         56 };
65             }
66              
67             sub exists {
68 13     13 0 4403 my ($self, $id) = @_;
69              
70 13 50       38 croak "Need an id" unless defined $id;
71              
72 13         270 $self->log->debug("Checking exists $id");
73              
74 13         2534 my $path = $self->store->path_string($id);
75              
76 13 100       361 defined($path) && -d $path;
77             }
78              
79             sub add {
80             my ($self, $data) = @_;
81              
82             croak "Need an id" unless defined $data && exists $data->{_id};
83              
84             my $id = $data->{_id};
85              
86             if (exists $data->{_stream}) {
87             croak "Can't add a file to the index";
88             }
89              
90             my $path = $self->store->path_string($id);
91              
92             unless (defined $path) {
93             my $err
94             = "Failed to create path from $id need a number of max "
95             . $self->store->keysize
96             . " digits";
97             $self->log->error($err);
98             Catmandu::BadArg->throw($err);
99             }
100              
101             $self->log->debug("Generating path $path for key $id");
102              
103             # Throws an exception when the path can't be created
104             path($path)->mkpath;
105              
106             my $new_data = $self->get($id);
107              
108             $data->{$_} = $new_data->{$_} for keys %$new_data;
109              
110             1;
111             }
112              
113             sub get {
114             my ($self, $id) = @_;
115              
116             croak "Need an id" unless defined $id;
117              
118             my $path = $self->store->path_string($id);
119              
120             unless ($path) {
121             $self->log->error(
122             "Failed to create path from $id need a number of max "
123             . $self->store->keysize
124             . " digits");
125             return undef;
126             }
127              
128             $self->log->debug("Loading path $path for id $id");
129              
130             return undef unless -d $path;
131              
132             my @stat = stat $path;
133              
134             return +{_id => $id,};
135             }
136              
137             sub delete {
138             my ($self, $id) = @_;
139              
140             croak "Need a key" unless defined $id;
141              
142             my $path = $self->store->path_string($id);
143              
144             unless ($path) {
145             $self->log->error("Failed to create path from $id");
146             return undef;
147             }
148              
149             $self->log->debug("Destoying path $path for key $id");
150              
151             return undef unless -d $path;
152              
153             # Throws an exception when the path can't be created
154             path($path)->remove_tree;
155              
156             1;
157             }
158              
159             sub delete_all {
160             my ($self) = @_;
161              
162             $self->each(
163             sub {
164             my $key = shift->{_id};
165             $self->delete($key);
166             }
167             );
168             }
169              
170             sub drop {
171 0     0 0   $_[0]->delete_all;
172             }
173              
174             sub commit {
175             return 1;
176             }
177              
178             1;
179              
180             __END__
181              
182             =pod
183              
184             =head1 NAME
185              
186             Catmandu::Store::File::BagIt::Index - Index of all "Folders" in a Catmandu::Store::File::BagIt
187              
188             =head1 SYNOPSIS
189              
190             use Catmandu;
191              
192             my $store = Catmandu->store('File::BagIt' , root => 't/data');
193              
194             my $index = $store->index;
195              
196             # List all containers
197             $index->each(sub {
198             my $container = shift;
199              
200             print "%s\n" , $container->{_id};
201             });
202              
203             # Add a new folder
204             $index->add({_id => '1234'});
205              
206             # Delete a folder
207             $index->delete(1234);
208              
209             # Get a folder
210             my $folder = $index->get(1234);
211              
212             # Get the files in an folder
213             my $files = $index->files(1234);
214              
215             $files->each(sub {
216             my $file = shift;
217              
218             my $name = $file->_id;
219             my $size = $file->size;
220             my $content_type = $file->content_type;
221             my $created = $file->created;
222             my $modified = $file->modified;
223              
224             $file->stream(IO::File->new(">/tmp/$name"), file);
225             });
226              
227             # Add a file
228             $files->upload(IO::File->new("<data.dat"),"data.dat");
229              
230             # Retrieve a file
231             my $file = $files->get("data.dat");
232              
233             # Stream a file to an IO::Handle
234             $files->stream(IO::File->new(">data.dat"),$file);
235              
236             # Delete a file
237             $files->delete("data.dat");
238              
239             # Delete a folders
240             $index->delete("1234");
241              
242             =head1 INHERITED METHODS
243              
244             This Catmandu::Bag implements:
245              
246             =over 3
247              
248             =item L<Catmandu::Bag>
249              
250             =item L<Catmandu::FileBag::Index>
251              
252             =item L<Catmandu::Droppable>
253              
254             =back
255              
256             =cut