Bug 43600 - Convert products/components to use ids instead of names.

Initial attempt by jake@bugzilla.org, updated by me r=joel, preed
parent 17b301e7
...@@ -111,13 +111,16 @@ sub initBug { ...@@ -111,13 +111,16 @@ sub initBug {
my $query = " my $query = "
select select
bugs.bug_id, alias, product, version, rep_platform, op_sys, bug_status, bugs.bug_id, alias, products.name, version, rep_platform, op_sys, bug_status,
resolution, priority, bug_severity, component, assigned_to, reporter, resolution, priority, bug_severity, components.name, assigned_to, reporter,
bug_file_loc, short_desc, target_milestone, qa_contact, bug_file_loc, short_desc, target_milestone, qa_contact,
status_whiteboard, date_format(creation_ts,'%Y-%m-%d %H:%i'), status_whiteboard, date_format(creation_ts,'%Y-%m-%d %H:%i'),
groupset, delta_ts, sum(votes.count) groupset, delta_ts, sum(votes.count)
from bugs left join votes using(bug_id) from bugs left join votes using(bug_id),
products, components
where bugs.bug_id = $bug_id where bugs.bug_id = $bug_id
AND products.id = bugs.product_id
AND components.id = bugs.component_id
group by bugs.bug_id"; group by bugs.bug_id";
&::SendSQL(&::SelectVisible($query, $user_id, $usergroupset)); &::SendSQL(&::SelectVisible($query, $user_id, $usergroupset));
......
...@@ -111,13 +111,16 @@ sub initBug { ...@@ -111,13 +111,16 @@ sub initBug {
my $query = " my $query = "
select select
bugs.bug_id, alias, product, version, rep_platform, op_sys, bug_status, bugs.bug_id, alias, products.name, version, rep_platform, op_sys, bug_status,
resolution, priority, bug_severity, component, assigned_to, reporter, resolution, priority, bug_severity, components.name, assigned_to, reporter,
bug_file_loc, short_desc, target_milestone, qa_contact, bug_file_loc, short_desc, target_milestone, qa_contact,
status_whiteboard, date_format(creation_ts,'%Y-%m-%d %H:%i'), status_whiteboard, date_format(creation_ts,'%Y-%m-%d %H:%i'),
groupset, delta_ts, sum(votes.count) groupset, delta_ts, sum(votes.count)
from bugs left join votes using(bug_id) from bugs left join votes using(bug_id),
products, components
where bugs.bug_id = $bug_id where bugs.bug_id = $bug_id
AND products.id = bugs.product_id
AND components.id = bugs.component_id
group by bugs.bug_id"; group by bugs.bug_id";
&::SendSQL(&::SelectVisible($query, $user_id, $usergroupset)); &::SendSQL(&::SelectVisible($query, $user_id, $usergroupset));
......
...@@ -66,13 +66,29 @@ sub init { ...@@ -66,13 +66,29 @@ sub init {
my @andlist; my @andlist;
# First, deal with all the old hard-coded non-chart-based poop. # First, deal with all the old hard-coded non-chart-based poop.
unshift(@supptables, if (&::lsearch($fieldsref, 'map_assigned_to.login_name') >= 0) {
("profiles map_assigned_to", push @supptables, "profiles AS map_assigned_to";
"profiles map_reporter", push @wherepart, "bugs.assigned_to = map_assigned_to.userid";
"LEFT JOIN profiles map_qa_contact ON bugs.qa_contact = map_qa_contact.userid")); }
unshift(@wherepart,
("bugs.assigned_to = map_assigned_to.userid", if (&::lsearch($fieldsref, 'map_reporter.login_name') >= 0) {
"bugs.reporter = map_reporter.userid")); push @supptables, "profiles AS map_reporter";
push @wherepart, "bugs.assigned_to = map_reporter.userid";
}
if (&::lsearch($fieldsref, 'map_qa_contact.login_name') >= 0) {
push @supptables, "LEFT JOIN profiles map_qa_contact ON bugs.qa_contact = map_qa_contact.userid";
}
if (&::lsearch($fieldsref, 'map_products.name') >= 0) {
push @supptables, "products AS map_products";
push @wherepart, "bugs.product_id = map_products.id";
}
if (&::lsearch($fieldsref, 'map_components.name') >= 0) {
push @supptables, "components AS map_components";
push @wherepart, "bugs.component_id = map_components.id";
}
my $minvotes; my $minvotes;
if (defined $F{'votes'}) { if (defined $F{'votes'}) {
...@@ -108,6 +124,18 @@ sub init { ...@@ -108,6 +124,18 @@ sub init {
} }
} }
if ($F{'product'}) {
push(@supptables, "products products_");
push(@wherepart, "products_.id = bugs.product_id");
push(@specialchart, ["products_.name", "anyexact", $F{'product'}]);
}
if ($F{'component'}) {
push(@supptables, "components components_");
push(@wherepart, "components_.id = bugs.component_id");
push(@specialchart, ["components_.name", "anyexact", $F{'component'}]);
}
if ($F{'keywords'}) { if ($F{'keywords'}) {
my $t = $F{'keywords_type'}; my $t = $F{'keywords_type'};
if (!$t || $t eq "or") { if (!$t || $t eq "or") {
...@@ -248,7 +276,7 @@ sub init { ...@@ -248,7 +276,7 @@ sub init {
my @funcdefs = my @funcdefs =
( (
"^(assigned_to|reporter)," => sub { "^(assigned_to|reporter)," => sub {
push(@supptables, "profiles map_$f"); push(@supptables, "profiles AS map_$f");
push(@wherepart, "bugs.$f = map_$f.userid"); push(@wherepart, "bugs.$f = map_$f.userid");
$f = "map_$f.login_name"; $f = "map_$f.login_name";
}, },
...@@ -391,6 +419,20 @@ sub init { ...@@ -391,6 +419,20 @@ sub init {
$f = "(to_days(now()) - to_days(bugs.delta_ts))"; $f = "(to_days(now()) - to_days(bugs.delta_ts))";
}, },
"^component,(?!changed)" => sub {
my $table = "components_$chartid";
push(@supptables, "components $table");
push(@wherepart, "bugs.component_id = $table.id");
$f = $ff = "$table.name";
},
"^product,(?!changed)" => sub {
my $table = "products_$chartid";
push(@supptables, "products $table");
push(@wherepart, "bugs.product_id = $table.id");
$f = $ff = "$table.name";
},
"^keywords," => sub { "^keywords," => sub {
&::GetVersionTable(); &::GetVersionTable();
my @list; my @list;
......
...@@ -947,7 +947,7 @@ sub CheckIfVotedConfirmed { ...@@ -947,7 +947,7 @@ sub CheckIfVotedConfirmed {
SendSQL("SELECT bugs.votes, bugs.bug_status, products.votestoconfirm, " . SendSQL("SELECT bugs.votes, bugs.bug_status, products.votestoconfirm, " .
" bugs.everconfirmed " . " bugs.everconfirmed " .
"FROM bugs, products " . "FROM bugs, products " .
"WHERE bugs.bug_id = $id AND products.product = bugs.product"); "WHERE bugs.bug_id = $id AND products.product_id = bugs.product_id");
my ($votes, $status, $votestoconfirm, $everconfirmed) = (FetchSQLData()); my ($votes, $status, $votestoconfirm, $everconfirmed) = (FetchSQLData());
if ($votes >= $votestoconfirm && $status eq $::unconfirmedstate) { if ($votes >= $votestoconfirm && $status eq $::unconfirmedstate) {
SendSQL("UPDATE bugs SET bug_status = 'NEW', everconfirmed = 1 " . SendSQL("UPDATE bugs SET bug_status = 'NEW', everconfirmed = 1 " .
......
...@@ -252,7 +252,7 @@ sub validateStatuses ...@@ -252,7 +252,7 @@ sub validateStatuses
FROM attachments, bugs, attachstatusdefs FROM attachments, bugs, attachstatusdefs
WHERE attachments.attach_id = $::FORM{'id'} WHERE attachments.attach_id = $::FORM{'id'}
AND attachments.bug_id = bugs.bug_id AND attachments.bug_id = bugs.bug_id
AND attachstatusdefs.product = bugs.product"); AND attachstatusdefs.product_id = bugs.product_id");
my @statusdefs; my @statusdefs;
push(@statusdefs, FetchSQLData()) while MoreSQLData(); push(@statusdefs, FetchSQLData()) while MoreSQLData();
PopGlobalSQLState(); PopGlobalSQLState();
...@@ -573,7 +573,7 @@ sub edit ...@@ -573,7 +573,7 @@ sub edit
SendSQL("SELECT id, name SendSQL("SELECT id, name
FROM attachstatusdefs, bugs FROM attachstatusdefs, bugs
WHERE bug_id = $bugid WHERE bug_id = $bugid
AND attachstatusdefs.product = bugs.product AND attachstatusdefs.product_id = bugs.product_id
ORDER BY sortkey"); ORDER BY sortkey");
while ( MoreSQLData() ) while ( MoreSQLData() )
{ {
......
...@@ -77,19 +77,27 @@ sub show_bug { ...@@ -77,19 +77,27 @@ sub show_bug {
# Populate the bug hash with the info we get directly from the DB. # Populate the bug hash with the info we get directly from the DB.
my $query = " my $query = "
SELECT bugs.bug_id, alias, product, version, rep_platform, SELECT bugs.bug_id, alias, products.name, version, rep_platform,
op_sys, bug_status, resolution, priority, op_sys, bug_status, resolution, priority,
bug_severity, component, assigned_to, reporter, bug_severity, components.name, assigned_to, reporter,
bug_file_loc, short_desc, target_milestone, bug_file_loc, short_desc, target_milestone,
qa_contact, status_whiteboard, qa_contact, status_whiteboard,
date_format(creation_ts,'%Y-%m-%d %H:%i'), date_format(creation_ts,'%Y-%m-%d %H:%i'),
groupset, delta_ts, sum(votes.count) groupset, delta_ts, sum(votes.count)
FROM bugs LEFT JOIN votes USING(bug_id) FROM bugs LEFT JOIN votes USING(bug_id), products, components
WHERE bugs.bug_id = $id WHERE bugs.bug_id = $id
AND bugs.product_id = products.id
AND bugs.component_id = components.id
GROUP BY bugs.bug_id"; GROUP BY bugs.bug_id";
SendSQL($query); SendSQL($query);
# The caller is meant to have checked this. Abort here so that
# we don't get obscure SQL errors, below
if (!MoreSQLData()) {
ThrowCodeError("No data when fetching bug $id");
}
my $value; my $value;
my @row = FetchSQLData(); my @row = FetchSQLData();
foreach my $field ("bug_id", "alias", "product", "version", "rep_platform", foreach my $field ("bug_id", "alias", "product", "version", "rep_platform",
......
...@@ -397,8 +397,8 @@ DefineColumn("resolution" , "bugs.resolution" , "Result" ...@@ -397,8 +397,8 @@ DefineColumn("resolution" , "bugs.resolution" , "Result"
DefineColumn("summary" , "bugs.short_desc" , "Summary" ); DefineColumn("summary" , "bugs.short_desc" , "Summary" );
DefineColumn("summaryfull" , "bugs.short_desc" , "Summary" ); DefineColumn("summaryfull" , "bugs.short_desc" , "Summary" );
DefineColumn("status_whiteboard" , "bugs.status_whiteboard" , "Status Summary" ); DefineColumn("status_whiteboard" , "bugs.status_whiteboard" , "Status Summary" );
DefineColumn("component" , "bugs.component" , "Component" ); DefineColumn("component" , "map_components.name" , "Component" );
DefineColumn("product" , "bugs.product" , "Product" ); DefineColumn("product" , "map_products.name" , "Product" );
DefineColumn("version" , "bugs.version" , "Version" ); DefineColumn("version" , "bugs.version" , "Version" );
DefineColumn("os" , "bugs.op_sys" , "OS" ); DefineColumn("os" , "bugs.op_sys" , "OS" );
DefineColumn("target_milestone" , "bugs.target_milestone" , "Target Milestone" ); DefineColumn("target_milestone" , "bugs.target_milestone" , "Target Milestone" );
...@@ -561,7 +561,7 @@ if ($order) { ...@@ -561,7 +561,7 @@ if ($order) {
# change it to order by the sortkey of the target_milestone first. # change it to order by the sortkey of the target_milestone first.
if ($db_order =~ /bugs.target_milestone/) { if ($db_order =~ /bugs.target_milestone/) {
$db_order =~ s/bugs.target_milestone/ms_order.sortkey,ms_order.value/; $db_order =~ s/bugs.target_milestone/ms_order.sortkey,ms_order.value/;
$query =~ s/\sWHERE\s/ LEFT JOIN milestones ms_order ON ms_order.value = bugs.target_milestone AND ms_order.product = bugs.product WHERE /; $query =~ s/\sWHERE\s/ LEFT JOIN milestones ms_order ON ms_order.value = bugs.target_milestone AND ms_order.product_id = bugs.product_id WHERE /;
} }
# If we are sorting by votes, sort in descending order if no explicit # If we are sorting by votes, sort in descending order if no explicit
......
...@@ -23,6 +23,8 @@ ...@@ -23,6 +23,8 @@
# Dan Mosedale <dmose@mozilla.org> # Dan Mosedale <dmose@mozilla.org>
# Dave Miller <justdave@syndicomm.com> # Dave Miller <justdave@syndicomm.com>
# Zach Lipton <zach@zachlipton.com> # Zach Lipton <zach@zachlipton.com>
# Jacob Steenhagen <jake@acutex.net>
# Bradley Baetz <bbaetz@student.usyd.edu.au>
# #
# #
# Direct any questions on this source code to # Direct any questions on this source code to
...@@ -1324,7 +1326,7 @@ $table{attachstatusdefs} = ...@@ -1324,7 +1326,7 @@ $table{attachstatusdefs} =
name VARCHAR(50) NOT NULL , name VARCHAR(50) NOT NULL ,
description MEDIUMTEXT NULL , description MEDIUMTEXT NULL ,
sortkey SMALLINT NOT NULL DEFAULT 0 , sortkey SMALLINT NOT NULL DEFAULT 0 ,
product VARCHAR(64) NOT NULL product_id SMALLINT NOT NULL
'; ';
# #
...@@ -1343,11 +1345,11 @@ $table{bugs} = ...@@ -1343,11 +1345,11 @@ $table{bugs} =
short_desc mediumtext, short_desc mediumtext,
op_sys enum($my_opsys) not null, op_sys enum($my_opsys) not null,
priority enum($my_priorities) not null, priority enum($my_priorities) not null,
product varchar(64) not null, product_id smallint not null,
rep_platform enum($my_platforms), rep_platform enum($my_platforms),
reporter mediumint not null, reporter mediumint not null,
version varchar(64) not null, version varchar(64) not null,
component varchar(50) not null, component_id smallint not null,
resolution enum("", "FIXED", "INVALID", "WONTFIX", "LATER", "REMIND", "DUPLICATE", "WORKSFORME", "MOVED") not null, resolution enum("", "FIXED", "INVALID", "WONTFIX", "LATER", "REMIND", "DUPLICATE", "WORKSFORME", "MOVED") not null,
target_milestone varchar(20) not null default "---", target_milestone varchar(20) not null default "---",
qa_contact mediumint not null, qa_contact mediumint not null,
...@@ -1369,10 +1371,10 @@ $table{bugs} = ...@@ -1369,10 +1371,10 @@ $table{bugs} =
index (bug_status), index (bug_status),
index (op_sys), index (op_sys),
index (priority), index (priority),
index (product), index (product_id),
index (reporter), index (reporter),
index (version), index (version),
index (component), index (component_id),
index (resolution), index (resolution),
index (target_milestone), index (target_milestone),
index (qa_contact), index (qa_contact),
...@@ -1408,11 +1410,15 @@ $table{longdescs} = ...@@ -1408,11 +1410,15 @@ $table{longdescs} =
$table{components} = $table{components} =
'value tinytext, 'id smallint not null auto_increment primary key,
program varchar(64), name varchar(64) not null,
product_id smallint not null,
initialowner mediumint not null, initialowner mediumint not null,
initialqacontact mediumint not null, initialqacontact mediumint not null,
description mediumtext not null'; description mediumtext not null,
unique(product_id,name),
index(name)';
$table{dependencies} = $table{dependencies} =
...@@ -1462,15 +1468,17 @@ $table{logincookies} = ...@@ -1462,15 +1468,17 @@ $table{logincookies} =
$table{products} = $table{products} =
'product varchar(64), 'id smallint not null auto_increment primary key,
name varchar(64) not null,
description mediumtext, description mediumtext,
milestoneurl tinytext not null, milestoneurl tinytext not null,
disallownew tinyint not null, disallownew tinyint not null,
votesperuser smallint not null, votesperuser smallint not null,
maxvotesperbug smallint not null default 10000, maxvotesperbug smallint not null default 10000,
votestoconfirm smallint not null, votestoconfirm smallint not null,
defaultmilestone varchar(20) not null default "---" defaultmilestone varchar(20) not null default "---",
';
unique(name)';
$table{profiles} = $table{profiles} =
...@@ -1521,7 +1529,7 @@ $table{fielddefs} = ...@@ -1521,7 +1529,7 @@ $table{fielddefs} =
$table{versions} = $table{versions} =
'value tinytext, 'value tinytext,
program varchar(64) not null'; product_id smallint not null';
$table{votes} = $table{votes} =
...@@ -1548,10 +1556,10 @@ $table{keyworddefs} = ...@@ -1548,10 +1556,10 @@ $table{keyworddefs} =
$table{milestones} = $table{milestones} =
'value varchar(20) not null, 'product_id smallint not null,
product varchar(64) not null, value varchar(20) not null,
sortkey smallint not null, sortkey smallint not null,
unique (product, value)'; unique (product_id, value)';
$table{shadowlog} = $table{shadowlog} =
'id int not null auto_increment primary key, 'id int not null auto_increment primary key,
...@@ -2077,22 +2085,27 @@ _End_Of_SQL_ ...@@ -2077,22 +2085,27 @@ _End_Of_SQL_
$sth->execute; $sth->execute;
my ($adminuid) = $sth->fetchrow_array; my ($adminuid) = $sth->fetchrow_array;
if (!$adminuid) { die "No administator!" } # should never get here if (!$adminuid) { die "No administator!" } # should never get here
$sth = $dbh->prepare("SELECT product FROM products"); $sth = $dbh->prepare("SELECT description FROM products");
$sth->execute; $sth->execute;
unless ($sth->rows) { unless ($sth->rows) {
print "Creating initial dummy product 'TestProduct' ...\n"; print "Creating initial dummy product 'TestProduct' ...\n";
$dbh->do('INSERT INTO products(product, description, milestoneurl, disallownew, votesperuser, votestoconfirm) VALUES ("TestProduct", $dbh->do('INSERT INTO products(name, description, milestoneurl, disallownew, votesperuser, votestoconfirm) VALUES ("TestProduct",
"This is a test product. This ought to be blown away and ' . "This is a test product. This ought to be blown away and ' .
'replaced with real stuff in a finished installation of ' . 'replaced with real stuff in a finished installation of ' .
'bugzilla.", "", 0, 0, 0)'); 'bugzilla.", "", 0, 0, 0)');
$dbh->do('INSERT INTO versions (value, program) VALUES ("other", "TestProduct")'); # We could probably just assume that this is "1", but better
$dbh->do("INSERT INTO components (value, program, description, initialowner, initialqacontact) # safe than sorry...
$sth = $dbh->prepare("SELECT LAST_INSERT_ID()");
$sth->execute;
my ($product_id) = $sth->fetchrow_array;
$dbh->do(qq{INSERT INTO versions (value, product_id) VALUES ("other", $product_id)});
$dbh->do("INSERT INTO components (name, product_id, description, initialowner, initialqacontact)
VALUES (" . VALUES (" .
"'TestComponent', 'TestProduct', " . "'TestComponent', $product_id, " .
"'This is a test component in the test product database. " . "'This is a test component in the test product database. " .
"This ought to be blown away and replaced with real stuff in " . "This ought to be blown away and replaced with real stuff in " .
"a finished installation of bugzilla.', $adminuid, 0)"); "a finished installation of bugzilla.', $adminuid, 0)");
$dbh->do('INSERT INTO milestones (product, value) VALUES ("TestProduct","---")'); $dbh->do(qq{INSERT INTO milestones (product_id, value) VALUES ($product_id,"---")});
} }
...@@ -2206,8 +2219,6 @@ AddField('products', 'disallownew', 'tinyint not null'); ...@@ -2206,8 +2219,6 @@ AddField('products', 'disallownew', 'tinyint not null');
AddField('products', 'milestoneurl', 'tinytext not null'); AddField('products', 'milestoneurl', 'tinytext not null');
AddField('components', 'initialqacontact', 'tinytext not null'); AddField('components', 'initialqacontact', 'tinytext not null');
AddField('components', 'description', 'mediumtext not null'); AddField('components', 'description', 'mediumtext not null');
ChangeFieldType('components', 'program', 'varchar(64)');
# 1999-06-22 Added an entry to the attachments table to record who the # 1999-06-22 Added an entry to the attachments table to record who the
# submitter was. Nothing uses this yet, but it still should be recorded. # submitter was. Nothing uses this yet, but it still should be recorded.
...@@ -2258,10 +2269,14 @@ AddField('products', 'votesperuser', 'mediumint not null'); ...@@ -2258,10 +2269,14 @@ AddField('products', 'votesperuser', 'mediumint not null');
# tinytext is equivalent to varchar(255), which is quite huge, so I change # tinytext is equivalent to varchar(255), which is quite huge, so I change
# them all to varchar(64). # them all to varchar(64).
ChangeFieldType ('bugs', 'product', 'varchar(64) not null'); # Only do this if these fields still exist - they're removed below, in
ChangeFieldType ('components', 'program', 'varchar(64)'); # a later change
ChangeFieldType ('products', 'product', 'varchar(64)'); if (GetFieldDef('products', 'product')) {
ChangeFieldType ('versions', 'program', 'varchar(64) not null'); ChangeFieldType ('bugs', 'product', 'varchar(64) not null');
ChangeFieldType ('components', 'program', 'varchar(64)');
ChangeFieldType ('products', 'product', 'varchar(64)');
ChangeFieldType ('versions', 'program', 'varchar(64) not null');
}
# 2000-01-16 Added a "keywords" field to the bugs table, which # 2000-01-16 Added a "keywords" field to the bugs table, which
# contains a string copy of the entries of the keywords table for this # contains a string copy of the entries of the keywords table for this
...@@ -3046,6 +3061,92 @@ if (GetFieldDef("namedqueries", "watchfordiffs")) { ...@@ -3046,6 +3061,92 @@ if (GetFieldDef("namedqueries", "watchfordiffs")) {
DropField("namedqueries", "watchfordiffs"); DropField("namedqueries", "watchfordiffs");
} }
# 2002-08-?? jake@acutex.net/bbaetz@student.usyd.edu.au - bug 43600
# Use integer IDs for products and components.
if (GetFieldDef("products", "product")) {
print "Updating database to use product IDs.\n";
# First, we need to remove possible NULL entries
# NULLs may exist, but won't have been used, since all the uses of them
# are in NOT NULL fields in other tables
$dbh->do("DELETE FROM products WHERE product IS NULL");
$dbh->do("DELETE FROM components WHERE value IS NULL");
AddField("products", "id", "smallint not null auto_increment primary key");
AddField("components", "product_id", "smallint not null");
AddField("versions", "product_id", "smallint not null");
AddField("milestones", "product_id", "smallint not null");
AddField("bugs", "product_id", "smallint not null");
AddField("attachstatusdefs", "product_id", "smallint not null");
my %products;
my $sth = $dbh->prepare("SELECT id, product FROM products");
$sth->execute;
while (my ($product_id, $product) = $sth->fetchrow_array()) {
if (exists $products{$product}) {
print "Ignoring duplicate product $product\n";
$dbh->do("DELETE FROM products WHERE id = $product_id");
next;
}
$products{$product} = 1;
$dbh->do("UPDATE components SET product_id = $product_id " .
"WHERE program = " . $dbh->quote($product));
$dbh->do("UPDATE versions SET product_id = $product_id " .
"WHERE program = " . $dbh->quote($product));
$dbh->do("UPDATE milestones SET product_id = $product_id " .
"WHERE product = " . $dbh->quote($product));
$dbh->do("UPDATE bugs SET product_id = $product_id, delta_ts=delta_ts " .
"WHERE product = " . $dbh->quote($product));
$dbh->do("UPDATE attachstatusdefs SET product_id = $product_id " .
"WHERE product = " . $dbh->quote($product));
}
print "Updating the database to use component IDs.\n";
AddField("components", "id", "smallint not null auto_increment primary key");
AddField("bugs", "component_id", "smallint not null");
my %components;
$sth = $dbh->prepare("SELECT id, value, product_id FROM components");
$sth->execute;
while (my ($component_id, $component, $product_id) = $sth->fetchrow_array()) {
if (exists $components{$component}) {
if (exists $components{$component}{$product_id}) {
print "Ignoring duplicate component $component for product $product_id\n";
$dbh->do("DELETE FROM components WHERE id = $component_id");
next;
}
} else {
$components{$component} = {};
}
$components{$component}{$product_id} = 1;
$dbh->do("UPDATE bugs SET component_id = $component_id, delta_ts=delta_ts " .
"WHERE component = " . $dbh->quote($component) .
" AND product_id = $product_id");
}
print "Fixing Indexes and Uniqueness.\n";
$dbh->do("ALTER TABLE milestones DROP INDEX product");
$dbh->do("ALTER TABLE milestones ADD UNIQUE (product_id, value)");
$dbh->do("ALTER TABLE bugs DROP INDEX product");
$dbh->do("ALTER TABLE bugs ADD INDEX (product_id)");
$dbh->do("ALTER TABLE bugs DROP INDEX component");
$dbh->do("ALTER TABLE bugs ADD INDEX (component_id)");
print "Removing, renaming, and retyping old product and component fields.\n";
DropField("components", "program");
DropField("versions", "program");
DropField("milestones", "product");
DropField("bugs", "product");
DropField("bugs", "component");
DropField("attachstatusdefs", "product");
RenameField("products", "product", "name");
ChangeFieldType("products", "name", "varchar(64) not null");
RenameField("components", "value", "name");
ChangeFieldType("components", "name", "varchar(64) not null");
print "Adding indexes for products and components tables.\n";
$dbh->do("ALTER TABLE products ADD UNIQUE (name)");
$dbh->do("ALTER TABLE components ADD UNIQUE (product_id, name)");
$dbh->do("ALTER TABLE components ADD INDEX (name)");
}
# If you had to change the --TABLE-- definition in any way, then add your # If you had to change the --TABLE-- definition in any way, then add your
# differential change code *** A B O V E *** this comment. # differential change code *** A B O V E *** this comment.
# #
......
...@@ -67,6 +67,9 @@ sub collect_stats { ...@@ -67,6 +67,9 @@ sub collect_stats {
my $dir = shift; my $dir = shift;
my $product = shift; my $product = shift;
my $when = localtime (time); my $when = localtime (time);
my $product_id = get_product_id($product) unless $product eq '-All-';
die "Unknown product $product" unless ($product_id or $product eq '-All-');
# NB: Need to mangle the product for the filename, but use the real # NB: Need to mangle the product for the filename, but use the real
# product name in the query # product name in the query
...@@ -82,7 +85,7 @@ sub collect_stats { ...@@ -82,7 +85,7 @@ sub collect_stats {
if( $product eq "-All-" ) { if( $product eq "-All-" ) {
SendSQL("select count(bug_status) from bugs where bug_status='$status'"); SendSQL("select count(bug_status) from bugs where bug_status='$status'");
} else { } else {
SendSQL("select count(bug_status) from bugs where bug_status='$status' and product='$product'"); SendSQL("select count(bug_status) from bugs where bug_status='$status' and product_id=$product_id");
} }
push @row, FetchOneColumn(); push @row, FetchOneColumn();
...@@ -92,7 +95,7 @@ sub collect_stats { ...@@ -92,7 +95,7 @@ sub collect_stats {
if( $product eq "-All-" ) { if( $product eq "-All-" ) {
SendSQL("select count(resolution) from bugs where resolution='$resolution'"); SendSQL("select count(resolution) from bugs where resolution='$resolution'");
} else { } else {
SendSQL("select count(resolution) from bugs where resolution='$resolution' and product='$product'"); SendSQL("select count(resolution) from bugs where resolution='$resolution' and product_id=$product_id");
} }
push @row, FetchOneColumn(); push @row, FetchOneColumn();
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
# #
# You need to work with bug_email.pl the MIME::Parser installed. # You need to work with bug_email.pl the MIME::Parser installed.
# #
# $Id: bug_email.pl,v 1.10 2002/07/25 01:47:19 justdave%syndicomm.com Exp $ # $Id: bug_email.pl,v 1.11 2002/08/12 05:43:05 bbaetz%student.usyd.edu.au Exp $
############################################################### ###############################################################
# 02/12/2000 (SML) # 02/12/2000 (SML)
...@@ -196,7 +196,7 @@ sub CheckPermissions { ...@@ -196,7 +196,7 @@ sub CheckPermissions {
sub CheckProduct { sub CheckProduct {
my $Product = shift; my $Product = shift;
SendSQL("select product from products where product='$Product'"); SendSQL("select name from products where name = " . SqlQuote($Product));
my $Result = FetchOneColumn(); my $Result = FetchOneColumn();
if (lc($Result) eq lc($Product)) { if (lc($Result) eq lc($Product)) {
return $Result; return $Result;
...@@ -211,7 +211,7 @@ sub CheckComponent { ...@@ -211,7 +211,7 @@ sub CheckComponent {
my $Product = shift; my $Product = shift;
my $Component = shift; my $Component = shift;
SendSQL("select value from components where program=" . SqlQuote($Product) . " and value=" . SqlQuote($Component) . ""); SendSQL("select components.name from components, products where components.product_id = products.id AND products.name=" . SqlQuote($Product) . " and components.name=" . SqlQuote($Component));
my $Result = FetchOneColumn(); my $Result = FetchOneColumn();
if (lc($Result) eq lc($Component)) { if (lc($Result) eq lc($Component)) {
return $Result; return $Result;
...@@ -226,7 +226,7 @@ sub CheckVersion { ...@@ -226,7 +226,7 @@ sub CheckVersion {
my $Product = shift; my $Product = shift;
my $Version = shift; my $Version = shift;
SendSQL("select value from versions where program=" . SqlQuote($Product) . " and value=" . SqlQuote($Version) . ""); SendSQL("select value from versions, products where versions.product_id = products.id AND products.name=" . SqlQuote($Product) . " and value=" . SqlQuote($Version));
my $Result = FetchOneColumn(); my $Result = FetchOneColumn();
if (lc($Result) eq lc($Version)) { if (lc($Result) eq lc($Version)) {
return $Result; return $Result;
...@@ -840,9 +840,9 @@ if (! CheckPermissions("CreateBugs", $SenderShort ) ) { ...@@ -840,9 +840,9 @@ if (! CheckPermissions("CreateBugs", $SenderShort ) ) {
# Set QA # Set QA
if (Param("useqacontact")) { if (Param("useqacontact")) {
SendSQL("select initialqacontact from components where program=" . SendSQL("select initialqacontact from components, products where components.product_id = products.id AND products.name=" .
SqlQuote($Control{'product'}) . SqlQuote($Control{'product'}) .
" and value=" . SqlQuote($Control{'component'})); " and components.name=" . SqlQuote($Control{'component'}));
$Control{'qacontact'} = FetchOneColumn(); $Control{'qacontact'} = FetchOneColumn();
} }
...@@ -863,7 +863,7 @@ if ( $Product eq "" ) { ...@@ -863,7 +863,7 @@ if ( $Product eq "" ) {
$Text .= "Valid products are:\n\t"; $Text .= "Valid products are:\n\t";
SendSQL("select product from products"); SendSQL("select name from products ORDER BY name");
@all_products = FetchAllSQLData(); @all_products = FetchAllSQLData();
$Text .= join( "\n\t", @all_products ) . "\n\n"; $Text .= join( "\n\t", @all_products ) . "\n\n";
$Text .= horLine(); $Text .= horLine();
...@@ -903,7 +903,7 @@ if ( $Component eq "" ) { ...@@ -903,7 +903,7 @@ if ( $Component eq "" ) {
foreach my $prod ( @all_products ) { foreach my $prod ( @all_products ) {
$Text .= "\nValid components for product `$prod' are: \n\t"; $Text .= "\nValid components for product `$prod' are: \n\t";
SendSQL("select value from components where program=" . SqlQuote( $prod ) . ""); SendSQL("SELECT components.name FROM components, products WHERE components.product_id=products.id AND products.name = " . SqlQuote($prod));
@val_components = FetchAllSQLData(); @val_components = FetchAllSQLData();
$Text .= join( "\n\t", @val_components ) . "\n"; $Text .= join( "\n\t", @val_components ) . "\n";
...@@ -936,9 +936,10 @@ if ( defined($Control{'assigned_to'}) ...@@ -936,9 +936,10 @@ if ( defined($Control{'assigned_to'})
&& $Control{'assigned_to'} !~ /^\s*$/ ) { && $Control{'assigned_to'} !~ /^\s*$/ ) {
$Control{'assigned_to'} = DBname_to_id($Control{'assigned_to'}); $Control{'assigned_to'} = DBname_to_id($Control{'assigned_to'});
} else { } else {
SendSQL("select initialowner from components where program=" . SendSQL("select initialowner from components, products where " .
" components.product_id=products.id AND products.name=" .
SqlQuote($Control{'product'}) . SqlQuote($Control{'product'}) .
" and value=" . SqlQuote($Control{'component'})); " and components.name=" . SqlQuote($Control{'component'}));
$Control{'assigned_to'} = FetchOneColumn(); $Control{'assigned_to'} = FetchOneColumn();
} }
...@@ -982,7 +983,7 @@ if ( $Version eq "" ) { ...@@ -982,7 +983,7 @@ if ( $Version eq "" ) {
foreach my $prod ( @all_products ) { foreach my $prod ( @all_products ) {
$Text .= "Valid versions for product " . SqlQuote( $prod ) . " are: \n\t"; $Text .= "Valid versions for product " . SqlQuote( $prod ) . " are: \n\t";
SendSQL("select value from versions where program=" . SqlQuote( $prod ) . ""); SendSQL("select value from versions, products where versions.product_id=products.id AND products.name=" . SqlQuote( $prod ));
@all_versions = FetchAllSQLData(); @all_versions = FetchAllSQLData();
$anz_versions = @all_versions; $anz_versions = @all_versions;
$Text .= join( "\n\t", @all_versions ) . "\n" ; $Text .= join( "\n\t", @all_versions ) . "\n" ;
...@@ -1176,11 +1177,20 @@ END ...@@ -1176,11 +1177,20 @@ END
my $query = "insert into bugs (\n" . join(",\n", @used_fields ) . my $query = "insert into bugs (\n" . join(",\n", @used_fields ) .
", bug_status, creation_ts, everconfirmed) values ( "; ", bug_status, creation_ts, everconfirmed) values ( ";
# 'Yuck'. Then again, this whole file should be rewritten anyway...
$query =~ s/product/product_id/;
$query =~ s/component/component_id/;
my $tmp_reply = "These values were stored by bugzilla:\n"; my $tmp_reply = "These values were stored by bugzilla:\n";
my $val; my $val;
foreach my $field (@used_fields) { foreach my $field (@used_fields) {
if( $field eq "groupset" ) { if( $field eq "groupset" ) {
$query .= $Control{$field} . ",\n"; $query .= $Control{$field} . ",\n";
} elsif ( $field eq 'product' ) {
$query .= get_product_id($Control{$field}) . ",\n";
} elsif ( $field eq 'component' ) {
$query .= get_component_id(get_product_id($Control{'product'}),
$Control{$field}) . ",\n";
} else { } else {
$query .= SqlQuote($Control{$field}) . ",\n"; $query .= SqlQuote($Control{$field}) . ",\n";
} }
...@@ -1210,8 +1220,8 @@ END ...@@ -1210,8 +1220,8 @@ END
my $ever_confirmed = 0; my $ever_confirmed = 0;
my $state = SqlQuote("UNCONFIRMED"); my $state = SqlQuote("UNCONFIRMED");
SendSQL("SELECT votestoconfirm FROM products WHERE product = " . SendSQL("SELECT votestoconfirm FROM products WHERE name = " .
SqlQuote($Control{'product'}) . ";"); SqlQuote($Control{'product'}));
if (!FetchOneColumn()) { if (!FetchOneColumn()) {
$ever_confirmed = 1; $ever_confirmed = 1;
$state = SqlQuote("NEW"); $state = SqlQuote("NEW");
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
use vars qw( use vars qw(
%FORM %FORM
%legal_product
$userid $userid
); );
...@@ -85,9 +86,9 @@ my $product = $::FORM{'product'}; ...@@ -85,9 +86,9 @@ my $product = $::FORM{'product'};
# which could enable people guessing product names to determine # which could enable people guessing product names to determine
# whether or not certain products exist in Bugzilla, even if they # whether or not certain products exist in Bugzilla, even if they
# cannot get any other information about that product. # cannot get any other information about that product.
grep($product eq $_ , @::legal_product) my $product_id = get_product_id($product);
|| DisplayError("The product name is invalid.")
&& exit; ThrowUserError("The product name is invalid.") unless $product_id;
# Make sure the user is authorized to access this product. # Make sure the user is authorized to access this product.
if (Param("usebuggroups") && GroupExists($product)) { if (Param("usebuggroups") && GroupExists($product)) {
...@@ -102,9 +103,9 @@ if (Param("usebuggroups") && GroupExists($product)) { ...@@ -102,9 +103,9 @@ if (Param("usebuggroups") && GroupExists($product)) {
###################################################################### ######################################################################
my @components; my @components;
SendSQL("SELECT value, initialowner, initialqacontact, description FROM " . SendSQL("SELECT name, initialowner, initialqacontact, description FROM " .
"components WHERE program = " . SqlQuote($product) . " ORDER BY " . "components WHERE product_id = $product_id ORDER BY " .
"value"); "name");
while (MoreSQLData()) { while (MoreSQLData()) {
my ($name, $initialowner, $initialqacontact, $description) = my ($name, $initialowner, $initialqacontact, $description) =
FetchSQLData(); FetchSQLData();
......
...@@ -62,6 +62,15 @@ my $product = formvalue("product"); ...@@ -62,6 +62,15 @@ my $product = formvalue("product");
my $sortvisible = formvalue("sortvisible"); my $sortvisible = formvalue("sortvisible");
my @buglist = (split(/[:,]/, formvalue("bug_id"))); my @buglist = (split(/[:,]/, formvalue("bug_id")));
my $product_id;
if ($product) {
$product_id = get_product_id($product);
if (!$product_id) {
ThrowUserError("The product <tt>" . html_quote($product) .
"</tt> does not exist");
}
}
# Small backwards-compatibility hack, dated 2002-04-10. # Small backwards-compatibility hack, dated 2002-04-10.
$sortby = "count" if $sortby eq "dup_count"; $sortby = "count" if $sortby eq "dup_count";
...@@ -143,16 +152,17 @@ if (scalar(%count)) { ...@@ -143,16 +152,17 @@ if (scalar(%count)) {
# WONTFIX. We want to see VERIFIED INVALID and WONTFIX because common # WONTFIX. We want to see VERIFIED INVALID and WONTFIX because common
# "bugs" which aren't bugs end up in this state. # "bugs" which aren't bugs end up in this state.
my $query = " my $query = "
SELECT bugs.bug_id, component, bug_severity, op_sys, target_milestone, SELECT bugs.bug_id, components.name, bug_severity, op_sys,
short_desc, bug_status, resolution target_milestone, short_desc, bug_status, resolution
FROM bugs FROM bugs, components
WHERE (bug_status != 'CLOSED') WHERE (bugs.component_id = components.id)
AND (bug_status != 'CLOSED')
AND ((bug_status = 'VERIFIED' AND resolution IN ('INVALID', 'WONTFIX')) AND ((bug_status = 'VERIFIED' AND resolution IN ('INVALID', 'WONTFIX'))
OR (bug_status != 'VERIFIED')) OR (bug_status != 'VERIFIED'))
AND bugs.bug_id IN (" . join(", ", keys %count) . ")"; AND bugs.bug_id IN (" . join(", ", keys %count) . ")";
# Limit to a single product if requested # Limit to a single product if requested
$query .= (" AND product = " . SqlQuote($product)) if $product; $query .= (" AND bugs.product_id = " . $product_id) if $product_id;
SendSQL(SelectVisible($query, SendSQL(SelectVisible($query,
$userid, $userid,
......
...@@ -155,7 +155,7 @@ sub validateSortKey ...@@ -155,7 +155,7 @@ sub validateSortKey
sub validateProduct sub validateProduct
{ {
# Retrieve a list of products. # Retrieve a list of products.
SendSQL("SELECT product FROM products"); SendSQL("SELECT name FROM products");
my @products; my @products;
push(@products, FetchSQLData()) while MoreSQLData(); push(@products, FetchSQLData()) while MoreSQLData();
...@@ -180,11 +180,13 @@ sub list ...@@ -180,11 +180,13 @@ sub list
# Retrieve a list of attachment status flags and create an array of hashes # Retrieve a list of attachment status flags and create an array of hashes
# in which each hash contains the data for one flag. # in which each hash contains the data for one flag.
SendSQL("SELECT id, name, description, sortkey, product, count(statusid) SendSQL("SELECT attachstatusdefs.id, attachstatusdefs.name, " .
FROM attachstatusdefs LEFT JOIN attachstatuses "attachstatusdefs.description, attachstatusdefs.sortkey, products.name, " .
ON attachstatusdefs.id=attachstatuses.statusid "count(attachstatusdefs.id) " .
GROUP BY id "FROM attachstatusdefs, products " .
ORDER BY sortkey"); "WHERE products.id = attachstatusdefs.product_id " .
"GROUP BY id " .
"ORDER BY attachstatusdefs.sortkey");
my @statusdefs; my @statusdefs;
while ( MoreSQLData() ) while ( MoreSQLData() )
{ {
...@@ -212,7 +214,7 @@ sub create ...@@ -212,7 +214,7 @@ sub create
# Display a form for creating a new attachment status flag. # Display a form for creating a new attachment status flag.
# Retrieve a list of products to which the attachment status may apply. # Retrieve a list of products to which the attachment status may apply.
SendSQL("SELECT product FROM products"); SendSQL("SELECT name FROM products");
my @products; my @products;
push(@products, FetchSQLData()) while MoreSQLData(); push(@products, FetchSQLData()) while MoreSQLData();
...@@ -236,14 +238,13 @@ sub insert ...@@ -236,14 +238,13 @@ sub insert
# in a SQL statement. # in a SQL statement.
my $name = SqlQuote($::FORM{'name'}); my $name = SqlQuote($::FORM{'name'});
my $desc = SqlQuote($::FORM{'desc'}); my $desc = SqlQuote($::FORM{'desc'});
my $product = SqlQuote($::FORM{'product'}); my $product_id = get_product_id($::FORM{'product'});
SendSQL("LOCK TABLES attachstatusdefs WRITE"); SendSQL("LOCK TABLES attachstatusdefs WRITE");
SendSQL("SELECT MAX(id) FROM attachstatusdefs"); SendSQL("SELECT MAX(id) FROM attachstatusdefs");
my $id = FetchSQLData() || 0; my $id = FetchSQLData() + 1;
$id++; SendSQL("INSERT INTO attachstatusdefs (id, name, description, sortkey, product_id)
SendSQL("INSERT INTO attachstatusdefs (id, name, description, sortkey, product) VALUES ($id, $name, $desc, $::FORM{'sortkey'}, $product_id)");
VALUES ($id, $name, $desc, $::FORM{'sortkey'}, $product)");
SendSQL("UNLOCK TABLES"); SendSQL("UNLOCK TABLES");
# Display the "administer attachment status flags" page # Display the "administer attachment status flags" page
...@@ -257,8 +258,11 @@ sub edit ...@@ -257,8 +258,11 @@ sub edit
# Display a form for editing an existing attachment status flag. # Display a form for editing an existing attachment status flag.
# Retrieve the definition from the database. # Retrieve the definition from the database.
SendSQL("SELECT name, description, sortkey, product SendSQL("SELECT attachstatusdefs.name, attachstatusdefs.description, " .
FROM attachstatusdefs WHERE id = $::FORM{'id'}"); " attachstatusdefs.sortkey, products.name " .
"FROM attachstatusdefs, products " .
"WHERE attachstatusdefs.product_id = products.id " .
" AND attachstatusdefs.id = $::FORM{'id'}");
my ($name, $desc, $sortkey, $product) = FetchSQLData(); my ($name, $desc, $sortkey, $product) = FetchSQLData();
# Define the variables and functions that will be passed to the UI template. # Define the variables and functions that will be passed to the UI template.
......
...@@ -55,9 +55,9 @@ sub TestProduct ($) ...@@ -55,9 +55,9 @@ sub TestProduct ($)
my $prod = shift; my $prod = shift;
# does the product exist? # does the product exist?
SendSQL("SELECT product SendSQL("SELECT name
FROM products FROM products
WHERE product=" . SqlQuote($prod)); WHERE name=" . SqlQuote($prod));
return FetchOneColumn(); return FetchOneColumn();
} }
...@@ -84,9 +84,10 @@ sub TestComponent ($$) ...@@ -84,9 +84,10 @@ sub TestComponent ($$)
my ($prod,$comp) = @_; my ($prod,$comp) = @_;
# does the product exist? # does the product exist?
SendSQL("SELECT program,value SendSQL("SELECT components.name
FROM components FROM components, products
WHERE program=" . SqlQuote($prod) . " and value=" . SqlQuote($comp)); WHERE products.id = components.product_id
AND products.name=" . SqlQuote($prod) . " AND components.name=" . SqlQuote($comp));
return FetchOneColumn(); return FetchOneColumn();
} }
...@@ -225,15 +226,14 @@ unless ($product) { ...@@ -225,15 +226,14 @@ unless ($product) {
PutHeader("Select product"); PutHeader("Select product");
if ($dobugcounts){ if ($dobugcounts){
SendSQL("SELECT products.product,products.description,COUNT(bug_id) SendSQL("SELECT products.name,products.description,COUNT(bug_id)
FROM products LEFT JOIN bugs FROM products LEFT JOIN bugs ON products.id = bugs.product_id
ON products.product=bugs.product GROUP BY products.name
GROUP BY products.product ORDER BY products.name");
ORDER BY products.product");
} else { } else {
SendSQL("SELECT products.product,products.description SendSQL("SELECT products.name,products.description
FROM products FROM products
ORDER BY products.product"); ORDER BY products.name");
} }
print "<TABLE BORDER=1 CELLPADDING=4 CELLSPACING=0><TR BGCOLOR=\"#6666FF\">\n"; print "<TABLE BORDER=1 CELLPADDING=4 CELLSPACING=0><TR BGCOLOR=\"#6666FF\">\n";
print " <TH ALIGN=\"left\">Edit components of ...</TH>\n"; print " <TH ALIGN=\"left\">Edit components of ...</TH>\n";
...@@ -270,18 +270,18 @@ unless ($product) { ...@@ -270,18 +270,18 @@ unless ($product) {
unless ($action) { unless ($action) {
PutHeader("Select component of $product"); PutHeader("Select component of $product");
CheckProduct($product); CheckProduct($product);
my $product_id = get_product_id($product);
if ($dobugcounts) { if ($dobugcounts) {
SendSQL("SELECT value,description,initialowner,initialqacontact,COUNT(bug_id) SendSQL("SELECT name,description,initialowner,initialqacontact,COUNT(bug_id)
FROM components LEFT JOIN bugs FROM components LEFT JOIN bugs ON components.id = bugs.component_id
ON components.program=bugs.product AND components.value=bugs.component WHERE components.product_id=$product_id
WHERE program=" . SqlQuote($product) . " GROUP BY name");
GROUP BY value");
} else { } else {
SendSQL("SELECT value,description,initialowner,initialqacontact SendSQL("SELECT name,description,initialowner,initialqacontact
FROM components FROM components
WHERE program=" . SqlQuote($product) . " WHERE product_id=$product_id
GROUP BY value"); GROUP BY name");
} }
print "<TABLE BORDER=1 CELLPADDING=4 CELLSPACING=0><TR BGCOLOR=\"#6666FF\">\n"; print "<TABLE BORDER=1 CELLPADDING=4 CELLSPACING=0><TR BGCOLOR=\"#6666FF\">\n";
print " <TH ALIGN=\"left\">Edit component ...</TH>\n"; print " <TH ALIGN=\"left\">Edit component ...</TH>\n";
...@@ -370,6 +370,7 @@ if ($action eq 'add') { ...@@ -370,6 +370,7 @@ if ($action eq 'add') {
if ($action eq 'new') { if ($action eq 'new') {
PutHeader("Adding new component of $product"); PutHeader("Adding new component of $product");
CheckProduct($product); CheckProduct($product);
my $product_id = get_product_id($product);
# Cleanups and valididy checks # Cleanups and valididy checks
...@@ -426,9 +427,9 @@ if ($action eq 'new') { ...@@ -426,9 +427,9 @@ if ($action eq 'new') {
# Add the new component # Add the new component
SendSQL("INSERT INTO components ( " . SendSQL("INSERT INTO components ( " .
"program, value, description, initialowner, initialqacontact " . "product_id, name, description, initialowner, initialqacontact " .
" ) VALUES ( " . " ) VALUES ( " .
SqlQuote($product) . "," . $product_id . "," .
SqlQuote($component) . "," . SqlQuote($component) . "," .
SqlQuote($description) . "," . SqlQuote($description) . "," .
SqlQuote($initialownerid) . "," . SqlQuote($initialownerid) . "," .
...@@ -457,20 +458,20 @@ if ($action eq 'new') { ...@@ -457,20 +458,20 @@ if ($action eq 'new') {
if ($action eq 'del') { if ($action eq 'del') {
PutHeader("Delete component of $product"); PutHeader("Delete component of $product");
CheckComponent($product, $component); CheckComponent($product, $component);
my $component_id = get_component_id(get_product_id($product), $component);
# display some data about the component # display some data about the component
SendSQL("SELECT products.product,products.description, SendSQL("SELECT products.name,products.description,
products.milestoneurl,products.disallownew, products.milestoneurl,products.disallownew,
components.program,components.value,components.initialowner, components.name,components.initialowner,
components.initialqacontact,components.description components.initialqacontact,components.description
FROM products FROM products
LEFT JOIN components on product=program LEFT JOIN components ON products.id = components.product_id
WHERE product=" . SqlQuote($product) . " WHERE components.id = $component_id");
AND value=" . SqlQuote($component) );
my ($product,$pdesc,$milestoneurl,$disallownew, my ($product,$pdesc,$milestoneurl,$disallownew,
$dummy,$component,$initialownerid,$initialqacontactid,$cdesc) = FetchSQLData(); $component,$initialownerid,$initialqacontactid,$cdesc) = FetchSQLData();
my $initialowner = $initialownerid ? DBID_to_name ($initialownerid) : "<FONT COLOR=\"red\">missing</FONT>"; my $initialowner = $initialownerid ? DBID_to_name ($initialownerid) : "<FONT COLOR=\"red\">missing</FONT>";
my $initialqacontact = $initialqacontactid ? DBID_to_name ($initialqacontactid) : "<FONT COLOR=\"red\">missing</FONT>"; my $initialqacontact = $initialqacontactid ? DBID_to_name ($initialqacontactid) : "<FONT COLOR=\"red\">missing</FONT>";
...@@ -503,8 +504,7 @@ if ($action eq 'del') { ...@@ -503,8 +504,7 @@ if ($action eq 'del') {
} }
SendSQL("SELECT count(bug_id) SendSQL("SELECT count(bug_id)
FROM bugs FROM bugs
WHERE product=" . SqlQuote($product) . " WHERE component_id = $component_id");
AND component=" . SqlQuote($component));
print "</TR><TR>\n"; print "</TR><TR>\n";
print " <TD VALIGN=\"top\">Component of product:</TD>\n"; print " <TD VALIGN=\"top\">Component of product:</TD>\n";
...@@ -574,6 +574,7 @@ one."; ...@@ -574,6 +574,7 @@ one.";
if ($action eq 'delete') { if ($action eq 'delete') {
PutHeader("Deleting component of $product"); PutHeader("Deleting component of $product");
CheckComponent($product,$component); CheckComponent($product,$component);
my $component_id = get_component_id(get_product_id($product),$component);
# lock the tables before we start to change everything: # lock the tables before we start to change everything:
...@@ -590,8 +591,7 @@ if ($action eq 'delete') { ...@@ -590,8 +591,7 @@ if ($action eq 'delete') {
if (Param("allowbugdeletion")) { if (Param("allowbugdeletion")) {
SendSQL("SELECT bug_id SendSQL("SELECT bug_id
FROM bugs FROM bugs
WHERE product=" . SqlQuote($product) . " WHERE component_id=$component_id");
AND component=" . SqlQuote($component));
while (MoreSQLData()) { while (MoreSQLData()) {
my $bugid = FetchOneColumn(); my $bugid = FetchOneColumn();
...@@ -607,14 +607,12 @@ if ($action eq 'delete') { ...@@ -607,14 +607,12 @@ if ($action eq 'delete') {
# Deleting the rest is easier: # Deleting the rest is easier:
SendSQL("DELETE FROM bugs SendSQL("DELETE FROM bugs
WHERE product=" . SqlQuote($product) . " WHERE component_id=$component_id");
AND component=" . SqlQuote($component));
print "Bugs deleted.<BR>\n"; print "Bugs deleted.<BR>\n";
} }
SendSQL("DELETE FROM components SendSQL("DELETE FROM components
WHERE program=" . SqlQuote($product) . " WHERE id=$component_id");
AND value=" . SqlQuote($component));
print "Components deleted.<P>\n"; print "Components deleted.<P>\n";
SendSQL("UNLOCK TABLES"); SendSQL("UNLOCK TABLES");
...@@ -634,19 +632,18 @@ if ($action eq 'delete') { ...@@ -634,19 +632,18 @@ if ($action eq 'delete') {
if ($action eq 'edit') { if ($action eq 'edit') {
PutHeader("Edit component of $product"); PutHeader("Edit component of $product");
CheckComponent($product,$component); CheckComponent($product,$component);
my $component_id = get_component_id(get_product_id($product),$component);
# get data of component # get data of component
SendSQL("SELECT products.product,products.description, SendSQL("SELECT products.name,products.description,
products.milestoneurl,products.disallownew, products.milestoneurl,products.disallownew,
components.program,components.value,components.initialowner, components.name,components.initialowner,
components.initialqacontact,components.description components.initialqacontact,components.description
FROM products FROM products LEFT JOIN components ON products.id = components.product_id
LEFT JOIN components on product=program WHERE components.id = $component_id");
WHERE product=" . SqlQuote($product) . "
AND value=" . SqlQuote($component) );
my ($product,$pdesc,$milestoneurl,$disallownew, my ($product,$pdesc,$milestoneurl,$disallownew,
$dummy,$component,$initialownerid,$initialqacontactid,$cdesc) = FetchSQLData(); $component,$initialownerid,$initialqacontactid,$cdesc) = FetchSQLData();
my $initialowner = $initialownerid ? DBID_to_name ($initialownerid) : ''; my $initialowner = $initialownerid ? DBID_to_name ($initialownerid) : '';
my $initialqacontact = $initialqacontactid ? DBID_to_name ($initialqacontactid) : ''; my $initialqacontact = $initialqacontactid ? DBID_to_name ($initialqacontactid) : '';
...@@ -663,8 +660,7 @@ if ($action eq 'edit') { ...@@ -663,8 +660,7 @@ if ($action eq 'edit') {
print " <TD>"; print " <TD>";
SendSQL("SELECT count(*) SendSQL("SELECT count(*)
FROM bugs FROM bugs
WHERE product=" . SqlQuote($product) . WHERE component_id=$component_id");
" and component=" . SqlQuote($component));
my $bugs = ''; my $bugs = '';
$bugs = FetchOneColumn() if MoreSQLData(); $bugs = FetchOneColumn() if MoreSQLData();
print $bugs || 'none'; print $bugs || 'none';
...@@ -707,13 +703,13 @@ if ($action eq 'update') { ...@@ -707,13 +703,13 @@ if ($action eq 'update') {
my $initialqacontact = trim($::FORM{initialqacontact} || ''); my $initialqacontact = trim($::FORM{initialqacontact} || '');
my $initialqacontactold = trim($::FORM{initialqacontactold} || ''); my $initialqacontactold = trim($::FORM{initialqacontactold} || '');
CheckComponent($product,$componentold);
# 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 bugs WRITE, SendSQL("LOCK TABLES components WRITE, products READ, profiles READ");
components WRITE, profiles READ"); CheckComponent($product,$componentold);
my $component_id = get_component_id(get_product_id($product),
$componentold);
if ($description ne $descriptionold) { if ($description ne $descriptionold) {
unless ($description) { unless ($description) {
...@@ -724,8 +720,7 @@ if ($action eq 'update') { ...@@ -724,8 +720,7 @@ if ($action eq 'update') {
} }
SendSQL("UPDATE components SendSQL("UPDATE components
SET description=" . SqlQuote($description) . " SET description=" . SqlQuote($description) . "
WHERE program=" . SqlQuote($product) . " WHERE id=$component_id");
AND value=" . SqlQuote($componentold));
print "Updated description.<BR>\n"; print "Updated description.<BR>\n";
} }
...@@ -748,8 +743,7 @@ if ($action eq 'update') { ...@@ -748,8 +743,7 @@ if ($action eq 'update') {
SendSQL("UPDATE components SendSQL("UPDATE components
SET initialowner=" . SqlQuote($initialownerid) . " SET initialowner=" . SqlQuote($initialownerid) . "
WHERE program=" . SqlQuote($product) . " WHERE id = $component_id");
AND value=" . SqlQuote($componentold));
print "Updated initial owner.<BR>\n"; print "Updated initial owner.<BR>\n";
} }
...@@ -764,8 +758,7 @@ if ($action eq 'update') { ...@@ -764,8 +758,7 @@ if ($action eq 'update') {
SendSQL("UPDATE components SendSQL("UPDATE components
SET initialqacontact=" . SqlQuote($initialqacontactid) . " SET initialqacontact=" . SqlQuote($initialqacontactid) . "
WHERE program=" . SqlQuote($product) . " WHERE id = $component_id");
AND value=" . SqlQuote($componentold));
print "Updated initial QA contact.<BR>\n"; print "Updated initial QA contact.<BR>\n";
} }
...@@ -784,15 +777,8 @@ if ($action eq 'update') { ...@@ -784,15 +777,8 @@ if ($action eq 'update') {
exit; exit;
} }
SendSQL("UPDATE bugs SendSQL("UPDATE components SET name=" . SqlQuote($component) .
SET component=" . SqlQuote($component) . ", "WHERE id=$component_id");
delta_ts = delta_ts
WHERE component=" . SqlQuote($componentold) . "
AND product=" . SqlQuote($product));
SendSQL("UPDATE components
SET value=" . SqlQuote($component) . "
WHERE value=" . SqlQuote($componentold) . "
AND program=" . SqlQuote($product));
unlink "data/versioncache"; unlink "data/versioncache";
print "Updated component name.<BR>\n"; print "Updated component name.<BR>\n";
......
...@@ -422,7 +422,7 @@ this box. It is <B>strongly</B> suggested that you review the bugs in this ...@@ -422,7 +422,7 @@ this box. It is <B>strongly</B> suggested that you review the bugs in this
group before checking the box.<P> group before checking the box.<P>
"; ";
} }
SendSQL("SELECT product FROM products WHERE product=" . SqlQuote($name)); SendSQL("SELECT name FROM products WHERE name=" . SqlQuote($name));
if (MoreSQLData()) { if (MoreSQLData()) {
$cantdelete = 1; $cantdelete = 1;
print " print "
...@@ -489,7 +489,7 @@ if ($action eq 'delete') { ...@@ -489,7 +489,7 @@ if ($action eq 'delete') {
$cantdelete = 1; $cantdelete = 1;
} }
} }
SendSQL("SELECT product FROM products WHERE product=" . SqlQuote($name)); SendSQL("SELECT name FROM products WHERE name=" . SqlQuote($name));
if (FetchOneColumn()) { if (FetchOneColumn()) {
if (!defined $::FORM{'unbind'}) { if (!defined $::FORM{'unbind'}) {
$cantdelete = 1; $cantdelete = 1;
......
...@@ -33,9 +33,9 @@ sub TestProduct ($) ...@@ -33,9 +33,9 @@ sub TestProduct ($)
my $prod = shift; my $prod = shift;
# does the product exist? # does the product exist?
SendSQL("SELECT product SendSQL("SELECT name
FROM products FROM products
WHERE product=" . SqlQuote($prod)); WHERE name=" . SqlQuote($prod));
return FetchOneColumn(); return FetchOneColumn();
} }
...@@ -62,9 +62,9 @@ sub TestMilestone ($$) ...@@ -62,9 +62,9 @@ sub TestMilestone ($$)
my ($prod,$mile) = @_; my ($prod,$mile) = @_;
# does the product exist? # does the product exist?
SendSQL("SELECT product,value SendSQL("SELECT products.name, value
FROM milestones FROM milestones, products
WHERE product=" . SqlQuote($prod) . " and value=" . SqlQuote($mile)); WHERE milestones.product_id=products.id AND products.name=" . SqlQuote($prod) . " and value=" . SqlQuote($mile));
return FetchOneColumn(); return FetchOneColumn();
} }
...@@ -183,10 +183,10 @@ if ($milestone) { ...@@ -183,10 +183,10 @@ if ($milestone) {
unless ($product) { unless ($product) {
PutHeader("Select product"); PutHeader("Select product");
SendSQL("SELECT products.product,products.description,'xyzzy' SendSQL("SELECT products.name,products.description,'xyzzy'
FROM products FROM products
GROUP BY products.product GROUP BY products.name
ORDER BY products.product"); ORDER BY products.name");
print "<TABLE BORDER=1 CELLPADDING=4 CELLSPACING=0><TR BGCOLOR=\"#6666FF\">\n"; print "<TABLE BORDER=1 CELLPADDING=4 CELLSPACING=0><TR BGCOLOR=\"#6666FF\">\n";
print " <TH ALIGN=\"left\">Edit milestones of ...</TH>\n"; print " <TH ALIGN=\"left\">Edit milestones of ...</TH>\n";
print " <TH ALIGN=\"left\">Description</TH>\n"; print " <TH ALIGN=\"left\">Description</TH>\n";
...@@ -216,10 +216,11 @@ unless ($product) { ...@@ -216,10 +216,11 @@ unless ($product) {
unless ($action) { unless ($action) {
PutHeader("Select milestone for $product"); PutHeader("Select milestone for $product");
CheckProduct($product); CheckProduct($product);
my $product_id = get_product_id($product);
SendSQL("SELECT value,sortkey SendSQL("SELECT value,sortkey
FROM milestones FROM milestones
WHERE product=" . SqlQuote($product) . " WHERE product_id=$product_id
ORDER BY sortkey,value"); ORDER BY sortkey,value");
print "<TABLE BORDER=1 CELLPADDING=4 CELLSPACING=0><TR BGCOLOR=\"#6666FF\">\n"; print "<TABLE BORDER=1 CELLPADDING=4 CELLSPACING=0><TR BGCOLOR=\"#6666FF\">\n";
...@@ -259,6 +260,7 @@ unless ($action) { ...@@ -259,6 +260,7 @@ unless ($action) {
if ($action eq 'add') { if ($action eq 'add') {
PutHeader("Add milestone for $product"); PutHeader("Add milestone for $product");
CheckProduct($product); CheckProduct($product);
my $product_id = get_product_id($product);
#print "This page lets you add a new milestone to a $::bugzilla_name tracked product.\n"; #print "This page lets you add a new milestone to a $::bugzilla_name tracked product.\n";
...@@ -287,6 +289,7 @@ if ($action eq 'add') { ...@@ -287,6 +289,7 @@ if ($action eq 'add') {
if ($action eq 'new') { if ($action eq 'new') {
PutHeader("Adding new milestone for $product"); PutHeader("Adding new milestone for $product");
CheckProduct($product); CheckProduct($product);
my $product_id = get_product_id($product);
# Cleanups and valididy checks # Cleanups and valididy checks
...@@ -305,10 +308,9 @@ if ($action eq 'new') { ...@@ -305,10 +308,9 @@ if ($action eq 'new') {
# Add the new milestone # Add the new milestone
SendSQL("INSERT INTO milestones ( " . SendSQL("INSERT INTO milestones ( " .
"value, product, sortkey" . "value, product_id, sortkey" .
" ) VALUES ( " . " ) VALUES ( " .
SqlQuote($milestone) . "," . SqlQuote($milestone) . ", $product_id, $sortkey)");
SqlQuote($product) . ", $sortkey)");
# Make versioncache flush # Make versioncache flush
unlink "data/versioncache"; unlink "data/versioncache";
...@@ -330,16 +332,17 @@ if ($action eq 'new') { ...@@ -330,16 +332,17 @@ if ($action eq 'new') {
if ($action eq 'del') { if ($action eq 'del') {
PutHeader("Delete milestone of $product"); PutHeader("Delete milestone of $product");
CheckMilestone($product, $milestone); CheckMilestone($product, $milestone);
my $product_id = get_product_id($product);
SendSQL("SELECT count(bug_id),product,target_milestone SendSQL("SELECT count(bug_id), product_id, target_milestone
FROM bugs FROM bugs
GROUP BY product,target_milestone GROUP BY product_id, target_milestone
HAVING product=" . SqlQuote($product) . " HAVING product_id=$product_id
AND target_milestone=" . SqlQuote($milestone)); AND target_milestone=" . SqlQuote($milestone));
my $bugs = FetchOneColumn(); my $bugs = FetchOneColumn();
SendSQL("SELECT defaultmilestone FROM products " . SendSQL("SELECT defaultmilestone FROM products " .
"WHERE product=" . SqlQuote($product)); "WHERE id=$product_id");
my $defaultmilestone = FetchOneColumn(); my $defaultmilestone = FetchOneColumn();
print "<TABLE BORDER=1 CELLPADDING=4 CELLSPACING=0>\n"; print "<TABLE BORDER=1 CELLPADDING=4 CELLSPACING=0>\n";
...@@ -405,6 +408,7 @@ one."; ...@@ -405,6 +408,7 @@ one.";
if ($action eq 'delete') { if ($action eq 'delete') {
PutHeader("Deleting milestone of $product"); PutHeader("Deleting milestone of $product");
CheckMilestone($product,$milestone); CheckMilestone($product,$milestone);
my $product_id = get_product_id($product);
# lock the tables before we start to change everything: # lock the tables before we start to change everything:
...@@ -422,7 +426,7 @@ if ($action eq 'delete') { ...@@ -422,7 +426,7 @@ if ($action eq 'delete') {
SendSQL("SELECT bug_id SendSQL("SELECT bug_id
FROM bugs FROM bugs
WHERE product=" . SqlQuote($product) . " WHERE product_id=$product_id
AND target_milestone=" . SqlQuote($milestone)); AND target_milestone=" . SqlQuote($milestone));
while (MoreSQLData()) { while (MoreSQLData()) {
my $bugid = FetchOneColumn(); my $bugid = FetchOneColumn();
...@@ -439,13 +443,13 @@ if ($action eq 'delete') { ...@@ -439,13 +443,13 @@ if ($action eq 'delete') {
# Deleting the rest is easier: # Deleting the rest is easier:
SendSQL("DELETE FROM bugs SendSQL("DELETE FROM bugs
WHERE product=" . SqlQuote($product) . " WHERE product_id=$product_id
AND target_milestone=" . SqlQuote($milestone)); AND target_milestone=" . SqlQuote($milestone));
print "Bugs deleted.<BR>\n"; print "Bugs deleted.<BR>\n";
} }
SendSQL("DELETE FROM milestones SendSQL("DELETE FROM milestones
WHERE product=" . SqlQuote($product) . " WHERE product_id=$product_id
AND value=" . SqlQuote($milestone)); AND value=" . SqlQuote($milestone));
print "Milestone deleted.<P>\n"; print "Milestone deleted.<P>\n";
SendSQL("UNLOCK TABLES"); SendSQL("UNLOCK TABLES");
...@@ -466,9 +470,10 @@ if ($action eq 'delete') { ...@@ -466,9 +470,10 @@ if ($action eq 'delete') {
if ($action eq 'edit') { if ($action eq 'edit') {
PutHeader("Edit milestone of $product"); PutHeader("Edit milestone of $product");
CheckMilestone($product,$milestone); CheckMilestone($product,$milestone);
my $product_id = get_product_id($product);
SendSQL("SELECT sortkey FROM milestones WHERE product=" . SendSQL("SELECT sortkey FROM milestones WHERE product_id=$product_id " .
SqlQuote($product) . " AND value = " . SqlQuote($milestone)); " AND value = " . SqlQuote($milestone));
my $sortkey = FetchOneColumn(); my $sortkey = FetchOneColumn();
print "<FORM METHOD=POST ACTION=editmilestones.cgi>\n"; print "<FORM METHOD=POST ACTION=editmilestones.cgi>\n";
...@@ -506,6 +511,7 @@ if ($action eq 'update') { ...@@ -506,6 +511,7 @@ if ($action eq 'update') {
my $sortkeyold = trim($::FORM{sortkeyold} || '0'); my $sortkeyold = trim($::FORM{sortkeyold} || '0');
CheckMilestone($product,$milestoneold); CheckMilestone($product,$milestoneold);
my $product_id = get_product_id($product);
SendSQL("LOCK TABLES bugs WRITE, SendSQL("LOCK TABLES bugs WRITE,
milestones WRITE, milestones WRITE,
...@@ -535,14 +541,14 @@ if ($action eq 'update') { ...@@ -535,14 +541,14 @@ if ($action eq 'update') {
SET target_milestone=" . SqlQuote($milestone) . ", SET target_milestone=" . SqlQuote($milestone) . ",
delta_ts=delta_ts delta_ts=delta_ts
WHERE target_milestone=" . SqlQuote($milestoneold) . " WHERE target_milestone=" . SqlQuote($milestoneold) . "
AND product=" . SqlQuote($product)); AND product_id=$product_id");
SendSQL("UPDATE milestones SendSQL("UPDATE milestones
SET value=" . SqlQuote($milestone) . " SET value=" . SqlQuote($milestone) . "
WHERE product=" . SqlQuote($product) . " WHERE product_id=$product_id
AND value=" . SqlQuote($milestoneold)); AND value=" . SqlQuote($milestoneold));
SendSQL("UPDATE products " . SendSQL("UPDATE products " .
"SET defaultmilestone = " . SqlQuote($milestone) . "SET defaultmilestone = " . SqlQuote($milestone) .
"WHERE product = " . SqlQuote($product) . " WHERE id = $product_id" .
" AND defaultmilestone = " . SqlQuote($milestoneold)); " AND defaultmilestone = " . SqlQuote($milestoneold));
unlink "data/versioncache"; unlink "data/versioncache";
print "Updated milestone.<BR>\n"; print "Updated milestone.<BR>\n";
......
...@@ -51,9 +51,9 @@ sub TestProduct ($) ...@@ -51,9 +51,9 @@ sub TestProduct ($)
my $prod = shift; my $prod = shift;
# does the product exist? # does the product exist?
SendSQL("SELECT product SendSQL("SELECT name
FROM products FROM products
WHERE product=" . SqlQuote($prod)); WHERE name=" . SqlQuote($prod));
return FetchOneColumn(); return FetchOneColumn();
} }
...@@ -206,12 +206,11 @@ my $localtrailer = "<A HREF=\"editproducts.cgi\">edit</A> more products"; ...@@ -206,12 +206,11 @@ my $localtrailer = "<A HREF=\"editproducts.cgi\">edit</A> more products";
unless ($action) { unless ($action) {
PutHeader("Select product"); PutHeader("Select product");
SendSQL("SELECT products.product,description,disallownew, SendSQL("SELECT products.name,description,disallownew,
votesperuser,maxvotesperbug,votestoconfirm,COUNT(bug_id) votesperuser,maxvotesperbug,votestoconfirm,COUNT(bug_id)
FROM products LEFT JOIN bugs FROM products LEFT JOIN bugs ON products.id = bugs.product_id
ON products.product=bugs.product GROUP BY products.name
GROUP BY products.product ORDER BY products.name");
ORDER BY products.product");
print "<TABLE BORDER=1 CELLPADDING=4 CELLSPACING=0><TR BGCOLOR=\"#6666FF\">\n"; print "<TABLE BORDER=1 CELLPADDING=4 CELLSPACING=0><TR BGCOLOR=\"#6666FF\">\n";
print " <TH ALIGN=\"left\">Edit product ...</TH>\n"; print " <TH ALIGN=\"left\">Edit product ...</TH>\n";
print " <TH ALIGN=\"left\">Description</TH>\n"; print " <TH ALIGN=\"left\">Description</TH>\n";
...@@ -330,7 +329,7 @@ if ($action eq 'new') { ...@@ -330,7 +329,7 @@ if ($action eq 'new') {
# Add the new product. # Add the new product.
SendSQL("INSERT INTO products ( " . SendSQL("INSERT INTO products ( " .
"product, description, milestoneurl, disallownew, votesperuser, " . "name, description, milestoneurl, disallownew, votesperuser, " .
"maxvotesperbug, votestoconfirm, defaultmilestone" . "maxvotesperbug, votestoconfirm, defaultmilestone" .
" ) VALUES ( " . " ) VALUES ( " .
SqlQuote($product) . "," . SqlQuote($product) . "," .
...@@ -339,14 +338,16 @@ if ($action eq 'new') { ...@@ -339,14 +338,16 @@ if ($action eq 'new') {
$disallownew . "," . $disallownew . "," .
"$votesperuser, $maxvotesperbug, $votestoconfirm, " . "$votesperuser, $maxvotesperbug, $votestoconfirm, " .
SqlQuote($defaultmilestone) . ")"); SqlQuote($defaultmilestone) . ")");
SendSQL("SELECT LAST_INSERT_ID()");
my $product_id = FetchOneColumn();
SendSQL("INSERT INTO versions ( " . SendSQL("INSERT INTO versions ( " .
"value, program" . "value, product_id" .
" ) VALUES ( " . " ) VALUES ( " .
SqlQuote($version) . "," . SqlQuote($version) . "," .
SqlQuote($product) . ")" ); $product_id . ")" );
SendSQL("INSERT INTO milestones (product, value) VALUES (" . SendSQL("INSERT INTO milestones (product_id, value) VALUES (" .
SqlQuote($product) . ", " . SqlQuote($defaultmilestone) . ")"); $product_id . ", " . SqlQuote($defaultmilestone) . ")");
# If we're using bug groups, then we need to create a group for this # If we're using bug groups, then we need to create a group for this
# product as well. -JMR, 2/16/00 # product as well. -JMR, 2/16/00
...@@ -416,10 +417,10 @@ if ($action eq 'del') { ...@@ -416,10 +417,10 @@ if ($action eq 'del') {
CheckProduct($product); CheckProduct($product);
# display some data about the product # display some data about the product
SendSQL("SELECT description, milestoneurl, disallownew SendSQL("SELECT product_id, description, milestoneurl, disallownew
FROM products FROM products
WHERE product=" . SqlQuote($product)); WHERE name=" . SqlQuote($product));
my ($description, $milestoneurl, $disallownew) = FetchSQLData(); my ($product_id, $description, $milestoneurl, $disallownew) = FetchSQLData();
my $milestonelink = $milestoneurl ? "<a href=\"$milestoneurl\">$milestoneurl</a>" my $milestonelink = $milestoneurl ? "<a href=\"$milestoneurl\">$milestoneurl</a>"
: "<font color=\"red\">missing</font>"; : "<font color=\"red\">missing</font>";
$description ||= "<FONT COLOR=\"red\">description missing</FONT>"; $description ||= "<FONT COLOR=\"red\">description missing</FONT>";
...@@ -468,9 +469,9 @@ if ($action eq 'del') { ...@@ -468,9 +469,9 @@ if ($action eq 'del') {
print "</TR><TR>\n"; print "</TR><TR>\n";
print " <TD VALIGN=\"top\">Components:</TD>\n"; print " <TD VALIGN=\"top\">Components:</TD>\n";
print " <TD VALIGN=\"top\">"; print " <TD VALIGN=\"top\">";
SendSQL("SELECT value,description SendSQL("SELECT name,description
FROM components FROM components
WHERE program=" . SqlQuote($product)); WHERE product_id=$product_id");
if (MoreSQLData()) { if (MoreSQLData()) {
print "<table>"; print "<table>";
while ( MoreSQLData() ) { while ( MoreSQLData() ) {
...@@ -489,7 +490,7 @@ if ($action eq 'del') { ...@@ -489,7 +490,7 @@ if ($action eq 'del') {
print " <TD VALIGN=\"top\">"; print " <TD VALIGN=\"top\">";
SendSQL("SELECT value SendSQL("SELECT value
FROM versions FROM versions
WHERE program=" . SqlQuote($product) . " WHERE product_id=$product_id
ORDER BY value"); ORDER BY value");
if (MoreSQLData()) { if (MoreSQLData()) {
my $br = 0; my $br = 0;
...@@ -512,7 +513,7 @@ if ($action eq 'del') { ...@@ -512,7 +513,7 @@ if ($action eq 'del') {
print " <TD>"; print " <TD>";
SendSQL("SELECT value SendSQL("SELECT value
FROM milestones FROM milestones
WHERE product=" . SqlQuote($product) . " WHERE product_id=$product_id
ORDER BY sortkey,value"); ORDER BY sortkey,value");
if(MoreSQLData()) { if(MoreSQLData()) {
my $br = 0; my $br = 0;
...@@ -530,10 +531,10 @@ if ($action eq 'del') { ...@@ -530,10 +531,10 @@ if ($action eq 'del') {
print "</TD>\n</TR><TR>\n"; print "</TD>\n</TR><TR>\n";
print " <TD VALIGN=\"top\">Bugs:</TD>\n"; print " <TD VALIGN=\"top\">Bugs:</TD>\n";
print " <TD VALIGN=\"top\">"; print " <TD VALIGN=\"top\">";
SendSQL("SELECT count(bug_id),product SendSQL("SELECT count(bug_id),product_id
FROM bugs FROM bugs
GROUP BY product GROUP BY product_id
HAVING product=" . SqlQuote($product)); HAVING product_id=$product_id");
my $bugs = FetchOneColumn(); my $bugs = FetchOneColumn();
print $bugs || 'none'; print $bugs || 'none';
...@@ -578,6 +579,7 @@ one."; ...@@ -578,6 +579,7 @@ one.";
if ($action eq 'delete') { if ($action eq 'delete') {
PutHeader("Deleting product"); PutHeader("Deleting product");
CheckProduct($product); CheckProduct($product);
my $product_id = get_product_id($product);
# lock the tables before we start to change everything: # lock the tables before we start to change everything:
...@@ -599,7 +601,7 @@ if ($action eq 'delete') { ...@@ -599,7 +601,7 @@ if ($action eq 'delete') {
if (Param("allowbugdeletion")) { if (Param("allowbugdeletion")) {
SendSQL("SELECT bug_id SendSQL("SELECT bug_id
FROM bugs FROM bugs
WHERE product=" . SqlQuote($product)); WHERE product_id=$product_id");
while (MoreSQLData()) { while (MoreSQLData()) {
my $bugid = FetchOneColumn(); my $bugid = FetchOneColumn();
...@@ -615,25 +617,25 @@ if ($action eq 'delete') { ...@@ -615,25 +617,25 @@ if ($action eq 'delete') {
# Deleting the rest is easier: # Deleting the rest is easier:
SendSQL("DELETE FROM bugs SendSQL("DELETE FROM bugs
WHERE product=" . SqlQuote($product)); WHERE product_id=$product_id");
print "Bugs deleted.<BR>\n"; print "Bugs deleted.<BR>\n";
} }
SendSQL("DELETE FROM components SendSQL("DELETE FROM components
WHERE program=" . SqlQuote($product)); WHERE product_id=$product_id");
print "Components deleted.<BR>\n"; print "Components deleted.<BR>\n";
SendSQL("DELETE FROM versions SendSQL("DELETE FROM versions
WHERE program=" . SqlQuote($product)); WHERE product_id=$product_id");
print "Versions deleted.<P>\n"; print "Versions deleted.<P>\n";
# deleting associated target milestones - matthew@zeroknowledge.com # deleting associated target milestones - matthew@zeroknowledge.com
SendSQL("DELETE FROM milestones SendSQL("DELETE FROM milestones
WHERE product=" . SqlQuote($product)); WHERE product_id=$product_id");
print "Milestones deleted.<BR>\n"; print "Milestones deleted.<BR>\n";
SendSQL("DELETE FROM products SendSQL("DELETE FROM products
WHERE product=" . SqlQuote($product)); WHERE product_id=$product_id");
print "Product '$product' deleted.<BR>\n"; print "Product '$product' deleted.<BR>\n";
# Added -JMR, 2/16/00 # Added -JMR, 2/16/00
...@@ -681,11 +683,11 @@ if ($action eq 'edit') { ...@@ -681,11 +683,11 @@ if ($action eq 'edit') {
CheckProduct($product); CheckProduct($product);
# get data of product # get data of product
SendSQL("SELECT description,milestoneurl,disallownew, SendSQL("SELECT id,description,milestoneurl,disallownew,
votesperuser,maxvotesperbug,votestoconfirm,defaultmilestone votesperuser,maxvotesperbug,votestoconfirm,defaultmilestone
FROM products FROM products
WHERE product=" . SqlQuote($product)); WHERE name=" . SqlQuote($product));
my ($description, $milestoneurl, $disallownew, my ($product_id,$description, $milestoneurl, $disallownew,
$votesperuser, $maxvotesperbug, $votestoconfirm, $defaultmilestone) = $votesperuser, $maxvotesperbug, $votestoconfirm, $defaultmilestone) =
FetchSQLData(); FetchSQLData();
...@@ -707,9 +709,9 @@ if ($action eq 'edit') { ...@@ -707,9 +709,9 @@ if ($action eq 'edit') {
print "</TR><TR VALIGN=top>\n"; print "</TR><TR VALIGN=top>\n";
print " <TH ALIGN=\"right\"><A HREF=\"editcomponents.cgi?product=", url_quote($product), "\">Edit components:</A></TH>\n"; print " <TH ALIGN=\"right\"><A HREF=\"editcomponents.cgi?product=", url_quote($product), "\">Edit components:</A></TH>\n";
print " <TD>"; print " <TD>";
SendSQL("SELECT value,description SendSQL("SELECT name,description
FROM components FROM components
WHERE program=" . SqlQuote($product)); WHERE product_id=$product_id");
if (MoreSQLData()) { if (MoreSQLData()) {
print "<table>"; print "<table>";
while ( MoreSQLData() ) { while ( MoreSQLData() ) {
...@@ -729,7 +731,7 @@ if ($action eq 'edit') { ...@@ -729,7 +731,7 @@ if ($action eq 'edit') {
print " <TD>"; print " <TD>";
SendSQL("SELECT value SendSQL("SELECT value
FROM versions FROM versions
WHERE program=" . SqlQuote($product) . " WHERE product_id=$product_id
ORDER BY value"); ORDER BY value");
if (MoreSQLData()) { if (MoreSQLData()) {
my $br = 0; my $br = 0;
...@@ -752,7 +754,7 @@ if ($action eq 'edit') { ...@@ -752,7 +754,7 @@ if ($action eq 'edit') {
print " <TD>"; print " <TD>";
SendSQL("SELECT value SendSQL("SELECT value
FROM milestones FROM milestones
WHERE product=" . SqlQuote($product) . " WHERE product_id=$product_id
ORDER BY sortkey,value"); ORDER BY sortkey,value");
if(MoreSQLData()) { if(MoreSQLData()) {
my $br = 0; my $br = 0;
...@@ -770,10 +772,10 @@ if ($action eq 'edit') { ...@@ -770,10 +772,10 @@ if ($action eq 'edit') {
print "</TD>\n</TR><TR>\n"; print "</TD>\n</TR><TR>\n";
print " <TH ALIGN=\"right\">Bugs:</TH>\n"; print " <TH ALIGN=\"right\">Bugs:</TH>\n";
print " <TD>"; print " <TD>";
SendSQL("SELECT count(bug_id),product SendSQL("SELECT count(bug_id),product_id
FROM bugs FROM bugs
GROUP BY product GROUP BY product_id
HAVING product=" . SqlQuote($product)); HAVING product_id=$product_id");
my $bugs = ''; my $bugs = '';
$bugs = FetchOneColumn() if MoreSQLData(); $bugs = FetchOneColumn() if MoreSQLData();
print $bugs || 'none'; print $bugs || 'none';
...@@ -837,6 +839,7 @@ if ($action eq 'update') { ...@@ -837,6 +839,7 @@ if ($action eq 'update') {
my $checkvotes = 0; my $checkvotes = 0;
CheckProduct($productold); CheckProduct($productold);
my $product_id = get_product_id($productold);
if ($maxvotesperbug !~ /^\d+$/ || $maxvotesperbug <= 0) { if ($maxvotesperbug !~ /^\d+$/ || $maxvotesperbug <= 0) {
print "Sorry, the max votes per bug must be a positive integer."; print "Sorry, the max votes per bug must be a positive integer.";
...@@ -844,22 +847,20 @@ if ($action eq 'update') { ...@@ -844,22 +847,20 @@ if ($action eq 'update') {
exit; exit;
} }
# Note that the order of this tests is important. If you change # Note that we got the $product_id using $productold above so it will
# them, be sure to test for WHERE='$product' or WHERE='$productold' # remain static even after we rename the product in the database.
SendSQL("LOCK TABLES bugs WRITE, SendSQL("LOCK TABLES products WRITE,
components WRITE, versions READ,
products WRITE,
versions WRITE,
groups WRITE, groups WRITE,
profiles WRITE, profiles WRITE,
milestones WRITE"); milestones READ");
if ($disallownew ne $disallownewold) { if ($disallownew ne $disallownewold) {
$disallownew ||= 0; $disallownew ||= 0;
SendSQL("UPDATE products SendSQL("UPDATE products
SET disallownew=$disallownew SET disallownew=$disallownew
WHERE product=" . SqlQuote($productold)); WHERE id=$product_id");
print "Updated bug submit status.<BR>\n"; print "Updated bug submit status.<BR>\n";
} }
...@@ -872,14 +873,14 @@ if ($action eq 'update') { ...@@ -872,14 +873,14 @@ if ($action eq 'update') {
} }
SendSQL("UPDATE products SendSQL("UPDATE products
SET description=" . SqlQuote($description) . " SET description=" . SqlQuote($description) . "
WHERE product=" . SqlQuote($productold)); WHERE id=$product_id");
print "Updated description.<BR>\n"; print "Updated description.<BR>\n";
} }
if (Param('usetargetmilestone') && $milestoneurl ne $milestoneurlold) { if (Param('usetargetmilestone') && $milestoneurl ne $milestoneurlold) {
SendSQL("UPDATE products SendSQL("UPDATE products
SET milestoneurl=" . SqlQuote($milestoneurl) . " SET milestoneurl=" . SqlQuote($milestoneurl) . "
WHERE product=" . SqlQuote($productold)); WHERE id=$product_id");
print "Updated mile stone URL.<BR>\n"; print "Updated mile stone URL.<BR>\n";
} }
...@@ -949,7 +950,7 @@ if ($action eq 'update') { ...@@ -949,7 +950,7 @@ if ($action eq 'update') {
if ($votesperuser ne $votesperuserold) { if ($votesperuser ne $votesperuserold) {
SendSQL("UPDATE products SendSQL("UPDATE products
SET votesperuser=$votesperuser SET votesperuser=$votesperuser
WHERE product=" . SqlQuote($productold)); WHERE id=$product_id");
print "Updated votes per user.<BR>\n"; print "Updated votes per user.<BR>\n";
$checkvotes = 1; $checkvotes = 1;
} }
...@@ -958,7 +959,7 @@ if ($action eq 'update') { ...@@ -958,7 +959,7 @@ if ($action eq 'update') {
if ($maxvotesperbug ne $maxvotesperbugold) { if ($maxvotesperbug ne $maxvotesperbugold) {
SendSQL("UPDATE products SendSQL("UPDATE products
SET maxvotesperbug=$maxvotesperbug SET maxvotesperbug=$maxvotesperbug
WHERE product=" . SqlQuote($productold)); WHERE id=$product_id");
print "Updated max votes per bug.<BR>\n"; print "Updated max votes per bug.<BR>\n";
$checkvotes = 1; $checkvotes = 1;
} }
...@@ -967,7 +968,7 @@ if ($action eq 'update') { ...@@ -967,7 +968,7 @@ if ($action eq 'update') {
if ($votestoconfirm ne $votestoconfirmold) { if ($votestoconfirm ne $votestoconfirmold) {
SendSQL("UPDATE products SendSQL("UPDATE products
SET votestoconfirm=$votestoconfirm SET votestoconfirm=$votestoconfirm
WHERE product=" . SqlQuote($productold)); WHERE id=$product_id");
print "Updated votes to confirm.<BR>\n"; print "Updated votes to confirm.<BR>\n";
$checkvotes = 1; $checkvotes = 1;
} }
...@@ -976,7 +977,7 @@ if ($action eq 'update') { ...@@ -976,7 +977,7 @@ if ($action eq 'update') {
if ($defaultmilestone ne $defaultmilestoneold) { if ($defaultmilestone ne $defaultmilestoneold) {
SendSQL("SELECT value FROM milestones " . SendSQL("SELECT value FROM milestones " .
"WHERE value = " . SqlQuote($defaultmilestone) . "WHERE value = " . SqlQuote($defaultmilestone) .
" AND product = " . SqlQuote($productold)); " 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.";
SendSQL("UNLOCK TABLES"); SendSQL("UNLOCK TABLES");
...@@ -985,7 +986,7 @@ if ($action eq 'update') { ...@@ -985,7 +986,7 @@ if ($action eq 'update') {
} }
SendSQL("UPDATE products " . SendSQL("UPDATE products " .
"SET defaultmilestone = " . SqlQuote($defaultmilestone) . "SET defaultmilestone = " . SqlQuote($defaultmilestone) .
"WHERE product=" . SqlQuote($productold)); "WHERE id=$product_id");
print "Updated default milestone.<BR>\n"; print "Updated default milestone.<BR>\n";
} }
...@@ -1006,11 +1007,7 @@ if ($action eq 'update') { ...@@ -1006,11 +1007,7 @@ if ($action eq 'update') {
exit; exit;
} }
SendSQL("UPDATE bugs SET product=$qp, delta_ts=delta_ts WHERE product=$qpold"); SendSQL("UPDATE products SET name=$qp WHERE id=$product_id");
SendSQL("UPDATE components SET program=$qp WHERE program=$qpold");
SendSQL("UPDATE products SET product=$qp WHERE product=$qpold");
SendSQL("UPDATE versions SET program=$qp WHERE program=$qpold");
SendSQL("UPDATE milestones SET product=$qp WHERE product=$qpold");
# Need to do an update to groups as well. If there is a corresponding # Need to do an update to groups as well. If there is a corresponding
# bug group, whether usebuggroups is currently set or not, we want to # bug group, whether usebuggroups is currently set or not, we want to
# update it so it will match in the future. If there is no group, this # update it so it will match in the future. If there is no group, this
...@@ -1031,7 +1028,7 @@ if ($action eq 'update') { ...@@ -1031,7 +1028,7 @@ if ($action eq 'update') {
SendSQL("SELECT votes.who, votes.bug_id " . SendSQL("SELECT votes.who, votes.bug_id " .
"FROM votes, bugs " . "FROM votes, bugs " .
"WHERE bugs.bug_id = votes.bug_id " . "WHERE bugs.bug_id = votes.bug_id " .
" AND bugs.product = $qp " . " AND bugs.product_id = $product_id " .
" AND votes.count > $maxvotesperbug"); " AND votes.count > $maxvotesperbug");
my @list; my @list;
while (MoreSQLData()) { while (MoreSQLData()) {
...@@ -1047,7 +1044,7 @@ if ($action eq 'update') { ...@@ -1047,7 +1044,7 @@ if ($action eq 'update') {
} }
SendSQL("SELECT votes.who, votes.count FROM votes, bugs " . SendSQL("SELECT votes.who, votes.count FROM votes, bugs " .
"WHERE bugs.bug_id = votes.bug_id " . "WHERE bugs.bug_id = votes.bug_id " .
" AND bugs.product = $qp"); " AND bugs.product_id = $product_id");
my %counts; my %counts;
while (MoreSQLData()) { while (MoreSQLData()) {
my ($who, $count) = (FetchSQLData()); my ($who, $count) = (FetchSQLData());
...@@ -1061,7 +1058,7 @@ if ($action eq 'update') { ...@@ -1061,7 +1058,7 @@ if ($action eq 'update') {
if ($counts{$who} > $votesperuser) { if ($counts{$who} > $votesperuser) {
SendSQL("SELECT votes.bug_id FROM votes, bugs " . SendSQL("SELECT votes.bug_id FROM votes, bugs " .
"WHERE bugs.bug_id = votes.bug_id " . "WHERE bugs.bug_id = votes.bug_id " .
" AND bugs.product = $qp " . " AND bugs.product_id = $product_id " .
" AND votes.who = $who"); " AND votes.who = $who");
while (MoreSQLData()) { while (MoreSQLData()) {
my $id = FetchSQLData(); my $id = FetchSQLData();
...@@ -1073,7 +1070,7 @@ if ($action eq 'update') { ...@@ -1073,7 +1070,7 @@ if ($action eq 'update') {
} }
} }
SendSQL("SELECT bug_id FROM bugs " . SendSQL("SELECT bug_id FROM bugs " .
"WHERE product = $qp " . "WHERE product_id = $product_id " .
" AND bug_status = '$::unconfirmedstate' " . " AND bug_status = '$::unconfirmedstate' " .
" AND votes >= $votestoconfirm"); " AND votes >= $votestoconfirm");
my @list; my @list;
......
...@@ -579,9 +579,10 @@ if ($action eq 'del') { ...@@ -579,9 +579,10 @@ if ($action eq 'del') {
# Check if the user is an initialowner # Check if the user is an initialowner
my $nodelete = ''; my $nodelete = '';
SendSQL("SELECT program, value SendSQL("SELECT products.name, components.name " .
FROM components "FROM products, components " .
WHERE initialowner=" . DBname_to_id($user)); "WHERE products.id = components.product_id " .
" AND initialowner=" . DBname_to_id($user));
$found = 0; $found = 0;
while (MoreSQLData()) { while (MoreSQLData()) {
if ($found) { if ($found) {
...@@ -603,9 +604,10 @@ if ($action eq 'del') { ...@@ -603,9 +604,10 @@ if ($action eq 'del') {
# Check if the user is an initialqacontact # Check if the user is an initialqacontact
SendSQL("SELECT program, value SendSQL("SELECT products.name, components.name " .
FROM components "FROM products, components " .
WHERE initialqacontact=" . DBname_to_id($user)); "WHERE products.id = components.id " .
" AND initialqacontact=" . DBname_to_id($user));
$found = 0; $found = 0;
while (MoreSQLData()) { while (MoreSQLData()) {
if ($found) { if ($found) {
......
...@@ -46,9 +46,9 @@ sub TestProduct ($) ...@@ -46,9 +46,9 @@ sub TestProduct ($)
my $prod = shift; my $prod = shift;
# does the product exist? # does the product exist?
SendSQL("SELECT product SendSQL("SELECT name
FROM products FROM products
WHERE product=" . SqlQuote($prod)); WHERE name=" . SqlQuote($prod));
return FetchOneColumn(); return FetchOneColumn();
} }
...@@ -75,9 +75,9 @@ sub TestVersion ($$) ...@@ -75,9 +75,9 @@ sub TestVersion ($$)
my ($prod,$ver) = @_; my ($prod,$ver) = @_;
# does the product exist? # does the product exist?
SendSQL("SELECT program,value SendSQL("SELECT products.name,value
FROM versions FROM versions, products
WHERE program=" . SqlQuote($prod) . " and value=" . SqlQuote($ver)); WHERE versions.product_id=products.id AND products.name=" . SqlQuote($prod) . " and value=" . SqlQuote($ver));
return FetchOneColumn(); return FetchOneColumn();
} }
...@@ -191,10 +191,10 @@ if ($version) { ...@@ -191,10 +191,10 @@ if ($version) {
unless ($product) { unless ($product) {
PutHeader("Select product"); PutHeader("Select product");
SendSQL("SELECT products.product,products.description,'xyzzy' SendSQL("SELECT products.name,products.description,'xyzzy'
FROM products FROM products
GROUP BY products.product GROUP BY products.name
ORDER BY products.product"); ORDER BY products.name");
print "<TABLE BORDER=1 CELLPADDING=4 CELLSPACING=0><TR BGCOLOR=\"#6666FF\">\n"; print "<TABLE BORDER=1 CELLPADDING=4 CELLSPACING=0><TR BGCOLOR=\"#6666FF\">\n";
print " <TH ALIGN=\"left\">Edit versions of ...</TH>\n"; print " <TH ALIGN=\"left\">Edit versions of ...</TH>\n";
print " <TH ALIGN=\"left\">Description</TH>\n"; print " <TH ALIGN=\"left\">Description</TH>\n";
...@@ -217,8 +217,6 @@ unless ($product) { ...@@ -217,8 +217,6 @@ unless ($product) {
exit; exit;
} }
# #
# action='' -> Show nice list of versions # action='' -> Show nice list of versions
# #
...@@ -226,24 +224,11 @@ unless ($product) { ...@@ -226,24 +224,11 @@ unless ($product) {
unless ($action) { unless ($action) {
PutHeader("Select version of $product"); PutHeader("Select version of $product");
CheckProduct($product); CheckProduct($product);
my $product_id = get_product_id($product);
=for me SendSQL("SELECT value
# Das geht nicht wie vermutet. Ich bekomme nicht alle Versionen
# angezeigt! Schade. Ich wrde gerne sehen, wieviel Bugs pro
# Version angegeben sind ...
SendSQL("SELECT value,program,COUNT(bug_id)
FROM versions LEFT JOIN bugs
ON program=product AND value=version
WHERE program=" . SqlQuote($product) . "
GROUP BY value");
=cut
SendSQL("SELECT value,program
FROM versions FROM versions
WHERE program=" . SqlQuote($product) . " WHERE product_id=$product_id
ORDER BY value"); ORDER BY value");
print "<TABLE BORDER=1 CELLPADDING=4 CELLSPACING=0><TR BGCOLOR=\"#6666FF\">\n"; print "<TABLE BORDER=1 CELLPADDING=4 CELLSPACING=0><TR BGCOLOR=\"#6666FF\">\n";
...@@ -252,8 +237,7 @@ unless ($action) { ...@@ -252,8 +237,7 @@ unless ($action) {
print " <TH ALIGN=\"left\">Action</TH>\n"; print " <TH ALIGN=\"left\">Action</TH>\n";
print "</TR>"; print "</TR>";
while ( MoreSQLData() ) { while ( MoreSQLData() ) {
my ($version,$dummy,$bugs) = FetchSQLData(); my $version = FetchOneColumn();
$bugs ||= 'none';
print "<TR>\n"; print "<TR>\n";
print " <TD VALIGN=\"top\"><A HREF=\"editversions.cgi?product=", url_quote($product), "&version=", url_quote($version), "&action=edit\"><B>$version</B></A></TD>\n"; print " <TD VALIGN=\"top\"><A HREF=\"editversions.cgi?product=", url_quote($product), "&version=", url_quote($version), "&action=edit\"><B>$version</B></A></TD>\n";
#print " <TD VALIGN=\"top\">$bugs</TD>\n"; #print " <TD VALIGN=\"top\">$bugs</TD>\n";
...@@ -281,6 +265,7 @@ unless ($action) { ...@@ -281,6 +265,7 @@ unless ($action) {
if ($action eq 'add') { if ($action eq 'add') {
PutHeader("Add version of $product"); PutHeader("Add version of $product");
CheckProduct($product); CheckProduct($product);
my $product_id = get_product_id($product);
#print "This page lets you add a new version to a bugzilla-tracked product.\n"; #print "This page lets you add a new version to a bugzilla-tracked product.\n";
...@@ -309,6 +294,7 @@ if ($action eq 'add') { ...@@ -309,6 +294,7 @@ if ($action eq 'add') {
if ($action eq 'new') { if ($action eq 'new') {
PutHeader("Adding new version"); PutHeader("Adding new version");
CheckProduct($product); CheckProduct($product);
my $product_id = get_product_id($product);
# Cleanups and valididy checks # Cleanups and valididy checks
...@@ -327,10 +313,9 @@ if ($action eq 'new') { ...@@ -327,10 +313,9 @@ if ($action eq 'new') {
# Add the new version # Add the new version
SendSQL("INSERT INTO versions ( " . SendSQL("INSERT INTO versions ( " .
"value, program" . "value, product_id" .
" ) VALUES ( " . " ) VALUES ( " .
SqlQuote($version) . "," . SqlQuote($version) . ", $product_id)");
SqlQuote($product) . ")");
# Make versioncache flush # Make versioncache flush
unlink "data/versioncache"; unlink "data/versioncache";
...@@ -352,12 +337,12 @@ if ($action eq 'new') { ...@@ -352,12 +337,12 @@ if ($action eq 'new') {
if ($action eq 'del') { if ($action eq 'del') {
PutHeader("Delete version of $product"); PutHeader("Delete version of $product");
CheckVersion($product, $version); CheckVersion($product, $version);
my $product_id = get_product_id($product);
SendSQL("SELECT count(bug_id),product,version SendSQL("SELECT count(bug_id)
FROM bugs FROM bugs
GROUP BY product,version WHERE product_id = $product_id
HAVING product=" . SqlQuote($product) . " AND version = " . SqlQuote($version));
AND version=" . SqlQuote($version));
my $bugs = FetchOneColumn(); my $bugs = FetchOneColumn();
print "<TABLE BORDER=1 CELLPADDING=4 CELLSPACING=0>\n"; print "<TABLE BORDER=1 CELLPADDING=4 CELLSPACING=0>\n";
...@@ -416,6 +401,7 @@ one."; ...@@ -416,6 +401,7 @@ one.";
if ($action eq 'delete') { if ($action eq 'delete') {
PutHeader("Deleting version of $product"); PutHeader("Deleting version of $product");
CheckVersion($product,$version); CheckVersion($product,$version);
my $product_id = get_product_id($product);
# lock the tables before we start to change everything: # lock the tables before we start to change everything:
...@@ -433,7 +419,7 @@ if ($action eq 'delete') { ...@@ -433,7 +419,7 @@ if ($action eq 'delete') {
SendSQL("SELECT bug_id SendSQL("SELECT bug_id
FROM bugs FROM bugs
WHERE product=" . SqlQuote($product) . " WHERE product_id=$product_id
AND version=" . SqlQuote($version)); AND version=" . SqlQuote($version));
while (MoreSQLData()) { while (MoreSQLData()) {
my $bugid = FetchOneColumn(); my $bugid = FetchOneColumn();
...@@ -450,13 +436,13 @@ if ($action eq 'delete') { ...@@ -450,13 +436,13 @@ if ($action eq 'delete') {
# Deleting the rest is easier: # Deleting the rest is easier:
SendSQL("DELETE FROM bugs SendSQL("DELETE FROM bugs
WHERE product=" . SqlQuote($product) . " WHERE product_id = $product_id
AND version=" . SqlQuote($version)); AND version=" . SqlQuote($version));
print "Bugs deleted.<BR>\n"; print "Bugs deleted.<BR>\n";
} }
SendSQL("DELETE FROM versions SendSQL("DELETE FROM versions
WHERE program=" . SqlQuote($product) . " WHERE product_id = $product_id
AND value=" . SqlQuote($version)); AND value=" . SqlQuote($version));
print "Version deleted.<P>\n"; print "Version deleted.<P>\n";
SendSQL("UNLOCK TABLES"); SendSQL("UNLOCK TABLES");
...@@ -477,6 +463,7 @@ if ($action eq 'delete') { ...@@ -477,6 +463,7 @@ if ($action eq 'delete') {
if ($action eq 'edit') { if ($action eq 'edit') {
PutHeader("Edit version of $product"); PutHeader("Edit version of $product");
CheckVersion($product,$version); CheckVersion($product,$version);
my $product_id = get_product_id($product);
print "<FORM METHOD=POST ACTION=editversions.cgi>\n"; print "<FORM METHOD=POST ACTION=editversions.cgi>\n";
print "<TABLE BORDER=0 CELLPADDING=4 CELLSPACING=0><TR>\n"; print "<TABLE BORDER=0 CELLPADDING=4 CELLSPACING=0><TR>\n";
...@@ -510,12 +497,14 @@ if ($action eq 'update') { ...@@ -510,12 +497,14 @@ if ($action eq 'update') {
my $versionold = trim($::FORM{versionold} || ''); my $versionold = trim($::FORM{versionold} || '');
CheckVersion($product,$versionold); CheckVersion($product,$versionold);
my $product_id = get_product_id($product);
# 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, SendSQL("LOCK TABLES bugs WRITE,
versions WRITE"); versions WRITE,
products READ");
if ($version ne $versionold) { if ($version ne $versionold) {
unless ($version) { unless ($version) {
...@@ -534,10 +523,10 @@ if ($action eq 'update') { ...@@ -534,10 +523,10 @@ if ($action eq 'update') {
SET version=" . SqlQuote($version) . ", SET version=" . SqlQuote($version) . ",
delta_ts = delta_ts delta_ts = delta_ts
WHERE version=" . SqlQuote($versionold) . " WHERE version=" . SqlQuote($versionold) . "
AND product=" . SqlQuote($product)); AND product_id = $product_id");
SendSQL("UPDATE versions SendSQL("UPDATE versions
SET value=" . SqlQuote($version) . " SET value=" . SqlQuote($version) . "
WHERE program=" . SqlQuote($product) . " WHERE product_id = $product_id
AND value=" . SqlQuote($versionold)); AND value=" . SqlQuote($versionold));
unlink "data/versioncache"; unlink "data/versioncache";
print "Updated version.<BR>\n"; print "Updated version.<BR>\n";
......
...@@ -240,6 +240,8 @@ if (lsearch(\@::enterable_products, $product) == -1) { ...@@ -240,6 +240,8 @@ if (lsearch(\@::enterable_products, $product) == -1) {
exit; exit;
} }
my $product_id = get_product_id($product);
if (0 == @{$::components{$product}}) { if (0 == @{$::components{$product}}) {
my $error = "Sorry; there needs to be at least one component for this " . my $error = "Sorry; there needs to be at least one component for this " .
"product in order to create a new bug. "; "product in order to create a new bug. ";
...@@ -261,8 +263,8 @@ elsif (1 == @{$::components{$product}}) { ...@@ -261,8 +263,8 @@ elsif (1 == @{$::components{$product}}) {
} }
my @components; my @components;
SendSQL("SELECT value, description FROM components " . SendSQL("SELECT name, description FROM components " .
"WHERE program = " . SqlQuote($product) . " ORDER BY value"); "WHERE product_id = $product_id ORDER BY name");
while (MoreSQLData()) { while (MoreSQLData()) {
my ($name, $description) = FetchSQLData(); my ($name, $description) = FetchSQLData();
...@@ -315,7 +317,7 @@ if (exists $::COOKIE{"VERSION-$product"} && ...@@ -315,7 +317,7 @@ if (exists $::COOKIE{"VERSION-$product"} &&
my @status = "NEW"; my @status = "NEW";
if (UserInGroup("editbugs") || UserInGroup("canconfirm")) { if (UserInGroup("editbugs") || UserInGroup("canconfirm")) {
SendSQL("SELECT votestoconfirm FROM products WHERE product = " . SendSQL("SELECT votestoconfirm FROM products WHERE name = " .
SqlQuote($product)); SqlQuote($product));
push(@status, $unconfirmedstate) if (FetchOneColumn()); push(@status, $unconfirmedstate) if (FetchOneColumn());
} }
......
...@@ -434,7 +434,10 @@ sub GenerateArrayCode { ...@@ -434,7 +434,10 @@ sub GenerateArrayCode {
sub GenerateVersionTable { sub GenerateVersionTable {
SendSQL("select value, program from versions order by value"); SendSQL("SELECT versions.value, products.name " .
"FROM versions, products " .
"WHERE products.id = versions.product_id " .
"ORDER BY versions.value");
my @line; my @line;
my %varray; my %varray;
my %carray; my %carray;
...@@ -446,7 +449,10 @@ sub GenerateVersionTable { ...@@ -446,7 +449,10 @@ sub GenerateVersionTable {
push @{$::versions{$p1}}, $v; push @{$::versions{$p1}}, $v;
$varray{$v} = 1; $varray{$v} = 1;
} }
SendSQL("select value, program from components order by value"); SendSQL("SELECT components.name, products.name " .
"FROM components, products " .
"WHERE products.id = components.product_id " .
"ORDER BY components.name");
while (@line = FetchSQLData()) { while (@line = FetchSQLData()) {
my ($c,$p) = (@line); my ($c,$p) = (@line);
if (!defined $::components{$p}) { if (!defined $::components{$p}) {
...@@ -464,7 +470,7 @@ sub GenerateVersionTable { ...@@ -464,7 +470,7 @@ sub GenerateVersionTable {
# about them anyway. # about them anyway.
my $mpart = $dotargetmilestone ? ", milestoneurl" : ""; my $mpart = $dotargetmilestone ? ", milestoneurl" : "";
SendSQL("select product, description, votesperuser, disallownew$mpart from products ORDER BY product"); SendSQL("select name, description, votesperuser, disallownew$mpart from products ORDER BY name");
while (@line = FetchSQLData()) { while (@line = FetchSQLData()) {
my ($p, $d, $votesperuser, $dis, $u) = (@line); my ($p, $d, $votesperuser, $dis, $u) = (@line);
$::proddesc{$p} = $d; $::proddesc{$p} = $d;
...@@ -546,7 +552,10 @@ sub GenerateVersionTable { ...@@ -546,7 +552,10 @@ sub GenerateVersionTable {
if ($dotargetmilestone) { if ($dotargetmilestone) {
# reading target milestones in from the database - matthew@zeroknowledge.com # reading target milestones in from the database - matthew@zeroknowledge.com
SendSQL("SELECT value, product FROM milestones ORDER BY sortkey, value"); SendSQL("SELECT milestones.value, products.name " .
"FROM milestones, products " .
"WHERE products.id = milestones.product_id " .
"ORDER BY milestones.sortkey, milestones.value");
my @line; my @line;
my %tmarray; my %tmarray;
@::legal_target_milestone = (); @::legal_target_milestone = ();
...@@ -943,6 +952,49 @@ sub DBNameToIdAndCheck { ...@@ -943,6 +952,49 @@ sub DBNameToIdAndCheck {
registered for a Bugzilla account."); registered for a Bugzilla account.");
} }
sub get_product_id {
my ($prod) = @_;
PushGlobalSQLState();
SendSQL("SELECT id FROM products WHERE name = " . SqlQuote($prod));
my ($prod_id) = FetchSQLData();
PopGlobalSQLState();
return $prod_id;
}
sub get_product_name {
my ($prod_id) = @_;
die "non-numeric prod_id '$prod_id' passed to get_product_name"
unless ($prod_id =~ /^\d+$/);
PushGlobalSQLState();
SendSQL("SELECT name FROM products WHERE id = $prod_id");
my ($prod) = FetchSQLData();
PopGlobalSQLState();
return $prod;
}
sub get_component_id {
my ($prod_id, $comp) = @_;
die "non-numeric prod_id '$prod_id' passed to get_component_id"
unless ($prod_id =~ /^\d+$/);
PushGlobalSQLState();
SendSQL("SELECT id FROM components " .
"WHERE product_id = $prod_id AND name = " . SqlQuote($comp));
my ($comp_id) = FetchSQLData();
PopGlobalSQLState();
return $comp_id;
}
sub get_component_name {
my ($comp_id) = @_;
die "non-numeric comp_id '$comp_id' passed to get_component_name"
unless ($comp_id =~ /^\d+$/);
PushGlobalSQLState();
SendSQL("SELECT name FROM components WHERE id = $comp_id");
my ($comp) = FetchSQLData();
PopGlobalSQLState();
return $comp;
}
# Use trick_taint() when you know that there is no way that the data # Use trick_taint() when you know that there is no way that the data
# in a scalar can be tainted, but taint mode still bails on it. # in a scalar can be tainted, but taint mode still bails on it.
# WARNING!! Using this routine on data that really could be tainted # WARNING!! Using this routine on data that really could be tainted
...@@ -1330,7 +1382,7 @@ sub RemoveVotes { ...@@ -1330,7 +1382,7 @@ sub RemoveVotes {
"FROM profiles " . "FROM profiles " .
"LEFT JOIN votes ON profiles.userid = votes.who " . "LEFT JOIN votes ON profiles.userid = votes.who " .
"LEFT JOIN bugs USING(bug_id) " . "LEFT JOIN bugs USING(bug_id) " .
"LEFT JOIN products USING(product)" . "LEFT JOIN products ON products.id = bugs.product_id " .
"WHERE votes.bug_id = $id " . "WHERE votes.bug_id = $id " .
$whopart); $whopart);
my @list; my @list;
......
...@@ -570,9 +570,10 @@ for (my $k=1 ; $k <= $bugqty ; $k++) { ...@@ -570,9 +570,10 @@ for (my $k=1 ; $k <= $bugqty ; $k++) {
push (@values, SqlQuote($qa_contact)); push (@values, SqlQuote($qa_contact));
push (@query, "qa_contact"); push (@query, "qa_contact");
} else { } else {
SendSQL("select initialqacontact from components where program=" . SendSQL("SELECT initialqacontact FROM components, products "
SqlQuote($product[0]) . "WHERE components.product_id = products.id" .
" and value=" . SqlQuote($component[0]) ); " AND products.name = " . SqlQuote($product[0]) .
" AND components.name = " . SqlQuote($component[0]) );
$qa_contact = FetchOneColumn(); $qa_contact = FetchOneColumn();
push (@values, SqlQuote(DBname_to_id($qa_contact)) ); push (@values, SqlQuote(DBname_to_id($qa_contact)) );
push (@query, "qa_contact"); push (@query, "qa_contact");
......
...@@ -41,7 +41,7 @@ GetVersionTable(); ...@@ -41,7 +41,7 @@ GetVersionTable();
my $generic_query = " my $generic_query = "
SELECT SELECT
bugs.bug_id, bugs.bug_id,
bugs.product, products.name,
bugs.version, bugs.version,
bugs.rep_platform, bugs.rep_platform,
bugs.op_sys, bugs.op_sys,
...@@ -49,7 +49,7 @@ my $generic_query = " ...@@ -49,7 +49,7 @@ my $generic_query = "
bugs.resolution, bugs.resolution,
bugs.priority, bugs.priority,
bugs.bug_severity, bugs.bug_severity,
bugs.component, components.name,
assign.login_name, assign.login_name,
report.login_name, report.login_name,
bugs.bug_file_loc, bugs.bug_file_loc,
...@@ -58,8 +58,9 @@ my $generic_query = " ...@@ -58,8 +58,9 @@ my $generic_query = "
bugs.qa_contact, bugs.qa_contact,
bugs.status_whiteboard, bugs.status_whiteboard,
bugs.keywords bugs.keywords
FROM bugs,profiles assign,profiles report FROM bugs,profiles assign,profiles report, products, components
WHERE assign.userid = bugs.assigned_to AND report.userid = bugs.reporter"; WHERE assign.userid = bugs.assigned_to AND report.userid = bugs.reporter
AND bugs.product_id=products.id AND bugs.component_id=components.id";
my $buglist = $::FORM{'buglist'} || my $buglist = $::FORM{'buglist'} ||
$::FORM{'bug_id'} || $::FORM{'bug_id'} ||
......
...@@ -70,6 +70,11 @@ $template->process("$template_name.txt.tmpl", $vars, \$comment) ...@@ -70,6 +70,11 @@ $template->process("$template_name.txt.tmpl", $vars, \$comment)
ValidateComment($comment); ValidateComment($comment);
my $product = $::FORM{'product'}; my $product = $::FORM{'product'};
my $product_id = get_product_id($product);
if (!$product_id) {
ThrowUserError("Sorry, the product <tt>" . html_quote($product) .
"</tt> does not exist");
}
# Set cookies # Set cookies
my $cookiepath = Param("cookiepath"); my $cookiepath = Param("cookiepath");
...@@ -100,7 +105,8 @@ if(Param("usebuggroupsentry") && GroupExists($product)) { ...@@ -100,7 +105,8 @@ if(Param("usebuggroupsentry") && GroupExists($product)) {
} }
} }
if (!$::FORM{'component'}) { my $component_id = get_component_id($product_id, $::FORM{component});
if (!$component_id) {
DisplayError("You must choose a component that corresponds to this bug. DisplayError("You must choose a component that corresponds to this bug.
If necessary, just guess."); If necessary, just guess.");
exit; exit;
...@@ -121,20 +127,20 @@ my $sql_component = SqlQuote($::FORM{'component'}); ...@@ -121,20 +127,20 @@ my $sql_component = SqlQuote($::FORM{'component'});
# Default assignee is the component owner. # Default assignee is the component owner.
if ($::FORM{'assigned_to'} eq "") { if ($::FORM{'assigned_to'} eq "") {
SendSQL("SELECT initialowner FROM components " . SendSQL("SELECT initialowner FROM components " .
"WHERE program=$sql_product AND value=$sql_component"); "WHERE id = $component_id");
$::FORM{'assigned_to'} = FetchOneColumn(); $::FORM{'assigned_to'} = FetchOneColumn();
} else { } else {
$::FORM{'assigned_to'} = DBNameToIdAndCheck(trim($::FORM{'assigned_to'})); $::FORM{'assigned_to'} = DBNameToIdAndCheck(trim($::FORM{'assigned_to'}));
} }
my @bug_fields = ("product", "version", "rep_platform", my @bug_fields = ("version", "rep_platform",
"bug_severity", "priority", "op_sys", "assigned_to", "bug_severity", "priority", "op_sys", "assigned_to",
"bug_status", "bug_file_loc", "short_desc", "component", "bug_status", "bug_file_loc", "short_desc",
"target_milestone"); "target_milestone");
if (Param("useqacontact")) { if (Param("useqacontact")) {
SendSQL("SELECT initialqacontact FROM components " . SendSQL("SELECT initialqacontact FROM components " .
"WHERE program=$sql_product AND value=$sql_component"); "WHERE id = $component_id");
my $qa_contact = FetchOneColumn(); my $qa_contact = FetchOneColumn();
if (defined $qa_contact && $qa_contact != 0) { if (defined $qa_contact && $qa_contact != 0) {
$::FORM{'qa_contact'} = $qa_contact; $::FORM{'qa_contact'} = $qa_contact;
...@@ -155,14 +161,14 @@ if (exists $::FORM{'bug_status'}) { ...@@ -155,14 +161,14 @@ if (exists $::FORM{'bug_status'}) {
if (!exists $::FORM{'bug_status'}) { if (!exists $::FORM{'bug_status'}) {
$::FORM{'bug_status'} = $::unconfirmedstate; $::FORM{'bug_status'} = $::unconfirmedstate;
SendSQL("SELECT votestoconfirm FROM products WHERE product=$sql_product"); SendSQL("SELECT votestoconfirm FROM products WHERE id = $product_id");
if (!FetchOneColumn()) { if (!FetchOneColumn()) {
$::FORM{'bug_status'} = "NEW"; $::FORM{'bug_status'} = "NEW";
} }
} }
if (!exists $::FORM{'target_milestone'}) { if (!exists $::FORM{'target_milestone'}) {
SendSQL("SELECT defaultmilestone FROM products WHERE product=$sql_product"); SendSQL("SELECT defaultmilestone FROM products WHERE name=$sql_product");
$::FORM{'target_milestone'} = FetchOneColumn(); $::FORM{'target_milestone'} = FetchOneColumn();
} }
...@@ -200,6 +206,11 @@ if (exists $::FORM{'bug_status'} ...@@ -200,6 +206,11 @@ if (exists $::FORM{'bug_status'}
$::FORM{'everconfirmed'} = 1; $::FORM{'everconfirmed'} = 1;
} }
$::FORM{'product_id'} = $product_id;
push(@used_fields, "product_id");
$::FORM{component_id} = $component_id;
push(@used_fields, "component_id");
my %ccids; my %ccids;
my @cc; my @cc;
......
...@@ -174,7 +174,8 @@ sub CheckonComment( $ ) { ...@@ -174,7 +174,8 @@ sub CheckonComment( $ ) {
# and make the user verify the version, component, target milestone, # and make the user verify the version, component, target milestone,
# and bug groups if so. # and bug groups if so.
if ( $::FORM{'id'} ) { if ( $::FORM{'id'} ) {
SendSQL("SELECT product FROM bugs WHERE bug_id = $::FORM{'id'}"); SendSQL("SELECT name FROM products, bugs " .
"WHERE products.id = bugs.product_id AND bug_id = $::FORM{'id'}");
$::oldproduct = FetchSQLData(); $::oldproduct = FetchSQLData();
} }
if ((($::FORM{'id'} && $::FORM{'product'} ne $::oldproduct) if ((($::FORM{'id'} && $::FORM{'product'} ne $::oldproduct)
...@@ -503,8 +504,8 @@ if($::usergroupset ne '0') { ...@@ -503,8 +504,8 @@ if($::usergroupset ne '0') {
} }
foreach my $field ("rep_platform", "priority", "bug_severity", foreach my $field ("rep_platform", "priority", "bug_severity",
"summary", "component", "bug_file_loc", "short_desc", "summary", "bug_file_loc", "short_desc",
"product", "version", "op_sys", "version", "op_sys",
"target_milestone", "status_whiteboard") { "target_milestone", "status_whiteboard") {
if (defined $::FORM{$field}) { if (defined $::FORM{$field}) {
if ($::FORM{$field} ne $::dontchange) { if ($::FORM{$field} ne $::dontchange) {
...@@ -514,6 +515,41 @@ foreach my $field ("rep_platform", "priority", "bug_severity", ...@@ -514,6 +515,41 @@ foreach my $field ("rep_platform", "priority", "bug_severity",
} }
} }
my $prod_id; # Remember, can't use this for mass changes
if ($::FORM{'product'} ne $::dontchange) {
$prod_id = get_product_id($::FORM{'product'});
if (! $prod_id) {
DisplayError("The <tt>" . html_quote($::FORM{'product'}) .
"</tt> product doesn't exist.");
exit;
}
DoComma();
$::query .= "product_id = $prod_id";
} else {
SendSQL("SELECT DISTINCT product_id FROM bugs WHERE bug_id IN (" .
join(',', @idlist) . ") LIMIT 2");
$prod_id = FetchOneColumn();
$prod_id = undef if (FetchOneColumn());
}
my $comp_id; # Remember, can't use this for mass changes
if ($::FORM{'component'} ne $::dontchange) {
if (!defined $prod_id) {
ThrowUserError("You cannot change the component from a list of bugs " .
"covering more than one product");
}
$comp_id = get_component_id($prod_id,
$::FORM{'component'});
if (! $comp_id) {
DisplayError("The <tt>" . html_quote($::FORM{'component'}) .
"</tt> component doesn't exist in the <tt>" .
html_quote($::FORM{'product'}) . "</tt> product");
exit;
}
DoComma();
$::query .= "component_id = $comp_id";
}
# If this installation uses bug aliases, and the user is changing the alias, # If this installation uses bug aliases, and the user is changing the alias,
# add this change to the query. # add this change to the query.
if (Param("usebugaliases") && defined($::FORM{'alias'})) { if (Param("usebugaliases") && defined($::FORM{'alias'})) {
...@@ -708,17 +744,15 @@ SWITCH: for ($::FORM{'knob'}) { ...@@ -708,17 +744,15 @@ SWITCH: for ($::FORM{'knob'}) {
DoConfirm(); DoConfirm();
} }
ChangeStatus('NEW'); ChangeStatus('NEW');
SendSQL("select initialowner from components where program=" . SendSQL("SELECT initialowner FROM components " .
SqlQuote($::FORM{'product'}) . " and value=" . "WHERE components.id = $comp_id");
SqlQuote($::FORM{'component'}));
my $newid = FetchOneColumn(); my $newid = FetchOneColumn();
my $newname = DBID_to_name($newid); my $newname = DBID_to_name($newid);
DoComma(); DoComma();
$::query .= "assigned_to = $newid"; $::query .= "assigned_to = $newid";
if (Param("useqacontact")) { if (Param("useqacontact")) {
SendSQL("select initialqacontact from components where program=" . SendSQL("SELECT initialqacontact FROM components " .
SqlQuote($::FORM{'product'}) . "WHERE components.id = $comp_id");
" and value=" . SqlQuote($::FORM{'component'}));
my $qacontact = FetchOneColumn(); my $qacontact = FetchOneColumn();
if (defined $qacontact && $qacontact != 0) { if (defined $qacontact && $qacontact != 0) {
DoComma(); DoComma();
...@@ -923,8 +957,9 @@ foreach my $id (@idlist) { ...@@ -923,8 +957,9 @@ foreach my $id (@idlist) {
SendSQL("LOCK TABLES bugs $write, bugs_activity $write, cc $write, " . SendSQL("LOCK TABLES bugs $write, bugs_activity $write, cc $write, " .
"cc AS selectVisible_cc $write, " . "cc AS selectVisible_cc $write, " .
"profiles $write, dependencies $write, votes $write, " . "profiles $write, dependencies $write, votes $write, " .
"products READ, components READ, " .
"keywords $write, longdescs $write, fielddefs $write, " . "keywords $write, longdescs $write, fielddefs $write, " .
"keyworddefs READ, groups READ, attachments READ, products READ"); "keyworddefs READ, groups READ, attachments READ");
my @oldvalues = SnapShotBug($id); my @oldvalues = SnapShotBug($id);
my %oldhash; my %oldhash;
my $i = 0; my $i = 0;
...@@ -1270,6 +1305,19 @@ foreach my $id (@idlist) { ...@@ -1270,6 +1305,19 @@ foreach my $id (@idlist) {
} }
if ($old ne $new) { if ($old ne $new) {
# Products and components are now stored in the DB using ID's
# We need to translate this to English before logging it
if ($col eq 'product_id') {
$old = get_product_name($old);
$new = get_product_name($new);
$col = 'product';
}
if ($col eq 'component_id') {
$old = get_component_name($old);
$new = get_component_name($new);
$col = 'component';
}
# save off the old value for passing to processmail so the old # save off the old value for passing to processmail so the old
# owner can be notified # owner can be notified
# #
......
...@@ -660,7 +660,7 @@ print qq{ ...@@ -660,7 +660,7 @@ print qq{
}; };
SendSQL("SELECT product,description FROM products ORDER BY product"); SendSQL("SELECT name, description FROM products ORDER BY name");
while (MoreSQLData()) { while (MoreSQLData()) {
my ($product, $productdesc) = FetchSQLData(); my ($product, $productdesc) = FetchSQLData();
...@@ -725,7 +725,11 @@ components and their associated products: ...@@ -725,7 +725,11 @@ components and their associated products:
foreach $product (@products) foreach $product (@products)
{ {
SendSQL("SELECT value,description FROM components WHERE program=" . SqlQuote($product) . " ORDER BY value"); SendSQL("SELECT components.name, components.description " .
"FROM components, products " .
"WHERE components.product_id = products.id" .
" AND products.name = " . SqlQuote($product) .
"ORDER BY name");
while (MoreSQLData()) { while (MoreSQLData()) {
......
...@@ -263,6 +263,7 @@ $when<p> ...@@ -263,6 +263,7 @@ $when<p>
FIN FIN
# Build up $query string # Build up $query string
my $prod_table = ($FORM{'product'} ne "-All-") ? ", products" : "";
my $query; my $query;
$query = <<FIN; $query = <<FIN;
select select
...@@ -272,12 +273,13 @@ select ...@@ -272,12 +273,13 @@ select
unix_timestamp(date_format(bugs.creation_ts, '%Y-%m-%d %h:%m:%s')) unix_timestamp(date_format(bugs.creation_ts, '%Y-%m-%d %h:%m:%s'))
from bugs, from bugs,
profiles assign profiles assign $prod_table
where bugs.assigned_to = assign.userid where bugs.assigned_to = assign.userid
FIN FIN
if ($FORM{'product'} ne "-All-" ) { if ($FORM{'product'} ne "-All-" ) {
$query .= "and bugs.product=".SqlQuote($FORM{'product'}); $query .= "and products.id = bugs.product_id\n";
$query .= "and products.name=".SqlQuote($FORM{'product'});
} }
$query .= "AND bugs.bug_status IN ('NEW', 'ASSIGNED', 'REOPENED')"; $query .= "AND bugs.bug_status IN ('NEW', 'ASSIGNED', 'REOPENED')";
...@@ -641,11 +643,11 @@ sub bybugs { ...@@ -641,11 +643,11 @@ sub bybugs {
sub most_doomed_for_milestone { sub most_doomed_for_milestone {
my $when = localtime (time); my $when = localtime (time);
my $ms = "M" . Param("curmilestone"); my $ms = "M" . Param("curmilestone");
my $product_id = get_product_id($FORM{'product'}) unless $FORM{'product'} eq '-All-';
print "<center>\n<h1>"; print "<center>\n<h1>";
if( $FORM{'product'} ne "-All-" ) { if( $FORM{'product'} ne "-All-" ) {
SendSQL("SELECT defaultmilestone FROM products WHERE product = " . SendSQL("SELECT defaultmilestone FROM products WHERE id = $product_id");
SqlQuote($FORM{'product'}));
$ms = FetchOneColumn(); $ms = FetchOneColumn();
print "Most Doomed for $ms ($FORM{'product'})"; print "Most Doomed for $ms ($FORM{'product'})";
} else { } else {
...@@ -661,7 +663,7 @@ sub most_doomed_for_milestone { ...@@ -661,7 +663,7 @@ sub most_doomed_for_milestone {
my $query; my $query;
$query = "select distinct assigned_to from bugs where target_milestone=\"$ms\""; $query = "select distinct assigned_to from bugs where target_milestone=\"$ms\"";
if ($FORM{'product'} ne "-All-" ) { if ($FORM{'product'} ne "-All-" ) {
$query .= "and bugs.product=".SqlQuote($FORM{'product'}); $query .= "and bugs.product_id=$product_id ";
} }
$query .= <<FIN; $query .= <<FIN;
and and
...@@ -687,7 +689,7 @@ FIN ...@@ -687,7 +689,7 @@ FIN
foreach $person (@people) { foreach $person (@people) {
my $query = "select count(bug_id) from bugs,profiles where target_milestone=\"$ms\" and userid=assigned_to and userid=\"$person\""; my $query = "select count(bug_id) from bugs,profiles where target_milestone=\"$ms\" and userid=assigned_to and userid=\"$person\"";
if( $FORM{'product'} ne "-All-" ) { if( $FORM{'product'} ne "-All-" ) {
$query .= "and bugs.product=".SqlQuote($FORM{'product'}); $query .= "and bugs.product_id=$product_id ";
} }
$query .= <<FIN; $query .= <<FIN;
and and
......
...@@ -203,15 +203,15 @@ CrossCheck("profiles", "userid", ...@@ -203,15 +203,15 @@ CrossCheck("profiles", "userid",
["watch", "watcher"], ["watch", "watcher"],
["watch", "watched"], ["watch", "watched"],
["tokens", "userid"], ["tokens", "userid"],
["components", "initialowner", "value"], ["components", "initialowner", "name"],
["components", "initialqacontact", "value", ["0"]]); ["components", "initialqacontact", "name", ["0"]]);
CrossCheck("products", "product", CrossCheck("products", "id",
["bugs", "product", "bug_id"], ["bugs", "product_id", "bug_id"],
["components", "program", "value"], ["components", "product_id", "name"],
["milestones", "product", "value"], ["milestones", "product_id", "value"],
["versions", "program", "value"], ["versions", "product_id", "value"],
["attachstatusdefs", "product", "name"]); ["attachstatusdefs", "product_id", "name"]);
########################################################################### ###########################################################################
# Perform group checks # Perform group checks
...@@ -239,17 +239,17 @@ while (@row = FetchSQLData()) { ...@@ -239,17 +239,17 @@ while (@row = FetchSQLData()) {
Status("Checking version/products"); Status("Checking version/products");
SendSQL("select distinct product, version from bugs"); SendSQL("select distinct product_id, version from bugs");
while (@row = FetchSQLData()) { while (@row = FetchSQLData()) {
my @copy = @row; my @copy = @row;
push(@checklist, \@copy); push(@checklist, \@copy);
} }
foreach my $ref (@checklist) { foreach my $ref (@checklist) {
my ($product, $version) = (@$ref); my ($product_id, $version) = (@$ref);
SendSQL("select count(*) from versions where program = " . SqlQuote($product) . " and value = " . SqlQuote($version)); SendSQL("select count(*) from versions where product_id = $product_id and value = " . SqlQuote($version));
if (FetchOneColumn() != 1) { if (FetchOneColumn() != 1) {
Alert("Bug(s) found with invalid product/version: $product/$version"); Alert("Bug(s) found with invalid product ID/version: $product_id/$version");
} }
} }
...@@ -257,17 +257,17 @@ foreach my $ref (@checklist) { ...@@ -257,17 +257,17 @@ foreach my $ref (@checklist) {
Status("Checking milestone/products"); Status("Checking milestone/products");
@checklist = (); @checklist = ();
SendSQL("select distinct product, target_milestone from bugs"); SendSQL("select distinct product_id, target_milestone from bugs");
while (@row = FetchSQLData()) { while (@row = FetchSQLData()) {
my @copy = @row; my @copy = @row;
push(@checklist, \@copy); push(@checklist, \@copy);
} }
foreach my $ref (@checklist) { foreach my $ref (@checklist) {
my ($product, $milestone) = (@$ref); my ($product_id, $milestone) = (@$ref);
SendSQL("SELECT count(*) FROM milestones WHERE product = " . SqlQuote($product) . " AND value = " . SqlQuote($milestone)); SendSQL("SELECT count(*) FROM milestones WHERE product_id = $product_id AND value = " . SqlQuote($milestone));
if(FetchOneColumn() != 1) { if(FetchOneColumn() != 1) {
Alert("Bug(s) found with invalid product/milestone: $product/$milestone"); Alert("Bug(s) found with invalid product ID/milestone: $product_id/$milestone");
} }
} }
...@@ -275,17 +275,17 @@ foreach my $ref (@checklist) { ...@@ -275,17 +275,17 @@ foreach my $ref (@checklist) {
Status("Checking default milestone/products"); Status("Checking default milestone/products");
@checklist = (); @checklist = ();
SendSQL("select product, defaultmilestone from products"); SendSQL("select id, defaultmilestone from products");
while (@row = FetchSQLData()) { while (@row = FetchSQLData()) {
my @copy = @row; my @copy = @row;
push(@checklist, \@copy); push(@checklist, \@copy);
} }
foreach my $ref (@checklist) { foreach my $ref (@checklist) {
my ($product, $milestone) = (@$ref); my ($product_id, $milestone) = (@$ref);
SendSQL("SELECT count(*) FROM milestones WHERE product = " . SqlQuote($product) . " AND value = " . SqlQuote($milestone)); SendSQL("SELECT count(*) FROM milestones WHERE product_id = $product_id AND value = " . SqlQuote($milestone));
if(FetchOneColumn() != 1) { if(FetchOneColumn() != 1) {
Alert("Product(s) found with invalid default milestone: $product/$milestone"); Alert("Product(s) found with invalid default milestone: $product_id/$milestone");
} }
} }
...@@ -293,19 +293,17 @@ foreach my $ref (@checklist) { ...@@ -293,19 +293,17 @@ foreach my $ref (@checklist) {
Status("Checking components/products"); Status("Checking components/products");
@checklist = (); @checklist = ();
SendSQL("select distinct product, component from bugs"); SendSQL("select distinct product_id, component_id from bugs");
while (@row = FetchSQLData()) { while (@row = FetchSQLData()) {
my @copy = @row; my @copy = @row;
push(@checklist, \@copy); push(@checklist, \@copy);
} }
foreach my $ref (@checklist) { foreach my $ref (@checklist) {
my ($product, $component) = (@$ref); my ($product_id, $component_id) = (@$ref);
SendSQL("select count(*) from components where program = " . SqlQuote($product) . " and value = " . SqlQuote($component)); SendSQL("select count(*) from components where product_id = $product_id and id = $component_id");
if (FetchOneColumn() != 1) { if (FetchOneColumn() != 1) {
my $link = "buglist.cgi?product=" . url_quote($product) . Alert(qq{Bug(s) found with invalid product/component ID: $product_id/$component_id});
"&component=" . url_quote($component);
Alert(qq{Bug(s) found with invalid product/component: $product/$component (<a href="$link">bug list</a>)});
} }
} }
...@@ -601,7 +599,7 @@ Status("Checking votes/everconfirmed"); ...@@ -601,7 +599,7 @@ Status("Checking votes/everconfirmed");
@badbugs = (); @badbugs = ();
SendSQL("SELECT bug_id FROM bugs, products " . SendSQL("SELECT bug_id FROM bugs, products " .
"WHERE bugs.product = products.product " . "WHERE bugs.product_id = products.id " .
"AND bug_status = " . SqlQuote($::unconfirmedstate) . ' ' . "AND bug_status = " . SqlQuote($::unconfirmedstate) . ' ' .
"AND votestoconfirm <= votes " . "AND votestoconfirm <= votes " .
"ORDER BY bug_id"); "ORDER BY bug_id");
......
...@@ -153,7 +153,7 @@ sub show_user { ...@@ -153,7 +153,7 @@ sub show_user {
# we can do it all in one query. # we can do it all in one query.
my %maxvotesperbug; my %maxvotesperbug;
if($canedit) { if($canedit) {
SendSQL("SELECT products.product, products.maxvotesperbug SendSQL("SELECT products.name, products.maxvotesperbug
FROM products"); FROM products");
while (MoreSQLData()) { while (MoreSQLData()) {
my ($prod, $max) = FetchSQLData(); my ($prod, $max) = FetchSQLData();
...@@ -173,10 +173,11 @@ sub show_user { ...@@ -173,10 +173,11 @@ sub show_user {
SendSQL("SELECT votes.bug_id, votes.count, bugs.short_desc, SendSQL("SELECT votes.bug_id, votes.count, bugs.short_desc,
bugs.bug_status bugs.bug_status
FROM votes, bugs FROM votes, bugs, products
WHERE votes.who = $who WHERE votes.who = $who
AND votes.bug_id = bugs.bug_id AND votes.bug_id = bugs.bug_id
AND bugs.product = " . SqlQuote($product) . AND bugs.product_id = products.id
AND products.name = " . SqlQuote($product) .
"ORDER BY votes.bug_id"); "ORDER BY votes.bug_id");
while (MoreSQLData()) { while (MoreSQLData()) {
...@@ -270,9 +271,9 @@ sub record_votes { ...@@ -270,9 +271,9 @@ sub record_votes {
# If the user is voting for bugs, make sure they aren't overstuffing # If the user is voting for bugs, make sure they aren't overstuffing
# the ballot box. # the ballot box.
if (scalar(@buglist)) { if (scalar(@buglist)) {
SendSQL("SELECT bugs.bug_id, bugs.product, products.maxvotesperbug SendSQL("SELECT bugs.bug_id, products.name, products.maxvotesperbug
FROM bugs, products FROM bugs, products
WHERE products.product = bugs.product WHERE products.id = bugs.product_id
AND bugs.bug_id IN (" . join(", ", @buglist) . ")"); AND bugs.bug_id IN (" . join(", ", @buglist) . ")");
my %prodcount; my %prodcount;
......
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