File Coverage

blib/lib/DBI/Format.pm
Criterion Covered Total %
statement 255 319 79.9
branch 40 74 54.0
condition 15 31 48.3
subroutine 26 29 89.6
pod 0 2 0.0
total 336 455 73.8


'; '; ", $widths->[$i]); ", \n"; \n";
line stmt bran cond sub pod time code
1             # -*- perl -*-
2             # vim:ts=2:sw=2:aw:ai:sta:nows
3             #
4             # DBI::Format - a package for displaying result tables
5             #
6             # Copyright (c) 1998 Jochen Wiedmann
7             # Copyright (c) 1998 Tim Bunce
8             #
9             # The DBI::Shell:Result module is free software; you can redistribute
10             # it and/or modify it under the same terms as Perl itself.
11             #
12             # Author: Jochen Wiedmann
13             # Am Eisteich 9
14             # 72555 Metzingen
15             # Germany
16             #
17             # Email: joe@ispsoft.de
18             # Phone: +49 7123 14881
19             #
20              
21 7     7   55 use strict;
  7         14  
  7         448  
22              
23             package DBI::Format;
24              
25             our $VERSION = '11.96_02'; # TRIAL VERSION
26             $VERSION = eval $VERSION;
27              
28 7     7   44 use Text::Abbrev;
  7         16  
  7         3428  
29              
30             sub available_formatters {
31 22     22 0 48 my ($use_abbrev) = @_;
32 22         179 my @fmt;
33 22         66 my @dir = grep { -d "$_/DBI/Format" } @INC;
  242         3151  
34 22         212 foreach my $dir (@dir) {
35 66 50       1864 opendir DIR, "$dir/DBI/Format" or warn "Unable to read $dir/DBI: $!\n";
36 66 100       1421 push @fmt, map { m/^(\w+)\.pm$/i ? ($1) : () } readdir DIR;
  264         1236  
37 66         835 closedir DIR;
38             }
39 22         85 my %fmt = map { (lc($_) => "DBI::Format::$_") } @fmt;
  132         437  
40 22         88 $fmt{box} = "DBI::Format::Box";
41 22         62 $fmt{partbox} = "DBI::Format::PartBox";
42 22         44 $fmt{neat} = "DBI::Format::Neat";
43 22         45 $fmt{raw} = "DBI::Format::Raw";
44 22         54 $fmt{string} = "DBI::Format::String";
45 22         51 $fmt{html} = "DBI::Format::HTML";
46 22         46 my $formatters = \%fmt;
47 22 50       73 if ($use_abbrev) {
48 22         136 $formatters = abbrev(keys %fmt);
49 22         4896 foreach my $abbrev (sort keys %$formatters) {
50 792   50     1446 $formatters->{$abbrev} = $fmt{ $formatters->{$abbrev} } || die;
51             }
52             }
53 22         117 return $formatters;
54             }
55              
56              
57             sub formatter {
58 22     22 0 69 my ($class, $mode, $use_abbrev) = @_;
59 22         55 $mode = lc($mode);
60 22         70 my $formatters = available_formatters($use_abbrev);
61 22         53 my $fmt = $formatters->{$mode};
62 22 50       60 if (!$fmt) {
63 0         0 $formatters = available_formatters(0);
64 0         0 die "Format '$mode' unavailable. Available formats: ".
65             join(", ", sort keys %$formatters)."\n";
66             }
67             {
68             # Attempt to determine if format mode is in the base class.
69 7     7   57 no strict 'refs';
  7         14  
  7         1224  
  22         37  
70 22         1633 eval "$fmt->new()";
71 22 100 66     154 if ( $@ and $@ =~ m/locate/ ) {
    50          
72 2     2   121 eval "use $fmt";
  2         1116  
  2         7  
  2         57  
73 2 50       17 die "$@\n" if $@;
74             } elsif ($@) {
75 0 0       0 die "$@\n" if $@;
76             }
77             }
78 22         216 return $fmt;
79             }
80              
81              
82             package DBI::Format::Base;
83              
84 7     7   54 use DBI qw(:sql_types);
  7         14  
  7         6927  
