Mark said:
Run some benchmarks (eg Benchmark::Timer) and establish where your code
is spending most of its time. Decide whether your application is already
fast enough. You can waste an awful lot of time trying to get minor
speed-ups, time that could be spent on more productive tasks.
If your existing codebase is composed of clear, maintainable code then
you are already ahead of your game. Performance, especially in a small
Hmm, all is made as modules/packages. I have made even a Column in a table
as a package, that I tie to, also a record is a tied hash. The great thing
with tie'ing is flexibility. The same code applies naturally to all tables.
The hash package that I tie to a record checks for column types and column
names and use them as parameters with CGI. Then I can use the column
information as input types ( textarea, input, checkboxes and such) in the
gui part.
Here is the tied table record hash package:
<code>
package TransPool::Row;
use TransPool::Column;
use TransPool::ColumnTypes;
use DBI;
use TransPool:

ebug;
use strict;
my $DEBUG = TransPool:

ebug->new()->{DEBUG};
sub TIEHASH
{
#DB HANDLE, TABLE NAME
my $self = shift;
my $dbh = shift;
my $tname = shift;
my $idcol = shift;
my $cond = shift;
my $table =
{
DBH=>$dbh,
TABLENAME=>$tname,
IDCOL=>$idcol,
CONDITION=>$cond,
COLUMNS=>{},
ROWS=>undef,
};
my $rh;
my $qcond = $dbh->quote($cond);
my $sql_on_id_col = "SELECT $idcol FROM $tname WHERE $idcol = $qcond";
my $sth = $dbh->prepare($sql_on_id_col);
if ( !$sth->execute() )
{
print "error:$sql_on_id_col:$DBI::errstr";
return bless $table, $self;
}
if ( $sth->rows == 0 )
{
my $sql_insert = "INSERT INTO $tname ($idcol) VALUES($qcond)";
my $sth_insert = $dbh->prepare($sql_insert);
$sth_insert->execute() or print "insert failed:$sql_insert:$DBI::errstr";
return bless $table, $self;
}
return bless $table, $self;
}
sub FETCH
{
my $self = shift;
my $key = shift;
#( $dbh, $table, $column, $idcol, $id ) = @_;
tie
$self->{COLUMNS}{$key},
"Column",
$self->{DBH},
$self->{TABLENAME},
$key,
$self->{IDCOL},
$self->{CONDITION}
;
return $self->{COLUMNS}{$key};
}
sub STORE
{
my $self = shift;
my $key = shift;
my $value = shift;
tie
$self->{COLUMNS}{$key},
"Column",
$self->{DBH},
$self->{TABLENAME},
$key,
$self->{IDCOL},
$self->{CONDITION}
;
$self->{COLUMNS}{$key} = $value;
}
sub DELETE
{
my $self = shift;
return undef;
}
sub CLEAR
{
#deletes a record as identified by the condition
my $self = shift;
my $qval = $self->{DBH}->quote($self->{CONDITION});
my $sql = "DELETE FROM $self->{TABLENAME} WHERE $self->{IDCOL}=$qval";
my $sth = $self->{DBH}->prepare($sql);
if ( !$sth->execute() )
{
print "failed to delete record(s):$sql:$DBI::errstr\n";
}
}
sub EXISTS
{
my $self = shift;
my $key = shift;
return exists $self->{COLUMNS}{$key};
}
sub FIRSTKEY
{
my $self = shift;
return scalar each %{$self->{COLUMNS}{Field}};
}
sub NEXTKEY
{
my $self = shift;
return scalar each %{$self->{COLUMNS}{Field}};
}
sub DESTROY
{
my $self = shift;
return;
}
1;
</code>
For example, this is what I do:
here is a sample parameter value pair list from CGI:
<cgi>
TransporterUniqueId=1
TransporterName=Oola Bandoola
TransporterAddress=Adr1
TransporterAddress2=Adr2
TransporterTel=1234
TransporterFax=2345
[email protected]
TransporterSite=
www.ownsite.obi
TransporterCountry=1
</cgi>
so, when those parameters arrive on the server I can just do:
my %row;
tie %row, "TransPool::Row", ...parameters here....set unique id;
and then after getting the cgi object from mod_perl I can loop on cgi params
( to update only those present in the cgi object):
foreach my $p($cgi->param)
{
$row{p} = $cgi->param($p);
}
or to get only the specified set of params
my @ary;
foreach my $p($cgi->param)
{
push @ary, $row{p};
}
return @ary;
application, is one of the last things you should worry about.
Yes, I guess you are right there, I'll go for maintainability and
flexibility and drop speed issues for now.
Note: somebody else will be able to give your more details about the
efficiency of tie. I never use it in my own code, and must admit have
not even read the documentation for it in some time.
Mark
General comments, or in particular, on this approach are very much welcome,
Thank's
Thank's for your input, Mark.
Greger