Store flagtypes.cc_list as user IDs in separate table

hinted-selects
Vitaliy Filippov 2014-08-22 18:58:06 +04:00
parent 95e2556c0a
commit f3ca192828
6 changed files with 65 additions and 37 deletions

View File

@ -501,8 +501,6 @@ use constant ABSTRACT_SCHEMA => {
id => {TYPE => 'INTSERIAL', NOTNULL => 1, PRIMARYKEY => 1},
name => {TYPE => 'varchar(255)', NOTNULL => 1},
description => {TYPE => 'MEDIUMTEXT', NOTNULL => 1},
# FIXME flagtypes.cc_list => store user ids
cc_list => {TYPE => 'varchar(255)'},
target_type => {TYPE => 'char(1)', NOTNULL => 1, DEFAULT => "'b'"},
is_active => {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'TRUE'},
is_requestable => {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'},
@ -514,6 +512,16 @@ use constant ABSTRACT_SCHEMA => {
],
},
flagtype_cc_list => {
FIELDS => [
object_id => {TYPE => 'INT4', NOTNULL => 1, REFERENCES => {TABLE => 'flagtypes', COLUMN => 'id', DELETE => 'CASCADE'}},
value_id => {TYPE => 'INT4', NOTNULL => 1, REFERENCES => {TABLE => 'profiles', COLUMN => 'userid'}},
],
INDEXES => [
PRIMARY => {FIELDS => [qw(object_id value_id)]},
],
},
# "flaginclusions" and "flagexclusions" specify the products/components
# a bug/attachment must belong to in order for flags of a given type
# to be set for them.

View File

@ -1135,7 +1135,7 @@ sub notify
}
}
my $cc_list = $flag ? $flag->type->cc_list : $old_flag->type->cc_list;
my $cc_list = $flag ? $flag->type->cc_list_obj : $old_flag->type->cc_list_obj;
# Is there someone to notify?
return unless ($addressee || $cc_list);
@ -1146,7 +1146,7 @@ sub notify
my $attachment_is_private = $attachment && $attachment->isprivate;
my %recipients;
foreach my $ccuser (@{ Bugzilla::User->match({ login_name => [ split /[, ]+/, $cc_list ] }) })
foreach my $ccuser (@$cc_list)
{
next if !$ccuser->can_see_bug($bug->bug_id);
next if $attachment_is_private && !$ccuser->is_insider;

View File

@ -78,7 +78,6 @@ use constant DB_COLUMNS => qw(
flagtypes.id
flagtypes.name
flagtypes.description
flagtypes.cc_list
flagtypes.target_type
flagtypes.sortkey
flagtypes.is_active
@ -133,7 +132,7 @@ Returns the description of the flagtype.
=item C<cc_list>
Returns the concatenated CC list for the flagtype, as a single string.
Returns the CC list for the flagtype, as an arrayref of Bugzilla::User objects.
=item C<target_type>
@ -170,7 +169,6 @@ Returns the sortkey of the flagtype.
sub id { return $_[0]->{'id'}; }
sub name { return $_[0]->{'name'}; }
sub description { return $_[0]->{'description'}; }
sub cc_list { return $_[0]->{'cc_list'}; }
sub target_type { return $_[0]->{'target_type'} eq 'b' ? 'bug' : 'attachment'; }
sub is_active { return $_[0]->{'is_active'}; }
sub is_requestable { return $_[0]->{'is_requestable'}; }
@ -180,6 +178,24 @@ sub sortkey { return $_[0]->{'sortkey'}; }
sub request_group_id { return $_[0]->{'request_group_id'}; }
sub grant_group_id { return $_[0]->{'grant_group_id'}; }
sub cc_list
{
my $self = shift;
return $self->{cc_list} if $self->{cc_list};
$self->{cc_list} = Bugzilla->dbh->selectall_arrayref(
'SELECT p.* FROM profiles p, flagtype_cc_list c'.
' WHERE c.value_id=p.userid AND c.object_id=?', {Slice=>{}}, $self->id
);
bless $_, 'Bugzilla::User' for @{$self->{cc_list}};
return $self->{cc_list};
}
sub cc_list_str
{
my $self = shift;
return join(', ', map { $_->login } @{$self->cc_list});
}
###############################
#### Methods ####
###############################

View File

@ -834,6 +834,25 @@ WHERE description LIKE\'%[CC:%\'');
$dbh->do("DELETE FROM fieldvaluecontrol WHERE field_id=0");
}
if ($dbh->bz_column_info('flagtypes', 'cc_list'))
{
my $add = [];
foreach my $type (@{$dbh->selectall_arrayref('SELECT * FROM flagtypes', {Slice=>{}})})
{
my $cc = [ split /[\s,]*,[\s,]*/, $type->{cc_list} ];
if (@$cc)
{
$cc = Bugzilla::User->match({ login_name => $cc });
push @$add, '('.$type->{id}.', '.$_->id.')' for @$cc;
}
}
if (@$add)
{
$dbh->do('INSERT INTO flagtype_cc_list (object_id, value_id) VALUES '.join(', ', @$add));
}
$dbh->bz_drop_column('flagtypes', 'cc_list');
}
_move_old_defaults($old_params);
################################################################