85              
86             sub new {
87 42     42   94 my $class = shift;
88 42 100       152 my $self = (@_ == 1) ? { %{shift()} } : { @_ };
  22         505  
89 42   33     225 bless ($self, (ref($class) || $class));
90 42         342 $self;
91             }
92              
93             sub setup_fh {
94 53     53   146 my ($self, $fh) = @_;
95              
96             # This method has grown confused as to what it's trying to do and why
97             # Partly because this module was written in pre-perl5.3 days
98             # the code in other methods originally did: $fh->print(...)
99             # because C didn't work reliably as a method call.
100             # Now the code uses C some of this may no longer be
101             # required. It's important that things like IO::Scalar handles work.
102              
103 53 0 33     188 return $self->{fh} if !$fh && $self->{fh};
104              
105 53   50     128 $fh ||= \*STDOUT;
106              
107 53 100       397 return $fh if ref($fh) =~ m/GLOB/;
108              
109 1 50       13 unless (UNIVERSAL::can($fh,'print')) { # not blessed
110 0         0 require FileHandle;
111 0         0 bless $fh => "FileHandle";
112             }
113              
114 1         4 return $fh;
115             }
116              
117              
118             sub trailer {
119 50     50   143 my($self) = @_;
120 50         159 my $fh = delete $self->{'fh'};
121 50         111 my $sth = delete $self->{'sth'};
122 50         124 my $rows = delete $self->{'rows'};
123 50         1440 print $fh ("[$rows rows of $sth->{NUM_OF_FIELDS} fields returned]\n");
124 50         414 delete $self->{'sep'};
125             }
126              
127             sub _determine_width {
128 19     19   303 my($self , $type, $precision) = @_;
129              
130 19 50 66     212 my $width =
    50 33        
    50          
    50          
    50          
131             (!defined($type)) ? 0 : # Is type defined?
132             ($type == SQL_DATE) ? 8 : # Is type a Date?
133             ($type == SQL_INTEGER # Is type an Integer?
134             and defined $precision
135             and $precision > 15 ) ? 10 :
136             ($type == SQL_NUMERIC # Is type a Numeric?
137             and defined $precision
138             and $precision > 15 ) ? 10 :
139             defined($precision) ? $precision: 0; # Default 0
140              
141 19         50 return $width;
142             }
143              
144              
145             package DBI::Format::Neat;
146              
147             @DBI::Format::Neat::ISA = qw(DBI::Format::Base);
148              
149             sub header {
150 26     26   78 my($self, $sth, $fh, $sep) = @_;
151 26         116 $self->{'fh'} = $fh = $self->setup_fh($fh);
152 26         119 $self->{'sth'} = $sth;
153 26         54 $self->{'rows'} = 0;
154 26 50       90 $self->{sep} = $sep if defined $sep;
155 26         70 print $fh (join($self->{sep}, @{$sth->{'NAME'}}), "\n");
  26         1221  
156             }
157              
158             sub row {
159 249     249   444 my($self, $rowref) = @_;
160 249         506 my @row = @$rowref;
161             # XXX note that neat/neat_list output is *not* ``safe''
162             # in the sense the it does not escape any chars and
163             # may truncate the string and may translate non-printable chars.
164             # We only deal with simple escaping here.
165 249         481 foreach(@row) {
166 1425 100       2376 next unless defined;
167 1407         2174 s/'/\\'/g;
168 1407         1938 s/\n/ /g;
169             }
170 249         400 my $fh = $self->{'fh'};
171 249         784 print $fh (DBI::neat_list(\@row, 9999, $self->{sep}),"\n");
172 249         11356 ++$self->{'rows'};
173             }
174              
175              
176              
177             package DBI::Format::Box;
178              
179 7     7   60 use DBI qw(:sql_types);
  7         13  
  7         6783  
180              
181             @DBI::Format::Box::ISA = qw(DBI::Format::Base);
182              
183             sub header {
184 1     1   5 my($self, $sth, $fh, $sep) = @_;
185 1         9 $self->{'fh'} = $fh = $self->setup_fh($fh);
186 1         14 $self->{'sth'} = $sth;
187 1         5 $self->{'data'} = [];
188 1 50       5 $self->{sep} = $sep if defined $sep;
189 1         7 my $types = $sth->{'TYPE'};
190 1         43 my @right_justify;
191             my @widths;
192 1         4 my $names = $sth->{'NAME'};
193 1         2 my $type;
194 1         7 for (my $i = 0; $i < $sth->{'NUM_OF_FIELDS'}; $i++) {
195 14 50       35 push(@widths, defined($names->[$i]) ? length($names->[$i]) : 0);
196 14         21 $type = $types->[$i];
197 14   66     174 push(@right_justify,
198             (defined($type) and ($type == SQL_NUMERIC ||
199             $type == SQL_DECIMAL ||
200             $type == SQL_INTEGER ||
201             $type == SQL_SMALLINT ||
202             $type == SQL_FLOAT ||
203             $type == SQL_REAL ||
204             $type == SQL_TINYINT))
205             );
206             }
207 1         4 $self->{'widths'} = \@widths;
208 1         5 $self->{'right_justify'} = \@right_justify;
209             }
210              
211              
212             sub row {
213 10     10   19 my($self, $orig_row) = @_;
214 10         14 my $i = 0;
215 10         14 my $col;
216 10         15 my $widths = $self->{'widths'};
217 10         32 my @row = @$orig_row; # don't mess with the original row
218             map {
219 10 50       18 if (!defined($_)) {
  140         218  
220 0         0 $_ = ' (NULL) ';
221             } else {
222 140         238 $_ =~ s/\n/\\n/g;
223 140         173 $_ =~ s/\t/\\t/g;
224 140         199 $_ =~ s/[\000-\037\177-\237]/./g;
225             }
226 140 100       251 if (length($_) > $widths->[$i]) {
227 12         14 $widths->[$i] = length($_);
228             }
229 140         191 ++$i;
230             } @row;
231 10         18 push @{$self->{data}}, \@row;
  10         60  
232             }
233              
234              
235             sub trailer {
236 1     1   3 my $self = shift;
237 1         3 my $widths = delete $self->{'widths'};
238 1         2 my $right_justify = delete $self->{'right_justify'};
239 1         4 my $sth = $self->{'sth'};
240 1         2 my $data = $self->{'data'};
241 1         2 $self->{'rows'} = @$data;
242              
243 1         2 my $format_sep = '+';
244 1         2 my $format_names = '|';
245 1         2 my $format_rows = '|';
246 1         21 for (my $i = 0; $i < $sth->{'NUM_OF_FIELDS'}; $i++) {
247 14         35 $format_sep .= ('-' x $widths->[$i]) . '+';
248 14         32 $format_names .= sprintf("%%-%ds|", $widths->[$i]);
249 14 100       79 $format_rows .= sprintf("%%"
250             . ($right_justify->[$i] ? "" : "-") . "%ds|",
251             $widths->[$i]);
252             }
253 1         3 $format_sep .= "\n";
254 1         2 $format_names .= "\n";
255 1         2 $format_rows .= "\n";
256              
257 1         2 my $fh = $self->{'fh'};
258 1         38 print $fh ($format_sep);
259 1         5 print $fh (sprintf($format_names, @{$sth->{'NAME'}}));
  1         21  
260 1         7 foreach my $row (@$data) {
261 10         70 print $fh ($format_sep);
262 10         131 print $fh (sprintf($format_rows, @$row));
263             }
264 1         9 print $fh ($format_sep);
265              
266 1         20 $self->SUPER::trailer(@_);
267             }
268              
269             package DBI::Format::PartBox;
270              
271 7     7   59 use DBI qw(:sql_types);
  7         13  
  7         17482  
