#!/usr/bin/perl # # $Id: db.pl,v 1.3 2004/01/29 07:57:04 jeffo Exp $ # # Source File: db.pl print "Content-Type: text/html\n\n"; # Get config use POSIX qw(iscntrl); use Data::Dumper; use logger; use dm; use toolbox; my $dbopts = { dbhost => $ENV{PGPORT} || `hostname`, dbport => $ENV{PGPORT} || 5432, dbname => $ENV{PGDATABASE} || 'template1', dbuser => $ENV{PGUSER} || 'tmdba', loadme => 1, cache => 1, }; chomp $dbopts->{dbhost}; my $dbversion; my $cgi = "/cgi-bin/db.pl"; my %ri_cache; sub numeric_type { my ($table, $attname) = @_; if ( $attname eq 'attnum' || $attname eq 'attnotnull' || $attname eq 'id' || $attname =~ /_id$/ ) { return 1; } return 0; } sub get_ri_info { my ($table, $column, $keyval, $opts) = @_; my $sql = qq{ SELECT t.tgargs FROM pg_trigger t, pg_class c WHERE c.relname= ? AND c.oid = t.tgrelid AND t.tgname like 'RI_ConstraintTrigger_%'; }; my $params; push( @$params, $table ); my $cachekey = $column.$keyval.$sql.join('',@$params).join('',$opts); my $data = ($ri_cache{$cachekey} ? $ri_cache{$cachekey} : dm::SelectData($sql, $params, $opts) ); $ri_cache{$cachekey} = $data; my $info = undef; foreach my $href ( @$data ) { ($nm,$thistable,$ftable,$x,$fkey,$fcol) = split('\0',$href->{tgargs}); if ( $thistable eq $table && $column eq $fkey ) { my $mkeyval = munge($keyval); $info->{fcol} = $fcol; $info->{ftable} = $ftable; return { %$info }; } } return undef; } sub get_pkey_cols { my ($table, $opts) = @_; $depth = (defined($depth) ? $depth : 1); my $sql = qq{ SELECT a.attname FROM pg_class c, pg_attribute a WHERE a.attnum > 0 AND a.attrelid = c.oid AND c.relname = ( SELECT pkidx.relname FROM pg_class c, pg_class pkidx, pg_index i WHERE c.relname = ? AND c.oid = i.indrelid AND i.indexrelid = pkidx.oid AND i.indisprimary AND i.indisunique ORDER BY pkidx.relname); }; my $params = [ $table ]; my $pkeycols = &dm::SelectData($sql, $params, $opts); return $pkeycols; } sub get_pkey_value { my ($table, $fkeycol, $fkeyval, $opts, $depth) = @_; $depth = (defined($depth) ? $depth : 1); my $sql = qq{ SELECT a.attname FROM pg_class c, pg_attribute a WHERE a.attnum > 0 AND a.attrelid = c.oid AND c.relname = ( SELECT pkidx.relname FROM pg_class c, pg_class pkidx, pg_index i WHERE c.relname = ? AND c.oid = i.indrelid AND i.indexrelid = pkidx.oid AND i.indisprimary AND i.indisunique ORDER BY pkidx.relname); }; my $params = [ $table ]; my $pkeycols = &dm::SelectData($sql, $params, $opts); my $pkeyval; my $info; my $selectclause; if ( ! $pkeycols ) { return ""; } foreach my $rec ( @$pkeycols ) { $selectclause .= ", " if length($selectclause); $selectclause .= $rec->{attname}; } $sql = qq{ SELECT $selectclause FROM $table WHERE $fkeycol = ?; }; $params = [ $fkeyval ]; $pkeyvals = &dm::SelectData($sql, $params, $opts); foreach my $rec ( @$pkeyvals ) { while ( my ($col, $val) = each %$rec ) { $info = get_ri_info( $table, $col, $val, $opts ); $pkeyval .= ", " if length($pkeyval); if ( $info ) { $pkeyval .= get_pkey_value($info->{ftable}, $info->{fcol}, $val, $opts, $depth + 1); } else { $pkeyval .= $val; } } } return $pkeyval; } sub tabledescription { my ($table, $opts) = @_; my $sql = qq{ select obj_description(c.oid) as "Table Description" from pg_class c where c.relname = '$table';}; return dm::SelectDataValue($sql,undef,$opts); } sub dataview { my ($opts) = @_; &logger::logdbg("Entering dataview..."); my $sortdir = ($opts->{sd} eq 'dn' ? 'up' : 'dn'); my $sortbyidx; my $offset = $opts->{off} ||= 0; my $limit = $opts->{rc} || 10; my $lastrec = $offset + $limit; my $nextoffset; my $extent = $limit; my $table = $opts->{t}; my $pkeycols = get_pkey_cols($table, $opts); my $sortby = $opts->{sb} || $pkeycols->[0]->{attname}; my $orderbyclause = $sortby; $orderbyclause .= ($orderbyclause ? ($sortdir eq 'up' ? ' ASC' : ' DESC'):""); for my $kcol ( @$pkeycols ) { $orderbyclause .= ', ' if ($orderbyclause); $orderbyclause .= "$kcol->{attname} ASC"; } # gather pre-existing filters... my $filters; my $filterhash; my $filternote; my $whereclause; my (@params, $col, $fop, $fopkey); while ( my($key,$val) = each %$opts ) { if ( $key =~ /^(_f)-(\S+)$/ ) { $col = $2; $fopkey = "${1}op-$col"; $fop = (defined($opts->{$fopkey}) ? $opts->{$fopkey} : '='); $filters .= "&" if length($filters); $filters .= "$key=$val"; $filters .= "&$fopkey=".munge($opts->{$fopkey}); $whereclause .= qq{ and } if ( length($whereclause) ); $whereclause .= qq{$col $fop ?}; push( @params, $val ); $filternote .= qq{ColumnOpValue\n} if ( ! length($filternote) ); $filternote .= qq{$col$fop$val\n}; $filterhash->{$col}{fop} = $fop; $filterhash->{$col}{val} = $val; } } $opts->{pk} = (defined($opts->{pk}) ? $opts->{pk} : 1); $opts->{sys} = (defined($opts->{sys}) ? $opts->{sys} : 0); $filters .= "&ff=$opts->{ff}"; $filters .= "&sys=$opts->{sys}"; my $desc = tabledescription($table,$opts); # Make sure these column headers don't have spaces for URI sorting... my $sql = qq{ select * from $table}; $sql .= qq{ where $whereclause} if ( length($whereclause) ); $sql .= qq{ order by $orderbyclause} if ( length($orderbyclause) ); $sql .= qq{ limit $limit offset $offset;}; logger::logdbg($sql); my $tmpopts = { %$opts }; $tmpopts->{want_array_refs} = 1; my $data = dm::SelectData($sql, \@params, $tmpopts); my $reccnt = scalar(@$data) - 1; &logger::logdbg("Got $reccnt rows from DB..."); $sortby ||= $data->[0][0]; my $totreccnt = dm::SelectDataValue("select count(id) from $table",undef,$opts); my ($html, $otherlabel, $labellink); $html .= qq{}; $html .= qq{}; $html .= qq{}; $html .= qq{}; $html .= breadcrumb_label($opts); $html .= qq{}; $html .= qq{}; $html .= breadcrumb($opts); $html .= qq{

