File Coverage

blib/lib/Class/Prevayler/CommandRecoverer.pm
Criterion Covered Total %
statement 23 70 32.8
branch 0 22 0.0
condition 0 6 0.0
subroutine 7 13 53.8
pod 0 2 0.0
total 30 113 26.5


line stmt bran cond sub pod time code
1              
2             package Class::Prevayler::CommandRecoverer;
3 1     1   5 use strict;
  1         2  
  1         40  
4 1     1   5 use warnings;
  1         10  
  1         31  
5 1     1   3 use Carp;
  1         2  
  1         51  
6              
7             BEGIN {
8 1     1   5 use Exporter ();
  1         1  
  1         18  
9 1     1   4 use vars qw ($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
  1         1  
  1         120  
10 1     1   20499 $VERSION = 0.02;
11 1         26 @ISA = qw (Exporter);
12              
13             #Give a hoot don't pollute, do not export more than needed by default
14 1         3 @EXPORT = qw ();
15 1         1 @EXPORT_OK = qw ();
16 1         720 %EXPORT_TAGS = ();
17             use Class::MethodMaker
18 1         8 new_with_init => 'new',
19             new_hash_init => 'hash_init',
20             get_set => [
21             'deserializer', 'directory',
22             'next_logfile_number', 'pending_commands',
23             '_filehandle',
24 1     1   919 ];
  1         18417  
25              
26             }
27              
28             ########################################### main pod documentation begin ##
29             # Below is the stub of documentation for your module. You better edit it!
30              
31             =head1 NAME
32              
33             Class::Prevayler::CommandRecoverer - Prevayler implementation - www.prevayler.org
34              
35              
36             =head1 DESCRIPTION
37              
38             this class is an internal part of the Class::Prevayler module.
39              
40             =head1 AUTHOR
41              
42             Nathanael Obermayer
43             CPAN ID: nathanael
44             natom-pause@smi2le.net
45             http://a.galaxy.far.far.away/modules
46              
47             =head1 COPYRIGHT
48              
49             This program is free software; you can redistribute
50             it and/or modify it under the same terms as Perl itself.
51              
52             The full text of the license can be found in the
53             LICENSE file included with this module.
54              
55              
56             =head1 SEE ALSO
57              
58             Class::Prevayler.
59              
60             =cut
61              
62             sub init {
63 0     0 0   my $self = shift;
64 0           my %values = (@_);
65 0           $self->hash_init(%values);
66 0 0 0       ( $self->directory && $self->deserializer )
67             or croak "need a directory and a deserializer!";
68 0           return;
69             }
70              
71             sub recover {
72 0     0 0   my ( $self, $system ) = @_;
73              
74 0           while ( $self->_execute_next_command($system) ) { }
75 0           return $system;
76             }
77              
78             sub _execute_next_command {
79 0     0     my ( $self, $system ) = @_;
80 0           while (1) {
81 0 0         unless ( $self->_filehandle ) {
82 0 0         my $filename = $self->_find_next_command_file
83             or return undef;
84 0           my $filehandle;
85 0 0         open( $filehandle, $filename )
86             or croak "couldn't open file $filename " . ": $!";
87 0           $self->_filehandle($filehandle);
88             }
89 0           my $cmd_obj = $self->_read_command( $self->_filehandle );
90 0 0         unless ($cmd_obj) {
91 0           close $self->_filehandle;
92 0           $self->_filehandle(undef);
93 0           $self->next_logfile_number( $self->next_logfile_number + 1 );
94 0           next;
95             }
96 0           $self->_execute_cmd( $cmd_obj, $system );
97 0           return 1;
98             }
99             }
100              
101             sub _execute_cmd {
102 0     0     my ( $self, $cmd_obj, $system ) = @_;
103 0           eval { $cmd_obj->execute($system); };
  0            
104             }
105              
106             sub _read_command {
107 0     0     my ( $self, $filehandle ) = @_;
108              
109 0           my $length = <$filehandle>;
110 0 0         return undef unless $length;
111 0           chomp($length);
112 0           my $file = '';
113 0           while ( length($file) < $length ) {
114 0           $file .= <$filehandle>;
115             }
116 0           chomp($file);
117 0           return $self->deserializer->($file);
118             }
119              
120             sub _find_next_command_file {
121 0     0     my ($self) = @_;
122              
123 0 0         unless ( $self->pending_commands ) {
124 0           local (*DIRHANDLE);
125 0 0         opendir DIRHANDLE, $self->directory()
126             or croak "couldn't open directory " . $self->directory . ": $!";
127 0           my @commands =
128             grep {
129 0           my ($number) = /(\d*)\.commandLog$/;
130 0 0 0       defined $number && $number >= $self->next_logfile_number ? 1 : 0;
131             } readdir DIRHANDLE;
132 0 0         return undef unless scalar @commands;
133 0           $self->pending_commands( [ sort @commands ] );
134             }
135 0 0         my $filename = shift @{ $self->pending_commands } or return undef;
  0            
136 0           return File::Spec->catfile( $self->directory, $filename );
137             }
138              
139             1; #this line is important and will help the module return a true value
140             __END__