summaryrefslogtreecommitdiffstats
path: root/Bugzilla/Attachment.pm
diff options
context:
space:
mode:
authorByron Jones <glob@mozilla.com>2015-07-14 08:55:43 +0200
committerByron Jones <glob@mozilla.com>2015-07-14 08:55:43 +0200
commit2bd3296eaa42479b1dd0aa5c12a442a86140b02c (patch)
treeca34781c1e5dddefeef80837136129bd631f9584 /Bugzilla/Attachment.pm
parent425d780e7f77d8cc38191331cbcc84d7af5c871a (diff)
downloadbugzilla-2bd3296eaa42479b1dd0aa5c12a442a86140b02c.tar.gz
bugzilla-2bd3296eaa42479b1dd0aa5c12a442a86140b02c.tar.xz
Bug 1180570 - store attachment size in the database
Diffstat (limited to 'Bugzilla/Attachment.pm')
-rw-r--r--Bugzilla/Attachment.pm61
1 files changed, 10 insertions, 51 deletions
diff --git a/Bugzilla/Attachment.pm b/Bugzilla/Attachment.pm
index 625d1cccf..95e6b2977 100644
--- a/Bugzilla/Attachment.pm
+++ b/Bugzilla/Attachment.pm
@@ -89,6 +89,7 @@ use constant DB_COLUMNS => qw(
mimetype
modification_time
submitter_id
+ attach_size
);
use constant REQUIRED_FIELD_MAP => {
@@ -359,45 +360,14 @@ sub data {
=item C<datasize>
-the length (in characters) of the attachment content
+the length (in bytes) of the attachment content
=back
=cut
-# datasize is a property of the data itself, and it's unclear whether we should
-# expose it at all, since you can easily derive it from the data itself: in TT,
-# attachment.data.size; in Perl, length($attachment->{data}). But perhaps
-# it makes sense for performance reasons, since accessing the data forces it
-# to get retrieved from the database/filesystem and loaded into memory,
-# while datasize avoids loading the attachment into memory, calling SQL's
-# LENGTH() function or stat()ing the file instead. I've left it in for now.
-
sub datasize {
- my $self = shift;
- return $self->{datasize} if defined $self->{datasize};
-
- # If we have already retrieved the data, return its size.
- return length($self->{data}) if exists $self->{data};
-
- $self->{datasize} =
- Bugzilla->dbh->selectrow_array("SELECT LENGTH(thedata)
- FROM attach_data
- WHERE id = ?",
- undef, $self->id) || 0;
-
- # If there's no attachment data in the database, either the attachment
- # is stored in a local file, and so retrieve its size from the file,
- # or the attachment has been deleted.
- unless ($self->{datasize}) {
- if (open(AH, '<', $self->_get_local_filename())) {
- binmode AH;
- $self->{datasize} = (stat(AH))[7];
- close(AH);
- }
- }
-
- return $self->{datasize};
+ return $_[0]->{attach_size};
}
=over
@@ -566,18 +536,18 @@ sub _check_data {
my ($invocant, $params) = @_;
my $data = $params->{data};
- $params->{filesize} = ref $data ? -s $data : length($data);
+ $params->{attach_size} = ref $data ? -s $data : length($data);
Bugzilla::Hook::process('attachment_process_data', { data => \$data,
attributes => $params });
- $params->{filesize} || ThrowUserError('zero_length_file');
+ $params->{attach_size} || ThrowUserError('zero_length_file');
# Make sure the attachment does not exceed the maximum permitted size.
my $max_size = max(Bugzilla->params->{'maxlocalattachment'} * 1048576,
Bugzilla->params->{'maxattachmentsize'} * 1024);
- if ($params->{filesize} > $max_size) {
- my $vars = { filesize => sprintf("%.0f", $params->{filesize}/1024) };
+ if ($params->{attach_size} > $max_size) {
+ my $vars = { filesize => sprintf("%.0f", $params->{attach_size}/1024) };
ThrowUserError('file_too_large', $vars);
}
return $data;
@@ -703,16 +673,6 @@ sub get_attachments_by_bug {
foreach my $attachment (@$attachments) {
$attachment->{attacher} = $user_map{$attachment->{submitter_id}};
}
-
- # Preload datasizes.
- my $sizes =
- $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);
-
- # Force the size of attachments not in the DB to be recalculated.
- $_->{datasize} = $sizes->{$_->id}->{datasize} || undef foreach @$attachments;
}
return $attachments;
}
@@ -842,13 +802,12 @@ sub create {
my $bug = delete $params->{bug};
$params->{bug_id} = $bug->id;
my $data = delete $params->{data};
- my $size = delete $params->{filesize};
my $attachment = $class->insert_create_data($params);
my $attachid = $attachment->id;
# The file is too large to be stored in the DB, so we store it locally.
- if ($size > Bugzilla->params->{'maxattachmentsize'} * 1024) {
+ if ($params->{attach_size} > Bugzilla->params->{'maxattachmentsize'} * 1024) {
my $attachdir = bz_locations()->{'attachdir'};
my $hash = ($attachid % 100) + 100;
$hash =~ s/.*(\d\d)$/group.$1/;
@@ -966,8 +925,8 @@ sub remove_from_db {
$dbh->do('DELETE FROM flags WHERE ' . $dbh->sql_in('id', $flag_ids))
if @$flag_ids;
$dbh->do('DELETE FROM attach_data WHERE id = ?', undef, $self->id);
- $dbh->do('UPDATE attachments SET mimetype = ?, ispatch = ?, isobsolete = ?
- WHERE attach_id = ?', undef, ('text/plain', 0, 1, $self->id));
+ $dbh->do('UPDATE attachments SET mimetype = ?, ispatch = ?, isobsolete = ?, attach_size = ?
+ WHERE attach_id = ?', undef, ('text/plain', 0, 1, 0, $self->id));
$dbh->bz_commit_transaction();
# As we don't call SUPER->remove_from_db we need to manually clear