Table: $table (Data)

}; $html .= qq{$filternote
Data Filters
\n} if ( length($filternote) ); $html .= ""; my $hdrrow; my (@hdrs, $i); foreach my $rowaref ( @$data ) { $hdrrow = ""; foreach my $hdr ( @$rowaref ) { my $thattrs = ($sortby eq $hdr ? qq{ bgcolor="#CCCCCC"} : ""); my $arrow = ($sortby eq $hdr ? ($sortdir eq 'up' ? ' ↓' : ' ↑') : ""); $arrow = qq{$arrow}; my $hdrlink = qq{$hdr$arrow}; $hdrrow .= qq{$hdrlink}; if ( $hdr eq $sortby ) { $sortbyidx = $i; } push(@hdrs, $hdr); $i++; } $hdrrow .= "\n"; last; } my $span = scalar(@hdrs); $html .= qq{}; $html .= qq{}; $html .= qq{} if ( length($filters) ); $html .= qq{\n}; $html .= $hdrrow; shift @$data; # discard headers my $sortf; if ( $sortby ) { if ( numeric_type($table, $sortby) ) { if ( $sortdir eq 'dn' ) { $sortf = sub { return $a->[$sortbyidx] <=> $b->[$sortbyidx]; }; } else { $sortf = sub { return $b->[$sortbyidx] <=> $a->[$sortbyidx]; }; } } else { if ( $sortdir eq 'dn' ) { $sortf = sub { return $a->[$sortbyidx] cmp $b->[$sortbyidx]; }; } else { $sortf = sub { return $b->[$sortbyidx] cmp $a->[$sortbyidx]; }; } } } else { $sortf = sub { return $a->[$sortbyidx] cmp $b->[$sortbyidx]; }; } $i = 0; my $fkeylink; foreach my $rowaref ( @$data ) { my $cellrow = ""; my $hi = 0; foreach my $cell ( @$rowaref ) { $fkeylink = undef; my $info = get_ri_info( $table, $hdrs[$hi], $cell, $opts ); my $mval = munge($cell); if ( $info && defined($cell) ) { if ( $opts->{pk} ) { my $pkeyval = get_pkey_value($info->{ftable}, $info->{fcol}, $cell, $opts); $cell = $pkeyval; } $fkeylink = qq{t=$info->{ftable}&_f-$info->{fcol}=$mval}; $fkeylink = qq{$cell}; } $cellrow .= qq{}; $hi++; } $cellrow .= "\n"; $html .= "$cellrow\n"; } my $navlink; $html .= "\n"; $html .= "
Description:  $desc
}; $html .= qq{View Schema...}; $html .= qq{Reset Filters...}; $html .= qq{Hide Primary Keys...}; } else { $html .= qq{&pk=1">Show Primary Keys...}; } $html .= qq{Hide Full Filters...}; } else { $html .= qq{&ff=1">Show Full Filters...}; } $opts->{fs} ||= 0; my $bfs = $opts->{fs} + 1; my $sfs = $opts->{fs} - 1; $opts->{fs} = ($opts->{fs} >= 0 ? "+".$opts->{fs} : $opts->{fs}); $bfs = ($bfs >= 0 ? "+".$bfs : $bfs); $sfs = ($sfs >= 0 ? "+".$sfs : $sfs); $html .= qq{Smaller Font...}; $html .= qq{Bigger Font...}; $html .= qq{
}; $cellrow .= qq{} if (defined($opts->{fs})); my ($filterlink, $op, $foplinks); if ( defined($fkeylink) ) { $cellrow .= qq{$fkeylink}; } else { if ( ! $opts->{ff} ) { $op = '='; $fop = ($op); $fopkey = "_fop-$hdrs[$hi]"; $filterlink = ""; $filterlink .= qq{$filters&} if $filters; $filterlink .= qq{_f-$hdrs[$hi]=$mval&$fopkey=}; $filterlink .= munge($fop); $cellrow .= qq{$cell}; } else { $cellrow .= qq{$cell}; } } $op = '<'; $fop = ($op); $fopkey = "_fop-$hdrs[$hi]"; $filterlink = ""; $filterlink .= qq{$filters&} if $filters; $filterlink .= qq{_f-$hdrs[$hi]=$mval&$fopkey=}; $filterlink .= munge($fop); $foplinks .= qq{}; $foplinks .= escape_special_chars($op); $foplinks .= qq{}; $foplinks .= qq{...}; $op = '<='; $fop = ($op); $fopkey = "_fop-$hdrs[$hi]"; $filterlink = ""; $filterlink .= qq{$filters&} if $filters; $filterlink .= qq{_f-$hdrs[$hi]=$mval&$fopkey=}; $filterlink .= munge($fop); $foplinks .= qq{}; $foplinks .= escape_special_chars($op); $foplinks .= qq{}; $foplinks .= qq{...}; $op = '='; $fop = ($op); $fopkey = "_fop-$hdrs[$hi]"; $filterlink = ""; $filterlink .= qq{$filters&} if $filters; $filterlink .= qq{_f-$hdrs[$hi]=$mval&$fopkey=}; $filterlink .= munge($fop); $foplinks .= qq{}; $foplinks .= escape_special_chars($op); $foplinks .= qq{}; $foplinks .= qq{...}; $op = '>='; $fop = ($op); $fopkey = "_fop-$hdrs[$hi]"; $filterlink = ""; $filterlink .= qq{$filters&} if $filters; $filterlink .= qq{_f-$hdrs[$hi]=$mval&$fopkey=}; $filterlink .= munge($fop); $foplinks .= qq{}; $foplinks .= escape_special_chars($op); $foplinks .= qq{}; $foplinks .= qq{...}; $op = '>'; $fop = ($op); $fopkey = "_fop-$hdrs[$hi]"; $filterlink = ""; $filterlink .= qq{$filters&} if $filters; $filterlink .= qq{_f-$hdrs[$hi]=$mval&$fopkey=}; $filterlink .= munge($fop); $foplinks .= qq{}; $foplinks .= escape_special_chars($op); $foplinks .= qq{}; if ( $opts->{ff} ) { $cellrow .= qq{   
(}; $cellrow .= $foplinks; $cellrow .= qq{)}; } $cellrow .= qq{
} if ( defined($opts->{fs}) ); $cellrow .= qq{
"; $html .= qq{($reccnt of $totreccnt from $table table) }; logger::logdbg("offset = $offset, reccnt = $reccnt, lastrec = $lastrec"); if ( $offset > 0 ) { $nextoffset = ($offset - $extent < 0 ? 0 : $offset - $extent); $navlink = qq{[Previous $extent...]}; $html .= "$navlink  "; $extent *= 2; $nextoffset = ($offset - $extent < 0 ? 0 : $offset - $extent); $navlink = qq{[Previous $extent...]}; $html .= "$navlink  "; } $extent = $limit; if ( $totreccnt > $lastrec ) { $nextoffset = $lastrec; $navlink = qq{[Next $extent...]}; $html .= "$navlink  "; $extent *= 2; $navlink = qq{[Next $extent...]}; $html .= "$navlink  "; } $html .= "
\n"; &logger::logdbg("Exiting schemaview..."); return $html; } sub schemaview { my ($opts) = @_; &logger::logdbg("Entering schemaview..."); my $table = $opts->{t}; my $desc = tabledescription($table,$opts); # Make sure these column headers don't have spaces for URI sorting... my $sql = qq{ SELECT a.attnum, a.attname, format_type(a.atttypid, a.atttypmod), a.attnotnull, a.atthasdef, ''||col_description(a.attrelid, a.attnum)||'' as "description" FROM pg_class c, pg_attribute a WHERE c.relname = '$table' AND a.attnum > 0 AND a.attrelid = c.oid ORDER BY a.attnum; }; my $tmpopts = { %$opts }; $tmpopts->{want_array_refs} = 1; my $data = dm::SelectData($sql, undef, $tmpopts); my ($html, $otherlabel, $labellink); $html = qq{}; $html .= qq{}; $html .= qq{}; $html .= qq{}; $html .= breadcrumb_label($opts); $html .= qq{}; $html .= qq{}; $html .= breadcrumb($opts); $html .= qq{

Table: $table (Schema)

}; $html .= ""; my $sortdir = ($opts->{sd} eq 'dn' ? 'up' : 'dn'); my $sortby = $opts->{sb} ||= $data->[0][0]; my $sortbyidx; my $hdrrow; my (@hdrs, $i); foreach my $rowaref ( @$data ) { $hdrrow = ""; foreach my $hdr ( @$rowaref ) { my $thattrs = ($sortby eq $hdr ? qq{ bgcolor="#CCCCCC"} : ""); my $arrow = ($sortby eq $hdr ? ($sortdir eq 'up' ? ' ↓' : ' ↑') : ""); $arrow = qq{$arrow}; my $hdrlink = qq{$hdr$arrow}; $hdrrow .= qq{$hdrlink}; if ( $hdr eq $sortby ) { $sortbyidx = $i; } push(@hdrs, $hdr); $i++; } $hdrrow .= "\n"; last; } my $span = scalar(@hdrs); $html .= qq{}; $html .= qq{}; $html .= qq{}; $html .= qq{\n}; $html .= $hdrrow; shift @$data; # discard headers my $sortf; if ( $sortby ) { if ( numeric_type($table, $sortby) ) { if ( $sortdir eq 'dn' ) { $sortf = sub { return $a->[$sortbyidx] <=> $b->[$sortbyidx]; }; } else { $sortf = sub { return $b->[$sortbyidx] <=> $a->[$sortbyidx]; }; } } else { if ( $sortdir eq 'dn' ) { $sortf = sub { return $a->[$sortbyidx] cmp $b->[$sortbyidx]; }; } else { $sortf = sub { return $b->[$sortbyidx] cmp $a->[$sortbyidx]; }; } } } else { $sortf = sub { return $a->[$sortbyidx] cmp $b->[$sortbyidx]; }; } &logger::logdbg("There are ".scalar(@$data)." rows."); foreach my $rowaref ( sort $sortf @$data ) { my $cellrow = ""; foreach my $cell ( @$rowaref ) { $cellrow .= qq{}; } $cellrow .= "\n"; $html .= $cellrow; } $html .= "
Description:  $desc
}; $html .= qq{View Data}; $html .= qq{
$cell
\n"; &logger::logdbg("Exiting schemaview..."); return $html; } sub tableview { my ($opts) = @_; if ( $opts->{v} eq 'schema' ) { return schemaview($opts); } else { return dataview($opts); } } sub dbviewhome { my ($opts) = @_; my $sql = qq{ select tablename as "Table" from pg_tables}; if ( ! $opts->{sys} ) { $sql .= qq{ where tablename not like 'pg_%'}; } $sql .= qq{ order by tablename}; $sql .= ';'; my $tmpopts = { %$opts }; $tmpopts->{want_array_refs} = 1; my $data = dm::SelectData($sql, undef, $tmpopts); my ($html, $otherlabel, $labellink); $html = qq{}; $html .= qq{}; $html .= qq{}; $html .= qq{}; $html .= breadcrumb_label($opts); $html .= qq{}; $html .= qq{}; $html .= breadcrumb($opts); $html .= ""; my $sortdir = ($opts->{sd} eq 'dn' ? 'up' : 'dn'); &logger::logdbg("sd = $opts->{sd} ===> sortdir = $sortdir"); my $sortby = $opts->{sb} || 'name'; my $tablehdr = qq{Table}; my $cnthdr = qq{Record Count}; my $tablehdrattrs = ($sortby eq 'name' ? qq{ bgcolor="#CCCCCC"} : ""); my $cnthdrattrs = ($sortby eq 'count' ? qq{ bgcolor="#CCCCCC"} : ""); $html .= "$tablehdr$cnthdr\n"; my $i = 0; my $table; my @recs; $opts->{sys} = (defined($opts->{sys}) ? $opts->{sys} : 0); foreach my $aref ( @$data ) { next if ($i++ == 0); my $v = shift @$aref; my $table = (defined($v) ? $v : ""); $sql = qq{select count(*) from $table;}; my $count = dm::SelectDataValue($sql, undef, $opts); push( @recs, { table => $table, count => $count } ); } my $sortf; if ( $sortby eq 'name' ) { if ( $sortdir eq 'dn' ) { $sortf = sub { return $a->{table} cmp $b->{table}; }; } else { $sortf = sub { return $b->{table} cmp $a->{table}; }; } } else { if ( $sortdir eq 'dn' ) { $sortf = sub { return $a->{count} <=> $b->{count}; }; } else { $sortf = sub { return $b->{count} <=> $a->{count}; }; } } foreach my $href ( sort $sortf @recs ) { my $row = ""; my $j = 0; my $table = $href->{table}; my $count = $href->{count}; my $desc = tabledescription($table,$opts); $row .= qq{}; $row .= qq{}; $row .= qq{}; $row .= "\n"; $html .= $row; } $html .= "
Description
$table$count$desc
\n"; return $html; } sub serverview { my ($opts) = @_; my $sql = qq{ select datname as "Database" from pg_database}; if ( ! $opts->{sys} ) { $sql .= qq{ where datname !~ 'template[01]'}; } $sql .= qq{ order by datname; }; my $tmpopts = { %$opts }; # $tmpopts->{want_array_refs} = 1; my $data = dm::SelectData($sql, undef, $tmpopts); my ($html, $otherlabel, $labellink); $html = breadcrumb($opts); $html .= qq{

$opts->{dbhost}:$opts->{dbport}

}; $html .= qq{Version:  $dbversion}; $html .= ""; my $sortdir = ($opts->{sd} eq 'dn' ? 'up' : 'dn'); my $sortby = $opts->{sb} || 'datname'; my $dbhdr = qq{Database}; my $dbhdrattrs = ($sortby eq 'datname' ? qq{ bgcolor="#CCCCCC"} : ""); $html .= "$dbhdr\n"; my $i = 0; my $table; my @recs; $opts->{sys} = (defined($opts->{sys}) ? $opts->{sys} : 0); my $sortf; if ( $sortdir eq 'dn' ) { $sortf = sub { return $a->{$sortby} cmp $b->{$sortby}; }; } else { $sortf = sub { return $b->{$sortby} cmp $a->{$sortby}; }; } print STDERR Dumper($data); foreach my $href ( sort $sortf @$data ) { my $row = ""; my $j = 0; my $db = $href->{Database}; $row .= qq{}; $row .= "\n"; $html .= $row; } $html .= "
$db
\n"; return $html; } sub dbview { my ($opts) = @_; if ( $opts->{t} ) { return tableview($opts); } else { return dbviewhome($opts); } } sub munge( $ ) { my ($string) = @_; $string =~ s/([\<\>\=\'\"\?\&\\!\$\#\@\*\;\:\r\n])/join('', '%', uc(unpack("H*",$1)))/eg; return $string; } sub unmunge( $ ) { my ($string) = @_; $string =~ s/%([<>=a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg; return $string; } my $escape_map = { '"' => '"', '&' => '&', '<' => '<', '>' => '>', '<=' => '≤', '=' => '=', '=>' => '≥', }; sub get_escape( $ ) { my ($char) = shift; if ( ! defined($escape_map->{$char}) ) { logger::logerr("WARNING: undefined escape for '$char'"); } return $escape_map->{$char}; } sub escape_special_chars( $ ) { my ($string) = @_; $string =~ s/([\"&<>=])/get_escape($1)/eg; return $string; } sub initialize { my ($FORM) = @_; if ( ! $FORM ) { &logger::logerr("Missing FORM hashref"); return undef; } my ($reqmeth,@cookies,$cookie,$nm,$vlu,$qstr); my ($contenttype,$srch,$trash,$boundary,$endboundary,$consep,@parts,); my ($contype,$content,%UI,%COOKIES,$part,@lines,$nme,$fname,$ftype,$line); my (@segs,$arraykey,%UPLOADED_FILES,@parameters,$pair); &logger::logdbg("Initializing..."); $FORM->{servertime} = POSIX::strftime($UI{DATETIME_FMT}, localtime(time)); # set variables from query parameters based on the request method $reqmeth = $ENV{'REQUEST_METHOD'}; @cookies = split(/\;/,$ENV{'HTTP_COOKIE'}); foreach $cookie (sort @cookies) { ($nm, $vlu) = split(/=/, $cookie); $nm =~ s/ //g; $vlu =~ tr/+/ /; $vlu = unmunge($vlu); $COOKIES{$nm} = $vlu; &logger::logdbg("\$COOKIES{$nm} = $COOKIES{$nm}"); } if ($reqmeth =~ /POST/i) { &logger::logdbg("Reading POST data..."); read (STDIN, $qstr, $ENV{'CONTENT_LENGTH'}); } else { if ($reqmeth =~ /GET/i) { &logger::logdbg("Reading GET data..."); $qstr=$ENV{'QUERY_STRING'}; } else { &logger::logdbg("Unrecognized request method: [$reqmeth]"); } } &logger::logdbg("qstr = $qstr"); if ($qstr) { $contenttype=$ENV{'CONTENT_TYPE'}; if ($contenttype =~ 'multipart/form-data') { $srch="boundary\="; ($trash,$boundary) = split(/$srch/, $contenttype); ($boundary, $trash) = split(/ /, $boundary); $endboundary = join('', $boundary, "\-\-"); $boundary = join('', $boundary, "\r\n"); ($qstr, $trash) = split(/$endboundary/, $qstr); @parts = split(/$boundary/, $qstr); $trash = shift @parts; $consep = "\r\n\r\n"; foreach $part (@parts) { ($contype, $content) = split(/$consep/, $part); if ($contype ne '') { $contype =~ s/\: /=/g; $contype =~ s/\r\n/; /g; @lines = split(/\; /, $contype); $nme = ""; $fname = ""; $ftype = ""; foreach $line (@lines) { $line =~ s/\"//g; ($nm,$vlu) = split(/=/, $line); $vlu =~ tr/+/ /; $vlu = unmunge($vlu); if ($nm eq 'filename') { @segs = split(/\./, $vlu); $ftype = $segs[$#segs]; } else { if ($nm eq 'name') { $nme = $vlu; } } } chop($content); chop($content); if ($ftype eq '') { if ($content =~ /\/ ) { $content =~ s/\//g; chop($content); chop($content); } else { $content =~ s/\r\n//g; } $content =~ tr/+/ /; $content = unmunge($content); if ($FORM->{$nme} eq '') { $FORM->{$nme} = $content; } else { $FORM->{$nme} = join(',', $FORM->{$nme}, $content); } } else { if ($ftype eq 'csv') { $content =~ s/\r//g; $content =~ s/\n\n/\n/g; } else { $content =~ s/(.*)\r\n/$1/; } $arraykey="$nme.$ftype"; $UPLOADED_FILES{$arraykey} = $content; } } } } else { # parse request parameters into variables @parameters = split(/&/, $qstr); foreach $pair (@parameters) { ($nm, $vlu) = split(/=/, $pair); $vlu =~ tr/+/ /; $vlu = unmunge($vlu); $FORM->{$nm} = $vlu; } } foreach my $key ( sort keys %$FORM ) { &logger::logdbg("\$FORM{$key} = '$FORM->{$key}'"); } return 1; } else { return 0; } } sub breadcrumb_label { my ($opts) = @_; my ($breadcrumb, $label); if ( $opts->{dbhost} ) { $label .= qq{$opts->{dbhost}}; } if ( $opts->{dbport} ) { $label .= ":$opts->{dbport}"; } $breadcrumb .= qq{$label}; if ( $opts->{dbname} ) { $label = ":$opts->{dbname}"; } else { return $breadcrumb; } if ( $opts->{t} ) { $label .= ":$opts->{t}"; } else { return $breadcrumb; } if ( $opts->{v} ) { $label .= " ($opts->{v})"; } $breadcrumb .= qq{$label}; return $breadcrumb; } sub breadcrumb { my ($opts) = @_; my ($hiddenargs, $fmtbegin, $fmtend); my ($breadcrumb, $args, $label, $fs); $fs = (defined($opts->{fs}) ? ($opts->{fs} - 1) : -1); $fs = "+$fs" if ( $fs >= 0 ); $fmtbegin = qq{}; $fmtend = qq{}; $separator = qq{...}; my @hiddenargs = qw( fs ff pk ); foreach my $harg ( @hiddenargs ) { if ( $opts->{$harg} ) { $hiddenargs .= qq{&} if length($hiddenargs); $hiddenargs .= qq{$harg=$opts->{$harg}}; } } if ( $opts->{dbhost} ) { $args .= qq{dbhost=$opts->{dbhost}}; $label .= qq{$opts->{dbhost}}; } if ( $opts->{dbport} ) { $args .= qq{&} if length($args); $args .= qq{dbport=$opts->{dbport}}; $label .= ":$opts->{dbport}"; } $breadcrumb .= qq{$fmtbegin$label$fmtend}; if ( $opts->{dbname} ) { $args = qq{&} if length($args); $args .= qq{dbname=$opts->{dbname}}; $label = "$opts->{dbname}"; } else { return $breadcrumb; } $breadcrumb .= qq{$separator$fmtbegin$label$fmtend}; if ( $opts->{t} ) { $args .= qq{&} if length($args); $args .= qq{t=$opts->{t}}; $label = "$opts->{t}"; } else { return $breadcrumb; } if ( $opts->{v} ) { $args .= qq{&} if length($args); $args .= qq{v=$opts->{v}}; $label .= " ($opts->{v})"; } $breadcrumb .= qq{$separator$fmtbegin$label$fmtend}; return $breadcrumb; } sub go { my %FORM; initialize(\%FORM); foreach my $key ( keys %FORM ) { $dbopts->{$key} = $FORM{$key}; } $dbversion = dm::SelectDataValue("select version();", undef, $dbopts); my $html; my $t0 = toolbox::NowAsScalar(); if ( defined($dbopts->{dbname}) && $dbopts->{dbname} !~ /^template[01]$/ ) { $html = &dbview($dbopts); } else { $html = &serverview($dbopts); } $html .= qq{
}; my $tf = toolbox::NowAsScalar(); my $size = length($html); $html .= sprintf("Generated %.1f KB in %.3f secs finishing %s
\n", ($size/1000), $tf - $t0, scalar(localtime(time))); $t0 = toolbox::NowAsScalar(); print $html; $tf = toolbox::NowAsScalar(); $html = sprintf("Transmitted %.1f KB in %.3f secs finishing %s\n", ($size/1000), $tf - $t0, scalar(localtime(time))); $html .= qq{}; $html .= qq{}; print $html; } &go(); 1;