# displaytable(TABLENAME, CONFIG...):
#
# stolen from sqltohtml in the ucd-snmp package
#
package NetSNMP::manager::displaytable;
use POSIX (isprint);
BEGIN {
use Exporter ();
use vars qw(@ISA @EXPORT_OK $tableparms $headerparms);
@ISA = qw(Exporter);
@EXPORT=qw(&displaytable &displaygraph);
require DBI;
require CGI;
use GD::Graph();
use GD::Graph::lines();
use GD::Graph::bars();
use GD::Graph::points();
use GD::Graph::linespoints();
use GD::Graph::area();
use GD::Graph::pie();
};
$tableparms="border=1 bgcolor=\"#c0c0e0\"";
$headerparms="border=1 bgcolor=\"#b0e0b0\"";
sub displaygraph {
my $dbh = shift;
my $tablename = shift;
my %config = @_;
my $type = $config{'-type'} || "lines";
my $x = $config{'-x'} || "640";
my $y = $config{'-y'} || "480";
my $bgcolor = $config{'-bgcolor'} || "white";
my $datecol = $config{'-xcol'} || "updated";
my $xtickevery = $config{'-xtickevery'} || 50;
my ($thetable);
# print STDERR join(",",@_),"\n";
return -1 if (!defined($dbh) || !defined($tablename) ||
!defined ($config{'-columns'}) ||
ref($config{'-columns'}) ne "ARRAY" ||
!defined ($config{'-indexes'}) ||
ref($config{'-indexes'}) ne "ARRAY");
my $cmd = "SELECT " .
join(",",@{$config{'-columns'}},
@{$config{'-indexes'}}, $datecol) .
" FROM $tablename $config{'-clauses'}";
( $thetable = $dbh->prepare($cmd))
or return -1;
( $thetable->execute )
or return -1;
my %data;
my $count = 0;
while( $row = $thetable->fetchrow_hashref() ) {
# XXX: multiple indexe columns -> unique name
# save all the row's data based on the index column(s)
foreach my $j (@{$config{'-columns'}}) {
if ($config{'-difference'} || $config{'-rate'}) {
if (defined($lastval{$row->{$config{'-indexes'}[0]}}{$j}{'value'})) {
$data{$row->{$config{'-indexes'}[0]}}{$row->{$datecol}}{$j}=
$row->{$j} -
$lastval{$row->{$config{'-indexes'}[0]}}{$j}{'value'};
#
# convert to a rate if desired.
#
if ($config{'-rate'}) {
if (($row->{$datecol} - $lastval{$row->{$config{'-indexes'}[0]}}{$j}{'index'})) {
$data{$row->{$config{'-indexes'}[0]}}{$row->{$datecol}}{$j} = $data{$row->{$config{'-indexes'}[0]}}{$row->{$datecol}}{$j}*$config{'-rate'}/($row->{$datecol} - $lastval{$row->{$config{'-indexes'}[0]}}{$j}{'index'});
} else {
$data{$row->{$config{'-indexes'}[0]}}{$row->{$datecol}}{$j} = -1;
}
}
}
$lastval{$row->{$config{'-indexes'}[0]}}{$j}{'value'} = $row->{$j};
$lastval{$row->{$config{'-indexes'}[0]}}{$j}{'index'} = $row->{$datecol};
} else {
$data{$row->{$config{'-indexes'}[0]}}{$row->{$datecol}}{$j} = $row->{$j};
}
#
# limit the data to a vertical range.
#
if (defined($config{'-max'}) &&
$data{$row->{$config{'-indexes'}[0]}}{$row->{$datecol}}{$j} >
$config{'-max'}) {
# set to max value
$data{$row->{$config{'-indexes'}[0]}}{$row->{$datecol}}{$j} =
$config{'-max'};
}
if (defined($config{'-min'}) &&
$data{$row->{$config{'-indexes'}[0]}}{$row->{$datecol}}{$j} <
$config{'-min'}) {
# set to min value
$data{$row->{$config{'-indexes'}[0]}}{$row->{$datecol}}{$j} =
$config{'-min'};
}
}
push @xdata,$row->{$datecol};
}
my @pngdata;
if (defined($config{'-createdata'})) {
&{$config{'-createdata'}}(\@pngdata, \@xdata, \%data);
} else {
push @pngdata, \@xdata;
my @datakeys = keys(%data);
# open(O,">/tmp/data");
foreach my $i (@datakeys) {
foreach my $j (@{$config{'-columns'}}) {
my @newrow;
foreach my $k (@xdata) {
# print O "i=$i k=$k j=$j :: $data{$i}{$k}{$j}\n";
push @newrow, ($data{$i}{$k}{$j} || 0);
}
push @pngdata,\@newrow;
}
}
}
# close O;
if ($#pngdata > 0) {
# create the graph itself
my $graph = new GD::Graph::lines($x, $y);
$graph->set('bgclr' => $bgcolor);
# print STDERR "columns: ", join(",",@{$config{'-columns'}}), "\n";
if (defined($config{'-legend'})) {
# print STDERR "legend: ", join(",",@{$config{'-legend'}}), "\n";
$graph->set_legend(@{$config{'-legend'}});
} else {
my @legend;
foreach my $xxx (@{$config{'-columns'}}) {
push @legend, "$xxx = $config{'-indexes'}[0]";
}
$graph->set_legend(@legend);
}
foreach my $i (qw(title x_label_skip x_labels_vertical x_tick_number x_number_format y_number_format x_min_value x_max_value y_min_value y_max_value)) {
# print STDERR "setting $i from -$i = " . $config{"-$i"} . "\n";
$graph->set("$i" => $config{"-$i"}) if ($config{"-$i"});
}
if ($config{'-pngparms'}) {
$graph->set(@{$config{'-pngparms'}});
}
print $graph->plot(\@pngdata);
return $#{$pngdata[0]};
}
return -1;
}
sub displaytable {
my $dbh = shift;
my $tablename = shift;
my %config = @_;
my $clauses = $config{'-clauses'};
my $dolink = $config{'-dolink'};
my $datalink = $config{'-datalink'};
my $beginhook = $config{'-beginhook'};
my $modifiedhook = $config{'-modifiedhook'};
my $endhook = $config{'-endhook'};
my $selectwhat = $config{'-select'};
# my $printonly = $config{'-printonly'};
$selectwhat = "*" if (!defined($selectwhat));
my $tableparms = $config{'-tableparms'} || $displaytable::tableparms;
my $headerparms = $config{'-headerparms'} || $displaytable::headerparms;
my ($thetable, $data, $ref, $prefs, $xlattable);
if ($config{'-dontdisplaycol'}) {
($prefs = $dbh->prepare($config{'-dontdisplaycol'}) )
or die "\nnot ok: $DBI::errstr\n";
}
# get a list of data from the table we want to display
( $thetable = $dbh->prepare("SELECT $selectwhat FROM $tablename $clauses"))
or return -1;
( $thetable->execute )
or return -1;
# get a list of data from the table we want to display
if ($config{'-xlat'}) {
( $xlattable =
$dbh->prepare("SELECT newname FROM $config{'-xlat'} where oldname = ?"))
or die "\nnot ok: $DBI::errstr\n";
}
# editable/markable setup
my $edited = 0;
my $editable = 0;
my $markable = 0;
my (@indexkeys, @valuekeys, $uph, %indexhash, $q);
if (defined($config{'-editable'})) {
$editable = 1;
}
if (defined($config{'-mark'}) || defined($config{'-onmarked'})) {
$markable = 1;
}
if (defined($config{'-CGI'}) && ref($config{'-CGI'}) eq "CGI") {
$q = $config{'-CGI'};
}
if (($editable || $markable)) {
if (ref($config{'-indexes'}) eq ARRAY && defined($q)) {
@indexkeys = @{$config{'-indexes'}};
foreach my $kk (@indexkeys) {
$indexhash{$kk} = 1;
}
} else {
$editable = $markable = 0;
print STDERR "displaytable error: no -indexes option specified or -CGI not specified\n";
}
}
if (($editable || $markable) &&
$q->param('edited_' . toalpha($tablename))) {
$edited = 1;
}
# table header
my $doheader = 1;
my @keys;
my $rowcount = 0;
$thetable->execute();
if ($editable || $markable) {
print "\n";
}
while( $data = $thetable->fetchrow_hashref() ) {
$rowcount++;
if ($edited && $editable && !defined($uph)) {
foreach my $kk (keys(%$data)) {
push (@valuekeys, maybe_from_hex($kk)) if (!defined($indexhash{$kk}));
}
my $cmd = "update $tablename set " .
join(" = ?, ",@valuekeys) .
" = ? where " .
join(" = ? and ",@indexkeys) .
" = ?";
$uph = $dbh->prepare($cmd);
# print STDERR "setting up: $cmd
\n";
}
if ($doheader) {
if ($config{'-selectorder'} &&
ref($config{'-selectorder'}) eq "ARRAY") {
@keys = @{$config{'-selectorder'}};
} elsif ($config{'-selectorder'}) {
$_ = $selectwhat;
@keys = split(/, */);
} else {
@keys = (sort keys(%$data));
}
if (defined($config{'-title'})) {
print "
$config{'-title'}\n";
} elsif (!defined($config{'-notitle'})) {
print "
";
print "" if (defined($dolink) &&
defined($ref = &$dolink($tablename)));
if ($config{'-xlat'}) {
my $toval = $xlattable->execute($tablename);
if ($toval > 0) {
print $xlattable->fetchrow_array;
} else {
print "$tablename";
}
} else {
print "$tablename";
}
print "" if (defined($ref));
print "\n";
}
print "
\n";
print "
Mark | \n"; } foreach $l (@keys) { if (!defined($prefs) || $prefs->execute($tablename, $l) eq "0E0") { print ""; print "" if (defined($dolink) && defined($ref = &$dolink($l))); if ($config{'-xlat'}) { my $toval = $xlattable->execute($l); if ($toval > 0) { print $xlattable->fetchrow_array; } else { print "$l"; } } else { print "$l"; } print "" if (defined($ref)); print " | "; } } } if (defined($endhook)) { &$endhook($dbh, $tablename); } if (!$config{'-noheaders'}) { print "
---|---|
param($ukey) eq "Y") ? " checked" : "") . "> | \n"; if ($q->param($ukey) eq "Y" && $config{'-onmarked'}) { &{$config{'-onmarked'}}($dbh, $tablename, $data); } } foreach $key (@keys) { if (!defined($prefs) || $prefs->execute($tablename, $key) eq "0E0") { print ""; print "" if (defined($datalink) && defined($ref = &$datalink($key, $data->{$key}))); if ($editable && !defined($indexhash{$key})) { my $ukey = to_unique_key($key, $data, @indexkeys); my $sz; if ($config{'-sizehash'}) { $sz = "size=" . $config{'-sizehash'}{$key}; } if (!$sz && $config{'-inputsize'}) { $sz = "size=" . $config{'-inputsize'}; } print STDERR "size $key: $sz from $config{'-sizehash'}{$key} / $config{'-inputsize'}\n"; print "{$key}) . "\" $sz>"; } else { if ($config{'-printer'}) { &{$config{'-printer'}}($key, $data->{$key}, $data); } elsif ($data->{$key} ne "") { print $data->{$key}; } else { print " "; } } print "" if (defined($ref)); print " | "; } } if (defined($endhook)) { &$endhook($dbh, $tablename, $data); } print "