View File

@ -296,7 +296,6 @@ sub insert {
check_token_data($token, 'add_flagtype');
my $name = validateName();
my $description = validateDescription();
my $cc_list = validateCCList();
validateTargetType();
validateSortKey();
validateIsActive();
@ -313,12 +312,12 @@ sub insert {
# Insert a record for the new flag type into the database.
$dbh->do('INSERT INTO flagtypes
(name, description, cc_list, target_type,
(name, description, target_type,
sortkey, is_active, is_requestable,
is_requesteeble, is_multiplicable,
grant_group_id, request_group_id)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
undef, ($name, $description, $cc_list, $target_type,
undef, ($name, $description, $target_type,
$cgi->param('sortkey'), $cgi->param('is_active'),
$cgi->param('is_requestable'), $cgi->param('is_requesteeble'),
$cgi->param('is_multiplicable'), scalar($cgi->param('grant_gid')),
@ -351,7 +350,6 @@ sub update {
my $id = $flag_type->id;
my $name = validateName();
my $description = validateDescription();
my $cc_list = validateCCList();
validateTargetType();
validateSortKey();
validateIsActive();
@ -364,12 +362,12 @@ sub update {
my $user = Bugzilla->user;
$dbh->bz_start_transaction();
$dbh->do('UPDATE flagtypes
SET name = ?, description = ?, cc_list = ?,
SET name = ?, description = ?,
sortkey = ?, is_active = ?, is_requestable = ?,
is_requesteeble = ?, is_multiplicable = ?,
grant_group_id = ?, request_group_id = ?
WHERE id = ?',
undef, ($name, $description, $cc_list, $cgi->param('sortkey'),
undef, ($name, $description, $cgi->param('sortkey'),
$cgi->param('is_active'), $cgi->param('is_requestable'),
$cgi->param('is_requesteeble'), $cgi->param('is_multiplicable'),
scalar($cgi->param('grant_gid')), scalar($cgi->param('request_gid')),
@ -538,29 +536,6 @@ sub validateDescription {
return $description;
}
sub validateCCList {
my $cc_list = $cgi->param('cc_list');
length($cc_list) <= 200
|| ThrowUserError("flag_type_cc_list_invalid",
{ cc_list => $cc_list });
my @addresses = split(/[, ]+/, $cc_list);
# We do not call Util::validate_email_syntax because these
# addresses do not require to match 'emailregexp' and do not
# depend on 'emailsuffix'. So we limit ourselves to a simple
# sanity check:
# - match the syntax of a fully qualified email address;
# - do not contain any illegal character.
foreach my $address (@addresses) {
($address =~ /^[\w\.\+\-=]+@[\w\.\-]+\.[\w\-]+$/
&& $address !~ /[\\\(\)<>&,;:"\[\] \t\r\n]/)
|| ThrowUserError('illegal_email_address',
{addr => $address, default => 1});
}
trick_taint($cc_list);
return $cc_list;
}
sub validateProduct {
my $product_name = shift;
return unless $product_name;
@ -665,6 +640,16 @@ sub validateAndSubmit {
$sth->execute($id, $product_id, $component_id);
}
}
my $cc_list = Bugzilla::User->match({ login_name => [ split /[\s,]*,[\s,]*/, scalar $cgi->param('cc_list') ] });
$dbh->do("DELETE FROM flagtype_cc_list WHERE object_id=?", undef, $id);
if (@$cc_list)
{
$dbh->do(
"INSERT INTO flagtype_cc_list (object_id, value_id) VALUES ".
join(', ', map { "(?, ?)" } @$cc_list), undef, map { ($id, $_->id) } @$cc_list
);
}
}
sub filter_group {

View File

@ -174,7 +174,7 @@
<kbd>[% Param('emailsuffix') %]</kbd> will <em>not</em> be appended
to these addresses, so you should add it explicitly if so desired.
[% END %]<br>
<input type="text" name="cc_list" value="[% type.cc_list FILTER html %]" size="80" maxlength="200">
<input type="text" name="cc_list" value="[% type.cc_list_str FILTER html %]" size="80" maxlength="200">
</td>
</tr>