File Coverage

blib/lib/DBI/Format/SQLMinus.pm
Criterion Covered Total %
statement 154 201 76.6
branch 46 82 56.1
condition 17 50 34.0
subroutine 8 9 88.8
pod 0 4 0.0
total 225 346 65.0


line stmt bran cond sub pod time code
1             # -*- perl -*-
2             # vim:ts=4:sw=4:aw:ai:
3             #
4             # DBI::Format::SQLMinus - a package for displaying result tables
5             #
6             # Copyright (c) 2001, 2002 Thomas A. Lowery
7             #
8             # The DBI::Shell::SQLMinus module is free software; you can redistribute
9             # it and/or modify it under the same terms as Perl itself.
10             #
11              
12             #
13             # The "meat" of this format comes from interaction with the sqlminus
14             # plugin module.
15             #
16              
17 1     1   7 use strict;
  1         3  
  1         75  
18              
19             package DBI::Format::SQLMinus;
20              
21             our $VERSION = '11.96_02'; # TRIAL VERSION
22             $VERSION = eval $VERSION;
23              
24             @DBI::Format::SQLMinus::ISA = qw(DBI::Format::Base);
25              
26 1     1   7 use Text::Abbrev;
  1         3  
  1         69  
27 1     1   7 use Text::Reform qw(form break_with);
  1         2  
  1         8  
28              
29 1     1   1182 use Data::Dumper;
  1         7210  
  1         518  
