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-67ecbb4d7f56master
parent
b71b4c7976
commit
724480a403
|
@ -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};
|
||||
}
|
||||
|
|
|
@ -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'});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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'},
|
||||
],
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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',});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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",
|
||||
};
|
||||
|
|
|
@ -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'),
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue