File Coverage

blib/lib/DBI/Shell/Spool.pm
Criterion Covered Total %
statement 47 53 88.6
branch 12 20 60.0
condition 1 6 16.6
subroutine 5 5 100.0
pod 0 2 0.0
total 65 86 75.5


line stmt bran cond sub pod time code
1             #
2             # Package meta, adds meta database commands to dbish
3             #
4             package DBI::Shell::Spool;
5              
6             our $VERSION = '11.97'; # VERSION
7 4     4   29 use strict;
  4         11  
  4         151  
8 4     4   22 use vars qw(@ISA);
  4         8  
  4         176  
9              
10 4     4   1526 use IO::Tee;
  4         8199  
  4         2329  
11              
12             sub init {
13 4     4 0 11 my ($self, $sh, @arg) = @_;
14              
15              
16 4         21 $sh->install_options(
17             [
18             [ 'spool' => 'off' ],
19             ]);
20 4         13 my $com_ref = $sh->{commands};
21             $com_ref->{spool} = {
22 4         30 hint =>
23             "spool: on/off or file name to send output to",
24             };
25            
26 4         14 return $self;
27             }
28              
29             #------------------------------------------------------------------
30             #
31             # Start or Stop spooling output.
32             # The spool support the follow states:
33             # spool - returns the current state of spooling, if on includes the file name.
34             # spool on - set the state to on, opens a default name of spool.lst (Yes, the
35             # Oracle default name). If the spool current state is already on, returns a
36             # warning message (Already spooling to file X).
37             # spool /path/file/name - set the state on, attempt to open the file name
38             # (using the IO::Tee object to allow multiplex output), and set the new IO
39             # handle to the default handle.
40             # spool off - set the state to off. If the previous state was on, flush the
41             # current buffer and close the file handle. If the previous state was off,
42             # return a warning message (Not current spooling).
43             #
44             #------------------------------------------------------------------
45             sub do_spool {
46 4     4 0 416 my ($sh, @args) = @_;
47              
48             # Get the current state of spool.
49 4 100       12 unless(@args) {
50 2 100       14 if ($sh->is_spooling) {
51             return $sh->print_buffer( qq{spooling output to file: },
52 1         5 $sh->{spool_file} );
53             } else {
54 1         5 return $sh->print_buffer( qq{not spooling} );
55             }
56             }
57              
58             # So what command did I get at this point?
59 2         5 my $command = shift @args;
60              
61 2 100       14 if ($command =~ m/\boff/i) { # Turn the spool off (if on).
62 1 50       5 if ($sh->is_spooling) { # spool on
63             # The tee object contains the open handles, get a list, shift the
64             # first (this should be STDOUT), flush. Then for the remainder
65             # flush each and close.
66 1         5 my @fhs = $sh->{out_fh}->handles;
67 1         11 $sh->{out_fh} = shift @fhs; select $sh->{out_fh};
  1         2  
68              
69 1         11 $sh->{out_fh}->flush;
70 1         16 $sh->spool_off; $sh->{spool_file} = undef;
  1         3  
71 1         2 foreach my $fh (@fhs) {
72 1         63 $fh->flush;
73 1         12 $fh->close;
74             }
75 1         21 $sh->{spool_fh} = undef;
76 1         9 return $sh->{out_fh};
77             }
78 0         0 return $sh->print_buffer( qq{not spooling} );
79             }
80              
81 1         2 my $spool_file = undef;
82 1 50       5 if ($command =~ m/on/i) { # Turn the spool off (if on).
83 0 0 0     0 unless(@args or $args[0] !~ m/!/) {
84 0         0 $spool_file = q{on.lst};
85             }
86             }
87              
88             # OK, now we're at the one to open the spool file. How do I handle if the
89             # file exists? Well, unless the next arg is a !, open the file for append.
90 1         2 my $mode = q{a+};
91 1 50 33     4 if (@args and $args[0] =~ m/!/) {
92 0         0 shift @args;
93 0         0 $mode = q{w};
94             }
95            
96 1         3 my $out_fh = $sh->{out_fh};
97              
98 1 50       5 $spool_file = defined $spool_file ? $spool_file : $command;
99              
100 1 50       3 if (defined $spool_file) {
101 1 50       9 my $tee_fh = new IO::Tee($out_fh, new IO::File($spool_file, $mode)) or
102             return $sh->alert(qq{Unable create IO::Tee ($spool_file) handle: $!\n});
103 1         266 $sh->{out_fh} = $tee_fh;
104 1         3 $sh->{spool_file} = $spool_file; $sh->spool_on;
  1         14  
105 1         4 $sh->{spool_fh} = ($tee_fh->handles)[1];
106 1         10 select $tee_fh;
107 1         12 return $sh->print_buffer( qq{spooling $spool_file} );
108             }
109 0           return $sh->alert( qq{spool command failed for unknown reason} );
110             }
111              
112             1;