272              
273             @DBI::Format::PartBox::ISA = qw(DBI::Format::Base);
274              
275             sub header {
276 0     0   0 my($self, $sth, $fh, $sep) = @_;
277 0         0 $self->{'fh'} = $fh = $self->setup_fh($fh);
278 0         0 $self->{'sth'} = $sth;
279 0         0 $self->{'data'} = [];
280 0 0       0 $self->{sep} = $sep if defined $sep;
281 0         0 my $types = $sth->{'TYPE'};
282 0         0 my @right_justify;
283             my @widths;
284 0         0 my $names = $sth->{'NAME'};
285 0         0 my $type;
286 0         0 for (my $i = 0; $i < $sth->{'NUM_OF_FIELDS'}; $i++) {
287 0 0       0 push(@widths, defined($names->[$i]) ? length($names->[$i]) : 0);
288 0         0 $type = $types->[$i];
289 0   0     0 push(@right_justify,
290             ($type == SQL_NUMERIC ||
291             $type == SQL_DECIMAL ||
292             $type == SQL_INTEGER ||
293             $type == SQL_SMALLINT ||
294             $type == SQL_FLOAT ||
295             $type == SQL_REAL ||
296             $type == SQL_TINYINT));
297             }
298 0         0 $self->{'widths'} = \@widths;
299 0         0 $self->{'right_justify'} = \@right_justify;
300             }
301              
302              
303             sub row {
304 0     0   0 my($self, $orig_row) = @_;
305 0         0 my $i = 0;
306 0         0 my $col;
307 0         0 my $widths = $self->{'widths'};
308 0         0 my @row = @$orig_row; # don't mess with the original row
309             map {
310 0 0       0 if (!defined($_)) {
  0         0  
311 0         0 $_ = ' (NULL) ';
312             } else {
313 0         0 $_ =~ s/\n/\\n/g;
314 0         0 $_ =~ s/\t/\\t/g;
315 0         0 $_ =~ s/[\000-\037\177-\237]/./g;
316             }
317 0 0       0 if (length($_) > $widths->[$i]) {
318 0         0 $widths->[$i] = length($_);
319             }
320 0         0 ++$i;
321             } @row;
322 0         0 push @{$self->{data}}, \@row;
  0         0  
323             }
324              
325              
326             sub trailer {
327 0     0   0 my $self = shift;
328 0         0 my $widths = delete $self->{'widths'};
329 0         0 my $right_justify = delete $self->{'right_justify'};
330 0         0 my $sth = $self->{'sth'};
331 0         0 my $data = $self->{'data'};
332 0         0 $self->{'rows'} = @$data;
333              
334 0         0 my $format_sep = '+';
335 0         0 my $format_names = '|';
336 0         0 my $format_rows = '|';
337 0         0 for (my $i = 0; $i < $sth->{'NUM_OF_FIELDS'}; $i++) {
338 0         0 $format_sep .= ('-' x $widths->[$i]) . '+';
339 0         0 $format_names .= sprintf("%%-%ds|", $widths->[$i]);
340 0 0       0 $format_rows .= sprintf("%%"
341             . ($right_justify->[$i] ? "" : "-") . "%ds|",
342             $widths->[$i]);
343             }
344 0         0 $format_sep .= "\n";
345 0         0 $format_names .= "\n";
346 0         0 $format_rows .= "\n";
347              
348 0         0 my $fh = $self->{'fh'};
349 0         0 print $fh ($format_sep);
350 0         0 print $fh (sprintf($format_names, @{$sth->{'NAME'}}));
  0         0  
351 0         0 print $fh ($format_sep);
352 0         0 foreach my $row (@$data) {
353             # print $fh ($format_sep);
354 0         0 print $fh (sprintf($format_rows, @$row));
355             }
356 0         0 print $fh ($format_sep);
357              
358 0         0 $self->SUPER::trailer(@_);
359             }
360              
361             package DBI::Format::Raw;
362              
363             @DBI::Format::Raw::ISA = qw(DBI::Format::Base);
364              
365             sub header {
366 1     1   5 my($self, $sth, $fh, $sep) = @_;
367 1         9 $self->{'fh'} = $fh = $self->setup_fh($fh);
368 1         15 $self->{'sth'} = $sth;
369 1         3 $self->{'rows'} = 0;
370 1 50       5 $self->{sep} = $sep if defined $sep;
371 1         4 print $fh (join($self->{sep}, @{$sth->{'NAME'}}), "\n");
  1         45  
372             }
373              
374             sub row {
375 10     10   19 my($self, $rowref) = @_;
376 10         37 local $^W = 0;
377 10         22 my @row = @$rowref;
378 10         20 my $fh = $self->{'fh'};
379 10         161 print $fh (join($self->{sep}, @row), "\n");
380 10         66 ++$self->{'rows'};
381             }
382              
383             package DBI::Format::String;
384              
385             @DBI::Format::String::ISA = qw(DBI::Format::Base);
386              
387             sub header {
388 1     1   4 my($self, $sth, $fh, $sep) = @_;
389 1         9 $self->{'fh'} = $fh = $self->setup_fh($fh);
390 1         14 $self->{'sth'} = $sth;
391 1         4 $self->{'data'} = [];
392 1 50       5 $self->{sep} = $sep if defined $sep;
393 1         5 my $types = $sth->{'TYPE'};
394 1         29 my @right_justify;
395             my @widths;
396 1         4 my $names = $sth->{'NAME'};
397 1         3 my $type;
398 1         8 for (my $i = 0; $i < $sth->{'NUM_OF_FIELDS'}; $i++) {
399 14         36 $type = $types->[$i];
400             push(@widths, $self->_determine_width(
401 14         65 $type, $sth->{PRECISION}->[$i] ));
402              
403 14   66     120 push(@right_justify,
404             (defined($type) and ($type == DBI::SQL_NUMERIC() ||
405             $type == DBI::SQL_DECIMAL() ||
406             $type == DBI::SQL_INTEGER() ||
407             $type == DBI::SQL_SMALLINT() ||
408             $type == DBI::SQL_FLOAT() ||
409             $type == DBI::SQL_REAL() ||
410             $type == DBI::SQL_TINYINT()))
411             );
412 14         18 my $format_names;
413 14         52 $format_names .= sprintf("%%-%ds ", $widths[$i]);
414 14         474 print $fh (sprintf($format_names, $names->[$i]));
415             }
416 1         5 $self->{'widths'} = \@widths;
417 1         3 $self->{'right_justify'} = \@right_justify;
418 1         13 print $fh "\n";
419              
420             }
421              
422              
423             sub row {
424 10     10   22 my($self, $orig_row) = @_;
425 10         16 my $i = 0;
426 10         13 my $col;
427 10         14 my $widths = $self->{'widths'};
428 10         14 my $right_justify = $self->{'right_justify'};
429 10         23 my @row = @$orig_row; # don't mess with the original row
430             map {
431 10 50       21 if (!defined($_)) {
  140         243  
432 0         0 $_ = ' (NULL) ';
433             } else {
434 140         221 $_ =~ s/\n/\\n/g;
435 140         167 $_ =~ s/\t/\\t/g;
436 140         185 $_ =~ s/[\000-\037\177-\237]/./g;
437             }
438 140         189 ++$i;
439             } @row;
440              
441 10         15 my $sth = $self->{'sth'};
442 10         16 my $data = $self->{'data'};
443 10         15 my $format_rows = ' ';
444 10         67 for (my $i = 0; $i < $sth->{'NUM_OF_FIELDS'}; $i++) {
445 140 100       835 $format_rows .= sprintf("%%"
446             . ($right_justify->[$i] ? "" : "-") . "%ds ",
447             $widths->[$i]);
448             }
449 10         22 $format_rows .= "\n";
450              
451 10         15 my $fh = $self->{'fh'};
452 10         358 print $fh (sprintf($format_rows, @row));
453 10         92 ++$self->{'rows'};
454             }
455              
456              
457             sub trailer {
458 1     1   4 my $self = shift;
459 1         3 my $widths = delete $self->{'widths'};
460 1         3 my $right_justify = delete $self->{'right_justify'};
461 1         9 $self->SUPER::trailer(@_);
462             }
463              
464             package DBI::Format::HTML;
465              
466             @DBI::Format::HTML::ISA = qw(DBI::Format::Base);
467              
468             sub header {
469 1     1   4 my($self, $sth, $fh) = @_;
470 1         9 $self->{'fh'} = $fh = $self->setup_fh($fh);
471 1         16 $self->{'sth'} = $sth;
472 1         4 $self->{'data'} = [];
473 1         5 my $types = $sth->{'TYPE'};
474 1         29 my @right_justify;
475             my @widths;
476 1         5 my $names = $sth->{'NAME'};
477 1         2 my $type;
478 1         8 for (my $i = 0; $i < $sth->{'NUM_OF_FIELDS'}; $i++) {
479 14 50       47 push(@widths, defined($names->[$i]) ? length($names->[$i]) : 0);
480 14         18 $type = $types->[$i];
481 14   66     154 push(@right_justify,
482             (defined $type and ($type == DBI::SQL_NUMERIC() ||
483             $type == DBI::SQL_DECIMAL() ||
484             $type == DBI::SQL_INTEGER() ||
485             $type == DBI::SQL_SMALLINT() ||
486             $type == DBI::SQL_FLOAT() ||
487             $type == DBI::SQL_REAL() ||
488             $type == DBI::SQL_TINYINT()))
489             );
490             }
491 1         4 $self->{'widths'} = \@widths;
492 1         5 $self->{'right_justify'} = \@right_justify;
493             }
494              
495              
496             sub row {
497 10     10   18 my($self, $orig_row) = @_;
498 10         18 my $i = 0;
499 10         12 my $col;
500 10         16 my $widths = $self->{'widths'};
501 10         26 my @row = @$orig_row; # don't mess with the original row
502             map {
503 10 50       26 if (!defined($_)) {
  140         206  
504 0         0 $_ = ' (NULL) ';
505             } else {
506 140         234 $_ =~ s/\n/\\n/g;
507 140         168 $_ =~ s/\t/\\t/g;
508 140         190 $_ =~ s/[\000-\037\177-\237]/./g;
509             }
510 140 100       233 if (length($_) > $widths->[$i]) {
511 12         16 $widths->[$i] = length($_);
512             }
513 140         212 ++$i;
514             } @row;
515 10         18 push @{$self->{data}}, \@row;
  10         32  
516             }
517              
518              
519             sub trailer {
520 1     1   3 my $self = shift;
521 1         4 my $widths = delete $self->{'widths'};
522 1         3 my $right_justify = delete $self->{'right_justify'};
523 1         2 my $sth = $self->{'sth'};
524 1         2 my $data = $self->{'data'};
525 1         3 $self->{'rows'} = @$data;
526              
527 1         3 my $format_sep = '+';
528 1         2 my $format_names = '
529 1         2 my $format_rows = '
530 1         20 for (my $i = 0; $i < $sth->{'NUM_OF_FIELDS'}; $i++) {
531 14         43 $format_names .= sprintf("%%-%ds
532 14 100       91 $format_rows .= sprintf("%%"
533             . ($right_justify->[$i] ? "" : "-") . "%ds
534             $widths->[$i]);
535             }
536 1         6 $format_sep .= "\n";
537 1         2 $format_names .= "
538 1         3 $format_rows .= "
539              
540 1         3 my $fh = $self->{'fh'};
541 1         36 print $fh("\n");
542 1         5 print $fh(sprintf($format_names, @{$sth->{'NAME'}}));
  1         24  
543 1         6 foreach my $row (@$data) {
544 10         112 print $fh (sprintf($format_rows, @$row));
545             }
546 1         9 print $fh ("
\n");
547              
548 1         10 $self->SUPER::trailer(@_);
549             }
550              
551              
552             1;
553              
554             =head1 NAME
555              
556             DBI::Format - A package for displaying result tables
557              
558             =head1 SYNOPSIS
559              
560             # create a new result object
561             $r = DBI::Format->new('var1' => 'val1', ...);
562              
563             # Prepare it for output by creating a header
564             $r->header($sth, $fh);
565              
566             # In a loop, display rows
567             while ($ref = $sth->fetchrow_arrayref()) {
568             $r->row($ref);
569             }
570              
571             # Finally create a trailer
572             $r->trailer();
573              
574              
575             =head1 DESCRIPTION
576              
577             THIS PACKAGE IS STILL VERY EXPERIMENTAL. THINGS WILL CHANGE.
578              
579             This package is used for making the output of DBI::Shell configurable.
580             The idea is to derive a subclass for any kind of output table you might
581             create. Examples are
582              
583             =over 8
584              
585             =item *
586              
587             a very simple output format as offered by DBI::neat_list().
588             L<"AVAILABLE SUBCLASSES">.
589              
590             =item *
591              
592             a box format, as offered by the Data::ShowTable module.
593              
594             =item *
595              
596             HTML format, as used in CGI binaries
597              
598             =item *
599              
600             postscript, to be piped into lpr or something similar
601              
602             =back
603              
604             In the future the package should also support interactive methods, for
605             example tab completion.
606              
607             These are the available methods:
608              
609             =over 8
610              
611             =item new(@attr)
612              
613             =item new(\%attr)
614              
615             (Class method) This is the constructor. You'd rather call a subclass
616             constructor. The construcor is accepting either a list of key/value
617             pairs or a hash ref.
618              
619             =item header($sth, $fh)
620              
621             (Instance method) This is called when a new result table should be
622             created to display the results of the statement handle B<$sth>. The
623             (optional) argument B<$fh> is an IO handle (or any object supporting
624             a I method), usually you use an IO::Wrap object for STDIN.
625              
626             The method will query the B<$sth> for its I, I,
627             I, I and I attributes and typically print a
628             header. In general you should not assume that B<$sth> is indeed a DBI
629             statement handle and better treat it as a hash ref with the above
630             attributes.
631              
632             =item row($ref)
633              
634             (Instance method) Prints the contents of the array ref B<$ref>. Usually
635             you obtain this array ref by calling B<$sth-Efetchrow_arrayref()>.
636              
637             =item trailer
638              
639             (Instance method) Once you have passed all result rows to the result
640             package, you should call the I method. This method can, for
641             example print the number of result rows.
642              
643             =back
644              
645              
646             =head1 AVAILABLE SUBCLASSES
647              
648             First of all, you can use the DBI::Format package itself: It's
649             not an abstract base class, but a very simple default using
650             DBI::neat_list().
651              
652              
653             =head2 Ascii boxes
654              
655             This subclass is using the I mode of the I module
656             internally. L.
657              
658             =head2 Raw
659              
660             Row is written without formating. Columns returned in comma or user defined
661             separated list.
662              
663             =head2 String
664              
665             Row is written using a string format. Future releases will include th ability
666             set the string format.
667              
668              
669             =head1 AUTHOR AND COPYRIGHT
670              
671             This module is Copyright (c) 1997, 1998
672              
673             Jochen Wiedmann
674             Am Eisteich 9
675             72555 Metzingen
676             Germany
677              
678             Email: joe@ispsoft.de
679             Phone: +49 7123 14887
680              
681             The DBD::Proxy module is free software; you can redistribute it and/or
682             modify it under the same terms as Perl itself.
683              
684              
685             =head1 SEE ALSO
686              
687             L, L, L