BigBadDave
Programmer
I need help in optimising the following script:
There must be better ways of looping the data and matching criteria.
Regards
David Byng
davidbyng@hotmail.com
Code:
use strict;
use 5;
use CGI qw(:standard);
use POSIX qw(strftime mktime);
use DBI;
my $from = main::param ("from");
my $to = main::param ("to");
my @from = split (/\//, $from);
$from = $from[2] . "-" . $from[1] . "-" . $from[0];
my @to = split (/\//, $to);
$to = $to[2] . "-" . $to[1] . "-" . $to[0];
my $vh = "";
my @vh = main::param ("vh");
foreach my $tmp (@vh) {
$vh .= "`virtual host` = '$tmp' AND";
}
$vh = "" if ($vh =~ m/all/i);
my $data = "";
my @dates = (0);
my @urls = (0);
my @times = (0);
my @entry = (0);
my @exit = (0);
my @comps = (0);
my @compsd = (0);
my $dbh = DBI->connect ("DBI:mysql:host=******;db=webstats;", "***", "", {PrintError => 0, RaiseError => 0});
$dbh->do ("CREATE TEMPORARY TABLE `tmp` SELECT `date`, `host name`, `url`, `time` FROM `access_log` WHERE $vh`date` >= '$from' AND `date` <= '$to' ORDER BY `date`, `host name`, `time`");
my $sth = $dbh->prepare ("SELECT DATE_FORMAT(`date`, '%y-%c-%e'), `url`, `time` FROM `tmp` ORDER BY `date`, `host name`, `time`");
$sth->execute ();
while (my @val = $sth->fetchrow_array ()) {
$dates[$#dates+1] = $val[0];
$urls[$#urls+1] = $val[1];
$times[$#times+1] = $val[2];
}
$sth->finish ();
$dbh->disconnect ();
my $i = 0;
foreach my $tmp (@urls) {
my @str = split (/:/, $times[$i]);
my @str4 = split (/-/, $dates[$i]);
my @str2 = split (/:/, $comps[$#comps]);
my @str3 = split (/-/, $compsd[$#compsd]);
my $tmpm = (localtime (mktime ($str[2],$str[1],$str[0],$str4[2],$str4[1],88) - mktime ($str2[2],$str2[1],$str2[0],$str3[2],$str3[1],88)))[1];
my $tmph = (localtime (mktime ($str[2],$str[1],$str[0],$str4[2],$str4[1],88) - mktime ($str2[2],$str2[1],$str2[0],$str3[2],$str3[1],88)))[2];
my $tmpd = (localtime (mktime ($str[2],$str[1],$str[0],$str4[2],$str4[1],88) - mktime ($str2[2],$str2[1],$str2[0],$str3[2],$str3[1],88)))[3];
my $tmpt = (localtime (mktime ($str[2],$str[1],$str[0],$str4[2],$str4[1],88) - mktime ($str2[2],$str2[1],$str2[0],$str3[2],$str3[1],88)))[4];
if ($tmpt > 1 || $tmpd > 1 || $tmph > 1 || $tmpm > 20) {
$entry[$#entry+1] = $tmp;
$exit[$#exit+1] = $urls[$i-1] if ($urls[$i-1]);
}
$comps[$#comps+1] = $times[$i];
$compsd[$#compsd+1] = $dates[$i];
$i++;
}
my $dbh = DBI->connect ("DBI:mysql:host=******;db=webstats;", "***", "", {PrintError => 0, RaiseError => 0});
$dbh->do ("CREATE TEMPORARY TABLE `entry` (`url` VARCHAR(255))");
$dbh->do ("CREATE TEMPORARY TABLE `exit` (`url` VARCHAR(255))");
$i = 0;
foreach my $tmp (@entry) {
next if (!$tmp);
$dbh->do ("INSERT INTO `entry` VALUES ('$tmp')");
$dbh->do ("INSERT INTO `exit` VALUES ('" . $urls[$i-1] . "')");
$i++;
}
print"Top 10 Entry URLS <table><tr><td>URL</td><td>Number</td></tr>";
my $sth = $dbh->prepare ("SELECT `url`, COUNT(`url`) AS `num` FROM `entry` GROUP BY `url` ORDER BY `num` DESC LIMIT 0, 10");
$sth->execute ();
while (my @val = $sth->fetchrow_array ()) {
print "<tr><td>$val[0]</td><td>$val[1]</td></tr>\n";
}
$sth->finish ();
print "</table><br />\n\n";
print"Top 10 Exit URLS <table><tr><td>URL</td><td>Number</td></tr>";
my $sth = $dbh->prepare ("SELECT `url`, COUNT(`url`) AS `num` FROM `exit` GROUP BY `url` ORDER BY `num` DESC LIMIT 0, 10");
$sth->execute ();
while (my @val = $sth->fetchrow_array ()) {
print "<tr><td>$val[0]</td><td>$val[1]</td></tr>\n";
}
$sth->finish ();
$dbh->disconnect ();
print "</table>";
There must be better ways of looping the data and matching criteria.
Regards
David Byng
davidbyng@hotmail.com