-
Notifications
You must be signed in to change notification settings - Fork 17
Code cleanup Perl
Mark Overmeer edited this page Mar 18, 2019
·
2 revisions
For good examples of coding, see pm/Taranis/Constituent/*.pm (since release 3.7.0) and scripts/mod_tools/phishing_checker/phishing_overview.pl (since release 3.6.0). Please study that code.
Do check the pattern of parameters very early in any each sub which receives form fields, using val_int and val_text
Only a few modules have been rewritten: have a look at the constituent handling and phishing checker for examples how code should look.
Module Taranis::DB is to replace Taranis::Database everywhere: it is so much simpler hence safer to use. Do not forget to read the docs on the glorious module DBIx::Simple.
Summarizing the changes which should be applied to existing code:
- From new() remove the creation of a
dbhattribute. - Remove any access to
$self->{dbh} - Remove explicit use of the
Sqlwrapper for theuse SQL::Abstract::Moremodule. - Replace call to
DatabaseintoDatabase->simple - For records, use new
add/get/deleteRecord() - For images, use new
add/get/deleteBlob() - Replace structures like
my $stmnt = "some query";
Database->prepare( $stmnt );
Database->executeWithBinds( @binds );
my $record = Database->fetchRow();my $record = Database->simple->query("some query", @binds)->hash;- Replace structures like
my ( $stmnt, @bind ) = $self->{sql}->select( $table, $select, \%where );
$self->{dbh}->prepare( $stmnt );
$self->{dbh}->executeWithBinds( @bind );
while ( $self->nextObject() ) { #XXX sometimes $self->{dbh}->nextObject
push ( @records, $self->getObject() );
}my @records = Database->simple->select($table, $select, \%where)->hashes;- The 'pm/' modules contain a lot of database error checking which can be removed. In ancient history, the 'RaiseError' flag on the database got set, which made all attempts to gracefully handle errors useless. But the related code did not get cleaned-up Example:
my ( $stmnt, @bind ) = $self->{sql}->delete( $table, $where );
$self->prepare( $stmnt );
my $result = $self->executeWithBinds( @bind )
if ( defined($result) && ( $result !~ m/(0E0)/i ) ) {
if ( $result > 0 ) {
return 1;
} elsif ( defined( $self->{db_error_msg} ) ) {
return 0;
}
} else {
$self->{db_error_msg} = "Delete failed, corresponding id not found in database.";
return 0;
}my ( $stmnt, @bind ) = $self->{sql}->delete( $table, $where );
$self->prepare( $stmnt );
my $result = $self->executeWithBinds( @bind )
return 1;Database->simple->delete($table, $where);
return 1;- Replace constructs like
$log_error_enabled = ( Config->{'syslog'} =~ /^on$/i ) ? 1 : 0;$log_error_enabled = Config->isEnabled('syslog');- Do not use the same reference more than once: use helper variables.
- Inline variables which are only used once, unless that adds complication to readibility.
- Switch 'use warnings;' on, per module: may produce many warnings.
- Replace "
my (%kvArgs) = @_" by "my %kvArgs = @_", because%kvArgsalready enforces LIST context. Yes,kvArgsis a stupid name. - Replace "
($condition) ? 1 : 0" by "$condition || 0". The parenthesis around the condition are superfluous. When setting-up template variables or database fields, you need an explicit '0' instead of 'undef' which is the default for false. - Replace
sub saveDossierDetails {
my ( %kvArgs) = @_;
my ( $dossierID );
if ( $kvArgs{id} =~ /^\d+$/) {
$dossierID = $kvArgs{id};sub saveDossierDetails(%) {
my %kvArgs = @_;
my $dossierID = val_int $kvArgs{id};
if($dossierID) {- Remove useless use of indirection:
my ($vars, $tpl);
my $tt = Taranis::Template->new();
if($id) {
$vars->{something} = 42;
} else {
$vars->{message} = "No permission";
}
my $html = $tt->processTemplate( $tpl, $vars, 1);my (%vars, $tpl);
if($id) {
$vars{something} = 42;
} else {
$vars{message} = "No permission";
}
my $tt = Taranis::Template->new;
my $html = $tt->processTemplate($tpl, \%vars, 1);images/taranis-logo-medium.png ©NCSC-NL, License: EUPL-1.2