groupstats.pl: Refactor query handling.

Don't misuse variables:
- Push other binding vars to (new) @Params instead of
  filling up @GroupList with things it wasn't meant for.
- Replace generic @QueryPart by @QueryGroupList and
  @QueryThreshold, then build $WhereClause from that.
- Don't use $OrderClause for setting level (more or
  less than x), use (new) $Level instead.

Signed-off-by: Thomas Hochstein <thh@inter.net>
This commit is contained in:
Thomas Hochstein 2010-10-31 21:34:04 +01:00
parent 59d0c5ef86
commit 6b95accbb4

View file

@ -84,38 +84,42 @@ my $DBHandle = InitDB(\%Conf,1);
### create report ### create report
# get list of newsgroups (-n) # get list of newsgroups (-n)
my ($QueryPart,@GroupList); my ($QueryGroupList,$QueryThreshold,@GroupList,@Params);
my $Newsgroups = $Options{'n'}; my $Newsgroups = $Options{'n'};
if ($Newsgroups) { if ($Newsgroups) {
# explode list of newsgroups for WHERE clause # explode list of newsgroups for WHERE clause
($QueryPart,@GroupList) = &SQLGroupList($Newsgroups); ($QueryGroupList,@GroupList) = &SQLGroupList($Newsgroups);
} else { } else {
# set to dummy value (always true) # set to dummy value (always true)
$QueryPart = 1; $QueryGroupList = 1;
}; };
# manage thresholds # manage thresholds
if (defined($Options{'t'})) { if (defined($Options{'t'})) {
if ($Options{'i'}) { if ($Options{'i'}) {
# -i: list groups below threshold # -i: list groups below threshold
$QueryPart .= ' AND postings < ?'; $QueryThreshold .= ' postings < ?';
} else { } else {
# default: list groups above threshold # default: list groups above threshold
$QueryPart .= ' AND postings > ?'; $QueryThreshold .= ' postings > ?';
}; };
# push threshold to GroupList to match number of binding vars for DBQuery->execute # push threshold to Params
push @GroupList,$Options{'t'}; push @Params,$Options{'t'};
} else {
# set to dummy value (always true)
$QueryThreshold = 1;
} }
# construct WHERE clause # construct WHERE clause
# $QueryPart is "list of newsgroup" (or 1), # $QueryGroupList is "list of newsgroup" (or 1),
# $QueryThreshold is threshold definition (or 1),
# &SQLHierarchies() takes care of the exclusion of hierarchy levels (.ALL) # &SQLHierarchies() takes care of the exclusion of hierarchy levels (.ALL)
# according to setting of -s # according to setting of -s
my $WhereClause = sprintf('month BETWEEN ? AND ? AND %s %s',$QueryPart,&SQLHierarchies($Options{'s'})); my $WhereClause = sprintf('month BETWEEN ? AND ? AND %s AND %s %s',$QueryGroupList,$QueryThreshold,&SQLHierarchies($Options{'s'}));
# get lenght of longest newsgroup delivered by query for formatting purposes # get lenght of longest newsgroup delivered by query for formatting purposes
# FIXME # FIXME
my $MaxLength = &GetMaxLenght($DBHandle,$Conf{'DBTableGrps'},'newsgroup',$WhereClause,$StartMonth,$EndMonth,@GroupList); my $MaxLength = &GetMaxLenght($DBHandle,$Conf{'DBTableGrps'},'newsgroup',$WhereClause,$StartMonth,$EndMonth,(@GroupList,@Params));
my ($OrderClause,$DBQuery); my ($OrderClause,$DBQuery);
# -b (best of / top list) defined? # -b (best of / top list) defined?
@ -138,29 +142,30 @@ if (!defined($Options{'b'}) and !defined($Options{'l'})) {
}; };
# set -b to 10 if < 1 (Top 10) # set -b to 10 if < 1 (Top 10)
$Options{'b'} = 10 if $Options{'b'} !~ /^\d*$/ or $Options{'b'} < 1; $Options{'b'} = 10 if $Options{'b'} !~ /^\d*$/ or $Options{'b'} < 1;
# push LIMIT to GroupList to match number of binding vars for DBQuery->execute # push LIMIT to Params
push @GroupList,$Options{'b'}; push @Params,$Options{'b'};
# prepare query: get sum of postings per group from groups table for given months and newsgroups with LIMIT # prepare query: get sum of postings per group from groups table for given months and newsgroups with LIMIT
$DBQuery = $DBHandle->prepare(sprintf("SELECT newsgroup,SUM(postings) AS postings FROM %s.%s WHERE %s GROUP BY newsgroup ORDER BY %s,newsgroup LIMIT ?",$Conf{'DBDatabase'},$Conf{'DBTableGrps'},$WhereClause,$OrderClause)); $DBQuery = $DBHandle->prepare(sprintf("SELECT newsgroup,SUM(postings) AS postings FROM %s.%s WHERE %s GROUP BY newsgroup ORDER BY %s,newsgroup LIMIT ?",$Conf{'DBDatabase'},$Conf{'DBTableGrps'},$WhereClause,$OrderClause));
} else { } else {
# -l must be set now, as all other cases have been taken care of # -l must be set now, as all other cases have been taken care of
# set sorting order (-i) # set sorting order (-i)
my ($Level);
if ($Options{'i'}) { if ($Options{'i'}) {
$OrderClause = '<'; $Level = '<';
} else { } else {
$OrderClause = '>'; $Level = '>';
}; };
# push level and $StartMonth,$EndMonth - again - to GroupList to match number of binding vars for DBQuery->execute # push level and $StartMonth,$EndMonth - again - to Params
# FIXME -- together with the query (see below) # FIXME -- together with the query (see below)
push @GroupList,$Options{'l'}; push @Params,$Options{'l'};
push @GroupList,$StartMonth,$EndMonth; push @Params,$StartMonth,$EndMonth;
# prepare query: get number of postings per group from groups table for given months and # prepare query: get number of postings per group from groups table for given months and
# FIXME -- this query is ... in dire need of impromevent # FIXME -- this query is ... in dire need of impromevent
$DBQuery = $DBHandle->prepare(sprintf("SELECT month,newsgroup,postings FROM %s.%s WHERE newsgroup IN (SELECT newsgroup FROM %s.%s WHERE %s GROUP BY newsgroup HAVING MAX(postings) %s ?) AND %s ORDER BY newsgroup,month",$Conf{'DBDatabase'},$Conf{'DBTableGrps'},$Conf{'DBDatabase'},$Conf{'DBTableGrps'},$WhereClause,$OrderClause,$WhereClause)); $DBQuery = $DBHandle->prepare(sprintf("SELECT month,newsgroup,postings FROM %s.%s WHERE newsgroup IN (SELECT newsgroup FROM %s.%s WHERE %s GROUP BY newsgroup HAVING MAX(postings) %s ?) AND %s ORDER BY newsgroup,month",$Conf{'DBDatabase'},$Conf{'DBTableGrps'},$Conf{'DBDatabase'},$Conf{'DBTableGrps'},$WhereClause,$Level,$WhereClause));
}; };
# execute query # execute query
$DBQuery->execute($StartMonth,$EndMonth,@GroupList) $DBQuery->execute($StartMonth,$EndMonth,@GroupList,@Params)
or die sprintf("$MySelf: E: Can't get groups data for %s to %s from %s.%s: %s\n",$StartMonth,$EndMonth,$Conf{'DBDatabase'},$Conf{'DBTableGrps'},$DBI::errstr); or die sprintf("$MySelf: E: Can't get groups data for %s to %s from %s.%s: %s\n",$StartMonth,$EndMonth,$Conf{'DBDatabase'},$Conf{'DBTableGrps'},$DBI::errstr);
# output results # output results