File Coverage

lib/Mail/Action/Role/Purge.pm
Criterion Covered Total %
statement 50 53 94.3
branch 12 18 66.6
condition 5 5 100.0
subroutine 11 11 100.0
pod 4 4 100.0
total 82 91 90.1


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             Mail::Action::Role::Purge - purge expired objects from Mail::Action::Storage
4             collections.
5              
6             =head1 SYNOPSIS
7              
8             use Mail::TempAddress::Addresses;
9             use Mail::Action::Role::Purge;
10             use Class::Roles
11             apply => {
12             role => 'Purge',
13             to => 'Mail::TempAddress::Addresses',
14             };
15             my $addrs = Mail::TempAddress::Addresses->new( '/foo' );
16             for my $addr( $addrs->object_names ) {
17             print "the address for ", $addr->owner, " expires at ",
18             scalar localtime($addr->expires), "\n";
19             if( $addr->expires < time() ) {
20             $addrs->delete_from_storage($addr);
21             }
22             }
23              
24             =head1 DESCRIPTION
25              
26             Mail::Action::Role::Purge provides a role to allow subclasses of
27             Mail::Action::Storage to retrieve the names of all object in the collection
28             and remove the file on disk underlying a named object.
29              
30             =cut
31              
32             package Mail::Action::Role::Purge;
33              
34 5     5   20227 use strict;
  5         12  
  5         213  
35 5     5   28 use Carp 'croak';
  5         9  
  5         311  
36              
37 5     5   3567 use Mail::Action::Storage;
  5         60440  
  5         211  
38             use Class::Roles
39 5         42 multi => {
40             'Purge' => [ qw|
41             object_names
42             num_objects
43             delete_from_storage
44             purge
45             |],
46 5     5   39 };
  5         9  
47            
48 5     5   376 use vars '$VERSION';
  5         8  
  5         229  
49              
50             $VERSION = '0.11';
51            
52 5     5   30 use File::Basename;
  5         8  
  5         400  
53 5     5   25 use Fcntl ':flock';
  5         6  
  5         2760  
54              
55             sub object_names
56             {
57            
58 19     19 1 35 my $self = shift;
59 19         77 my $dir = $self->storage_dir;
60 19         128 my $extension = $self->storage_extension();
61 170         4344 my @files = map {
62 19         3185 scalar( s/\.$extension//, basename $_)
63             } glob("$dir/*.$extension");
64 19 100       253 return wantarray ? @files : \@files;
65            
66             }
67              
68             sub num_objects
69             {
70            
71 14     14 1 76644 my $self = shift;
72 14   100     26 return scalar @{ $self->object_names } || 0;
73            
74             }
75              
76             sub delete_from_storage
77             {
78            
79 15     15 1 20 my $self = shift;
80 15         36 my $name = shift;
81 15         46 my $file = $self->storage_file($name);
82 15 50       290 unless( $file ) {
83 0         0 $! = "no object by that name";
84 0         0 return undef;
85             }
86 15 50       1357 open( OUT, '+< ' . $file ) or croak "cannot open $file: $!";
87 15 50       114 flock OUT, LOCK_EX or croak "cannot lock $file: $!";
88 15 50       674 unlink($file) && return 1;
89 0         0 return undef;
90            
91             }
92              
93             sub purge
94             {
95              
96 5     5 1 12 my $self = shift;
97              
98 5         8 my $min_ts;
99 5 100       15 if( my $min_age = shift ) {
100 2         21 my $subtract = Mail::Action::Address->process_time( $min_age );
101 2         55 $min_ts = time() - $subtract;
102             }
103             else {
104 3         7 $min_ts = time();
105             }
106              
107 5         7 my $purged = 0;
108 5         15 for( $self->object_names ) {
109 55         182 my $addy = $self->fetch($_);
110 55 50       75818 next unless $addy;
111 55         190 my $expires = $addy->expires();
112 55 100 100     741 if( $expires && $expires < $min_ts ) {
113 15 50       41 $self->delete_from_storage($_) && $purged++;
114             }
115             }
116            
117 5         30 return $purged;
118              
119             }
120              
121             # keep require happy
122             1;
123              
124              
125             __END__