/usr/local/CPAN/Sash/Sash/Table.pm
package Sash::Table;
use strict;
use warnings;
# Nice adapter and decorator pattern implementations here.
use Text::ASCIITable;
use base qw( Data::Table );
use Carp;
sub new {
my $class = shift;
my $data = shift;
my $header = shift;
my $attributes = shift || $header;
# The zero as the last attribute indicates we want row based table and not
# a column based one.
my $self = $class->SUPER::new( $data, $header, 0 );
bless $self, 'Sash::Table';
$self->attributes( $attributes );
return $self;
}
sub attributes {
my $self = shift;
$self->{attributes} = ( shift || $self->{attributes} );
}
sub clone {
my $self = shift;
# This is one way to do it without introspecting on the parent
# and knowing anything about it's implementation details.
my $data = $self->rowRefs;
my $clone = $self->SUPER::new( $data, $self->{header}, 0 );
$clone->attributes( $self->attributes );
return $clone;
}
sub sort {
my $self = shift;
# Override the default behavior of doing an in place manipulation
# on the data to be consistent with the other table operations in
# the api.
my $clone = $self->clone;
# If you think $self is correct here than you really do not understand
# deep recursion in perl
my $sorted = $clone->SUPER::sort( @_ );
croak 'Unable to sort data' unless $sorted;
return $clone;
}
sub match_string {
my $self = shift;
# Pay attention and be crafty here in that we want Sash::Table not Data::Table.
my $result = $self->SUPER::match_string( @_ );
return bless $result, ( ref $self || $self );
}
sub display {
my $self = shift;
my $elapsed = shift;
my $table = Text::ASCIITable->new;
$table->setCols( $self->header );
# This represents the total number of rows in the result set.
my $row_count = scalar( @{$self->rowRefs} );
# This is the total number of attributes that make up a single
# row in the result set.
my $attribute_count = scalar( @{$self->attributes} );
# We keep track of "vertical" rows because if you don't take
# into account attributes then the row count is off.
my $row_counter = 1;
my $vertical_row_counter = 1;
if ( Sash::Properties->output eq Sash::Properties->vertical ) {
# accounted
$row_count = $row_count / scalar( @{$self->attributes} );
# Puts a pretty border around the row data.
$table->addRow( 'row', $vertical_row_counter );
$table->addRowLine;
}
foreach ( @{$self->rowRefs} ) {
# Must have
$table->addRow( @$_ );
# Make the vertical output correct and with its row counter
# line visible in a pretty border
if (
( $row_counter++ % $attribute_count == 0 ) &&
( $row_counter/$attribute_count <= $row_count ) &&
( Sash::Properties->output eq Sash::Properties->vertical )
) {
$vertical_row_counter++;
$table->addRowLine;
$table->addRow( 'row', $vertical_row_counter );
$table->addRowLine;
}
}
# Table layout to emulate mysql
print $table->draw(
['+','+','-','+'],
['|','|','|'],
['+','+','-','+'],
['|','|','|'],
['+','+','-','+'],
) . "\n";
my $message = $row_count . ' rows in set ';
$message .= $elapsed if $elapsed;
print "$message\n";
return;
}
1;