Bug 70605 - Change multi-select fields storage method - store IDs instead of values

git-svn-id: svn://svn.office.custis.ru/3rdparty/bugzilla.org/trunk@1505 6955db30-a419-402b-8a0d-67ecbb4d7f56
master
vfilippov 2012-01-16 15:20:39 +00:00
parent b71b4c7976
commit 724480a403
8 changed files with 63 additions and 30 deletions

View File

@ -569,10 +569,11 @@ sub create {
foreach my $field (keys %$ms_values) {
$dbh->do("DELETE FROM bug_$field where bug_id = ?",
undef, $bug->bug_id);
foreach my $value ( @{$ms_values->{$field}} ) {
$dbh->do("INSERT INTO bug_$field (bug_id, value) VALUES (?,?)",
undef, $bug->bug_id, $value);
}
$dbh->do(
"INSERT INTO bug_$field (bug_id, value_id) SELECT ?, id FROM $field".
" WHERE value IN (".join(',', ('?') x @{$ms_values->{$field}}).")",
undef, $bug->bug_id, @{$ms_values->{$field}}
);
}
# And insert the comment. We always insert a comment on bug creation,
@ -1064,10 +1065,11 @@ sub update
$dbh->do("DELETE FROM bug_$name where bug_id = ?",
undef, $self->id);
foreach my $value (@{$self->$name}) {
$dbh->do("INSERT INTO bug_$name (bug_id, value) VALUES (?,?)",
undef, $self->id, $value);
}
$dbh->do(
"INSERT INTO bug_$name (bug_id, value_id) SELECT ?, id FROM $name".
" WHERE value IN (".join(',', ('?') x @{$self->$name}).")",
undef, $self->bug_id, @{$self->$name}
);
}
}
@ -4088,7 +4090,7 @@ sub AUTOLOAD {
trick_taint($attr);
$self->{$attr} ||= Bugzilla->dbh->selectcol_arrayref(
"SELECT value FROM bug_$attr WHERE bug_id = ? ORDER BY value",
"SELECT value FROM bug_$attr, $attr WHERE value_id=id AND bug_id=? ORDER BY value",
undef, $self->id);
return $self->{$attr};
}

View File

@ -733,8 +733,8 @@ sub bz_add_field_tables {
$self->bz_add_fk($ms_table, 'bug_id', {TABLE => 'bugs',
COLUMN => 'bug_id',
DELETE => 'CASCADE'});
$self->bz_add_fk($ms_table, 'value', {TABLE => $field->name,
COLUMN => 'value'});
$self->bz_add_fk($ms_table, 'value_id', {TABLE => $field->name,
COLUMN => 'id'});
}
}

View File

