Commit d3f8bf36 authored by mkanat%kerio.com's avatar mkanat%kerio.com

Bug 280503: Replace "LOCK/UNLOCK TABLES" with Bugzilla::DB function call

Patch By Tomas Kopal <Tomas.Kopal@altap.cz> r=mkanat,a=myk
parent f95d1fab
...@@ -66,6 +66,8 @@ use base qw(Exporter); ...@@ -66,6 +66,8 @@ use base qw(Exporter);
DEFAULT_QUERY_NAME DEFAULT_QUERY_NAME
COMMENT_COLS COMMENT_COLS
UNLOCK_ABORT
); );
@Bugzilla::Constants::EXPORT_OK = qw(contenttypes); @Bugzilla::Constants::EXPORT_OK = qw(contenttypes);
...@@ -217,4 +219,8 @@ use constant DEFAULT_QUERY_NAME => '(Default query)'; ...@@ -217,4 +219,8 @@ use constant DEFAULT_QUERY_NAME => '(Default query)';
# The column length for displayed (and wrapped) bug comments. # The column length for displayed (and wrapped) bug comments.
use constant COMMENT_COLS => 80; 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; 1;
...@@ -501,8 +501,8 @@ formatted SQL command have prefix C<sql_>. All other methods have prefix C<bz_>. ...@@ -501,8 +501,8 @@ formatted SQL command have prefix C<sql_>. All other methods have prefix C<bz_>.
set even without locking tables first without raising an error set even without locking tables first without raising an error
to simplify error handling. to simplify error handling.
Abstract method, should be overriden by database specific code. Abstract method, should be overriden by database specific code.
Params: $abort = true (1) if the operation on locked tables failed Params: $abort = UNLOCK_ABORT (true, 1) if the operation on locked tables
(if transactions are supported, the action will be rolled failed (if transactions are supported, the action will be rolled
back). False (0) or no param if the operation succeeded. back). False (0) or no param if the operation succeeded.
Returns: none Returns: none
......
...@@ -27,6 +27,7 @@ use base qw(Exporter); ...@@ -27,6 +27,7 @@ use base qw(Exporter);
@Bugzilla::Error::EXPORT = qw(ThrowCodeError ThrowTemplateError ThrowUserError); @Bugzilla::Error::EXPORT = qw(ThrowCodeError ThrowTemplateError ThrowUserError);
use Bugzilla::Config; use Bugzilla::Config;
use Bugzilla::Constants;
use Bugzilla::Util; use Bugzilla::Util;
use Date::Format; use Date::Format;
...@@ -37,7 +38,7 @@ sub _throw_error { ...@@ -37,7 +38,7 @@ sub _throw_error {
$vars->{error} = $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 a writable data/errorlog exists, log error details there.
if (-w "data/errorlog") { if (-w "data/errorlog") {
......
...@@ -170,7 +170,7 @@ sub writeToDatabase { ...@@ -170,7 +170,7 @@ sub writeToDatabase {
my $self = shift; my $self = shift;
my $dbh = Bugzilla->dbh; 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 $category_id = getCategoryID($self->{'category'});
my $subcategory_id = getCategoryID($self->{'subcategory'}); my $subcategory_id = getCategoryID($self->{'subcategory'});
...@@ -210,7 +210,7 @@ sub writeToDatabase { ...@@ -210,7 +210,7 @@ sub writeToDatabase {
|| &::ThrowCodeError("missing_series_id", { 'series' => $self }); || &::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 # Check whether a series with this name, category and subcategory exists in
......
...@@ -52,13 +52,14 @@ my $maxtokenage = 3; ...@@ -52,13 +52,14 @@ my $maxtokenage = 3;
sub IssueEmailChangeToken { sub IssueEmailChangeToken {
my ($userid, $old_email, $new_email) = @_; my ($userid, $old_email, $new_email) = @_;
my $dbh = Bugzilla->dbh;
my $token_ts = time(); my $token_ts = time();
my $issuedate = time2str("%Y-%m-%d %H:%M", $token_ts); my $issuedate = time2str("%Y-%m-%d %H:%M", $token_ts);
# Generate a unique token and insert it into the tokens table. # Generate a unique token and insert it into the tokens table.
# We have to lock the tokens table before generating the token, # We have to lock the tokens table before generating the token,
# since the database must be queried for token uniqueness. # since the database must be queried for token uniqueness.
&::SendSQL("LOCK TABLES tokens WRITE"); $dbh->bz_lock_tables('tokens WRITE');
my $token = GenerateUniqueToken(); my $token = GenerateUniqueToken();
my $quotedtoken = &::SqlQuote($token); my $quotedtoken = &::SqlQuote($token);
my $quoted_emails = &::SqlQuote($old_email . ":" . $new_email); my $quoted_emails = &::SqlQuote($old_email . ":" . $new_email);
...@@ -72,7 +73,7 @@ sub IssueEmailChangeToken { ...@@ -72,7 +73,7 @@ sub IssueEmailChangeToken {
tokentype , eventdata ) tokentype , eventdata )
VALUES ( $userid , '$issuedate' , $quotedtoken , VALUES ( $userid , '$issuedate' , $quotedtoken ,
'emailnew' , $quoted_emails )"); 'emailnew' , $quoted_emails )");
&::SendSQL("UNLOCK TABLES"); $dbh->bz_unlock_tables();
# Mail the user the token along with instructions for using it. # Mail the user the token along with instructions for using it.
...@@ -110,6 +111,8 @@ sub IssuePasswordToken { ...@@ -110,6 +111,8 @@ sub IssuePasswordToken {
my ($loginname) = @_; my ($loginname) = @_;
my $dbh = Bugzilla->dbh;
# Retrieve the user's ID from the database. # Retrieve the user's ID from the database.
my $quotedloginname = &::SqlQuote($loginname); my $quotedloginname = &::SqlQuote($loginname);
&::SendSQL("SELECT profiles.userid, tokens.issuedate FROM profiles &::SendSQL("SELECT profiles.userid, tokens.issuedate FROM profiles
...@@ -129,13 +132,13 @@ sub IssuePasswordToken { ...@@ -129,13 +132,13 @@ sub IssuePasswordToken {
# Generate a unique token and insert it into the tokens table. # Generate a unique token and insert it into the tokens table.
# We have to lock the tokens table before generating the token, # We have to lock the tokens table before generating the token,
# since the database must be queried for token uniqueness. # since the database must be queried for token uniqueness.
&::SendSQL("LOCK TABLES tokens WRITE"); $dbh->bz_lock_tables('tokens WRITE');
my $token = GenerateUniqueToken(); my $token = GenerateUniqueToken();
my $quotedtoken = &::SqlQuote($token); my $quotedtoken = &::SqlQuote($token);
my $quotedipaddr = &::SqlQuote($::ENV{'REMOTE_ADDR'}); my $quotedipaddr = &::SqlQuote($::ENV{'REMOTE_ADDR'});
&::SendSQL("INSERT INTO tokens ( userid , issuedate , token , tokentype , eventdata ) &::SendSQL("INSERT INTO tokens ( userid , issuedate , token , tokentype , eventdata )
VALUES ( $userid , NOW() , $quotedtoken , 'password' , $quotedipaddr )"); VALUES ( $userid , NOW() , $quotedtoken , 'password' , $quotedipaddr )");
&::SendSQL("UNLOCK TABLES"); $dbh->bz_unlock_tables();
# Mail the user the token along with instructions for using it. # Mail the user the token along with instructions for using it.
...@@ -158,10 +161,11 @@ sub IssuePasswordToken { ...@@ -158,10 +161,11 @@ sub IssuePasswordToken {
sub CleanTokenTable { sub CleanTokenTable {
&::SendSQL("LOCK TABLES tokens WRITE"); my $dbh = Bugzilla->dbh;
$dbh->bz_lock_tables('tokens WRITE');
&::SendSQL("DELETE FROM tokens &::SendSQL("DELETE FROM tokens
WHERE TO_DAYS(NOW()) - TO_DAYS(issuedate) >= " . $maxtokenage); WHERE TO_DAYS(NOW()) - TO_DAYS(issuedate) >= " . $maxtokenage);
&::SendSQL("UNLOCK TABLES"); $dbh->bz_unlock_tables();
} }
...@@ -198,6 +202,8 @@ sub Cancel { ...@@ -198,6 +202,8 @@ sub Cancel {
my ($token, $cancelaction) = @_; my ($token, $cancelaction) = @_;
my $dbh = Bugzilla->dbh;
# Quote the token for inclusion in SQL statements. # Quote the token for inclusion in SQL statements.
my $quotedtoken = &::SqlQuote($token); my $quotedtoken = &::SqlQuote($token);
...@@ -232,9 +238,9 @@ sub Cancel { ...@@ -232,9 +238,9 @@ sub Cancel {
Bugzilla::BugMail::MessageToMTA($message); Bugzilla::BugMail::MessageToMTA($message);
# Delete the token from the database. # 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("DELETE FROM tokens WHERE token = $quotedtoken");
&::SendSQL("UNLOCK TABLES"); $dbh->bz_unlock_tables();
} }
sub DeletePasswordTokens { sub DeletePasswordTokens {
......
...@@ -384,10 +384,9 @@ sub derive_groups { ...@@ -384,10 +384,9 @@ sub derive_groups {
my $sth; my $sth;
$dbh->do(q{LOCK TABLES profiles WRITE, $dbh->bz_lock_tables('profiles WRITE', 'user_group_map WRITE',
user_group_map WRITE, 'group_group_map READ',
group_group_map READ, 'groups READ') unless $already_locked;
groups READ}) unless $already_locked;
# avoid races, we are only up to date as of the BEGINNING of this process # avoid races, we are only up to date as of the BEGINNING of this process
my $time = $dbh->selectrow_array("SELECT NOW()"); my $time = $dbh->selectrow_array("SELECT NOW()");
...@@ -459,7 +458,7 @@ sub derive_groups { ...@@ -459,7 +458,7 @@ sub derive_groups {
undef, undef,
$time, $time,
$id); $id);
$dbh->do("UNLOCK TABLES") unless $already_locked; $dbh->bz_unlock_tables() unless $already_locked;
} }
sub can_bless { sub can_bless {
......
...@@ -1051,15 +1051,16 @@ sub edit ...@@ -1051,15 +1051,16 @@ sub edit
sub update sub update
{ {
# Updates an attachment record. # Updates an attachment record.
my $dbh = Bugzilla->dbh;
# Get the bug ID for the bug to which this attachment is attached. # Get the bug ID for the bug to which this attachment is attached.
SendSQL("SELECT bug_id FROM attachments WHERE attach_id = $::FORM{'id'}"); SendSQL("SELECT bug_id FROM attachments WHERE attach_id = $::FORM{'id'}");
my $bugid = FetchSQLData(); my $bugid = FetchSQLData();
# Lock database tables in preparation for updating the attachment. # Lock database tables in preparation for updating the attachment.
SendSQL("LOCK TABLES attachments WRITE , flags WRITE , " . $dbh->bz_lock_tables('attachments WRITE', 'flags WRITE' ,
"flagtypes READ , fielddefs READ , bugs_activity WRITE, " . 'flagtypes READ', 'fielddefs READ', 'bugs_activity WRITE',
"flaginclusions AS i READ, flagexclusions AS e READ, " . 'flaginclusions AS i READ', 'flagexclusions AS e READ',
# cc, bug_group_map, user_group_map, and groups are in here so we # cc, bug_group_map, user_group_map, and groups are in here so we
# can check the permissions of flag requestees and email addresses # can check the permissions of flag requestees and email addresses
# on the flag type cc: lists via the CanSeeBug # on the flag type cc: lists via the CanSeeBug
...@@ -1067,9 +1068,9 @@ sub update ...@@ -1067,9 +1068,9 @@ sub update
# Bugzilla::User needs to rederive groups. profiles and # Bugzilla::User needs to rederive groups. profiles and
# user_group_map would be READ locks instead of WRITE locks if it # 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. # weren't for derive_groups, which needs to write to those tables.
"bugs READ, profiles WRITE, " . 'bugs READ', 'profiles WRITE',
"cc READ, bug_group_map READ, user_group_map WRITE, " . 'cc READ', 'bug_group_map READ', 'user_group_map WRITE',
"group_group_map READ, groups READ"); 'group_group_map READ', 'groups READ');
# Get a copy of the attachment record before we make changes # Get a copy of the attachment record before we make changes
# so we can record those changes in the activity table. # so we can record those changes in the activity table.
...@@ -1140,7 +1141,7 @@ sub update ...@@ -1140,7 +1141,7 @@ sub update
Bugzilla::Flag::process($target, $timestamp, \%::FORM); Bugzilla::Flag::process($target, $timestamp, \%::FORM);
# Unlock all database tables now that we are finished updating the database. # 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, # If the user submitted a comment while editing the attachment,
# add the comment to the bug. # add the comment to the bug.
......
...@@ -250,7 +250,7 @@ sub InsertNamedQuery ($$$;$) { ...@@ -250,7 +250,7 @@ sub InsertNamedQuery ($$$;$) {
# it when we display it to the user. # it when we display it to the user.
trick_taint($query); trick_taint($query);
$dbh->do("LOCK TABLES namedqueries WRITE"); $dbh->bz_lock_tables('namedqueries WRITE');
my $result = $dbh->selectrow_array("SELECT userid FROM namedqueries" my $result = $dbh->selectrow_array("SELECT userid FROM namedqueries"
. " WHERE userid = ? AND name = ?" . " WHERE userid = ? AND name = ?"
...@@ -269,7 +269,7 @@ sub InsertNamedQuery ($$$;$) { ...@@ -269,7 +269,7 @@ sub InsertNamedQuery ($$$;$) {
, undef, ($userid, $query_name, $query, $link_in_footer)); , undef, ($userid, $query_name, $query, $link_in_footer));
} }
$dbh->do("UNLOCK TABLES"); $dbh->bz_unlock_tables();
return $query_existed_before; return $query_existed_before;
} }
......
...@@ -2722,7 +2722,7 @@ if (GetFieldDef('bugs', 'long_desc')) { ...@@ -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"; print "bugs to process; a line of dots will be printed for each 50.\n\n";
$| = 1; $| = 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'); $dbh->do('DELETE FROM longdescs');
...@@ -2823,7 +2823,7 @@ if (GetFieldDef('bugs', 'long_desc')) { ...@@ -2823,7 +2823,7 @@ if (GetFieldDef('bugs', 'long_desc')) {
DropField('bugs', 'long_desc'); DropField('bugs', 'long_desc');
$dbh->do("UNLOCK TABLES"); $dbh->bz_unlock_tables();
} }
...@@ -2836,7 +2836,7 @@ if (GetFieldDef('bugs_activity', 'field')) { ...@@ -2836,7 +2836,7 @@ if (GetFieldDef('bugs_activity', 'field')) {
'mediumint not null, ADD INDEX (fieldid)'); 'mediumint not null, ADD INDEX (fieldid)');
print "Populating new fieldid field ...\n"; 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'); my $sth = $dbh->prepare('SELECT DISTINCT field FROM bugs_activity');
$sth->execute(); $sth->execute();
...@@ -2856,7 +2856,7 @@ if (GetFieldDef('bugs_activity', 'field')) { ...@@ -2856,7 +2856,7 @@ if (GetFieldDef('bugs_activity', 'field')) {
} }
$dbh->do("UPDATE bugs_activity SET fieldid = $id WHERE field = $q"); $dbh->do("UPDATE bugs_activity SET fieldid = $id WHERE field = $q");
} }
$dbh->do("UNLOCK TABLES"); $dbh->bz_unlock_tables();
DropField('bugs_activity', 'field'); DropField('bugs_activity', 'field');
} }
......
...@@ -205,7 +205,7 @@ if ($action eq 'delete') { ...@@ -205,7 +205,7 @@ if ($action eq 'delete') {
} }
# lock the tables before we start to change everything: # 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 # delete
$sth = $dbh->prepare("DELETE FROM classifications WHERE id=?"); $sth = $dbh->prepare("DELETE FROM classifications WHERE id=?");
...@@ -217,7 +217,7 @@ if ($action eq 'delete') { ...@@ -217,7 +217,7 @@ if ($action eq 'delete') {
WHERE classification_id=?"); WHERE classification_id=?");
$sth->execute($classification_id); $sth->execute($classification_id);
$dbh->do("UNLOCK TABLES"); $dbh->bz_unlock_tables();
unlink "data/versioncache"; unlink "data/versioncache";
...@@ -283,7 +283,7 @@ if ($action eq 'update') { ...@@ -283,7 +283,7 @@ if ($action eq 'update') {
# above so it will remain static even after we rename the # above so it will remain static even after we rename the
# classification in the database. # classification in the database.
$dbh->do("LOCK TABLES classifications WRITE"); $dbh->bz_lock_tables('classifications WRITE');
if ($description ne $descriptionold) { if ($description ne $descriptionold) {
$sth = $dbh->prepare("UPDATE classifications $sth = $dbh->prepare("UPDATE classifications
...@@ -295,12 +295,12 @@ if ($action eq 'update') { ...@@ -295,12 +295,12 @@ if ($action eq 'update') {
if ($classification ne $classificationold) { if ($classification ne $classificationold) {
unless ($classification) { unless ($classification) {
$dbh->do("UNLOCK TABLES"); $dbh->bz_unlock_tables(UNLOCK_ABORT);
ThrowUserError("classification_not_specified") ThrowUserError("classification_not_specified")
} }
if (TestClassification($classification)) { if (TestClassification($classification)) {
$dbh->do("UNLOCK TABLES"); $dbh->bz_unlock_tables(UNLOCK_ABORT);
ThrowUserError("classification_already_exists", { name => $classification }); ThrowUserError("classification_already_exists", { name => $classification });
} }
$sth = $dbh->prepare("UPDATE classifications $sth = $dbh->prepare("UPDATE classifications
...@@ -308,7 +308,7 @@ if ($action eq 'update') { ...@@ -308,7 +308,7 @@ if ($action eq 'update') {
$sth->execute($classification,$classification_id); $sth->execute($classification,$classification_id);
$vars->{'updated_classification'} = 1; $vars->{'updated_classification'} = 1;
} }
$dbh->do("UNLOCK TABLES"); $dbh->bz_unlock_tables();
unlink "data/versioncache"; unlink "data/versioncache";
LoadTemplate($action); LoadTemplate($action);
......
...@@ -39,6 +39,7 @@ use Bugzilla::Util; ...@@ -39,6 +39,7 @@ use Bugzilla::Util;
use vars qw($template $vars); use vars qw($template $vars);
my $cgi = Bugzilla->cgi; my $cgi = Bugzilla->cgi;
my $dbh = Bugzilla->dbh;
my $showbugcounts = (defined $cgi->param('showbugcounts')); my $showbugcounts = (defined $cgi->param('showbugcounts'));
...@@ -445,13 +446,13 @@ if ($action eq 'delete') { ...@@ -445,13 +446,13 @@ if ($action eq 'delete') {
# lock the tables before we start to change everything: # lock the tables before we start to change everything:
SendSQL("LOCK TABLES attachments WRITE, $dbh->bz_lock_tables('attachments WRITE',
bugs WRITE, 'bugs WRITE',
bugs_activity WRITE, 'bugs_activity WRITE',
components WRITE, 'components WRITE',
dependencies WRITE, 'dependencies WRITE',
flaginclusions WRITE, 'flaginclusions WRITE',
flagexclusions WRITE"); 'flagexclusions WRITE');
# According to MySQL doc I cannot do a DELETE x.* FROM x JOIN Y, # 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 # so I have to iterate over bugs and delete all the indivial entries
...@@ -491,7 +492,7 @@ if ($action eq 'delete') { ...@@ -491,7 +492,7 @@ if ($action eq 'delete') {
SendSQL("DELETE FROM components SendSQL("DELETE FROM components
WHERE id=$component_id"); WHERE id=$component_id");
SendSQL("UNLOCK TABLES"); $dbh->bz_unlock_tables();
unlink "$datadir/versioncache"; unlink "$datadir/versioncache";
...@@ -575,14 +576,15 @@ if ($action eq 'update') { ...@@ -575,14 +576,15 @@ if ($action eq 'update') {
# Note that the order of this tests is important. If you change # Note that the order of this tests is important. If you change
# them, be sure to test for WHERE='$component' or WHERE='$componentold' # 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); CheckComponent($product, $componentold);
my $component_id = get_component_id(get_product_id($product), my $component_id = get_component_id(get_product_id($product),
$componentold); $componentold);
if ($description ne $descriptionold) { if ($description ne $descriptionold) {
unless ($description) { unless ($description) {
SendSQL("UNLOCK TABLES"); $dbh->bz_unlock_tables(UNLOCK_ABORT);
ThrowUserError('component_blank_description', ThrowUserError('component_blank_description',
{'name' => $componentold}); {'name' => $componentold});
exit; exit;
...@@ -600,7 +602,7 @@ if ($action eq 'update') { ...@@ -600,7 +602,7 @@ if ($action eq 'update') {
my $initialownerid = DBname_to_id($initialowner); my $initialownerid = DBname_to_id($initialowner);
unless ($initialownerid) { unless ($initialownerid) {
SendSQL("UNLOCK TABLES"); $dbh->bz_unlock_tables(UNLOCK_ABORT);
ThrowUserError('component_need_valid_initialowner', ThrowUserError('component_need_valid_initialowner',
{'name' => $componentold}); {'name' => $componentold});
exit; exit;
...@@ -618,7 +620,7 @@ if ($action eq 'update') { ...@@ -618,7 +620,7 @@ if ($action eq 'update') {
if (Param('useqacontact') && $initialqacontact ne $initialqacontactold) { if (Param('useqacontact') && $initialqacontact ne $initialqacontactold) {
my $initialqacontactid = DBname_to_id($initialqacontact); my $initialqacontactid = DBname_to_id($initialqacontact);
if (!$initialqacontactid && $initialqacontact ne '') { if (!$initialqacontactid && $initialqacontact ne '') {
SendSQL("UNLOCK TABLES"); $dbh->bz_unlock_tables(UNLOCK_ABORT);
ThrowUserError('component_need_valid_initialqacontact', ThrowUserError('component_need_valid_initialqacontact',
{'name' => $componentold}); {'name' => $componentold});
exit; exit;
...@@ -635,13 +637,13 @@ if ($action eq 'update') { ...@@ -635,13 +637,13 @@ if ($action eq 'update') {
if ($component ne $componentold) { if ($component ne $componentold) {
unless ($component) { unless ($component) {
SendSQL("UNLOCK TABLES"); $dbh->bz_unlock_tables(UNLOCK_ABORT);
ThrowUserError('component_must_have_a_name', ThrowUserError('component_must_have_a_name',
{'name' => $componentold}); {'name' => $componentold});
exit; exit;
} }
if (TestComponent($product, $component)) { if (TestComponent($product, $component)) {
SendSQL("UNLOCK TABLES"); $dbh->bz_unlock_tables(UNLOCK_ABORT);
ThrowUserError('component_already_exists', ThrowUserError('component_already_exists',
{'name' => $component}); {'name' => $component});
exit; exit;
...@@ -655,7 +657,7 @@ if ($action eq 'update') { ...@@ -655,7 +657,7 @@ if ($action eq 'update') {
} }
SendSQL("UNLOCK TABLES"); $dbh->bz_unlock_tables();
$vars->{'name'} = $component; $vars->{'name'} = $component;
$vars->{'product'} = $product; $vars->{'product'} = $product;
......
...@@ -221,13 +221,16 @@ sub insert { ...@@ -221,13 +221,16 @@ sub insert {
validateAllowMultiple(); validateAllowMultiple();
validateGroups(); validateGroups();
my $dbh = Bugzilla->dbh;
my $name = SqlQuote($::FORM{'name'}); my $name = SqlQuote($::FORM{'name'});
my $description = SqlQuote($::FORM{'description'}); my $description = SqlQuote($::FORM{'description'});
my $cc_list = SqlQuote($::FORM{'cc_list'}); my $cc_list = SqlQuote($::FORM{'cc_list'});
my $target_type = $::FORM{'target_type'} eq "bug" ? "b" : "a"; my $target_type = $::FORM{'target_type'} eq "bug" ? "b" : "a";
SendSQL("LOCK TABLES flagtypes WRITE, products READ, components READ, " . $dbh->bz_lock_tables('flagtypes WRITE', 'products READ',
"flaginclusions WRITE, flagexclusions WRITE"); 'components READ', 'flaginclusions WRITE',
'flagexclusions WRITE');
# Determine the new flag type's unique identifier. # Determine the new flag type's unique identifier.
SendSQL("SELECT MAX(id) FROM flagtypes"); SendSQL("SELECT MAX(id) FROM flagtypes");
...@@ -256,7 +259,7 @@ sub insert { ...@@ -256,7 +259,7 @@ sub insert {
} }
} }
SendSQL("UNLOCK TABLES"); $dbh->bz_unlock_tables();
$vars->{'name'} = $::FORM{'name'}; $vars->{'name'} = $::FORM{'name'};
$vars->{'message'} = "flag_type_created"; $vars->{'message'} = "flag_type_created";
...@@ -283,12 +286,15 @@ sub update { ...@@ -283,12 +286,15 @@ sub update {
validateAllowMultiple(); validateAllowMultiple();
validateGroups(); validateGroups();
my $dbh = Bugzilla->dbh;
my $name = SqlQuote($::FORM{'name'}); my $name = SqlQuote($::FORM{'name'});
my $description = SqlQuote($::FORM{'description'}); my $description = SqlQuote($::FORM{'description'});
my $cc_list = SqlQuote($::FORM{'cc_list'}); my $cc_list = SqlQuote($::FORM{'cc_list'});
SendSQL("LOCK TABLES flagtypes WRITE, products READ, components READ, " . $dbh->bz_lock_tables('flagtypes WRITE', 'products READ',
"flaginclusions WRITE, flagexclusions WRITE"); 'components READ', 'flaginclusions WRITE',
'flagexclusions WRITE');
SendSQL("UPDATE flagtypes SendSQL("UPDATE flagtypes
SET name = $name , SET name = $name ,
description = $description , description = $description ,
...@@ -316,7 +322,7 @@ sub update { ...@@ -316,7 +322,7 @@ sub update {
} }
} }
SendSQL("UNLOCK TABLES"); $dbh->bz_unlock_tables();
# Clear existing flags for bugs/attachments in categories no longer on # 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. # the list of inclusions or that have been added to the list of exclusions.
...@@ -385,8 +391,10 @@ sub confirmDelete ...@@ -385,8 +391,10 @@ sub confirmDelete
sub deleteType { sub deleteType {
validateID(); validateID();
SendSQL("LOCK TABLES flagtypes WRITE, flags WRITE, " . my $dbh = Bugzilla->dbh;
"flaginclusions WRITE, flagexclusions WRITE");
$dbh->bz_lock_tables('flagtypes WRITE', 'flags WRITE',
'flaginclusions WRITE', 'flagexclusions WRITE');
# Get the name of the flag type so we can tell users # Get the name of the flag type so we can tell users
# what was deleted. # what was deleted.
...@@ -397,7 +405,7 @@ sub deleteType { ...@@ -397,7 +405,7 @@ sub deleteType {
SendSQL("DELETE FROM flaginclusions WHERE type_id = $::FORM{'id'}"); SendSQL("DELETE FROM flaginclusions WHERE type_id = $::FORM{'id'}");
SendSQL("DELETE FROM flagexclusions WHERE type_id = $::FORM{'id'}"); SendSQL("DELETE FROM flagexclusions WHERE type_id = $::FORM{'id'}");
SendSQL("DELETE FROM flagtypes WHERE id = $::FORM{'id'}"); SendSQL("DELETE FROM flagtypes WHERE id = $::FORM{'id'}");
SendSQL("UNLOCK TABLES"); $dbh->bz_unlock_tables();
$vars->{'message'} = "flag_type_deleted"; $vars->{'message'} = "flag_type_deleted";
...@@ -414,9 +422,11 @@ sub deactivate { ...@@ -414,9 +422,11 @@ sub deactivate {
validateID(); validateID();
validateIsActive(); 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("UPDATE flagtypes SET is_active = 0 WHERE id = $::FORM{'id'}");
SendSQL("UNLOCK TABLES"); $dbh->bz_unlock_tables();
$vars->{'message'} = "flag_type_deactivated"; $vars->{'message'} = "flag_type_deactivated";
$vars->{'flag_type'} = Bugzilla::FlagType::get($::FORM{'id'}); $vars->{'flag_type'} = Bugzilla::FlagType::get($::FORM{'id'});
......
...@@ -483,10 +483,8 @@ if (($action eq 'remove_all_regexp') || ($action eq 'remove_all')) { ...@@ -483,10 +483,8 @@ if (($action eq 'remove_all_regexp') || ($action eq 'remove_all')) {
WHERE id = ?"); WHERE id = ?");
$sth->execute($gid); $sth->execute($gid);
my ($name, $regexp) = $sth->fetchrow_array(); my ($name, $regexp) = $sth->fetchrow_array();
$dbh->do("LOCK TABLES $dbh->bz_lock_tables('groups WRITE', 'profiles READ',
groups WRITE, 'user_group_map WRITE');
profiles READ,
user_group_map WRITE");
$sth = $dbh->prepare("SELECT user_group_map.user_id, profiles.login_name $sth = $dbh->prepare("SELECT user_group_map.user_id, profiles.login_name
FROM user_group_map, profiles FROM user_group_map, profiles
WHERE user_group_map.user_id = profiles.userid WHERE user_group_map.user_id = profiles.userid
...@@ -516,7 +514,7 @@ if (($action eq 'remove_all_regexp') || ($action eq 'remove_all')) { ...@@ -516,7 +514,7 @@ if (($action eq 'remove_all_regexp') || ($action eq 'remove_all')) {
SET last_changed = NOW() SET last_changed = NOW()
WHERE id = ?"); WHERE id = ?");
$sth->execute($gid); $sth->execute($gid);
$dbh->do("UNLOCK TABLES"); $dbh->bz_unlock_tables();
$vars->{'users'} = \@users; $vars->{'users'} = \@users;
$vars->{'name'} = $name; $vars->{'name'} = $name;
...@@ -545,9 +543,9 @@ sub doGroupChanges { ...@@ -545,9 +543,9 @@ sub doGroupChanges {
my $dbh = Bugzilla->dbh; my $dbh = Bugzilla->dbh;
my $sth; my $sth;
$dbh->do("LOCK TABLES groups WRITE, group_group_map WRITE, $dbh->bz_lock_tables('groups WRITE', 'group_group_map WRITE',
user_group_map WRITE, profiles READ, 'user_group_map WRITE', 'profiles READ',
namedqueries READ, whine_queries READ"); 'namedqueries READ', 'whine_queries READ');
# Check that the given group ID and regular expression are valid. # Check that the given group ID and regular expression are valid.
# If tests are successful, trimmed values are returned by CheckGroup*. # If tests are successful, trimmed values are returned by CheckGroup*.
...@@ -651,6 +649,6 @@ sub doGroupChanges { ...@@ -651,6 +649,6 @@ sub doGroupChanges {
# mark the changes # mark the changes
SendSQL("UPDATE groups SET last_changed = NOW() WHERE id = $gid"); SendSQL("UPDATE groups SET last_changed = NOW() WHERE id = $gid");
} }
$dbh->do("UNLOCK TABLES"); $dbh->bz_unlock_tables();
return $gid, $chgs, $name, $regexp; return $gid, $chgs, $name, $regexp;
} }
...@@ -360,11 +360,11 @@ if ($action eq 'delete') { ...@@ -360,11 +360,11 @@ if ($action eq 'delete') {
# lock the tables before we start to change everything: # lock the tables before we start to change everything:
$dbh->do('LOCK TABLES attachments WRITE, $dbh->bz_lock_tables('attachments WRITE',
bugs WRITE, 'bugs WRITE',
bugs_activity WRITE, 'bugs_activity WRITE',
milestones WRITE, 'milestones WRITE',
dependencies WRITE'); 'dependencies WRITE');
# According to MySQL doc I cannot do a DELETE x.* FROM x JOIN Y, # 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 # so I have to iterate over bugs and delete all the indivial entries
...@@ -425,7 +425,7 @@ if ($action eq 'delete') { ...@@ -425,7 +425,7 @@ if ($action eq 'delete') {
$product_id, $product_id,
$milestone); $milestone);
$dbh->do('UNLOCK TABLES'); $dbh->bz_unlock_tables();
unlink "$datadir/versioncache"; unlink "$datadir/versioncache";
...@@ -497,9 +497,9 @@ if ($action eq 'update') { ...@@ -497,9 +497,9 @@ if ($action eq 'update') {
my $dbh = Bugzilla->dbh; my $dbh = Bugzilla->dbh;
$dbh->do("LOCK TABLES bugs WRITE, $dbh->bz_lock_tables('bugs WRITE',
milestones WRITE, 'milestones WRITE',
products WRITE"); 'products WRITE');
# Need to store because detaint_natural() will delete this if # Need to store because detaint_natural() will delete this if
# invalid # invalid
...@@ -507,7 +507,7 @@ if ($action eq 'update') { ...@@ -507,7 +507,7 @@ if ($action eq 'update') {
if ($sortkey != $sortkeyold) { if ($sortkey != $sortkeyold) {
if (!detaint_natural($sortkey)) { if (!detaint_natural($sortkey)) {
$dbh->do('UNLOCK TABLES'); $dbh->bz_unlock_tables(UNLOCK_ABORT);
ThrowUserError('milestone_sortkey_invalid', ThrowUserError('milestone_sortkey_invalid',
{'name' => $milestone, {'name' => $milestone,
'sortkey' => $stored_sortkey}); 'sortkey' => $stored_sortkey});
...@@ -532,12 +532,12 @@ if ($action eq 'update') { ...@@ -532,12 +532,12 @@ if ($action eq 'update') {
if ($milestone ne $milestoneold) { if ($milestone ne $milestoneold) {
unless ($milestone) { unless ($milestone) {
$dbh->do('UNLOCK TABLES'); $dbh->bz_unlock_tables(UNLOCK_ABORT);
ThrowUserError('milestone_blank_name'); ThrowUserError('milestone_blank_name');
exit; exit;
} }
if (TestMilestone($product, $milestone)) { if (TestMilestone($product, $milestone)) {
$dbh->do('UNLOCK TABLES'); $dbh->bz_unlock_tables(UNLOCK_ABORT);
ThrowUserError('milestone_already_exists', ThrowUserError('milestone_already_exists',
{'name' => $milestone, {'name' => $milestone,
'product' => $product}); 'product' => $product});
...@@ -579,7 +579,7 @@ if ($action eq 'update') { ...@@ -579,7 +579,7 @@ if ($action eq 'update') {
$vars->{'updated_name'} = 1; $vars->{'updated_name'} = 1;
} }
$dbh->do('UNLOCK TABLES'); $dbh->bz_unlock_tables();
$vars->{'name'} = $milestone; $vars->{'name'} = $milestone;
$vars->{'product'} = $product; $vars->{'product'} = $product;
......
...@@ -231,7 +231,6 @@ sub EmitFormElements ($$$$$$$$$) ...@@ -231,7 +231,6 @@ sub EmitFormElements ($$$$$$$$$)
sub PutTrailer (@) sub PutTrailer (@)
{ {
my (@links) = ("Back to the <A HREF=\"query.cgi\">query page</A>", @_); my (@links) = ("Back to the <A HREF=\"query.cgi\">query page</A>", @_);
SendSQL("UNLOCK TABLES");
my $count = $#links; my $count = $#links;
my $num = 0; my $num = 0;
...@@ -281,6 +280,7 @@ my $headerdone = 0; ...@@ -281,6 +280,7 @@ my $headerdone = 0;
my $localtrailer = "<A HREF=\"editproducts.cgi\">edit</A> more products"; my $localtrailer = "<A HREF=\"editproducts.cgi\">edit</A> more products";
my $classhtmlvarstart = ""; my $classhtmlvarstart = "";
my $classhtmlvar = ""; my $classhtmlvar = "";
my $dbh = Bugzilla->dbh;
if (Param('useclassification') && (defined $classification)) { if (Param('useclassification') && (defined $classification)) {
$classhtmlvar = "&classification=" . url_quote($classification); $classhtmlvar = "&classification=" . url_quote($classification);
...@@ -336,7 +336,6 @@ unless ($action) { ...@@ -336,7 +336,6 @@ unless ($action) {
CheckClassificationNew($classification); CheckClassificationNew($classification);
} }
my $dbh = Bugzilla->dbh;
my @execute_params = (); my @execute_params = ();
my @products = (); my @products = ();
...@@ -786,19 +785,19 @@ if ($action eq 'delete') { ...@@ -786,19 +785,19 @@ if ($action eq 'delete') {
# lock the tables before we start to change everything: # lock the tables before we start to change everything:
SendSQL("LOCK TABLES attachments WRITE, $dbh->bz_lock_tables('attachments WRITE',
bugs WRITE, 'bugs WRITE',
bugs_activity WRITE, 'bugs_activity WRITE',
components WRITE, 'components WRITE',
dependencies WRITE, 'dependencies WRITE',
versions WRITE, 'versions WRITE',
products WRITE, 'products WRITE',
groups WRITE, 'groups WRITE',
group_control_map WRITE, 'group_control_map WRITE',
profiles WRITE, 'profiles WRITE',
milestones WRITE, 'milestones WRITE',
flaginclusions WRITE, 'flaginclusions WRITE',
flagexclusions WRITE"); 'flagexclusions WRITE');
# According to MySQL doc I cannot do a DELETE x.* FROM x JOIN Y, # 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 # so I have to iterate over bugs and delete all the indivial entries
...@@ -854,6 +853,8 @@ if ($action eq 'delete') { ...@@ -854,6 +853,8 @@ if ($action eq 'delete') {
WHERE id=$product_id"); WHERE id=$product_id");
print "Product '$product' deleted.<BR>\n"; print "Product '$product' deleted.<BR>\n";
$dbh->bz_unlock_tables();
unlink "$datadir/versioncache"; unlink "$datadir/versioncache";
PutTrailer($localtrailer); PutTrailer($localtrailer);
exit; exit;
...@@ -1107,12 +1108,12 @@ if ($action eq 'updategroupcontrols') { ...@@ -1107,12 +1108,12 @@ if ($action eq 'updategroupcontrols') {
header_done => 1}); header_done => 1});
} }
} }
SendSQL("LOCK TABLES groups READ, $dbh->bz_lock_tables('groups READ',
group_control_map WRITE, 'group_control_map WRITE',
bugs WRITE, 'bugs WRITE',
bugs_activity WRITE, 'bugs_activity WRITE',
bug_group_map WRITE, 'bug_group_map WRITE',
fielddefs READ"); 'fielddefs READ');
SendSQL("SELECT id, name, entry, membercontrol, othercontrol, canedit " . SendSQL("SELECT id, name, entry, membercontrol, othercontrol, canedit " .
"FROM groups " . "FROM groups " .
"LEFT JOIN group_control_map " . "LEFT JOIN group_control_map " .
...@@ -1234,6 +1235,8 @@ if ($action eq 'updategroupcontrols') { ...@@ -1234,6 +1235,8 @@ if ($action eq 'updategroupcontrols') {
} }
print "added $count bugs<p>\n"; print "added $count bugs<p>\n";
} }
$dbh->bz_unlock_tables();
print "Group control updates done<P>\n"; print "Group control updates done<P>\n";
PutTrailer($localtrailer); PutTrailer($localtrailer);
...@@ -1289,12 +1292,12 @@ if ($action eq 'update') { ...@@ -1289,12 +1292,12 @@ if ($action eq 'update') {
# Note that we got the $product_id using $productold above so it will # Note that we got the $product_id using $productold above so it will
# remain static even after we rename the product in the database. # remain static even after we rename the product in the database.
SendSQL("LOCK TABLES products WRITE, $dbh->bz_lock_tables('products WRITE',
versions READ, 'versions READ',
groups WRITE, 'groups WRITE',
group_control_map WRITE, 'group_control_map WRITE',
profiles WRITE, 'profiles WRITE',
milestones READ"); 'milestones READ');
if ($disallownew ne $disallownewold) { if ($disallownew ne $disallownewold) {
$disallownew = $disallownew ? 1 : 0; $disallownew = $disallownew ? 1 : 0;
...@@ -1307,6 +1310,7 @@ if ($action eq 'update') { ...@@ -1307,6 +1310,7 @@ if ($action eq 'update') {
if ($description ne $descriptionold) { if ($description ne $descriptionold) {
unless ($description) { unless ($description) {
print "Sorry, I can't delete the description."; print "Sorry, I can't delete the description.";
$dbh->bz_unlock_tables(UNLOCK_ABORT);
PutTrailer($localtrailer); PutTrailer($localtrailer);
exit; exit;
} }
...@@ -1357,6 +1361,7 @@ if ($action eq 'update') { ...@@ -1357,6 +1361,7 @@ if ($action eq 'update') {
" AND product_id = $product_id"); " AND product_id = $product_id");
if (!FetchOneColumn()) { if (!FetchOneColumn()) {
print "Sorry, the milestone $defaultmilestone must be defined first."; print "Sorry, the milestone $defaultmilestone must be defined first.";
$dbh->bz_unlock_tables(UNLOCK_ABORT);
PutTrailer($localtrailer); PutTrailer($localtrailer);
exit; exit;
} }
...@@ -1372,7 +1377,7 @@ if ($action eq 'update') { ...@@ -1372,7 +1377,7 @@ if ($action eq 'update') {
if ($product ne $productold) { if ($product ne $productold) {
unless ($product) { unless ($product) {
print "Sorry, I can't delete the product name."; print "Sorry, I can't delete the product name.";
SendSQL("UNLOCK TABLES"); $dbh->bz_unlock_tables(UNLOCK_ABORT);
PutTrailer($localtrailer); PutTrailer($localtrailer);
exit; exit;
} }
...@@ -1380,7 +1385,7 @@ if ($action eq 'update') { ...@@ -1380,7 +1385,7 @@ if ($action eq 'update') {
if (lc($product) ne lc($productold) && if (lc($product) ne lc($productold) &&
TestProduct($product)) { TestProduct($product)) {
print "Sorry, product name '$product' is already in use."; print "Sorry, product name '$product' is already in use.";
SendSQL("UNLOCK TABLES"); $dbh->bz_unlock_tables(UNLOCK_ABORT);
PutTrailer($localtrailer); PutTrailer($localtrailer);
exit; exit;
} }
...@@ -1388,8 +1393,8 @@ if ($action eq 'update') { ...@@ -1388,8 +1393,8 @@ if ($action eq 'update') {
SendSQL("UPDATE products SET name=$qp WHERE id=$product_id"); SendSQL("UPDATE products SET name=$qp WHERE id=$product_id");
print "Updated product name.<BR>\n"; print "Updated product name.<BR>\n";
} }
$dbh->bz_unlock_tables();
unlink "$datadir/versioncache"; unlink "$datadir/versioncache";
SendSQL("UNLOCK TABLES");
if ($checkvotes) { if ($checkvotes) {
# 1. too many votes for a single user on a single bug. # 1. too many votes for a single user on a single bug.
......
...@@ -39,6 +39,7 @@ use Bugzilla::Config qw(:DEFAULT $datadir); ...@@ -39,6 +39,7 @@ use Bugzilla::Config qw(:DEFAULT $datadir);
use vars qw($template $vars); use vars qw($template $vars);
my $cgi = Bugzilla->cgi; my $cgi = Bugzilla->cgi;
my $dbh = Bugzilla->dbh;
# TestProduct: just returns if the specified product does exists # TestProduct: just returns if the specified product does exists
# CheckProduct: same check, optionally emit an error text # CheckProduct: same check, optionally emit an error text
...@@ -303,11 +304,11 @@ if ($action eq 'delete') { ...@@ -303,11 +304,11 @@ if ($action eq 'delete') {
# lock the tables before we start to change everything: # lock the tables before we start to change everything:
SendSQL("LOCK TABLES attachments WRITE, $dbh->bz_lock_tables('attachments WRITE',
bugs WRITE, 'bugs WRITE',
bugs_activity WRITE, 'bugs_activity WRITE',
versions WRITE, 'versions WRITE',
dependencies WRITE"); 'dependencies WRITE');
# According to MySQL doc I cannot do a DELETE x.* FROM x JOIN Y, # 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 # so I have to iterate over bugs and delete all the indivial entries
...@@ -347,7 +348,7 @@ if ($action eq 'delete') { ...@@ -347,7 +348,7 @@ if ($action eq 'delete') {
WHERE product_id = $product_id WHERE product_id = $product_id
AND value = " . SqlQuote($version)); AND value = " . SqlQuote($version));
SendSQL("UNLOCK TABLES;"); $dbh->bz_unlock_tables();
unlink "$datadir/versioncache"; unlink "$datadir/versioncache";
...@@ -399,18 +400,18 @@ if ($action eq 'update') { ...@@ -399,18 +400,18 @@ if ($action eq 'update') {
# Note that the order of this tests is important. If you change # Note that the order of this tests is important. If you change
# them, be sure to test for WHERE='$version' or WHERE='$versionold' # them, be sure to test for WHERE='$version' or WHERE='$versionold'
SendSQL("LOCK TABLES bugs WRITE, $dbh->bz_lock_tables('bugs WRITE',
versions WRITE, 'versions WRITE',
products READ"); 'products READ');
if ($version ne $versionold) { if ($version ne $versionold) {
unless ($version) { unless ($version) {
SendSQL('UNLOCK TABLES'); $dbh->bz_unlock_tables(UNLOCK_ABORT);
ThrowUserError('version_blank_name'); ThrowUserError('version_blank_name');
exit; exit;
} }
if (TestVersion($product,$version)) { if (TestVersion($product,$version)) {
SendSQL('UNLOCK TABLES'); $dbh->bz_unlock_tables(UNLOCK_ABORT);
ThrowUserError('version_already_exists', ThrowUserError('version_already_exists',
{'name' => $version, {'name' => $version,
'product' => $product}); 'product' => $product});
...@@ -430,7 +431,7 @@ if ($action eq 'update') { ...@@ -430,7 +431,7 @@ if ($action eq 'update') {
$vars->{'updated_name'} = 1; $vars->{'updated_name'} = 1;
} }
SendSQL('UNLOCK TABLES'); $dbh->bz_unlock_tables();
$vars->{'name'} = $version; $vars->{'name'} = $version;
$vars->{'product'} = $product; $vars->{'product'} = $product;
......
...@@ -60,6 +60,7 @@ my $user = Bugzilla->login(LOGIN_REQUIRED); ...@@ -60,6 +60,7 @@ my $user = Bugzilla->login(LOGIN_REQUIRED);
my $whoid = $user->id; my $whoid = $user->id;
my $cgi = Bugzilla->cgi; my $cgi = Bugzilla->cgi;
my $dbh = Bugzilla->dbh;
my $requiremilestone = 0; my $requiremilestone = 0;
...@@ -1134,22 +1135,22 @@ foreach my $id (@idlist) { ...@@ -1134,22 +1135,22 @@ foreach my $id (@idlist) {
$bug_changed = 0; $bug_changed = 0;
my $write = "WRITE"; # Might want to make a param to control my $write = "WRITE"; # Might want to make a param to control
# whether we do LOW_PRIORITY ... # whether we do LOW_PRIORITY ...
SendSQL("LOCK TABLES bugs $write, bugs_activity $write, cc $write, " . $dbh->bz_lock_tables("bugs $write", "bugs_activity $write",
"cc AS selectVisible_cc $write, " . "cc $write", "cc AS selectVisible_cc $write",
"profiles $write, dependencies $write, votes $write, " . "profiles $write", "dependencies $write", "votes $write",
"products READ, components READ, " . "products READ", "components READ",
"keywords $write, longdescs $write, fielddefs $write, " . "keywords $write", "longdescs $write", "fielddefs $write",
"bug_group_map $write, flags $write, duplicates $write," . "bug_group_map $write", "flags $write", "duplicates $write",
# user_group_map would be a READ lock except that Flag::process # user_group_map would be a READ lock except that Flag::process
# may call Flag::notify, which creates a new user object, # may call Flag::notify, which creates a new user object,
# which might call derive_groups, which wants a WRITE lock on that # which might call derive_groups, which wants a WRITE lock on that
# table. group_group_map is in here at all because derive_groups # table. group_group_map is in here at all because derive_groups
# needs it. # needs it.
"user_group_map $write, group_group_map READ, flagtypes READ, " . "user_group_map $write", "group_group_map READ", "flagtypes READ",
"flaginclusions AS i READ, flagexclusions AS e READ, " . "flaginclusions AS i READ", "flagexclusions AS e READ",
"keyworddefs READ, groups READ, attachments READ, " . "keyworddefs READ", "groups READ", "attachments READ",
"group_control_map AS oldcontrolmap READ, " . "group_control_map AS oldcontrolmap READ",
"group_control_map AS newcontrolmap READ, " . "group_control_map AS newcontrolmap READ",
"group_control_map READ"); "group_control_map READ");
# Fun hack. @::log_columns only contains the component_id, # Fun hack. @::log_columns only contains the component_id,
# not the name (since bug 43600 got fixed). So, we need to have # not the name (since bug 43600 got fixed). So, we need to have
...@@ -1270,7 +1271,7 @@ foreach my $id (@idlist) { ...@@ -1270,7 +1271,7 @@ foreach my $id (@idlist) {
$vars->{'bug_id'} = $id; $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. # Warn the user about the mid-air collision and ask them what to do.
$template->process("bug/process/midair.html.tmpl", $vars) $template->process("bug/process/midair.html.tmpl", $vars)
...@@ -1773,7 +1774,7 @@ foreach my $id (@idlist) { ...@@ -1773,7 +1774,7 @@ foreach my $id (@idlist) {
if ($bug_changed) { if ($bug_changed) {
SendSQL("UPDATE bugs SET delta_ts = $sql_timestamp WHERE bug_id = $id"); SendSQL("UPDATE bugs SET delta_ts = $sql_timestamp WHERE bug_id = $id");
} }
SendSQL("UNLOCK TABLES"); $dbh->bz_unlock_tables();
$vars->{'mailrecipients'} = { 'cc' => \@ccRemoved, $vars->{'mailrecipients'} = { 'cc' => \@ccRemoved,
'owner' => $origOwner, 'owner' => $origOwner,
......
...@@ -88,7 +88,7 @@ if ($userid) { ...@@ -88,7 +88,7 @@ if ($userid) {
# If the query name contains invalid characters, don't import. # If the query name contains invalid characters, don't import.
$name =~ /[<>&]/ && next; $name =~ /[<>&]/ && next;
trick_taint($name); trick_taint($name);
$dbh->do("LOCK TABLES namedqueries WRITE"); $dbh->bz_lock_tables('namedqueries WRITE');
my $query = $dbh->selectrow_array( my $query = $dbh->selectrow_array(
"SELECT query FROM namedqueries " . "SELECT query FROM namedqueries " .
"WHERE userid = ? AND name = ?", "WHERE userid = ? AND name = ?",
...@@ -98,7 +98,7 @@ if ($userid) { ...@@ -98,7 +98,7 @@ if ($userid) {
"(userid, name, query) VALUES " . "(userid, name, query) VALUES " .
"(?, ?, ?)", undef, ($userid, $name, $value)); "(?, ?, ?)", undef, ($userid, $name, $value));
} }
$dbh->do("UNLOCK TABLES"); $dbh->bz_unlock_tables();
} }
$cgi->send_cookie(-name => $cookiename, $cgi->send_cookie(-name => $cookiename,
-expires => "Fri, 01-Jan-2038 00:00:00 GMT"); -expires => "Fri, 01-Jan-2038 00:00:00 GMT");
...@@ -358,7 +358,7 @@ $vars->{'bug_severity'} = \@::legal_severity; ...@@ -358,7 +358,7 @@ $vars->{'bug_severity'} = \@::legal_severity;
# Boolean charts # Boolean charts
my @fields; my @fields;
push(@fields, { name => "noop", description => "---" }); push(@fields, { name => "noop", description => "---" });
push(@fields, Bugzilla->dbh->bz_get_field_defs()); push(@fields, $dbh->bz_get_field_defs());
$vars->{'fields'} = \@fields; $vars->{'fields'} = \@fields;
# Creating new charts - if the cmd-add value is there, we define the field # Creating new charts - if the cmd-add value is there, we define the field
......
...@@ -71,6 +71,7 @@ sub BugListLinks { ...@@ -71,6 +71,7 @@ sub BugListLinks {
Bugzilla->login(LOGIN_REQUIRED); Bugzilla->login(LOGIN_REQUIRED);
my $cgi = Bugzilla->cgi; my $cgi = Bugzilla->cgi;
my $dbh = Bugzilla->dbh;
# Make sure the user is authorized to access sanitycheck.cgi. Access # Make sure the user is authorized to access sanitycheck.cgi. Access
# is restricted to logged-in users who have "editbugs" privileges, # is restricted to logged-in users who have "editbugs" privileges,
...@@ -95,7 +96,7 @@ PutHeader("Bugzilla Sanity Check"); ...@@ -95,7 +96,7 @@ PutHeader("Bugzilla Sanity Check");
if (defined $cgi->param('rebuildvotecache')) { if (defined $cgi->param('rebuildvotecache')) {
Status("OK, now rebuilding vote cache."); 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("UPDATE bugs SET votes = 0");
SendSQL("SELECT bug_id, SUM(vote_count) FROM votes GROUP BY bug_id"); SendSQL("SELECT bug_id, SUM(vote_count) FROM votes GROUP BY bug_id");
my %votes; my %votes;
...@@ -106,7 +107,7 @@ if (defined $cgi->param('rebuildvotecache')) { ...@@ -106,7 +107,7 @@ if (defined $cgi->param('rebuildvotecache')) {
foreach my $id (keys %votes) { foreach my $id (keys %votes) {
SendSQL("UPDATE bugs SET votes = $votes{$id} WHERE bug_id = $id"); SendSQL("UPDATE bugs SET votes = $votes{$id} WHERE bug_id = $id");
} }
SendSQL("UNLOCK TABLES"); $dbh->bz_unlock_tables();
Status("Vote cache has been rebuilt."); Status("Vote cache has been rebuilt.");
} }
...@@ -148,7 +149,7 @@ if (defined $cgi->param('cleangroupsnow')) { ...@@ -148,7 +149,7 @@ if (defined $cgi->param('cleangroupsnow')) {
Status("Cutoff is $cutoff"); Status("Cutoff is $cutoff");
SendSQL("SELECT COUNT(*) FROM user_group_map"); SendSQL("SELECT COUNT(*) FROM user_group_map");
(my $before) = FetchSQLData(); (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 " . SendSQL("SELECT userid FROM profiles " .
"WHERE refreshed_when > 0 " . "WHERE refreshed_when > 0 " .
"AND refreshed_when < " . SqlQuote($cutoff) . "AND refreshed_when < " . SqlQuote($cutoff) .
...@@ -162,7 +163,7 @@ if (defined $cgi->param('cleangroupsnow')) { ...@@ -162,7 +163,7 @@ if (defined $cgi->param('cleangroupsnow')) {
SendSQL("UPDATE profiles SET refreshed_when = 0 WHERE userid = $id"); SendSQL("UPDATE profiles SET refreshed_when = 0 WHERE userid = $id");
PopGlobalSQLState(); PopGlobalSQLState();
} }
SendSQL("UNLOCK TABLES"); $dbh->bz_unlock_tables();
SendSQL("SELECT COUNT(*) FROM user_group_map"); SendSQL("SELECT COUNT(*) FROM user_group_map");
(my $after) = FetchSQLData(); (my $after) = FetchSQLData();
Status("Cleaned table for $count users " . Status("Cleaned table for $count users " .
...@@ -537,7 +538,8 @@ Status("Checking cached keywords"); ...@@ -537,7 +538,8 @@ Status("Checking cached keywords");
my %realk; my %realk;
if (defined $cgi->param('rebuildkeywordcache')) { 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 " . SendSQL("SELECT keywords.bug_id, keyworddefs.name " .
...@@ -596,7 +598,7 @@ if (@badbugs) { ...@@ -596,7 +598,7 @@ if (@badbugs) {
} }
if (defined $cgi->param('rebuildkeywordcache')) { if (defined $cgi->param('rebuildkeywordcache')) {
SendSQL("UNLOCK TABLES"); $dbh->bz_unlock_tables();
} }
########################################################################### ###########################################################################
......
...@@ -192,6 +192,8 @@ sub cancelChangePassword { ...@@ -192,6 +192,8 @@ sub cancelChangePassword {
} }
sub changePassword { sub changePassword {
my $dbh = Bugzilla->dbh;
# Quote the password and token for inclusion into SQL statements. # Quote the password and token for inclusion into SQL statements.
my $cryptedpassword = bz_crypt($cgi->param('password')); my $cryptedpassword = bz_crypt($cgi->param('password'));
my $quotedpassword = SqlQuote($cryptedpassword); my $quotedpassword = SqlQuote($cryptedpassword);
...@@ -202,12 +204,12 @@ sub changePassword { ...@@ -202,12 +204,12 @@ sub changePassword {
# Update the user's password in the profiles table and delete the token # Update the user's password in the profiles table and delete the token
# from the tokens table. # from the tokens table.
SendSQL("LOCK TABLES profiles WRITE , tokens WRITE"); $dbh->bz_lock_tables('profiles WRITE', 'tokens WRITE');
SendSQL("UPDATE profiles SendSQL("UPDATE profiles
SET cryptpassword = $quotedpassword SET cryptpassword = $quotedpassword
WHERE userid = $userid"); WHERE userid = $userid");
SendSQL("DELETE FROM tokens WHERE token = $::quotedtoken"); SendSQL("DELETE FROM tokens WHERE token = $::quotedtoken");
SendSQL("UNLOCK TABLES"); $dbh->bz_unlock_tables();
Bugzilla->logout_user_by_id($userid); Bugzilla->logout_user_by_id($userid);
...@@ -229,6 +231,7 @@ sub confirmChangeEmail { ...@@ -229,6 +231,7 @@ sub confirmChangeEmail {
} }
sub changeEmail { sub changeEmail {
my $dbh = Bugzilla->dbh;
# Get the user's ID from the tokens table. # Get the user's ID from the tokens table.
SendSQL("SELECT userid, eventdata FROM tokens SendSQL("SELECT userid, eventdata FROM tokens
...@@ -251,14 +254,14 @@ sub changeEmail { ...@@ -251,14 +254,14 @@ sub changeEmail {
# Update the user's login name in the profiles table and delete the token # Update the user's login name in the profiles table and delete the token
# from the tokens table. # from the tokens table.
SendSQL("LOCK TABLES profiles WRITE , tokens WRITE"); $dbh->bz_lock_tables('profiles WRITE', 'tokens WRITE');
SendSQL("UPDATE profiles SendSQL("UPDATE profiles
SET login_name = $quotednewemail SET login_name = $quotednewemail
WHERE userid = $userid"); WHERE userid = $userid");
SendSQL("DELETE FROM tokens WHERE token = $::quotedtoken"); SendSQL("DELETE FROM tokens WHERE token = $::quotedtoken");
SendSQL("DELETE FROM tokens WHERE userid = $userid SendSQL("DELETE FROM tokens WHERE userid = $userid
AND tokentype = 'emailnew'"); AND tokentype = 'emailnew'");
SendSQL("UNLOCK TABLES"); $dbh->bz_unlock_tables();
# The email address has been changed, so we need to rederive the groups # The email address has been changed, so we need to rederive the groups
my $user = new Bugzilla::User($userid); my $user = new Bugzilla::User($userid);
...@@ -276,6 +279,8 @@ sub changeEmail { ...@@ -276,6 +279,8 @@ sub changeEmail {
} }
sub cancelChangeEmail { sub cancelChangeEmail {
my $dbh = Bugzilla->dbh;
# Get the user's ID from the tokens table. # Get the user's ID from the tokens table.
SendSQL("SELECT userid, tokentype, eventdata FROM tokens SendSQL("SELECT userid, tokentype, eventdata FROM tokens
WHERE token = $::quotedtoken"); WHERE token = $::quotedtoken");
...@@ -292,11 +297,11 @@ sub cancelChangeEmail { ...@@ -292,11 +297,11 @@ sub cancelChangeEmail {
if($actualemail ne $old_email) { if($actualemail ne $old_email) {
my $quotedoldemail = SqlQuote($old_email); my $quotedoldemail = SqlQuote($old_email);
SendSQL("LOCK TABLES profiles WRITE"); $dbh->bz_lock_tables('profiles WRITE');
SendSQL("UPDATE profiles SendSQL("UPDATE profiles
SET login_name = $quotedoldemail SET login_name = $quotedoldemail
WHERE userid = $userid"); WHERE userid = $userid");
SendSQL("UNLOCK TABLES"); $dbh->bz_unlock_tables();
# email has changed, so rederive groups # email has changed, so rederive groups
# Note that this is done _after_ the tables are unlocked # Note that this is done _after_ the tables are unlocked
...@@ -318,11 +323,11 @@ sub cancelChangeEmail { ...@@ -318,11 +323,11 @@ sub cancelChangeEmail {
$vars->{'new_email'} = $new_email; $vars->{'new_email'} = $new_email;
Bugzilla::Token::Cancel($::token, $vars->{'message'}); Bugzilla::Token::Cancel($::token, $vars->{'message'});
SendSQL("LOCK TABLES tokens WRITE"); $dbh->bz_lock_tables('tokens WRITE');
SendSQL("DELETE FROM tokens SendSQL("DELETE FROM tokens
WHERE userid = $userid WHERE userid = $userid
AND tokentype = 'emailold' OR tokentype = 'emailnew'"); AND tokentype = 'emailold' OR tokentype = 'emailnew'");
SendSQL("UNLOCK TABLES"); $dbh->bz_unlock_tables();
# Return HTTP response headers. # Return HTTP response headers.
print $cgi->header(); print $cgi->header();
......
...@@ -195,6 +195,7 @@ sub DoEmail { ...@@ -195,6 +195,7 @@ sub DoEmail {
sub SaveEmail { sub SaveEmail {
my $updateString = ""; my $updateString = "";
my $cgi = Bugzilla->cgi; my $cgi = Bugzilla->cgi;
my $dbh = Bugzilla->dbh;
if (defined $cgi->param('ExcludeSelf')) { if (defined $cgi->param('ExcludeSelf')) {
$updateString .= 'ExcludeSelf~on'; $updateString .= 'ExcludeSelf~on';
...@@ -226,7 +227,7 @@ sub SaveEmail { ...@@ -226,7 +227,7 @@ sub SaveEmail {
# we don't really care if anyone reads the watch table. So # we don't really care if anyone reads the watch table. So
# some small amount of contention could be gotten rid of by # some small amount of contention could be gotten rid of by
# using user-defined locks rather than table locking. # 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 # what the db looks like now
my $origWatchedUsers = new Bugzilla::RelationSet; my $origWatchedUsers = new Bugzilla::RelationSet;
...@@ -244,7 +245,7 @@ sub SaveEmail { ...@@ -244,7 +245,7 @@ sub SaveEmail {
($CCDELTAS[0] eq "") || SendSQL($CCDELTAS[0]); ($CCDELTAS[0] eq "") || SendSQL($CCDELTAS[0]);
($CCDELTAS[1] eq "") || SendSQL($CCDELTAS[1]); ($CCDELTAS[1] eq "") || SendSQL($CCDELTAS[1]);
SendSQL("UNLOCK TABLES"); $dbh->bz_unlock_tables();
} }
} }
......
...@@ -120,6 +120,7 @@ sub show_user { ...@@ -120,6 +120,7 @@ sub show_user {
GetVersionTable(); GetVersionTable();
my $cgi = Bugzilla->cgi; 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. # If a bug_id is given, and we're editing, we'll add it to the votes list.
$bug_id ||= ""; $bug_id ||= "";
...@@ -130,9 +131,9 @@ sub show_user { ...@@ -130,9 +131,9 @@ sub show_user {
my $canedit = (Param('usevotes') && $userid == $who) ? 1 : 0; my $canedit = (Param('usevotes') && $userid == $who) ? 1 : 0;
SendSQL("LOCK TABLES bugs READ, products READ, votes WRITE, $dbh->bz_lock_tables('bugs READ', 'products READ', 'votes WRITE',
cc READ, bug_group_map READ, user_group_map READ, 'cc READ', 'bug_group_map READ', 'user_group_map READ',
cc AS selectVisible_cc READ, groups READ"); 'cc AS selectVisible_cc READ', 'groups READ');
if ($canedit && $bug_id) { if ($canedit && $bug_id) {
# Make sure there is an entry for this bug # Make sure there is an entry for this bug
...@@ -212,7 +213,7 @@ sub show_user { ...@@ -212,7 +213,7 @@ sub show_user {
} }
SendSQL("DELETE FROM votes WHERE vote_count <= 0"); SendSQL("DELETE FROM votes WHERE vote_count <= 0");
SendSQL("UNLOCK TABLES"); $dbh->bz_unlock_tables();
$vars->{'canedit'} = $canedit; $vars->{'canedit'} = $canedit;
$vars->{'voting_user'} = { "login" => $name }; $vars->{'voting_user'} = { "login" => $name };
...@@ -231,6 +232,7 @@ sub record_votes { ...@@ -231,6 +232,7 @@ sub record_votes {
############################################################################ ############################################################################
my $cgi = Bugzilla->cgi; my $cgi = Bugzilla->cgi;
my $dbh = Bugzilla->dbh;
# Build a list of bug IDs for which votes have been submitted. Votes # 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 # are submitted in form fields in which the field names are the bug
...@@ -314,12 +316,13 @@ sub record_votes { ...@@ -314,12 +316,13 @@ sub record_votes {
# for products that only allow one vote per bug). In that case, we still # for products that only allow one vote per bug). In that case, we still
# need to clear the user's votes from the database. # need to clear the user's votes from the database.
my %affected; my %affected;
SendSQL("LOCK TABLES bugs WRITE, bugs_activity WRITE, votes WRITE, $dbh->bz_lock_tables('bugs WRITE', 'bugs_activity WRITE',
longdescs WRITE, profiles READ, products READ, components READ, 'votes WRITE', 'longdescs WRITE', 'profiles READ',
cc READ, dependencies READ, groups READ, fielddefs READ, 'products READ', 'components READ', 'cc READ',
namedqueries READ, whine_queries READ, watch READ, 'dependencies READ', 'groups READ', 'fielddefs READ',
profiles AS watchers READ, profiles AS watched READ, 'namedqueries READ', 'whine_queries READ', 'watch READ',
user_group_map READ, bug_group_map 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. # Take note of, and delete the user's old votes from the database.
SendSQL("SELECT bug_id FROM votes WHERE who = $who"); SendSQL("SELECT bug_id FROM votes WHERE who = $who");
...@@ -349,7 +352,7 @@ sub record_votes { ...@@ -349,7 +352,7 @@ sub record_votes {
$vars->{'header_done'} = 1 if $confirmed; $vars->{'header_done'} = 1 if $confirmed;
} }
SendSQL("UNLOCK TABLES"); $dbh->bz_unlock_tables();
$vars->{'votes_recorded'} = 1; $vars->{'votes_recorded'} = 1;
} }
...@@ -220,12 +220,11 @@ sub get_next_event { ...@@ -220,12 +220,11 @@ sub get_next_event {
# Loop until there's something to return # Loop until there's something to return
until (scalar keys %{$event}) { until (scalar keys %{$event}) {
$dbh->do("LOCK TABLE " . $dbh->bz_lock_tables('whine_schedules WRITE',
"whine_schedules WRITE, " . 'whine_events READ',
"whine_events READ, " . 'profiles READ',
"profiles READ, " . 'groups READ',
"groups READ, " . 'user_group_map READ');
"user_group_map READ");
# Get the event ID for the first pending schedule # Get the event ID for the first pending schedule
$sth_next_scheduled_event->execute; $sth_next_scheduled_event->execute;
...@@ -262,7 +261,7 @@ sub get_next_event { ...@@ -262,7 +261,7 @@ sub get_next_event {
reset_timer($sid); reset_timer($sid);
} }
$dbh->do("UNLOCK TABLES"); $dbh->bz_unlock_tables();
# Only set $event if the user is allowed to do whining # Only set $event if the user is allowed to do whining
if ($owner->in_group('bz_canusewhines')) { if ($owner->in_group('bz_canusewhines')) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment