From d3f8bf365e5b93f58497a25e07fde7ce30884f9d Mon Sep 17 00:00:00 2001 From: "mkanat%kerio.com" <> Date: Fri, 18 Feb 2005 05:57:26 +0000 Subject: Bug 280503: Replace "LOCK/UNLOCK TABLES" with Bugzilla::DB function call Patch By Tomas Kopal r=mkanat,a=myk --- Bugzilla/Constants.pm | 6 +++++ Bugzilla/DB.pm | 4 +-- Bugzilla/Error.pm | 3 ++- Bugzilla/Series.pm | 4 +-- Bugzilla/Token.pm | 22 +++++++++++------ Bugzilla/User.pm | 9 +++---- attachment.cgi | 21 ++++++++-------- buglist.cgi | 4 +-- checksetup.pl | 8 +++--- editclassifications.cgi | 12 ++++----- editcomponents.cgi | 32 ++++++++++++------------ editflagtypes.cgi | 48 +++++++++++++++++++++--------------- editgroups.cgi | 16 ++++++------ editmilestones.cgi | 26 ++++++++++---------- editproducts.cgi | 65 ++++++++++++++++++++++++++----------------------- editversions.cgi | 25 ++++++++++--------- process_bug.cgi | 27 ++++++++++---------- query.cgi | 6 ++--- sanitycheck.cgi | 14 ++++++----- token.cgi | 21 ++++++++++------ userprefs.cgi | 7 +++--- votes.cgi | 31 ++++++++++++----------- whine.pl | 13 +++++----- 23 files changed, 232 insertions(+), 192 deletions(-) diff --git a/Bugzilla/Constants.pm b/Bugzilla/Constants.pm index 3ef3cc634..a3e16251c 100644 --- a/Bugzilla/Constants.pm +++ b/Bugzilla/Constants.pm @@ -66,6 +66,8 @@ use base qw(Exporter); DEFAULT_QUERY_NAME COMMENT_COLS + + UNLOCK_ABORT ); @Bugzilla::Constants::EXPORT_OK = qw(contenttypes); @@ -217,4 +219,8 @@ use constant DEFAULT_QUERY_NAME => '(Default query)'; # The column length for displayed (and wrapped) bug comments. use constant COMMENT_COLS => 80; +# used by Bugzilla::DB to indicate that tables are being unlocked +# because of error +use constant UNLOCK_ABORT => 1; + 1; diff --git a/Bugzilla/DB.pm b/Bugzilla/DB.pm index 3e3f45c66..d1ecfcb2e 100644 --- a/Bugzilla/DB.pm +++ b/Bugzilla/DB.pm @@ -501,8 +501,8 @@ formatted SQL command have prefix C. All other methods have prefix C. set even without locking tables first without raising an error to simplify error handling. Abstract method, should be overriden by database specific code. - Params: $abort = true (1) if the operation on locked tables failed - (if transactions are supported, the action will be rolled + Params: $abort = UNLOCK_ABORT (true, 1) if the operation on locked tables + failed (if transactions are supported, the action will be rolled back). False (0) or no param if the operation succeeded. Returns: none diff --git a/Bugzilla/Error.pm b/Bugzilla/Error.pm index 96017f368..e86b1c41a 100644 --- a/Bugzilla/Error.pm +++ b/Bugzilla/Error.pm @@ -27,6 +27,7 @@ use base qw(Exporter); @Bugzilla::Error::EXPORT = qw(ThrowCodeError ThrowTemplateError ThrowUserError); use Bugzilla::Config; +use Bugzilla::Constants; use Bugzilla::Util; use Date::Format; @@ -37,7 +38,7 @@ sub _throw_error { $vars->{error} = $error; - Bugzilla->dbh->do("UNLOCK TABLES") if $unlock_tables; + Bugzilla->dbh->bz_unlock_tables(UNLOCK_ABORT) if $unlock_tables; # If a writable data/errorlog exists, log error details there. if (-w "data/errorlog") { diff --git a/Bugzilla/Series.pm b/Bugzilla/Series.pm index a4bd6654f..53e6fbabf 100644 --- a/Bugzilla/Series.pm +++ b/Bugzilla/Series.pm @@ -170,7 +170,7 @@ sub writeToDatabase { my $self = shift; my $dbh = Bugzilla->dbh; - $dbh->do("LOCK TABLES series_categories WRITE, series WRITE"); + $dbh->bz_lock_tables('series_categories WRITE', 'series WRITE'); my $category_id = getCategoryID($self->{'category'}); my $subcategory_id = getCategoryID($self->{'subcategory'}); @@ -210,7 +210,7 @@ sub writeToDatabase { || &::ThrowCodeError("missing_series_id", { 'series' => $self }); } - $dbh->do("UNLOCK TABLES"); + $dbh->bz_unlock_tables(); } # Check whether a series with this name, category and subcategory exists in diff --git a/Bugzilla/Token.pm b/Bugzilla/Token.pm index 90efe99bd..9caf91ab2 100644 --- a/Bugzilla/Token.pm +++ b/Bugzilla/Token.pm @@ -52,13 +52,14 @@ my $maxtokenage = 3; sub IssueEmailChangeToken { my ($userid, $old_email, $new_email) = @_; + my $dbh = Bugzilla->dbh; my $token_ts = time(); my $issuedate = time2str("%Y-%m-%d %H:%M", $token_ts); # Generate a unique token and insert it into the tokens table. # We have to lock the tokens table before generating the token, # since the database must be queried for token uniqueness. - &::SendSQL("LOCK TABLES tokens WRITE"); + $dbh->bz_lock_tables('tokens WRITE'); my $token = GenerateUniqueToken(); my $quotedtoken = &::SqlQuote($token); my $quoted_emails = &::SqlQuote($old_email . ":" . $new_email); @@ -72,7 +73,7 @@ sub IssueEmailChangeToken { tokentype , eventdata ) VALUES ( $userid , '$issuedate' , $quotedtoken , 'emailnew' , $quoted_emails )"); - &::SendSQL("UNLOCK TABLES"); + $dbh->bz_unlock_tables(); # Mail the user the token along with instructions for using it. @@ -110,6 +111,8 @@ sub IssuePasswordToken { my ($loginname) = @_; + my $dbh = Bugzilla->dbh; + # Retrieve the user's ID from the database. my $quotedloginname = &::SqlQuote($loginname); &::SendSQL("SELECT profiles.userid, tokens.issuedate FROM profiles @@ -129,13 +132,13 @@ sub IssuePasswordToken { # Generate a unique token and insert it into the tokens table. # We have to lock the tokens table before generating the token, # since the database must be queried for token uniqueness. - &::SendSQL("LOCK TABLES tokens WRITE"); + $dbh->bz_lock_tables('tokens WRITE'); my $token = GenerateUniqueToken(); my $quotedtoken = &::SqlQuote($token); my $quotedipaddr = &::SqlQuote($::ENV{'REMOTE_ADDR'}); &::SendSQL("INSERT INTO tokens ( userid , issuedate , token , tokentype , eventdata ) VALUES ( $userid , NOW() , $quotedtoken , 'password' , $quotedipaddr )"); - &::SendSQL("UNLOCK TABLES"); + $dbh->bz_unlock_tables(); # Mail the user the token along with instructions for using it. @@ -158,10 +161,11 @@ sub IssuePasswordToken { sub CleanTokenTable { - &::SendSQL("LOCK TABLES tokens WRITE"); + my $dbh = Bugzilla->dbh; + $dbh->bz_lock_tables('tokens WRITE'); &::SendSQL("DELETE FROM tokens WHERE TO_DAYS(NOW()) - TO_DAYS(issuedate) >= " . $maxtokenage); - &::SendSQL("UNLOCK TABLES"); + $dbh->bz_unlock_tables(); } @@ -198,6 +202,8 @@ sub Cancel { my ($token, $cancelaction) = @_; + my $dbh = Bugzilla->dbh; + # Quote the token for inclusion in SQL statements. my $quotedtoken = &::SqlQuote($token); @@ -232,9 +238,9 @@ sub Cancel { Bugzilla::BugMail::MessageToMTA($message); # Delete the token from the database. - &::SendSQL("LOCK TABLES tokens WRITE"); + $dbh->bz_lock_tables('tokens WRITE'); &::SendSQL("DELETE FROM tokens WHERE token = $quotedtoken"); - &::SendSQL("UNLOCK TABLES"); + $dbh->bz_unlock_tables(); } sub DeletePasswordTokens { diff --git a/Bugzilla/User.pm b/Bugzilla/User.pm index 8f5f6a762..67b79f168 100644 --- a/Bugzilla/User.pm +++ b/Bugzilla/User.pm @@ -384,10 +384,9 @@ sub derive_groups { my $sth; - $dbh->do(q{LOCK TABLES profiles WRITE, - user_group_map WRITE, - group_group_map READ, - groups READ}) unless $already_locked; + $dbh->bz_lock_tables('profiles WRITE', 'user_group_map WRITE', + 'group_group_map READ', + 'groups READ') unless $already_locked; # avoid races, we are only up to date as of the BEGINNING of this process my $time = $dbh->selectrow_array("SELECT NOW()"); @@ -459,7 +458,7 @@ sub derive_groups { undef, $time, $id); - $dbh->do("UNLOCK TABLES") unless $already_locked; + $dbh->bz_unlock_tables() unless $already_locked; } sub can_bless { diff --git a/attachment.cgi b/attachment.cgi index d58395efc..5e10d8fee 100755 --- a/attachment.cgi +++ b/attachment.cgi @@ -1051,15 +1051,16 @@ sub edit sub update { # Updates an attachment record. + my $dbh = Bugzilla->dbh; # Get the bug ID for the bug to which this attachment is attached. SendSQL("SELECT bug_id FROM attachments WHERE attach_id = $::FORM{'id'}"); my $bugid = FetchSQLData(); - + # Lock database tables in preparation for updating the attachment. - SendSQL("LOCK TABLES attachments WRITE , flags WRITE , " . - "flagtypes READ , fielddefs READ , bugs_activity WRITE, " . - "flaginclusions AS i READ, flagexclusions AS e READ, " . + $dbh->bz_lock_tables('attachments WRITE', 'flags WRITE' , + 'flagtypes READ', 'fielddefs READ', 'bugs_activity WRITE', + 'flaginclusions AS i READ', 'flagexclusions AS e READ', # cc, bug_group_map, user_group_map, and groups are in here so we # can check the permissions of flag requestees and email addresses # on the flag type cc: lists via the CanSeeBug @@ -1067,10 +1068,10 @@ sub update # Bugzilla::User needs to rederive groups. profiles and # user_group_map would be READ locks instead of WRITE locks if it # weren't for derive_groups, which needs to write to those tables. - "bugs READ, profiles WRITE, " . - "cc READ, bug_group_map READ, user_group_map WRITE, " . - "group_group_map READ, groups READ"); - + 'bugs READ', 'profiles WRITE', + 'cc READ', 'bug_group_map READ', 'user_group_map WRITE', + 'group_group_map READ', 'groups READ'); + # Get a copy of the attachment record before we make changes # so we can record those changes in the activity table. SendSQL("SELECT description, mimetype, filename, ispatch, isobsolete, isprivate @@ -1138,9 +1139,9 @@ sub update # Update flags. my $target = Bugzilla::Flag::GetTarget(undef, $::FORM{'id'}); Bugzilla::Flag::process($target, $timestamp, \%::FORM); - + # Unlock all database tables now that we are finished updating the database. - SendSQL("UNLOCK TABLES"); + $dbh->bz_unlock_tables(); # If the user submitted a comment while editing the attachment, # add the comment to the bug. diff --git a/buglist.cgi b/buglist.cgi index f6869b349..891926d4e 100755 --- a/buglist.cgi +++ b/buglist.cgi @@ -250,7 +250,7 @@ sub InsertNamedQuery ($$$;$) { # it when we display it to the user. trick_taint($query); - $dbh->do("LOCK TABLES namedqueries WRITE"); + $dbh->bz_lock_tables('namedqueries WRITE'); my $result = $dbh->selectrow_array("SELECT userid FROM namedqueries" . " WHERE userid = ? AND name = ?" @@ -269,7 +269,7 @@ sub InsertNamedQuery ($$$;$) { , undef, ($userid, $query_name, $query, $link_in_footer)); } - $dbh->do("UNLOCK TABLES"); + $dbh->bz_unlock_tables(); return $query_existed_before; } diff --git a/checksetup.pl b/checksetup.pl index c99beb3a5..79095ee3a 100755 --- a/checksetup.pl +++ b/checksetup.pl @@ -2722,7 +2722,7 @@ if (GetFieldDef('bugs', 'long_desc')) { print "bugs to process; a line of dots will be printed for each 50.\n\n"; $| = 1; - $dbh->do("LOCK TABLES bugs write, longdescs write, profiles write"); + $dbh->bz_lock_tables('bugs write', 'longdescs write', 'profiles write'); $dbh->do('DELETE FROM longdescs'); @@ -2823,7 +2823,7 @@ if (GetFieldDef('bugs', 'long_desc')) { DropField('bugs', 'long_desc'); - $dbh->do("UNLOCK TABLES"); + $dbh->bz_unlock_tables(); } @@ -2836,7 +2836,7 @@ if (GetFieldDef('bugs_activity', 'field')) { 'mediumint not null, ADD INDEX (fieldid)'); print "Populating new fieldid field ...\n"; - $dbh->do("LOCK TABLES bugs_activity WRITE, fielddefs WRITE"); + $dbh->bz_lock_tables('bugs_activity WRITE', 'fielddefs WRITE'); my $sth = $dbh->prepare('SELECT DISTINCT field FROM bugs_activity'); $sth->execute(); @@ -2856,7 +2856,7 @@ if (GetFieldDef('bugs_activity', 'field')) { } $dbh->do("UPDATE bugs_activity SET fieldid = $id WHERE field = $q"); } - $dbh->do("UNLOCK TABLES"); + $dbh->bz_unlock_tables(); DropField('bugs_activity', 'field'); } diff --git a/editclassifications.cgi b/editclassifications.cgi index 777e76f75..fd02befef 100755 --- a/editclassifications.cgi +++ b/editclassifications.cgi @@ -205,7 +205,7 @@ if ($action eq 'delete') { } # lock the tables before we start to change everything: - $dbh->do("LOCK TABLES classifications WRITE, products WRITE"); + $dbh->bz_lock_tables('classifications WRITE', 'products WRITE'); # delete $sth = $dbh->prepare("DELETE FROM classifications WHERE id=?"); @@ -217,7 +217,7 @@ if ($action eq 'delete') { WHERE classification_id=?"); $sth->execute($classification_id); - $dbh->do("UNLOCK TABLES"); + $dbh->bz_unlock_tables(); unlink "data/versioncache"; @@ -283,7 +283,7 @@ if ($action eq 'update') { # above so it will remain static even after we rename the # classification in the database. - $dbh->do("LOCK TABLES classifications WRITE"); + $dbh->bz_lock_tables('classifications WRITE'); if ($description ne $descriptionold) { $sth = $dbh->prepare("UPDATE classifications @@ -295,12 +295,12 @@ if ($action eq 'update') { if ($classification ne $classificationold) { unless ($classification) { - $dbh->do("UNLOCK TABLES"); + $dbh->bz_unlock_tables(UNLOCK_ABORT); ThrowUserError("classification_not_specified") } if (TestClassification($classification)) { - $dbh->do("UNLOCK TABLES"); + $dbh->bz_unlock_tables(UNLOCK_ABORT); ThrowUserError("classification_already_exists", { name => $classification }); } $sth = $dbh->prepare("UPDATE classifications @@ -308,7 +308,7 @@ if ($action eq 'update') { $sth->execute($classification,$classification_id); $vars->{'updated_classification'} = 1; } - $dbh->do("UNLOCK TABLES"); + $dbh->bz_unlock_tables(); unlink "data/versioncache"; LoadTemplate($action); diff --git a/editcomponents.cgi b/editcomponents.cgi index f1d20fbd5..08cfab14c 100755 --- a/editcomponents.cgi +++ b/editcomponents.cgi @@ -39,6 +39,7 @@ use Bugzilla::Util; use vars qw($template $vars); my $cgi = Bugzilla->cgi; +my $dbh = Bugzilla->dbh; my $showbugcounts = (defined $cgi->param('showbugcounts')); @@ -445,13 +446,13 @@ if ($action eq 'delete') { # lock the tables before we start to change everything: - SendSQL("LOCK TABLES attachments WRITE, - bugs WRITE, - bugs_activity WRITE, - components WRITE, - dependencies WRITE, - flaginclusions WRITE, - flagexclusions WRITE"); + $dbh->bz_lock_tables('attachments WRITE', + 'bugs WRITE', + 'bugs_activity WRITE', + 'components WRITE', + 'dependencies WRITE', + 'flaginclusions WRITE', + 'flagexclusions WRITE'); # According to MySQL doc I cannot do a DELETE x.* FROM x JOIN Y, # so I have to iterate over bugs and delete all the indivial entries @@ -491,7 +492,7 @@ if ($action eq 'delete') { SendSQL("DELETE FROM components WHERE id=$component_id"); - SendSQL("UNLOCK TABLES"); + $dbh->bz_unlock_tables(); unlink "$datadir/versioncache"; @@ -575,14 +576,15 @@ if ($action eq 'update') { # Note that the order of this tests is important. If you change # them, be sure to test for WHERE='$component' or WHERE='$componentold' - SendSQL("LOCK TABLES components WRITE, products READ, profiles READ"); + $dbh->bz_lock_tables('components WRITE', 'products READ', + 'profiles READ'); CheckComponent($product, $componentold); my $component_id = get_component_id(get_product_id($product), $componentold); if ($description ne $descriptionold) { unless ($description) { - SendSQL("UNLOCK TABLES"); + $dbh->bz_unlock_tables(UNLOCK_ABORT); ThrowUserError('component_blank_description', {'name' => $componentold}); exit; @@ -600,7 +602,7 @@ if ($action eq 'update') { my $initialownerid = DBname_to_id($initialowner); unless ($initialownerid) { - SendSQL("UNLOCK TABLES"); + $dbh->bz_unlock_tables(UNLOCK_ABORT); ThrowUserError('component_need_valid_initialowner', {'name' => $componentold}); exit; @@ -618,7 +620,7 @@ if ($action eq 'update') { if (Param('useqacontact') && $initialqacontact ne $initialqacontactold) { my $initialqacontactid = DBname_to_id($initialqacontact); if (!$initialqacontactid && $initialqacontact ne '') { - SendSQL("UNLOCK TABLES"); + $dbh->bz_unlock_tables(UNLOCK_ABORT); ThrowUserError('component_need_valid_initialqacontact', {'name' => $componentold}); exit; @@ -635,13 +637,13 @@ if ($action eq 'update') { if ($component ne $componentold) { unless ($component) { - SendSQL("UNLOCK TABLES"); + $dbh->bz_unlock_tables(UNLOCK_ABORT); ThrowUserError('component_must_have_a_name', {'name' => $componentold}); exit; } if (TestComponent($product, $component)) { - SendSQL("UNLOCK TABLES"); + $dbh->bz_unlock_tables(UNLOCK_ABORT); ThrowUserError('component_already_exists', {'name' => $component}); exit; @@ -655,7 +657,7 @@ if ($action eq 'update') { } - SendSQL("UNLOCK TABLES"); + $dbh->bz_unlock_tables(); $vars->{'name'} = $component; $vars->{'product'} = $product; diff --git a/editflagtypes.cgi b/editflagtypes.cgi index 48074863a..c28fda4ba 100755 --- a/editflagtypes.cgi +++ b/editflagtypes.cgi @@ -220,15 +220,18 @@ sub insert { validateIsRequesteeble(); validateAllowMultiple(); validateGroups(); - + + my $dbh = Bugzilla->dbh; + my $name = SqlQuote($::FORM{'name'}); my $description = SqlQuote($::FORM{'description'}); my $cc_list = SqlQuote($::FORM{'cc_list'}); my $target_type = $::FORM{'target_type'} eq "bug" ? "b" : "a"; - - SendSQL("LOCK TABLES flagtypes WRITE, products READ, components READ, " . - "flaginclusions WRITE, flagexclusions WRITE"); - + + $dbh->bz_lock_tables('flagtypes WRITE', 'products READ', + 'components READ', 'flaginclusions WRITE', + 'flagexclusions WRITE'); + # Determine the new flag type's unique identifier. SendSQL("SELECT MAX(id) FROM flagtypes"); my $id = FetchSQLData() + 1; @@ -255,8 +258,8 @@ sub insert { "component_id) VALUES ($id, $product_id, $component_id)"); } } - - SendSQL("UNLOCK TABLES"); + + $dbh->bz_unlock_tables(); $vars->{'name'} = $::FORM{'name'}; $vars->{'message'} = "flag_type_created"; @@ -282,13 +285,16 @@ sub update { validateIsRequesteeble(); validateAllowMultiple(); validateGroups(); - + + my $dbh = Bugzilla->dbh; + my $name = SqlQuote($::FORM{'name'}); my $description = SqlQuote($::FORM{'description'}); my $cc_list = SqlQuote($::FORM{'cc_list'}); - - SendSQL("LOCK TABLES flagtypes WRITE, products READ, components READ, " . - "flaginclusions WRITE, flagexclusions WRITE"); + + $dbh->bz_lock_tables('flagtypes WRITE', 'products READ', + 'components READ', 'flaginclusions WRITE', + 'flagexclusions WRITE'); SendSQL("UPDATE flagtypes SET name = $name , description = $description , @@ -316,7 +322,7 @@ sub update { } } - SendSQL("UNLOCK TABLES"); + $dbh->bz_unlock_tables(); # Clear existing flags for bugs/attachments in categories no longer on # the list of inclusions or that have been added to the list of exclusions. @@ -384,9 +390,11 @@ sub confirmDelete sub deleteType { validateID(); - - SendSQL("LOCK TABLES flagtypes WRITE, flags WRITE, " . - "flaginclusions WRITE, flagexclusions WRITE"); + + my $dbh = Bugzilla->dbh; + + $dbh->bz_lock_tables('flagtypes WRITE', 'flags WRITE', + 'flaginclusions WRITE', 'flagexclusions WRITE'); # Get the name of the flag type so we can tell users # what was deleted. @@ -397,7 +405,7 @@ sub deleteType { SendSQL("DELETE FROM flaginclusions WHERE type_id = $::FORM{'id'}"); SendSQL("DELETE FROM flagexclusions WHERE type_id = $::FORM{'id'}"); SendSQL("DELETE FROM flagtypes WHERE id = $::FORM{'id'}"); - SendSQL("UNLOCK TABLES"); + $dbh->bz_unlock_tables(); $vars->{'message'} = "flag_type_deleted"; @@ -413,10 +421,12 @@ sub deleteType { sub deactivate { validateID(); validateIsActive(); - - SendSQL("LOCK TABLES flagtypes WRITE"); + + my $dbh = Bugzilla->dbh; + + $dbh->bz_lock_tables('flagtypes WRITE'); SendSQL("UPDATE flagtypes SET is_active = 0 WHERE id = $::FORM{'id'}"); - SendSQL("UNLOCK TABLES"); + $dbh->bz_unlock_tables(); $vars->{'message'} = "flag_type_deactivated"; $vars->{'flag_type'} = Bugzilla::FlagType::get($::FORM{'id'}); diff --git a/editgroups.cgi b/editgroups.cgi index 818997114..c3be719c7 100755 --- a/editgroups.cgi +++ b/editgroups.cgi @@ -483,10 +483,8 @@ if (($action eq 'remove_all_regexp') || ($action eq 'remove_all')) { WHERE id = ?"); $sth->execute($gid); my ($name, $regexp) = $sth->fetchrow_array(); - $dbh->do("LOCK TABLES - groups WRITE, - profiles READ, - user_group_map WRITE"); + $dbh->bz_lock_tables('groups WRITE', 'profiles READ', + 'user_group_map WRITE'); $sth = $dbh->prepare("SELECT user_group_map.user_id, profiles.login_name FROM user_group_map, profiles WHERE user_group_map.user_id = profiles.userid @@ -516,7 +514,7 @@ if (($action eq 'remove_all_regexp') || ($action eq 'remove_all')) { SET last_changed = NOW() WHERE id = ?"); $sth->execute($gid); - $dbh->do("UNLOCK TABLES"); + $dbh->bz_unlock_tables(); $vars->{'users'} = \@users; $vars->{'name'} = $name; @@ -545,9 +543,9 @@ sub doGroupChanges { my $dbh = Bugzilla->dbh; my $sth; - $dbh->do("LOCK TABLES groups WRITE, group_group_map WRITE, - user_group_map WRITE, profiles READ, - namedqueries READ, whine_queries READ"); + $dbh->bz_lock_tables('groups WRITE', 'group_group_map WRITE', + 'user_group_map WRITE', 'profiles READ', + 'namedqueries READ', 'whine_queries READ'); # Check that the given group ID and regular expression are valid. # If tests are successful, trimmed values are returned by CheckGroup*. @@ -651,6 +649,6 @@ sub doGroupChanges { # mark the changes SendSQL("UPDATE groups SET last_changed = NOW() WHERE id = $gid"); } - $dbh->do("UNLOCK TABLES"); + $dbh->bz_unlock_tables(); return $gid, $chgs, $name, $regexp; } diff --git a/editmilestones.cgi b/editmilestones.cgi index 4da121848..7364d4d06 100755 --- a/editmilestones.cgi +++ b/editmilestones.cgi @@ -360,11 +360,11 @@ if ($action eq 'delete') { # lock the tables before we start to change everything: - $dbh->do('LOCK TABLES attachments WRITE, - bugs WRITE, - bugs_activity WRITE, - milestones WRITE, - dependencies WRITE'); + $dbh->bz_lock_tables('attachments WRITE', + 'bugs WRITE', + 'bugs_activity WRITE', + 'milestones WRITE', + 'dependencies WRITE'); # According to MySQL doc I cannot do a DELETE x.* FROM x JOIN Y, # so I have to iterate over bugs and delete all the indivial entries @@ -425,7 +425,7 @@ if ($action eq 'delete') { $product_id, $milestone); - $dbh->do('UNLOCK TABLES'); + $dbh->bz_unlock_tables(); unlink "$datadir/versioncache"; @@ -497,9 +497,9 @@ if ($action eq 'update') { my $dbh = Bugzilla->dbh; - $dbh->do("LOCK TABLES bugs WRITE, - milestones WRITE, - products WRITE"); + $dbh->bz_lock_tables('bugs WRITE', + 'milestones WRITE', + 'products WRITE'); # Need to store because detaint_natural() will delete this if # invalid @@ -507,7 +507,7 @@ if ($action eq 'update') { if ($sortkey != $sortkeyold) { if (!detaint_natural($sortkey)) { - $dbh->do('UNLOCK TABLES'); + $dbh->bz_unlock_tables(UNLOCK_ABORT); ThrowUserError('milestone_sortkey_invalid', {'name' => $milestone, 'sortkey' => $stored_sortkey}); @@ -532,12 +532,12 @@ if ($action eq 'update') { if ($milestone ne $milestoneold) { unless ($milestone) { - $dbh->do('UNLOCK TABLES'); + $dbh->bz_unlock_tables(UNLOCK_ABORT); ThrowUserError('milestone_blank_name'); exit; } if (TestMilestone($product, $milestone)) { - $dbh->do('UNLOCK TABLES'); + $dbh->bz_unlock_tables(UNLOCK_ABORT); ThrowUserError('milestone_already_exists', {'name' => $milestone, 'product' => $product}); @@ -579,7 +579,7 @@ if ($action eq 'update') { $vars->{'updated_name'} = 1; } - $dbh->do('UNLOCK TABLES'); + $dbh->bz_unlock_tables(); $vars->{'name'} = $milestone; $vars->{'product'} = $product; diff --git a/editproducts.cgi b/editproducts.cgi index 0fa2ddbae..f066f7029 100755 --- a/editproducts.cgi +++ b/editproducts.cgi @@ -231,7 +231,6 @@ sub EmitFormElements ($$$$$$$$$) sub PutTrailer (@) { my (@links) = ("Back to the query page", @_); - SendSQL("UNLOCK TABLES"); my $count = $#links; my $num = 0; @@ -281,6 +280,7 @@ my $headerdone = 0; my $localtrailer = "edit more products"; my $classhtmlvarstart = ""; my $classhtmlvar = ""; +my $dbh = Bugzilla->dbh; if (Param('useclassification') && (defined $classification)) { $classhtmlvar = "&classification=" . url_quote($classification); @@ -336,7 +336,6 @@ unless ($action) { CheckClassificationNew($classification); } - my $dbh = Bugzilla->dbh; my @execute_params = (); my @products = (); @@ -786,19 +785,19 @@ if ($action eq 'delete') { # lock the tables before we start to change everything: - SendSQL("LOCK TABLES attachments WRITE, - bugs WRITE, - bugs_activity WRITE, - components WRITE, - dependencies WRITE, - versions WRITE, - products WRITE, - groups WRITE, - group_control_map WRITE, - profiles WRITE, - milestones WRITE, - flaginclusions WRITE, - flagexclusions WRITE"); + $dbh->bz_lock_tables('attachments WRITE', + 'bugs WRITE', + 'bugs_activity WRITE', + 'components WRITE', + 'dependencies WRITE', + 'versions WRITE', + 'products WRITE', + 'groups WRITE', + 'group_control_map WRITE', + 'profiles WRITE', + 'milestones WRITE', + 'flaginclusions WRITE', + 'flagexclusions WRITE'); # According to MySQL doc I cannot do a DELETE x.* FROM x JOIN Y, # so I have to iterate over bugs and delete all the indivial entries @@ -854,6 +853,8 @@ if ($action eq 'delete') { WHERE id=$product_id"); print "Product '$product' deleted.
\n"; + $dbh->bz_unlock_tables(); + unlink "$datadir/versioncache"; PutTrailer($localtrailer); exit; @@ -1107,12 +1108,12 @@ if ($action eq 'updategroupcontrols') { header_done => 1}); } } - SendSQL("LOCK TABLES groups READ, - group_control_map WRITE, - bugs WRITE, - bugs_activity WRITE, - bug_group_map WRITE, - fielddefs READ"); + $dbh->bz_lock_tables('groups READ', + 'group_control_map WRITE', + 'bugs WRITE', + 'bugs_activity WRITE', + 'bug_group_map WRITE', + 'fielddefs READ'); SendSQL("SELECT id, name, entry, membercontrol, othercontrol, canedit " . "FROM groups " . "LEFT JOIN group_control_map " . @@ -1234,6 +1235,8 @@ if ($action eq 'updategroupcontrols') { } print "added $count bugs

\n"; } + $dbh->bz_unlock_tables(); + print "Group control updates done

\n"; PutTrailer($localtrailer); @@ -1289,12 +1292,12 @@ if ($action eq 'update') { # Note that we got the $product_id using $productold above so it will # remain static even after we rename the product in the database. - SendSQL("LOCK TABLES products WRITE, - versions READ, - groups WRITE, - group_control_map WRITE, - profiles WRITE, - milestones READ"); + $dbh->bz_lock_tables('products WRITE', + 'versions READ', + 'groups WRITE', + 'group_control_map WRITE', + 'profiles WRITE', + 'milestones READ'); if ($disallownew ne $disallownewold) { $disallownew = $disallownew ? 1 : 0; @@ -1307,6 +1310,7 @@ if ($action eq 'update') { if ($description ne $descriptionold) { unless ($description) { print "Sorry, I can't delete the description."; + $dbh->bz_unlock_tables(UNLOCK_ABORT); PutTrailer($localtrailer); exit; } @@ -1357,6 +1361,7 @@ if ($action eq 'update') { " AND product_id = $product_id"); if (!FetchOneColumn()) { print "Sorry, the milestone $defaultmilestone must be defined first."; + $dbh->bz_unlock_tables(UNLOCK_ABORT); PutTrailer($localtrailer); exit; } @@ -1372,7 +1377,7 @@ if ($action eq 'update') { if ($product ne $productold) { unless ($product) { print "Sorry, I can't delete the product name."; - SendSQL("UNLOCK TABLES"); + $dbh->bz_unlock_tables(UNLOCK_ABORT); PutTrailer($localtrailer); exit; } @@ -1380,7 +1385,7 @@ if ($action eq 'update') { if (lc($product) ne lc($productold) && TestProduct($product)) { print "Sorry, product name '$product' is already in use."; - SendSQL("UNLOCK TABLES"); + $dbh->bz_unlock_tables(UNLOCK_ABORT); PutTrailer($localtrailer); exit; } @@ -1388,8 +1393,8 @@ if ($action eq 'update') { SendSQL("UPDATE products SET name=$qp WHERE id=$product_id"); print "Updated product name.
\n"; } + $dbh->bz_unlock_tables(); unlink "$datadir/versioncache"; - SendSQL("UNLOCK TABLES"); if ($checkvotes) { # 1. too many votes for a single user on a single bug. diff --git a/editversions.cgi b/editversions.cgi index 222e7dd8e..ee4a83d77 100755 --- a/editversions.cgi +++ b/editversions.cgi @@ -39,6 +39,7 @@ use Bugzilla::Config qw(:DEFAULT $datadir); use vars qw($template $vars); my $cgi = Bugzilla->cgi; +my $dbh = Bugzilla->dbh; # TestProduct: just returns if the specified product does exists # CheckProduct: same check, optionally emit an error text @@ -303,11 +304,11 @@ if ($action eq 'delete') { # lock the tables before we start to change everything: - SendSQL("LOCK TABLES attachments WRITE, - bugs WRITE, - bugs_activity WRITE, - versions WRITE, - dependencies WRITE"); + $dbh->bz_lock_tables('attachments WRITE', + 'bugs WRITE', + 'bugs_activity WRITE', + 'versions WRITE', + 'dependencies WRITE'); # According to MySQL doc I cannot do a DELETE x.* FROM x JOIN Y, # so I have to iterate over bugs and delete all the indivial entries @@ -347,7 +348,7 @@ if ($action eq 'delete') { WHERE product_id = $product_id AND value = " . SqlQuote($version)); - SendSQL("UNLOCK TABLES;"); + $dbh->bz_unlock_tables(); unlink "$datadir/versioncache"; @@ -399,18 +400,18 @@ if ($action eq 'update') { # Note that the order of this tests is important. If you change # them, be sure to test for WHERE='$version' or WHERE='$versionold' - SendSQL("LOCK TABLES bugs WRITE, - versions WRITE, - products READ"); + $dbh->bz_lock_tables('bugs WRITE', + 'versions WRITE', + 'products READ'); if ($version ne $versionold) { unless ($version) { - SendSQL('UNLOCK TABLES'); + $dbh->bz_unlock_tables(UNLOCK_ABORT); ThrowUserError('version_blank_name'); exit; } if (TestVersion($product,$version)) { - SendSQL('UNLOCK TABLES'); + $dbh->bz_unlock_tables(UNLOCK_ABORT); ThrowUserError('version_already_exists', {'name' => $version, 'product' => $product}); @@ -430,7 +431,7 @@ if ($action eq 'update') { $vars->{'updated_name'} = 1; } - SendSQL('UNLOCK TABLES'); + $dbh->bz_unlock_tables(); $vars->{'name'} = $version; $vars->{'product'} = $product; diff --git a/process_bug.cgi b/process_bug.cgi index 6daa6d64e..abbad43f9 100755 --- a/process_bug.cgi +++ b/process_bug.cgi @@ -60,6 +60,7 @@ my $user = Bugzilla->login(LOGIN_REQUIRED); my $whoid = $user->id; my $cgi = Bugzilla->cgi; +my $dbh = Bugzilla->dbh; my $requiremilestone = 0; @@ -1134,22 +1135,22 @@ foreach my $id (@idlist) { $bug_changed = 0; my $write = "WRITE"; # Might want to make a param to control # whether we do LOW_PRIORITY ... - SendSQL("LOCK TABLES bugs $write, bugs_activity $write, cc $write, " . - "cc AS selectVisible_cc $write, " . - "profiles $write, dependencies $write, votes $write, " . - "products READ, components READ, " . - "keywords $write, longdescs $write, fielddefs $write, " . - "bug_group_map $write, flags $write, duplicates $write," . + $dbh->bz_lock_tables("bugs $write", "bugs_activity $write", + "cc $write", "cc AS selectVisible_cc $write", + "profiles $write", "dependencies $write", "votes $write", + "products READ", "components READ", + "keywords $write", "longdescs $write", "fielddefs $write", + "bug_group_map $write", "flags $write", "duplicates $write", # user_group_map would be a READ lock except that Flag::process # may call Flag::notify, which creates a new user object, # which might call derive_groups, which wants a WRITE lock on that # table. group_group_map is in here at all because derive_groups # needs it. - "user_group_map $write, group_group_map READ, flagtypes READ, " . - "flaginclusions AS i READ, flagexclusions AS e READ, " . - "keyworddefs READ, groups READ, attachments READ, " . - "group_control_map AS oldcontrolmap READ, " . - "group_control_map AS newcontrolmap READ, " . + "user_group_map $write", "group_group_map READ", "flagtypes READ", + "flaginclusions AS i READ", "flagexclusions AS e READ", + "keyworddefs READ", "groups READ", "attachments READ", + "group_control_map AS oldcontrolmap READ", + "group_control_map AS newcontrolmap READ", "group_control_map READ"); # Fun hack. @::log_columns only contains the component_id, # not the name (since bug 43600 got fixed). So, we need to have @@ -1270,7 +1271,7 @@ foreach my $id (@idlist) { $vars->{'bug_id'} = $id; - SendSQL("UNLOCK TABLES"); + $dbh->bz_unlock_tables(UNLOCK_ABORT); # Warn the user about the mid-air collision and ask them what to do. $template->process("bug/process/midair.html.tmpl", $vars) @@ -1773,7 +1774,7 @@ foreach my $id (@idlist) { if ($bug_changed) { SendSQL("UPDATE bugs SET delta_ts = $sql_timestamp WHERE bug_id = $id"); } - SendSQL("UNLOCK TABLES"); + $dbh->bz_unlock_tables(); $vars->{'mailrecipients'} = { 'cc' => \@ccRemoved, 'owner' => $origOwner, diff --git a/query.cgi b/query.cgi index 2715b5549..2806cdd24 100755 --- a/query.cgi +++ b/query.cgi @@ -88,7 +88,7 @@ if ($userid) { # If the query name contains invalid characters, don't import. $name =~ /[<>&]/ && next; trick_taint($name); - $dbh->do("LOCK TABLES namedqueries WRITE"); + $dbh->bz_lock_tables('namedqueries WRITE'); my $query = $dbh->selectrow_array( "SELECT query FROM namedqueries " . "WHERE userid = ? AND name = ?", @@ -98,7 +98,7 @@ if ($userid) { "(userid, name, query) VALUES " . "(?, ?, ?)", undef, ($userid, $name, $value)); } - $dbh->do("UNLOCK TABLES"); + $dbh->bz_unlock_tables(); } $cgi->send_cookie(-name => $cookiename, -expires => "Fri, 01-Jan-2038 00:00:00 GMT"); @@ -358,7 +358,7 @@ $vars->{'bug_severity'} = \@::legal_severity; # Boolean charts my @fields; push(@fields, { name => "noop", description => "---" }); -push(@fields, Bugzilla->dbh->bz_get_field_defs()); +push(@fields, $dbh->bz_get_field_defs()); $vars->{'fields'} = \@fields; # Creating new charts - if the cmd-add value is there, we define the field diff --git a/sanitycheck.cgi b/sanitycheck.cgi index 7bd42d22d..81afe79c5 100755 --- a/sanitycheck.cgi +++ b/sanitycheck.cgi @@ -71,6 +71,7 @@ sub BugListLinks { Bugzilla->login(LOGIN_REQUIRED); my $cgi = Bugzilla->cgi; +my $dbh = Bugzilla->dbh; # Make sure the user is authorized to access sanitycheck.cgi. Access # is restricted to logged-in users who have "editbugs" privileges, @@ -95,7 +96,7 @@ PutHeader("Bugzilla Sanity Check"); if (defined $cgi->param('rebuildvotecache')) { Status("OK, now rebuilding vote cache."); - SendSQL("LOCK TABLES bugs WRITE, votes READ"); + $dbh->bz_lock_tables('bugs WRITE', 'votes READ'); SendSQL("UPDATE bugs SET votes = 0"); SendSQL("SELECT bug_id, SUM(vote_count) FROM votes GROUP BY bug_id"); my %votes; @@ -106,7 +107,7 @@ if (defined $cgi->param('rebuildvotecache')) { foreach my $id (keys %votes) { SendSQL("UPDATE bugs SET votes = $votes{$id} WHERE bug_id = $id"); } - SendSQL("UNLOCK TABLES"); + $dbh->bz_unlock_tables(); Status("Vote cache has been rebuilt."); } @@ -148,7 +149,7 @@ if (defined $cgi->param('cleangroupsnow')) { Status("Cutoff is $cutoff"); SendSQL("SELECT COUNT(*) FROM user_group_map"); (my $before) = FetchSQLData(); - SendSQL("LOCK TABLES user_group_map WRITE, profiles WRITE"); + $dbh->bz_lock_tables('user_group_map WRITE', 'profiles WRITE'); SendSQL("SELECT userid FROM profiles " . "WHERE refreshed_when > 0 " . "AND refreshed_when < " . SqlQuote($cutoff) . @@ -162,7 +163,7 @@ if (defined $cgi->param('cleangroupsnow')) { SendSQL("UPDATE profiles SET refreshed_when = 0 WHERE userid = $id"); PopGlobalSQLState(); } - SendSQL("UNLOCK TABLES"); + $dbh->bz_unlock_tables(); SendSQL("SELECT COUNT(*) FROM user_group_map"); (my $after) = FetchSQLData(); Status("Cleaned table for $count users " . @@ -537,7 +538,8 @@ Status("Checking cached keywords"); my %realk; if (defined $cgi->param('rebuildkeywordcache')) { - SendSQL("LOCK TABLES bugs write, keywords read, keyworddefs read"); + $dbh->bz_lock_tables('bugs write', 'keywords read', + 'keyworddefs read'); } SendSQL("SELECT keywords.bug_id, keyworddefs.name " . @@ -596,7 +598,7 @@ if (@badbugs) { } if (defined $cgi->param('rebuildkeywordcache')) { - SendSQL("UNLOCK TABLES"); + $dbh->bz_unlock_tables(); } ########################################################################### diff --git a/token.cgi b/token.cgi index bf810834f..d8c3fe288 100755 --- a/token.cgi +++ b/token.cgi @@ -192,6 +192,8 @@ sub cancelChangePassword { } sub changePassword { + my $dbh = Bugzilla->dbh; + # Quote the password and token for inclusion into SQL statements. my $cryptedpassword = bz_crypt($cgi->param('password')); my $quotedpassword = SqlQuote($cryptedpassword); @@ -202,12 +204,12 @@ sub changePassword { # Update the user's password in the profiles table and delete the token # from the tokens table. - SendSQL("LOCK TABLES profiles WRITE , tokens WRITE"); + $dbh->bz_lock_tables('profiles WRITE', 'tokens WRITE'); SendSQL("UPDATE profiles SET cryptpassword = $quotedpassword WHERE userid = $userid"); SendSQL("DELETE FROM tokens WHERE token = $::quotedtoken"); - SendSQL("UNLOCK TABLES"); + $dbh->bz_unlock_tables(); Bugzilla->logout_user_by_id($userid); @@ -229,6 +231,7 @@ sub confirmChangeEmail { } sub changeEmail { + my $dbh = Bugzilla->dbh; # Get the user's ID from the tokens table. SendSQL("SELECT userid, eventdata FROM tokens @@ -251,14 +254,14 @@ sub changeEmail { # Update the user's login name in the profiles table and delete the token # from the tokens table. - SendSQL("LOCK TABLES profiles WRITE , tokens WRITE"); + $dbh->bz_lock_tables('profiles WRITE', 'tokens WRITE'); SendSQL("UPDATE profiles SET login_name = $quotednewemail WHERE userid = $userid"); SendSQL("DELETE FROM tokens WHERE token = $::quotedtoken"); SendSQL("DELETE FROM tokens WHERE userid = $userid AND tokentype = 'emailnew'"); - SendSQL("UNLOCK TABLES"); + $dbh->bz_unlock_tables(); # The email address has been changed, so we need to rederive the groups my $user = new Bugzilla::User($userid); @@ -276,6 +279,8 @@ sub changeEmail { } sub cancelChangeEmail { + my $dbh = Bugzilla->dbh; + # Get the user's ID from the tokens table. SendSQL("SELECT userid, tokentype, eventdata FROM tokens WHERE token = $::quotedtoken"); @@ -292,11 +297,11 @@ sub cancelChangeEmail { if($actualemail ne $old_email) { my $quotedoldemail = SqlQuote($old_email); - SendSQL("LOCK TABLES profiles WRITE"); + $dbh->bz_lock_tables('profiles WRITE'); SendSQL("UPDATE profiles SET login_name = $quotedoldemail WHERE userid = $userid"); - SendSQL("UNLOCK TABLES"); + $dbh->bz_unlock_tables(); # email has changed, so rederive groups # Note that this is done _after_ the tables are unlocked @@ -318,11 +323,11 @@ sub cancelChangeEmail { $vars->{'new_email'} = $new_email; Bugzilla::Token::Cancel($::token, $vars->{'message'}); - SendSQL("LOCK TABLES tokens WRITE"); + $dbh->bz_lock_tables('tokens WRITE'); SendSQL("DELETE FROM tokens WHERE userid = $userid AND tokentype = 'emailold' OR tokentype = 'emailnew'"); - SendSQL("UNLOCK TABLES"); + $dbh->bz_unlock_tables(); # Return HTTP response headers. print $cgi->header(); diff --git a/userprefs.cgi b/userprefs.cgi index f62f02500..193a4d73f 100755 --- a/userprefs.cgi +++ b/userprefs.cgi @@ -195,7 +195,8 @@ sub DoEmail { sub SaveEmail { my $updateString = ""; my $cgi = Bugzilla->cgi; - + my $dbh = Bugzilla->dbh; + if (defined $cgi->param('ExcludeSelf')) { $updateString .= 'ExcludeSelf~on'; } else { @@ -226,7 +227,7 @@ sub SaveEmail { # we don't really care if anyone reads the watch table. So # some small amount of contention could be gotten rid of by # using user-defined locks rather than table locking. - SendSQL("LOCK TABLES watch WRITE, profiles READ"); + $dbh->bz_lock_tables('watch WRITE', 'profiles READ'); # what the db looks like now my $origWatchedUsers = new Bugzilla::RelationSet; @@ -244,7 +245,7 @@ sub SaveEmail { ($CCDELTAS[0] eq "") || SendSQL($CCDELTAS[0]); ($CCDELTAS[1] eq "") || SendSQL($CCDELTAS[1]); - SendSQL("UNLOCK TABLES"); + $dbh->bz_unlock_tables(); } } diff --git a/votes.cgi b/votes.cgi index 7e2caf2a8..3a22c90b0 100755 --- a/votes.cgi +++ b/votes.cgi @@ -118,8 +118,9 @@ sub show_bug { # doing the viewing, give them the option to edit them too. sub show_user { GetVersionTable(); - + my $cgi = Bugzilla->cgi; + my $dbh = Bugzilla->dbh; # If a bug_id is given, and we're editing, we'll add it to the votes list. $bug_id ||= ""; @@ -129,11 +130,11 @@ sub show_user { my $userid = Bugzilla->user->id; my $canedit = (Param('usevotes') && $userid == $who) ? 1 : 0; - - SendSQL("LOCK TABLES bugs READ, products READ, votes WRITE, - cc READ, bug_group_map READ, user_group_map READ, - cc AS selectVisible_cc READ, groups READ"); - + + $dbh->bz_lock_tables('bugs READ', 'products READ', 'votes WRITE', + 'cc READ', 'bug_group_map READ', 'user_group_map READ', + 'cc AS selectVisible_cc READ', 'groups READ'); + if ($canedit && $bug_id) { # Make sure there is an entry for this bug # in the vote table, just so that things display right. @@ -212,7 +213,7 @@ sub show_user { } SendSQL("DELETE FROM votes WHERE vote_count <= 0"); - SendSQL("UNLOCK TABLES"); + $dbh->bz_unlock_tables(); $vars->{'canedit'} = $canedit; $vars->{'voting_user'} = { "login" => $name }; @@ -231,6 +232,7 @@ sub record_votes { ############################################################################ my $cgi = Bugzilla->cgi; + my $dbh = Bugzilla->dbh; # Build a list of bug IDs for which votes have been submitted. Votes # are submitted in form fields in which the field names are the bug @@ -314,12 +316,13 @@ sub record_votes { # for products that only allow one vote per bug). In that case, we still # need to clear the user's votes from the database. my %affected; - SendSQL("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"); + $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'); # Take note of, and delete the user's old votes from the database. SendSQL("SELECT bug_id FROM votes WHERE who = $who"); @@ -349,7 +352,7 @@ sub record_votes { $vars->{'header_done'} = 1 if $confirmed; } - SendSQL("UNLOCK TABLES"); + $dbh->bz_unlock_tables(); $vars->{'votes_recorded'} = 1; } diff --git a/whine.pl b/whine.pl index 920b27d05..0e469e8ad 100755 --- a/whine.pl +++ b/whine.pl @@ -220,12 +220,11 @@ sub get_next_event { # Loop until there's something to return until (scalar keys %{$event}) { - $dbh->do("LOCK TABLE " . - "whine_schedules WRITE, " . - "whine_events READ, " . - "profiles READ, " . - "groups READ, " . - "user_group_map READ"); + $dbh->bz_lock_tables('whine_schedules WRITE', + 'whine_events READ', + 'profiles READ', + 'groups READ', + 'user_group_map READ'); # Get the event ID for the first pending schedule $sth_next_scheduled_event->execute; @@ -262,7 +261,7 @@ sub get_next_event { reset_timer($sid); } - $dbh->do("UNLOCK TABLES"); + $dbh->bz_unlock_tables(); # Only set $event if the user is allowed to do whining if ($owner->in_group('bz_canusewhines')) { -- cgit v1.2.3-24-g4f1b