summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Lawrence <dlawrence@mozilla.com>2014-01-07 06:10:18 +0100
committerDave Lawrence <dlawrence@mozilla.com>2014-01-07 06:10:18 +0100
commit678ad6b0f33fbd05da033ce04f14e14951aa7a9e (patch)
tree54bbdb8986641b8fdb1ac369f4f096b3ac17651b
parentae708fdf327467851f95a2a4b6e81cf352d318f9 (diff)
downloadbugzilla-678ad6b0f33fbd05da033ce04f14e14951aa7a9e.tar.gz
bugzilla-678ad6b0f33fbd05da033ce04f14e14951aa7a9e.tar.xz
Bug 956052 - backport upstream bug 945535 to bmo/4.2 for performance improvement in bugs with large number of attachments
-rw-r--r--Bugzilla/Attachment.pm36
1 files changed, 21 insertions, 15 deletions
diff --git a/Bugzilla/Attachment.pm b/Bugzilla/Attachment.pm
index 1a12e65b1..bb0f83aba 100644
--- a/Bugzilla/Attachment.pm
+++ b/Bugzilla/Attachment.pm
@@ -62,6 +62,7 @@ use Bugzilla::Hook;
use File::Copy;
use List::Util qw(max);
+use Storable qw(dclone);
use base qw(Bugzilla::Object);
@@ -635,12 +636,12 @@ sub _check_is_private {
=over
-=item C<get_attachments_by_bug($bug_id)>
+=item C<get_attachments_by_bug($bug)>
Description: retrieves and returns the attachments the currently logged in
user can view for the given bug.
-Params: C<$bug_id> - integer - the ID of the bug for which
+Params: C<$bug> - Bugzilla::Bug object - the bug for which
to retrieve and return attachments.
Returns: a reference to an array of attachment objects.
@@ -648,14 +649,14 @@ Returns: a reference to an array of attachment objects.
=cut
sub get_attachments_by_bug {
- my ($class, $bug_id, $vars) = @_;
+ my ($class, $bug, $vars) = @_;
my $user = Bugzilla->user;
my $dbh = Bugzilla->dbh;
# By default, private attachments are not accessible, unless the user
# is in the insider group or submitted the attachment.
my $and_restriction = '';
- my @values = ($bug_id);
+ my @values = ($bug->id);
unless ($user->is_insider) {
$and_restriction = 'AND (isprivate = 0 OR submitter_id = ?)';
@@ -672,17 +673,22 @@ sub get_attachments_by_bug {
# attachment listed here, we collect all the data at once and
# populate $attachment->{flags} ourselves.
if ($vars->{preload}) {
- $_->{flags} = [] foreach @$attachments;
- my %att = map { $_->id => $_ } @$attachments;
+ # Preload flag types and flags
+ my $vars = { target_type => 'attachment',
+ product_id => $bug->product_id,
+ component_id => $bug->component_id,
+ attach_id => $attach_ids };
+ my $flag_types = Bugzilla::Flag->_flag_types($vars);
- my $flags = Bugzilla::Flag->match({ bug_id => $bug_id,
- target_type => 'attachment' });
-
- # Exclude flags for private attachments you cannot see.
- @$flags = grep {exists $att{$_->attach_id}} @$flags;
-
- push(@{$att{$_->attach_id}->{flags}}, $_) foreach @$flags;
- $attachments = [sort {$a->id <=> $b->id} values %att];
+ foreach my $attachment (@$attachments) {
+ $attachment->{flag_types} = [];
+ my $new_types = dclone($flag_types);
+ foreach my $new_type (@$new_types) {
+ $new_type->{flags} = [ grep($_->attach_id == $attachment->id,
+ @{ $new_type->{flags} }) ];
+ push(@{ $attachment->{flag_types} }, $new_type);
+ }
+ }
# Preload attachers.
my %user_ids = map { $_->{submitter_id} => 1 } @$attachments;
@@ -697,7 +703,7 @@ sub get_attachments_by_bug {
$dbh->selectall_hashref('SELECT attach_id, LENGTH(thedata) AS datasize
FROM attachments LEFT JOIN attach_data ON attach_id = id
WHERE bug_id = ?',
- 'attach_id', undef, $bug_id);
+ 'attach_id', undef, $bug->id);
# Force the size of attachments not in the DB to be recalculated.
$_->{datasize} = $sizes->{$_->id}->{datasize} || undef foreach @$attachments;