File Coverage

blib/lib/Net/Amazon/S3/Client/Bucket.pm
Criterion Covered Total %
statement 67 69 97.1
branch 12 24 50.0
condition 2 5 40.0
subroutine 17 17 100.0
pod 9 10 90.0
total 107 125 85.6


line stmt bran cond sub pod time code
1             $Net::Amazon::S3::Client::Bucket::VERSION = '0.991';
2             use Moose 0.85;
3 99     99   649 use MooseX::StrictConstructor 0.16;
  99         1967  
  99         677  
4 99     99   540036 use Data::Stream::Bulk::Callback;
  99         1585  
  99         608  
5 99     99   303437 use MooseX::Types::DateTime::MoreCoercions 0.07 qw( DateTime );
  99         10644113  
  99         4250  
6 99     99   44444  
  99         87840311  
  99         677  
7             # ABSTRACT: An easy-to-use Amazon S3 client bucket
8              
9             has 'client' =>
10             ( is => 'ro', isa => 'Net::Amazon::S3::Client', required => 1 );
11             has 'name' => ( is => 'ro', isa => 'Str', required => 1 );
12             has 'creation_date' =>
13             ( is => 'ro', isa => DateTime, coerce => 1, required => 0 );
14             has 'owner_id' => ( is => 'ro', isa => 'Str', required => 0 );
15             has 'owner_display_name' => ( is => 'ro', isa => 'Str', required => 0 );
16             has 'region' => (
17             is => 'ro',
18             lazy => 1,
19             predicate => 'has_region',
20             default => sub { $_[0]->location_constraint },
21             );
22              
23              
24             __PACKAGE__->meta->make_immutable;
25              
26             my ($self, %conf) = @_;
27              
28 17     17   53 my $response = $self->_perform_operation (
29             'Net::Amazon::S3::Operation::Bucket::Create',
30              
31             (acl => $conf{acl}) x!! defined $conf{acl},
32             (acl_short => $conf{acl_short}) x!! defined $conf{acl_short},
33             (location_constraint => $conf{location_constraint}) x!! defined $conf{location_constraint},
34             );
35              
36 17         122 return unless $response->is_success;
37              
38 6 50       213 return $response->http_response;
39             }
40 6         232  
41             my $self = shift;
42              
43             my $response = $self->_perform_operation (
44 6     6 1 14 'Net::Amazon::S3::Operation::Bucket::Delete',
45             );
46 6         15  
47             return unless $response->is_success;
48             return $response->http_response;
49             }
50 1 50       12  
51 1         44 my $self = shift;
52              
53             my $response = $self->_perform_operation (
54             'Net::Amazon::S3::Operation::Bucket::Acl::Fetch',
55 5     5 1 10 );
56              
57 5         21 return if $response->is_error;
58             return $response->http_response->content;
59             }
60              
61 1 50       4 my ($self, %params) = @_;
62 1         29  
63             my $response = $self->_perform_operation (
64             'Net::Amazon::S3::Operation::Bucket::Acl::Set',
65             %params,
66 9     9 0 40 );
67              
68 9         39 return $response->is_success;
69             }
70              
71             my ($self, %params) = @_;
72              
73 5         222 my $response = $self->_perform_operation (
74             'Net::Amazon::S3::Operation::Bucket::Tags::Add',
75              
76             tags => $params{tags},
77 5     5 1 16 );
78              
79             return $response->is_success;
80             }
81              
82             my ($self, $conf) = @_;
83 5         24  
84             my $response = $self->_perform_operation (
85 1         10 'Net::Amazon::S3::Operation::Bucket::Tags::Delete',
86             );
87              
88             return $response->is_success;
89 5     5 1 19 }
90              
91 5         24 my $self = shift;
92              
93             my $response = $self->_perform_operation (
94             'Net::Amazon::S3::Operation::Bucket::Location',
95 1         11 );
96              
97             return unless $response->is_success;
98             return $response->location;
99 1     1 1 3 }
100              
101 1         5  
102             my ( $self, $conf ) = @_;
103             $conf ||= {};
104             my $prefix = $conf->{prefix};
105 0 0       0 my $delimiter = $conf->{delimiter};
106 0         0  
107             my $marker = undef;
108             my $end = 0;
109 87     87 1 2598  
110             return Data::Stream::Bulk::Callback->new(
111             callback => sub {
112 8     8 1 35  
113 8   50     19 return undef if $end;
114 8         17  
115 8         12 my $response = $self->_perform_operation (
116             'Net::Amazon::S3::Operation::Objects::List',
117 8         14  
118 8         12 marker => $marker,
119             prefix => $prefix,
120             delimiter => $delimiter,
121             );
122              
123 8 50   8   2515 return unless $response->is_success;
124              
125 8         32 my @objects;
126             foreach my $node ($response->contents) {
127             push @objects, $self->object_class->new (
128             client => $self->client,
129             bucket => $self,
130             key => $node->{key},
131             etag => $node->{etag},
132             size => $node->{size},
133 4 50       38 last_modified_raw => $node->{last_modified},
134             );
135 4         69 }
136 4         17  
137             return undef unless @objects;
138              
139             $end = 1 unless $response->is_truncated;
140              
141             $marker = $response->next_marker
142             || $objects[-1]->key;
143              
144 5         17 return \@objects;
145             }
146             );
147 4 100       14 }
148              
149 3 50       13 my $self = shift;
150             my @objects = @_;
151 3   33     10 return unless( scalar(@objects) );
152              
153             # Since delete can handle up to 1000 requests, be a little bit nicer
154 3         14 # and slice up requests and also allow keys to be strings
155             # rather than only objects.
156 8         334 my $last_result;
157             while (scalar(@objects) > 0) {
158             my $response = $self->_perform_operation (
159             'Net::Amazon::S3::Operation::Objects::Delete',
160 5     5 1 14  
161 5         26 keys => [
162 5 50       13 map { ref ($_) ? $_->key : $_ }
163             splice @objects, 0, ((scalar(@objects) > 1000) ? 1000 : scalar(@objects))
164             ]
165             );
166              
167 5         7 $last_result = $response;
168 5         13  
169             last unless $response->is_success;
170             }
171             return $last_result->http_response;
172             }
173 5 50       19  
  11 50       56  
