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);
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;
......@@ -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
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
......
......@@ -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") {
......
......@@ -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
......
......@@ -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 {
......
......@@ -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 {
......
......@@ -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.
......
......@@ -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;
}
......
......@@ -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');
}
......
......@@ -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);
......
......@@ -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;
......
......@@ -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'});
......
......@@ -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;
}
......@@ -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;
......
......@@ -231,7 +231,6 @@ sub EmitFormElements ($$$$$$$$$)
sub PutTrailer (@)
{
my (@links) = ("Back to the <A HREF=\"query.cgi\">query page</A>", @_);
SendSQL("UNLOCK TABLES");
my $count = $#links;
my $num = 0;
......@@ -281,6 +280,7 @@ my $headerdone = 0;
my $localtrailer = "<A HREF=\"editproducts.cgi\">edit</A> 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.<BR>\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<p>\n";
}
$dbh->bz_unlock_tables();
print "Group control updates done<P>\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.<BR>\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.
......
......@@ -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;
......
......@@ -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,
......
......@@ -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
......
......@@ -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();
}
###########################################################################
......
......@@ -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();
......
......@@ -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();
}
}
......
......@@ -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;
}
......@@ -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')) {
......
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