File Coverage

blib/lib/Xtract/Publish.pm
Criterion Covered Total %
statement 121 133 90.9
branch 51 64 79.6
condition 7 9 77.7
subroutine 25 25 100.0
pod 1 14 7.1
total 205 245 83.6


line stmt bran cond sub pod time code
1             package Xtract::Publish;
2              
3 5     5   39633 use 5.008005;
  5         16  
  5         265  
4 5     5   29 use strict;
  5         10  
  5         336  
5 5     5   26 use Carp ();
  5         20  
  5         103  
6 5     5   6031 use File::Copy 0 ();
  5         19630  
  5         161  
7 5     5   1032 use File::Remove 1.42 ();
  5         2709  
  5         196  
8 5     5   2104 use Params::Util 0.35 ();
  5         9154  
  5         169  
9 5     5   6591 use IO::Compress::Gzip 2.008 ();
  5         15546224  
  5         201  
10 5     5   6081 use IO::Compress::Bzip2 2.008 ();
  5         69787  
  5         510  
11 5     5   9689 use Xtract::LZMA ();
  5         17  
  5         319  
12              
13             our $VERSION = '0.16';
14              
15 5     5   5628 use Mouse 0.93;
  5         278515  
  5         43  
16              
17             has 'sqlite' => (
18             is => 'ro',
19             isa => 'Str',
20             required => 1,
21             );
22              
23             has 'from' => (
24             is => 'ro',
25             isa => 'Str',
26             required => 0,
27             predicate => 'has_from',
28             );
29              
30             sub flag ($$) {
31 30     30 0 104 has $_[0] => (
32             is => 'rw',
33             isa => 'Bool',
34             required => 1,
35             default => $_[1],
36             );
37             }
38              
39             flag 'raw' => 1;
40             flag 'gz' => 1;
41             flag 'bz2' => 0;
42             flag 'lz' => 0;
43             flag 'atomic' => 0;
44             flag 'trace' => 0;
45              
46 5     5   3271 no Mouse;
  5         13  
  5         32  
