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