30              
31             sub header {
32 20     20 0 67 my($self, $sth, $fh, $sep) = @_;
33 20         118 $self->{'fh'} = $self->setup_fh($fh);
34 20         54 $self->{'sth'} = $sth;
35 20         68 $self->{'data'} = [];
36 20         55 $self->{'formats'} = [];
37 20 50       83 $self->{sep} = $sep if defined $sep;
38             #
39             # determine default behavior based either on the setting in
40             # sqlminus, or pre-defined defaults. Without sqlminus loaded,
41             # these defaults setting are static. Using the sqlminus "set"
42             # command to change setting.
43             #
44              
45 20         65 my ($breaks, $set, $column_format, $column_header_format, $sqlminus);
46              
47 20 50       91 if ( exists $self->{plugin}->{sqlminus} ) {
48              
49             # sqlminus plugin installed.
50 20         54 $sqlminus = $self->{plugin}->{sqlminus};
51              
52 20         47 $set = $sqlminus->{set_current};
53 20         39 $column_format = $sqlminus->{column_format};
54             $column_header_format =
55 20         42 $sqlminus->{column_header_format};
56 20         43 $breaks = $sqlminus->{break_current};
57             } else {
58 0         0 warn 'sqlminus plugin not installed\n';
59 0         0 $sqlminus = undef;
60 0         0 $set = {};
61 0         0 $column_format = {};
62 0         0 $column_header_format = {};
63             }
64              
65 20         64 $self->{feedback} = $set->{feedback};
66 20         51 $self->{limit} = $set->{limit};
67 20         47 $self->{null} = $set->{null};
68 20         45 $self->{pagesize} = $set->{pagesize};
69 20         47 $self->{recsepchar} = $set->{recsepchar};
70 20         54 $self->{recsep} = $set->{recsep};
71              
72 20         43 $self->{pagefeed} = undef;
73 20         39 $self->{pagelen} = 66;
74 20         44 $self->{pagenum} = 0;
75              
76             # $self->{breaks};
77              
78 20         126 my $types = $sth->{'TYPE'};
79 20         637 my @right_justify;
80             my @widths;
81 20         0 my @heading;
82 20         0 my @display;
83 20         78 my $names = $sth->{'NAME'};
84 20         82 my $names_lc = $sth->{'NAME_lc'};
85 20         117 my $type;
86             my $format_row;
87 20         0 my @ul;
88 20         0 my @fmtfunc;
89 20         0 my @commify;
90              
91 20         260 my $attribs = {
92             name => undef
93             ,name_lc => undef
94             ,precision => undef
95             ,scale => undef
96             ,len => undef
97             ,commify => undef
98             ,fmtfunc => undef
99             ,justify => undef
100             ,type => undef
101             ,format => undef
102             ,display => undef
103             ,heading => undef
104             };
105              
106 20         65 my @columns = ();
107              
108 20         146 for (my $i = 0; $i < $sth->{'NUM_OF_FIELDS'}; $i++) {
109              
110              
111 32         70 my $myattribs = ();
112 32         471 $myattribs->{$_} = undef foreach ( sort keys %$attribs );
113              
114 32         104 my ($format_names, $heading, $width, $type, $justify);
115             # Default, left justify everything.
116 32         68 $justify = '<';
117 32         62 $myattribs->{justify} = q{<};
118              
119 32         75 push(@display, 1);
120              
121 32         62 $myattribs->{display}++;
122              
123 32         85 $myattribs->{name} = $names->[$i];
124 32         61 $myattribs->{name_lc} = $names_lc->[$i];
125              
126 32         67 my $n_lc = $names_lc->[$i];
127             # Determine if a break point exists.
128 32 50       111 if ( exists $breaks->{$n_lc} ) {
129 0         0 print "Column " . $n_lc . " has a break point\n";
130 0         0 push @{$self->{breaks}->{order_of}}, $n_lc;
  0         0  
131 0         0 for (keys %{$breaks->{$n_lc}}) {
  0         0  
132             $self->{breaks}->{$n_lc}->{$_} =
133 0         0 $breaks->{$n_lc}->{$_};
134             }
135              
136 0         0 $self->{breaks}->{$n_lc}->{last_break_point} = undef;
137             }
138              
139 32 100       106 if ( exists $column_format->{$names_lc->[$i]} ) {
140 28         77 my $cf = $column_format->{$names_lc->[$i]};
141              
142             # Determine if the column formating is on or off.
143 28 100 66     132 if ( exists $cf->{on} and $cf->{on} ) {
144              
145             # Determine if this column is printed.
146             # If this column is set to noprint, then skip.
147 27 100 66     130 if (exists $cf->{noprint} and $cf->{noprint}) {
148 2         5 $myattribs->{display} = 0;
149 2         4 $display[$i] = 0;
150             # Need to remember the attributes set for this column
151 2         7 push(@columns, $myattribs);
152 2         13 next;
153             }
154              
155 25 50 33     126 if ( exists $cf->{format} and defined $cf->{format} ) {
156 25         52 $format_names = $cf->{format};
157 1     1   10 no warnings 'redundant';
  1         2  
  1         3084  
158 25         87 $width = length sprintf( $format_names, " " );
159             }
160              
161 25 100 66     116 if ( exists $cf->{justify} and defined $cf->{justify} ) {
162 3 100       17 $justify = '^' if $cf->{justify} =~ m/^c/;
163 3 100       16 $justify = '<' if $cf->{justify} =~ m/^l/;
164 3 100       15 $justify = '>' if $cf->{justify} =~ m/^r/;
165              
166 3         9 $myattribs->{justify} = $justify;
167             }
168              
169 25 100 66     97 if (exists $cf->{heading} and defined $cf->{heading}) {
170 9         26 $heading = $cf->{heading};
171 9         22 $myattribs->{heading} = $heading;
172             }
173            
174             }
175              
176 26         61 push( @fmtfunc , $cf->{format_function} );
177 26         62 $myattribs->{fmtfunc} = $cf->{format_function};
178 26   50     107 push( @commify , $cf->{'commify'} || 0 );
179 26         46 $myattribs->{commify} = $cf->{commify};
180              
181 26         53 $myattribs->{precision} = $cf->{precision};
182 26         43 $myattribs->{scale} = $cf->{scale};
183 26         50 $myattribs->{len} = $cf->{len};
184             }
185            
186              
187 30 100       64 $heading = $names->[$i] unless $heading;
188              
189 30         59 push(@heading, $heading);
190              
191 30         52 $type = $types->[$i];
192 30         61 $myattribs->{type} = $type;
193              
194 30 100       80 if ( $width ) {
195 25         39 push( @widths, $width );
196 25         59 $myattribs->{width} = $width;
197             } else {
198             push(@widths, $self->_determine_width(
199 5         33 $type, $sth->{PRECISION}->[$i] ));
200              
201 5 100 100     31 $widths[$i] = length $names->[$i]
202             if (length $names->[$i] > ($widths[$i]||0));
203 5         13 $width = $widths[$i];
204 5         10 $myattribs->{width} = $width;
205             }
206              
207              
208 30 50       60 if ( $justify ) {
209 30         53 push( @right_justify, $justify );
210 30         108 $myattribs->{justify} = $justify;
211             } else {
212 0   0     0 push(@right_justify,
213             ($type == DBI::SQL_NUMERIC() ||
214             $type == DBI::SQL_DECIMAL() ||
215             $type == DBI::SQL_INTEGER() ||
216             $type == DBI::SQL_SMALLINT() ||
217             $type == DBI::SQL_FLOAT() ||
218             $type == DBI::SQL_REAL() ||
219             $type == DBI::SQL_BIGINT() ||
220             $type == DBI::SQL_TINYINT()));
221             $myattribs->{justify} =
222 0   0     0 ($type == DBI::SQL_NUMERIC() ||
223             $type == DBI::SQL_DECIMAL() ||
224             $type == DBI::SQL_INTEGER() ||
225             $type == DBI::SQL_SMALLINT() ||
226             $type == DBI::SQL_FLOAT() ||
227             $type == DBI::SQL_REAL() ||
228             $type == DBI::SQL_BIGINT() ||
229             $type == DBI::SQL_TINYINT());
230             }
231              
232 30 100       82 $format_names = $justify x $width
233             unless $format_names;
234            
235             push( @ul, defined $set->{underline}
236 30 100       141 ? "$set->{underline}" x $width
237             : '-' x $width
238             );
239            
240              
241             $set->{linesize} += $widths[$i]
242 30 50       80 unless $set->{linesize};
243              
244 30         67 $format_row .= $format_names;
245 30         72 $format_row .= $set->{headsep};
246              
247              
248 30         248 push(@columns, $myattribs);
249             }
250              
251 20         78 $self->{'formats'} = \$format_row;
252 20         130 $self->{'columns'} = \@columns;
253 20         54 $self->{'headings'} = \@heading;
254 20         50 $self->{'ul'} = \@ul;
255              
256 20         45 $column_header_format = $format_row;
257             # print $fh form $header_form, (sprintf($format_row, @heading)), "\n" if $set->{heading};
258             print $fh form $column_header_format, @heading
259 20 50       136 if $set->{heading};
260             print $fh form $column_header_format, @ul
261 20 100       11115 if $set->{underline};
262             print $fh "\n"
263 20 100 66     7793 if $set->{heading} and ! $set->{underline};
264             }
265              
266             sub re_headers {
267 0     0 0 0 my($self) = @_;
268 0         0 my $fh = $self->{'fh'};
269              
270              
271 0         0 my ($set, $column_format, $column_header_format, $sqlminus);
272              
273 0 0       0 if ( exists $self->{plugin}->{sqlminus} ) {
274             # sqlminus plugin installed.
275 0         0 $sqlminus = $self->{plugin}->{sqlminus};
276 0         0 $set = $sqlminus->{set_current};
277             } else {
278 0         0 return warn 'sqlminus plugin not installed\n';
279             }
280              
281 0         0 $column_header_format = ${$self->{'formats'}};
  0         0  
282              
283             print $fh "\n"
284 0 0       0 if defined $set->{heading};
285 0         0 print $fh form $column_header_format, @{$self->{headings}}
286 0 0       0 if defined $set->{heading};
287 0         0 print $fh form $column_header_format, @{$self->{ul}}
288 0 0       0 if defined $set->{underline};
289             print $fh "\n"
290 0 0 0     0 if defined $set->{heading} and not defined $set->{underline};
291              
292             }
293              
294              
295             sub row {
296 200     200 0 412 my($self, $orig_row) = @_;
297 200         310 my $i = 0;
298 200         348 my @row = @$orig_row; # don't mess with the original row
299              
300             # default value for null, is blank.
301 200   50     775 my $null = $self->{'null'} || '';
302 200         328 my $columns = $self->{'columns'};
303              
304 200         302 my $breaks = $self->{'breaks'};
305              
306             map {
307 200 50       370 if (!defined($_)) {
  320         645  
308 0         0 $_ = $null;
309             } else {
310 320         815 $_ =~ s/\n/\\n/g;
311 320         485 $_ =~ s/\t/\\t/g;
312 320         454 $_ =~ s/\r/\\r/g;
313 320         662 $_ =~ s/[\000-\037\177-\237]/./g;
314             }
315 320         619 ++$i;
316             } @row;
317              
318 200         292 my $format_rows = ${$self->{'formats'}};
  200         404  
319              
320             # if (exists $self->{'formats'} and defined $self->{'formats'} ){
321             # #print "using existing format '$format_rows'\n";
322             # $format_rows = ${$self->{'formats'}};
323             # } else {
324             # for (my $i = 0; $i < $sth->{'NUM_OF_FIELDS'}; $i++) {
325             # $format_rows .=
326             # ($right_justify->[$i] ? "<" : ">")
327             # x $widths->[$i]
328             # . ($self->{recsep}?$self->{recsepchar}:'');
329             # }
330             # }
331              
332 200         365 $format_rows .= "\n";
333              
334 200         285 my $fh = $self->{'fh'};
335 200         278 my @data; my $skip_rows = 0; my $skip_page = undef;
  200         261  
  200         297  
336             COLUMN:
337 200         1310 for (my $i = 0; $i < $self->{'sth'}->{'NUM_OF_FIELDS'}; $i++) {
338              
339 320         607 my $attribs = $columns->[$i];
340 320 50       1088 if ( exists $breaks->{$attribs->{name_lc}} ) {
341              
342 0         0 my $brk = $breaks->{$attribs->{name_lc}};
343              
344 0 0 0     0 if (defined $brk->{last_break_point} and
345             $brk->{last_break_point} ne $row[$i]) {
346 0 0       0 if (exists $brk->{skip}) {
347             $skip_rows = $skip_rows >= $brk->{skip} ? $skip_rows :
348 0 0       0 $brk->{skip};
349             }
350              
351 0 0       0 if (exists $brk->{skip_page}) {
352 0         0 $skip_page = 1;
353             }
354             }
355              
356 0 0       0 if (exists $brk->{nodup}) {
357 0 0 0     0 if (defined $brk->{last_break_point}
358             and $brk->{last_break_point} eq $row[$i]) {
359 0         0 push (@data, q{}); # empty row (noduplicate display)
360 0         0 $brk->{last_break_point} = $row[$i];
361 0         0 next COLUMN;
362             }
363             }
364              
365 0         0 $brk->{last_break_point} = $row[$i];
366             }
367              
368 320 100       711 next unless ($attribs->{'display'});
369              
370 300 50       608 if ((ref $attribs->{fmtfunc}) eq 'CODE') {
371             # warn "fmtcall\n";
372             push( @data ,
373             $attribs->{fmtfunc}(
374             $row[$i]
375             ,$attribs->{precision} || $attribs->{width}
376             ,$attribs->{scale} || 0
377 0   0     0 ,$attribs->{'commify'}) );
      0        
378             } else {
379 300         1566 push( @data , $row[$i] );
380             }
381             }
382              
383             # Deal with the breaks.
384 200 50       620 if ($skip_page) {
    50          
385 0         0 print $fh q{ };
386             } elsif ($skip_rows) {
387 0         0 print $fh "\n" x $skip_rows;
388             }
389              
390 200         713 print $fh form (
391             { 'break' => break_with('') }
392             , $format_rows, @data
393             );
394              
395 200         96566 ++$self->{'rows'};
396              
397             # Send a undef back to caller, signal limit reached.
398 200 50 33     634 if (defined $self->{limit} and $self->{rows} >= $self->{limit}) {
399 0         0 return undef;
400             }
401             # Determine if this number of rows displayed is modulo of pagesize
402 200 50 33     437 if (defined $self->{pagesize}
403             and ($self->{'rows'} % $self->{pagesize}) == 0 ) {
404 0         0 $self->re_headers();
405             }
406              
407 200         878 return $self->{rows};
408             }
409              
410              
411             sub trailer {
412 20     20 0 45 my $self = shift;
413 20         52 my $widths = delete $self->{'widths'};
414 20         47 my $right_justify = delete $self->{'right_justify'};
415              
416 20         74 delete $self->{recsep};
417 20         45 delete $self->{recsepchar};
418 20         701 print "Page Number: ", $self->{pagenum}, "\n";
419              
420 20         174 $self->SUPER::trailer(@_);
421             }
422              
423             1;
424              
425             =head1 NAME
426              
427             DBI::Format::SQLMinus - A package for displaying result tables
428              
429             =head1 SYNOPSIS
430              
431             =head1 DESCRIPTION
432              
433             THIS PACKAGE IS STILL VERY EXPERIMENTAL. THINGS WILL CHANGE.
434              
435             =head1 AUTHOR AND COPYRIGHT
436              
437             Orignal Format module is Copyright (c) 1997, 1998
438              
439             Jochen Wiedmann
440             Am Eisteich 9
441             72555 Metzingen
442             Germany
443              
444             Email: joe@ispsoft.de
445             Phone: +49 7123 14887
446              
447             SQLMinus is Copyright (c) 2001, 2002 Thomas A. Lowery
448              
449             The DBI::Format::SQLMinus module is free software; you can redistribute it and/or
450             modify it under the same terms as Perl itself.
451              
452              
453             =head1 SEE ALSO
454              
455             L, L, L