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_02'; # TRIAL VERSION
7             $VERSION = eval $VERSION;
8 4     4   31 use strict;
  4         9  
  4         189  
9 4     4   23 use vars qw(@ISA);
  4         8  
  4         203  
10              
11 4     4   1502 use IO::Tee;
  4         8466  
  4         2582  
12              
13             sub init {
14 4     4 0 13 my ($self, $sh, @arg) = @_;
15              
16              
17 4         19 $sh->install_options(
18             [
19             [ 'spool' => 'off' ],
20             ]);
21 4         11 my $com_ref = $sh->{commands};
22             $com_ref->{spool} = {
23 4         19 hint =>
24             "spool: on/off or file name to send output to",
25             };
26            
27 4         13 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 406 my ($sh, @args) = @_;
48              
49             # Get the current state of spool.
50 4 100       13 unless(@args) {
51 2 100       14 if ($sh->is_spooling) {
52             return $sh->print_buffer( qq{spooling output to file: },
53 1         5 $sh->{spool_file} );
54             } else {
55 1         5 return $sh->print_buffer( qq{not spooling} );
56             }
57             }
58              
59             # So what command did I get at this point?
60 2         6 my $command = shift @args;
61              
62 2 100       12 if ($command =~ m/\boff/i) { # Turn the spool off (if on).
63 1 50       7 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         7 my @fhs = $sh->{out_fh}->handles;
68 1         11 $sh->{out_fh} = shift @fhs; select $sh->{out_fh};
  1         3  
69              
70 1         12 $sh->{out_fh}->flush;
71 1         20 $sh->spool_off; $sh->{spool_file} = undef;
  1         3  
72 1         4 foreach my $fh (@fhs) {
73 1         69 $fh->flush;
74 1         13 $fh->close;
75             }
76 1         23 $sh->{spool_fh} = undef;
77 1         8 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       5 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       4 if (defined $spool_file) {
102 1 50       9 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         273 $sh->{out_fh} = $tee_fh;
105 1         3 $sh->{spool_file} = $spool_file; $sh->spool_on;
  1         31  
106 1         4 $sh->{spool_fh} = ($tee_fh->handles)[1];
107 1         12 select $tee_fh;
108 1         11 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;