@ -1560,10 +1560,10 @@ use constant ABSTRACT_SCHEMA => {
use constant MULTI_SELECT_VALUE_TABLE => {
FIELDS => [
bug_id => {TYPE => 'INT3', NOTNULL => 1},
value => {TYPE => 'varchar(255)', NOTNULL => 1},
value_id => {TYPE => 'INT2', NOTNULL => 1, DEFAULT => 0},
],
INDEXES => [
bug_id_idx => {FIELDS => [qw( bug_id value)], TYPE => 'UNIQUE'},
bug_id_idx => {FIELDS => [qw(bug_id value_id)], TYPE => 'UNIQUE'},
],
};

View File

@ -174,12 +174,7 @@ sub update {
my ($changes, $old_self) = $self->SUPER::update(@_);
if (exists $changes->{$self->NAME_FIELD}) {
my ($old, $new) = @{ $changes->{$self->NAME_FIELD} };
if ($self->field->type == FIELD_TYPE_MULTI_SELECT)
{
$dbh->do("UPDATE bug_$fname SET value = ? WHERE value = ?",
undef, $new, $old);
}
else
if ($self->field->type != FIELD_TYPE_MULTI_SELECT)
{
$self->field->{has_activity} = 1;
$dbh->do(
@ -362,7 +357,7 @@ sub bug_count {
my $count;
if ($self->field->type == FIELD_TYPE_MULTI_SELECT) {
$count = $dbh->selectrow_array("SELECT COUNT(*) FROM bug_$fname
WHERE value = ?", undef, $self->name);
WHERE value_id = ?", undef, $self->id);
}
else {
$count = $dbh->selectrow_array("SELECT COUNT(*) FROM bugs

View File

@ -561,6 +561,9 @@ sub update_table_definitions {
$dbh->bz_alter_column('series', 'query',
{ TYPE => 'MEDIUMTEXT', NOTNULL => 1 });
# Make multi select tables to store IDs, not values
_convert_multiselects();
# Add FK to multi select field tables
_add_foreign_keys_to_multiselects();
@ -3235,6 +3238,26 @@ sub _check_content_length {
}
}
sub _convert_multiselects
{
my $dbh = Bugzilla->dbh;
my $fields = $dbh->selectcol_arrayref(
'SELECT name FROM fielddefs WHERE type=' . FIELD_TYPE_MULTI_SELECT
);
foreach my $field (@$fields)
{
if (!$dbh->bz_column_info("bug_$field", 'value_id'))
{
$dbh->bz_add_column("bug_$field", value_id => {TYPE => 'INT2', NOTNULL => 1, DEFAULT => 0});
$dbh->do("UPDATE bug_$field bf, $field f SET bf.value_id=f.id WHERE bf.value=f.value");
$dbh->bz_drop_fk("bug_$field", 'value');
$dbh->bz_drop_column("bug_$field", 'value');
}
}
}
sub _add_foreign_keys_to_multiselects {
my $dbh = Bugzilla->dbh;
@ -3248,9 +3271,9 @@ sub _add_foreign_keys_to_multiselects {
COLUMN => 'bug_id',
DELETE => 'CASCADE',});
$dbh->bz_add_fk("bug_$name", "value", {TABLE => $name,
COLUMN => 'value',
DELETE => 'RESTRICT',});
$dbh->bz_add_fk("bug_$name", "value_id", {TABLE => $name,
COLUMN => 'id',
DELETE => 'RESTRICT',});
}
}

View File

@ -576,6 +576,11 @@ sub STATIC_COLUMNS
{
push @bugid_fields, $field;
}
elsif ($field->type == FIELD_TYPE_MULTI_SELECT)
{
$columns->{$id}->{name} = "$id.value";
$columns->{$id}->{joins} = [ "LEFT JOIN (bug_$id INNER JOIN $id ON $id.id=bug_$id.value_id) ON bug_$id.bug_id=bugs.bug_id" ];
}
}
# Fields of bugs related to selected by some BUG_ID type field
@ -2489,7 +2494,9 @@ sub _multiselect_nonchanged
my @terms;
my $t = "bug_$self->{field}";
my $ft = $self->{field};
my $ta = $t.'_'.$self->{sequence};
my $fta = $ft.'_'.$self->{sequence};
my @v = ref $self->{value} ? @{$self->{value}} : $self->{value};
$self->{quoted} = join ', ', map { $dbh->quote($_) } @v;
@ -2498,26 +2505,26 @@ sub _multiselect_nonchanged
if ($self->{type} eq 'anywords' || $self->{type} eq 'anyexact')
{
$self->{term} = {
table => "$t $ta",
where => "$ta.value IN ($self->{quoted})",
table => "($t $ta INNER JOIN $ft $fta WHERE $fta.id=$t.value_id)",
where => "$fta.value IN ($self->{quoted})",
bugid_field => "$ta.bug_id",
};
}
elsif ($self->{type} eq 'allwords')
{
$self->{term} = {
table => "(SELECT bug_id FROM $t WHERE value IN ($self->{quoted})".
table => "(SELECT bug_id FROM $t, $ft WHERE id=value_id AND value IN ($self->{quoted})".
" GROUP BY bug_id HAVING COUNT(bug_id) = ".@v.") $ta",
bugid_field => "$ta.bug_id",
};
}
else
{
$self->{fieldsql} = $self->{field} = "$ta.value";
$self->{fieldsql} = $self->{field} = "$fta.value";
$self->{value} = $v[0];
$self->call_op;
$self->{term} = {
table => "$t $ta",
table => "($t $ta INNER JOIN $ft $fta WHERE $fta.id=$t.value_id)",
where => $self->{term},
bugid_field => "$ta.bug_id",
};

View File

@ -68,7 +68,7 @@ elsif ($action eq 'new')
clone_bug => scalar $cgi->param('clone_bug'),
obsolete => scalar $cgi->param('obsolete'),
custom => 1,
buglist => (scalar $cgi->param('type') == FIELD_TYPE_MULTI_SELECT ? 0 : 1),
buglist => 1, # FIXME remove non-editable 'buglist' field spec
visibility_field_id => scalar $cgi->param('visibility_field_id'),
value_field_id => scalar $cgi->param('value_field_id'),
add_to_deps => scalar $cgi->param('add_to_deps'),

View File

@ -57,7 +57,13 @@ function initQueryformFields()
for (var i in qfVisibility)
{
if (!qfHandling[i])
handleQueryformField(null, document.getElementById(i));
{
var e = document.getElementById(i);
if (e)
handleQueryformField(null, e);
else
qfHandling[i] = true;
}
initQueryformField(i);
}
}