From c48c345eb62acb75a46db84f5d6ab53d164d01ef Mon Sep 17 00:00:00 2001 From: "lpsolit%gmail.com" <> Date: Tue, 23 Aug 2005 19:17:16 +0000 Subject: Bug 303366: Possible locking tables conflict when voting for bugs - Patch by Frédéric Buclin r=wurblzap a=justdave MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Bugzilla/Bug.pm | 9 --------- editproducts.cgi | 28 ++++++++++++++++++++-------- votes.cgi | 37 +++++++++++++++++++++++++------------ 3 files changed, 45 insertions(+), 29 deletions(-) diff --git a/Bugzilla/Bug.pm b/Bugzilla/Bug.pm index ec1927355..c287d0c0c 100755 --- a/Bugzilla/Bug.pm +++ b/Bugzilla/Bug.pm @@ -1128,15 +1128,6 @@ sub CheckIfVotedConfirmed { "*** This bug has been confirmed by popular vote. ***", 0, $timestamp); - my $template = Bugzilla->template; - my $vars = $::vars; - - $vars->{'type'} = "votes"; - $vars->{'id'} = $id; - $vars->{'mailrecipients'} = { 'changer' => $who }; - - $template->process("bug/process/results.html.tmpl", $vars) - || ThrowTemplateError($template->error()); $ret = 1; } return $ret; diff --git a/editproducts.cgi b/editproducts.cgi index d6d909360..59ff7bdec 100755 --- a/editproducts.cgi +++ b/editproducts.cgi @@ -1369,16 +1369,28 @@ if ($action eq 'update') { } } # 3. enough votes to confirm - SendSQL("SELECT bug_id FROM bugs " . - "WHERE product_id = $product_id " . - " AND bug_status = 'UNCONFIRMED' " . - " AND votes >= $votestoconfirm"); - if (MoreSQLData()) { + my $bug_list = $dbh->selectcol_arrayref("SELECT bug_id FROM bugs + WHERE product_id = ? + AND bug_status = 'UNCONFIRMED' + AND votes >= ?", + undef, ($product_id, $votestoconfirm)); + if (scalar(@$bug_list)) { print "
Checking unconfirmed bugs in this product for any which now have sufficient votes."; } - while (MoreSQLData()) { - # The user id below is used for activity log purposes - CheckIfVotedConfirmed(FetchOneColumn(), Bugzilla->user->id); + my @updated_bugs = (); + foreach my $bug_id (@$bug_list) { + my $confirmed = CheckIfVotedConfirmed($bug_id, $whoid); + push (@updated_bugs, $bug_id) if $confirmed; + } + + $vars->{'type'} = "votes"; + $vars->{'mailrecipients'} = { 'changer' => $whoid }; + $vars->{'header_done'} = 1; + + foreach my $bug_id (@updated_bugs) { + $vars->{'id'} = $bug_id; + $template->process("bug/process/results.html.tmpl", $vars) + || ThrowTemplateError($template->error()); } } diff --git a/votes.cgi b/votes.cgi index 8d7e7cf63..13f1ec7e2 100755 --- a/votes.cgi +++ b/votes.cgi @@ -319,13 +319,8 @@ sub record_votes { # need to clear the user's votes from the database. my %affected; $dbh->bz_lock_tables('bugs WRITE', 'bugs_activity WRITE', - 'votes WRITE', 'longdescs WRITE', 'profiles READ', - 'products READ', 'components READ', 'cc READ', - 'dependencies READ', 'groups READ', 'fielddefs READ', - 'namedqueries READ', 'whine_queries READ', 'watch READ', - 'profiles AS watchers READ', 'profiles AS watched READ', - 'user_group_map READ', 'bug_group_map READ', - 'email_setting READ'); + 'votes WRITE', 'longdescs WRITE', + 'products READ', 'fielddefs READ'); # Take note of, and delete the user's old votes from the database. SendSQL("SELECT bug_id FROM votes WHERE who = $who"); @@ -347,15 +342,33 @@ sub record_votes { # Update the cached values in the bugs table print $cgi->header(); + my @updated_bugs = (); + + my $sth_getVotes = $dbh->prepare("SELECT SUM(vote_count) FROM votes + WHERE bug_id = ?"); + + my $sth_updateVotes = $dbh->prepare("UPDATE bugs SET votes = ? + WHERE bug_id = ?"); + foreach my $id (keys %affected) { - SendSQL("SELECT sum(vote_count) FROM votes WHERE bug_id = $id"); - my $v = FetchOneColumn() || 0; - SendSQL("UPDATE bugs SET votes = $v WHERE bug_id = $id"); + $sth_getVotes->execute($id); + my $v = $sth_getVotes->fetchrow_array || 0; + $sth_updateVotes->execute($v, $id); + my $confirmed = CheckIfVotedConfirmed($id, $who); - $vars->{'header_done'} = 1 if $confirmed; + push (@updated_bugs, $id) if $confirmed; } - $dbh->bz_unlock_tables(); + $vars->{'type'} = "votes"; + $vars->{'mailrecipients'} = { 'changer' => $who }; + + foreach my $bug_id (@updated_bugs) { + $vars->{'id'} = $bug_id; + $template->process("bug/process/results.html.tmpl", $vars) + || ThrowTemplateError($template->error()); + # Set header_done to 1 only after the first bug. + $vars->{'header_done'} = 1; + } $vars->{'votes_recorded'} = 1; } -- cgit v1.2.3-24-g4f1b