47              
48              
49              
50              
51              
52             ######################################################################
53             # Constructor and Accessors
54              
55             sub new {
56 4     4 1 8258 my $self = shift->SUPER::new(@_);
57              
58             # Check params
59 4 50 66     519 if ( $self->has_from and not -f $self->from ) {
60 0         0 Carp::croak("Source file '" . $self->from . "' does not exist");
61             }
62              
63 4         43 return $self;
64             }
65              
66             sub sqlite_gz {
67 15     15 0 162 $_[0]->sqlite . '.gz';
68             }
69              
70             sub sqlite_bz2 {
71 13     13 0 200 $_[0]->sqlite . '.bz2';
72             }
73              
74             sub sqlite_lz {
75 14     14 0 4065 $_[0]->sqlite . '.lz';
76             }
77              
78              
79              
80              
81              
82              
83             ######################################################################
84             # Main Methods
85              
86             sub run {
87 4     4 0 13 my $self = shift;
88              
89             # Copy the source SQLite database
90 4         20 my $sqlite = $self->write_sqlite;
91 4 100       19 if ( defined $sqlite ) {
92 2         10 $self->remove($sqlite);
93 2         12 $self->copy( $self->from => $sqlite );
94             }
95              
96             # Where to we create the archives from?
97 4 100       35 $sqlite = defined($sqlite) ? $sqlite : $self->sqlite;
98              
99             # Create the GZip archive
100 4         20 my $gz = $self->write_gz;
101 4 100       58 if ( defined $gz ) {
102 3         15 $self->remove($gz);
103 3         21 $self->say("Compressing '$sqlite' into '$gz'");
104 3         33 my $rv = IO::Compress::Gzip::gzip(
105             $sqlite => $gz,
106             AutoClose => 1,
107             BinModeIn => 1,
108             );
109 3 50       10940 unless ( $rv ) {
110 0         0 Carp::croak("Failed to create gzip archive '$gz'");
111             }
112             }
113              
114             # Create the BZip2 archive
115 4         21 my $bz2 = $self->write_bz2;
116 4 100       17 if ( defined $bz2 ) {
117 3         24 $self->remove($bz2);
118 3         20 $self->say("Compressing '$sqlite' into '$bz2'");
119 3         22 my $rv = IO::Compress::Bzip2::bzip2(
120             $sqlite => $bz2,
121             AutoClose => 1,
122             BinModeIn => 1,
123             );
124 3 50       6511 unless ( $rv ) {
125 0         0 Carp::croak("Failed to create bzip2 archive '$bz2'");
126             }
127             }
128              
129             # Create the LZMA archive
130 4         20 my $lz = $self->write_lz;
131 4 100       17 if ( defined $lz ) {
132 3         13 $self->remove($lz);
133 3         21 $self->say("Compressing '$sqlite' into '$lz'");
134 3         35 Xtract::LZMA->compress( $sqlite => $lz );
135             }
136              
137             # Atomically overwrite the original archives
138 4 100       57 if ( $self->atomic ) {
139 1 50       23 if ( $sqlite ne $self->sqlite ) {
140 1         31 $self->move( $sqlite => $self->sqlite );
141             }
142 1 50       7 if ( defined $gz ) {
143 0         0 $self->move( $gz => $self->sqlite_gz );
144             }
145 1 50       8 if ( defined $bz2 ) {
146 1         8 $self->move( $bz2 => $self->sqlite_bz2 );
147             }
148 1 50       8 if ( defined $lz ) {
149 1         6 $self->move( $lz => $self->sqlite_lz );
150             }
151             }
152              
153             # Remove any archives we may have had previously that we don't any more
154 4 100       32 unless ( defined $gz ) {
155 1         8 $self->remove( $self->sqlite_gz );
156             }
157 4 100       42 unless ( defined $bz2 ) {
158 1         4 $self->remove( $self->sqlite_bz2 );
159             }
160 4 100       31 unless ( defined $lz ) {
161 1         3 $self->remove( $self->sqlite_lz );
162             }
163 4 100 100     85 if ( $self->from and not $self->raw ) {
164 1         5 $self->remove( $self->sqlite );
165             }
166              
167 4         70 return 1;
168             }
169              
170             sub write_sqlite {
171 8     8 0 6409 my $self = shift;
172 8 100 66     99 if ( defined $self->from and $self->sqlite ne $self->from ) {
173 6 100       26 if ( $self->atomic ) {
174 3         41 return $self->sqlite . '.tmp';
175             } else {
176 3         29 return $self->sqlite;
177             }
178             }
179 2         7 return undef;
180             }
181              
182             sub write_gz {
183 8     8 0 20 my $self = shift;
184 8 100       44 if ( $self->gz ) {
185 5 50       25 if ( $self->atomic ) {
186 0         0 return $self->sqlite . '.tmp.gz';
187             } else {
188 5         22 return $self->sqlite_gz;
189             }
190             }
191 3         11 return undef;
192             }
193              
194             sub write_bz2 {
195 8     8 0 18 my $self = shift;
196 8 100       72 if ( $self->bz2 ) {
197 5 100       107 if ( $self->atomic ) {
198 3         33 return $self->sqlite . '.tmp.bz2';
199             } else {
200 2         13 return $self->sqlite_bz2;
201             }
202             }
203 3         9 return undef;
204             }
205              
206             sub write_lz {
207 8     8 0 19 my $self = shift;
208 8 100       52 if ( $self->lz ) {
209 5 100       31 if ( $self->atomic ) {
210 3         35 return $self->sqlite . '.tmp.lz';
211             } else {
212 2         12 return $self->sqlite_lz;
213             }
214             }
215 3         14 return undef;
216             }
217              
218              
219              
220              
221              
222             ######################################################################
223             # Support Methods
224              
225             sub say {
226 19 50   19 0 164 if ( Params::Util::_CODE($_[0]->trace) ) {
    50          
227 0         0 $_[0]->say( @_[1..$#_] );
228             } elsif ( $_[0]->trace ) {
229 0         0 my $t = scalar localtime time;
230 0         0 print map { "[$t] $_\n" } @_[1..$#_];
  0         0  
231             }
232             }
233              
234             sub copy {
235 2     2 0 4 my $self = shift;
236 2         17 $self->say("Copying '$_[0]' to '$_[1]'");
237 2 50       17 unless ( File::Copy::copy(@_) ) {
238 0         0 Carp::croak("Failed to copy '$_[0]' to '$_[1]'");
239             }
240 2         916 return 1;
241             }
242              
243             sub move {
244 3     3 0 15 my $self = shift;
245 3 100       43 if ( -f $_[1] ) {
246 1         19 $self->say("Moving '$_[0]' over existing '$_[1]'");
247             } else {
248 2         26 $self->say("Moving '$_[0]' to '$_[1]'");
249             }
250 3         17 $self->say("Copying '$_[0]' to '$_[1]'");
251 3 50       24 unless ( File::Copy::move(@_) ) {
252 0         0 Carp::croak("Failed to move '$_[0]' to '$_[1]'");
253             }
254 3         388 return 1;
255             }
256              
257             sub remove {
258 15     15 0 27 my $self = shift;
259 15         27 my $file = shift;
260            
261             # Flush any existing file
262 15 100       231 if ( -f $file ) {
263 2         8 $self->say("Removing '$file'");
264 2 50       18 unless ( File::Remove::remove( $file ) ) {
265 0         0 Carp::croak("Failed to remove existing '$file'");
266             }
267             }
268              
269 15         363 return 1;
270             }
271              
272             1;