174             my ( $self, %conf ) = @_;
175             return $self->object_class->new(
176             client => $self->client,
177             bucket => $self,
178 1         3 %conf,
179             );
180 1 50       11 }
181              
182 1         45 my ($self, $operation, %params) = @_;
183              
184             $self->client->_perform_operation ($operation => (
185             bucket => $self->name,
186 82     82 1 347 %params,
187 82         288 ));
188             }
189              
190             1;
191              
192              
193             =pod
194              
195 139     139   485 =encoding UTF-8
196              
197 139         3768 =head1 NAME
198              
199             Net::Amazon::S3::Client::Bucket - An easy-to-use Amazon S3 client bucket
200              
201             =head1 VERSION
202              
203             version 0.991
204              
205             =head1 SYNOPSIS
206              
207             # return the bucket name
208             print $bucket->name . "\n";
209              
210             # return the bucket location constraint
211             print "Bucket is in the " . $bucket->location_constraint . "\n";
212              
213             # return the ACL XML
214             my $acl = $bucket->acl;
215              
216             # list objects in the bucket
217             # this returns a L<Data::Stream::Bulk> object which returns a
218             # stream of L<Net::Amazon::S3::Client::Object> objects, as it may
219             # have to issue multiple API requests
220             my $stream = $bucket->list;
221             until ( $stream->is_done ) {
222             foreach my $object ( $stream->items ) {
223             ...
224             }
225             }
226              
227             # or list by a prefix
228             my $prefix_stream = $bucket->list( { prefix => 'logs/' } );
229              
230             # returns a L<Net::Amazon::S3::Client::Object>, which can then
231             # be used to get or put
232             my $object = $bucket->object( key => 'this is the key' );
233              
234             # delete the bucket (it must be empty)
235             $bucket->delete;
236              
237             =head1 DESCRIPTION
238              
239             This module represents buckets.
240              
241             =for test_synopsis no strict 'vars'
242              
243             =head1 METHODS
244              
245             =head2 acl
246              
247             # return the ACL XML
248             my $acl = $bucket->acl;
249              
250             =head2 add_tags
251              
252             $bucket->add_tags (
253             tags => { tag1 => 'val1', ... },
254             )
255              
256             =head2 delete_tags
257              
258             $bucket->delete_tags;
259              
260             =head2 delete
261              
262             # delete the bucket (it must be empty)
263             $bucket->delete;
264              
265             =head2 list
266              
267             # list objects in the bucket
268             # this returns a L<Data::Stream::Bulk> object which returns a
269             # stream of L<Net::Amazon::S3::Client::Object> objects, as it may
270             # have to issue multiple API requests
271             my $stream = $bucket->list;
272             until ( $stream->is_done ) {
273             foreach my $object ( $stream->items ) {
274             ...
275             }
276             }
277              
278             # or list by a prefix
279             my $prefix_stream = $bucket->list( { prefix => 'logs/' } );
280              
281             # you can emulate folders by using prefix with delimiter
282             # which shows only entries starting with the prefix but
283             # not containing any more delimiter (thus no subfolders).
284             my $folder_stream = $bucket->list( { prefix => 'logs/', delimiter => '/' } );
285              
286             =head2 location_constraint
287              
288             # return the bucket location constraint
289             print "Bucket is in the " . $bucket->location_constraint . "\n";
290              
291             =head2 name
292              
293             # return the bucket name
294             print $bucket->name . "\n";
295              
296             =head2 object
297              
298             # returns a L<Net::Amazon::S3::Client::Object>, which can then
299             # be used to get or put
300             my $object = $bucket->object( key => 'this is the key' );
301              
302             =head2 delete_multi_object
303              
304             # delete multiple objects using a multi object delete operation
305             # Accepts a list of L<Net::Amazon::S3::Client::Object or String> objects.
306             $bucket->delete_multi_object($object1, $object2)
307              
308             =head2 object_class
309              
310             # returns string "Net::Amazon::S3::Client::Object"
311             # allowing subclasses to add behavior.
312             my $object_class = $bucket->object_class;
313              
314             =head1 AUTHOR
315              
316             Branislav Zahradník <barney@cpan.org>
317              
318             =head1 COPYRIGHT AND LICENSE
319              
320             This software is copyright (c) 2022 by Amazon Digital Services, Leon Brocard, Brad Fitzpatrick, Pedro Figueiredo, Rusty Conover, Branislav Zahradník.
321              
322             This is free software; you can redistribute it and/or modify it under
323             the same terms as the Perl 5 programming language system itself.
324              
325             =cut