From 4c3e00573133dfc53d07805629af19599aaef7df Mon Sep 17 00:00:00 2001 From: Byron Jones Date: Thu, 22 Nov 2012 22:39:05 +0800 Subject: Bug 811280: Adds a caching mechanism to Bugzilla::Object to avoid querying the database repeatedly for the same information r=dkl,a=LpSolit --- Bugzilla/Attachment.pm | 2 +- Bugzilla/Bug.pm | 21 +++++++++++++++++---- Bugzilla/Comment.pm | 3 ++- Bugzilla/Object.pm | 31 ++++++++++++++++++++++++++++++- Bugzilla/Product.pm | 4 ++-- Bugzilla/Template.pm | 6 +++--- 6 files changed, 55 insertions(+), 12 deletions(-) (limited to 'Bugzilla') diff --git a/Bugzilla/Attachment.pm b/Bugzilla/Attachment.pm index ba6c25736..c00b931fb 100644 --- a/Bugzilla/Attachment.pm +++ b/Bugzilla/Attachment.pm @@ -144,7 +144,7 @@ sub bug { my $self = shift; require Bugzilla::Bug; - $self->{bug} ||= Bugzilla::Bug->new($self->bug_id); + $self->{bug} ||= Bugzilla::Bug->new({ id => $self->bug_id, cache => 1 }); return $self->{bug}; } diff --git a/Bugzilla/Bug.pm b/Bugzilla/Bug.pm index 4a1723754..b72a8fcdb 100644 --- a/Bugzilla/Bug.pm +++ b/Bugzilla/Bug.pm @@ -318,9 +318,13 @@ sub new { # If we get something that looks like a word (not a number), # make it the "name" param. - if (!defined $param || (!ref($param) && $param !~ /^\d+$/)) { + if (!defined $param + || (!ref($param) && $param =~ /\D/) + || (ref($param) && $param->{id} =~ /\D/)) + { if ($param) { - $param = { name => $param }; + $param = { name => ref($param) ? $param->{id} : $param, + cache => ref($param) ? $param->{cache} : 0 }; } else { # We got something that's not a number. @@ -354,6 +358,13 @@ sub new { return $self; } +sub cache_key { + my $class = shift; + my $key = $class->SUPER::cache_key(@_) + || return; + return $key . ',' . Bugzilla->user->id; +} + sub check { my $class = shift; my ($id, $field) = @_; @@ -3216,7 +3227,8 @@ sub component_obj { my ($self) = @_; return $self->{component_obj} if defined $self->{component_obj}; return {} if $self->{error}; - $self->{component_obj} = new Bugzilla::Component($self->{component_id}); + $self->{component_obj} = + new Bugzilla::Component({ id => $self->{component_id}, cache => 1 }); return $self->{component_obj}; } @@ -3424,7 +3436,8 @@ sub product { sub product_obj { my $self = shift; return {} if $self->{error}; - $self->{product_obj} ||= new Bugzilla::Product($self->{product_id}); + $self->{product_obj} ||= + new Bugzilla::Product({ id => $self->{product_id}, cache => 1 }); return $self->{product_obj}; } diff --git a/Bugzilla/Comment.pm b/Bugzilla/Comment.pm index 7cf924893..2a7633bc2 100644 --- a/Bugzilla/Comment.pm +++ b/Bugzilla/Comment.pm @@ -130,7 +130,8 @@ sub is_about_attachment { sub attachment { my ($self) = @_; return undef if not $self->is_about_attachment; - $self->{attachment} ||= new Bugzilla::Attachment($self->extra_data); + $self->{attachment} ||= + new Bugzilla::Attachment({ id => $self->extra_data, cache => 1 }); return $self->{attachment}; } diff --git a/Bugzilla/Object.pm b/Bugzilla/Object.pm index ce59a23f0..9d7ab7391 100644 --- a/Bugzilla/Object.pm +++ b/Bugzilla/Object.pm @@ -59,6 +59,8 @@ sub new { sub _init { my $class = shift; my ($param) = @_; + my $object = $class->_cache_get($param); + return $object if $object; my $dbh = Bugzilla->dbh; my $columns = join(',', $class->_get_db_columns); my $table = $class->DB_TABLE; @@ -69,7 +71,6 @@ sub _init { if (ref $param eq 'HASH') { $id = $param->{id}; } - my $object; if (defined $id) { # We special-case if somebody specifies an ID, so that we can @@ -112,9 +113,37 @@ sub _init { "SELECT $columns FROM $table WHERE $condition", undef, @values); } + $class->_cache_set($param, $object) if $object; return $object; } +# Provides a mechanism for objects to be cached in the request_cahce +sub _cache_get { + my $class = shift; + my ($param) = @_; + my $cache_key = $class->cache_key($param) + || return; + return Bugzilla->request_cache->{$cache_key}; +} + +sub _cache_set { + my $class = shift; + my ($param, $object) = @_; + my $cache_key = $class->cache_key($param) + || return; + Bugzilla->request_cache->{$cache_key} = $object; +} + +sub cache_key { + my $class = shift; + my ($param) = @_; + if (ref($param) && $param->{cache} && ($param->{id} || $param->{name})) { + return $class . ',' . ($param->{id} || $param->{name}); + } else { + return; + } +} + sub check { my ($invocant, $param) = @_; my $class = ref($invocant) || $invocant; diff --git a/Bugzilla/Product.pm b/Bugzilla/Product.pm index 894db422e..536961ce5 100644 --- a/Bugzilla/Product.pm +++ b/Bugzilla/Product.pm @@ -810,8 +810,8 @@ sub flag_types { sub classification { my $self = shift; - $self->{'classification'} ||= - new Bugzilla::Classification($self->classification_id); + $self->{'classification'} ||= + new Bugzilla::Classification({ id => $self->classification_id, cache => 1 }); return $self->{'classification'}; } diff --git a/Bugzilla/Template.pm b/Bugzilla/Template.pm index e13efec2b..f62a7c498 100644 --- a/Bugzilla/Template.pm +++ b/Bugzilla/Template.pm @@ -284,7 +284,7 @@ sub get_attachment_link { my $dbh = Bugzilla->dbh; $user ||= Bugzilla->user; - my $attachment = new Bugzilla::Attachment($attachid); + my $attachment = new Bugzilla::Attachment({ id => $attachid, cache => 1 }); if ($attachment) { my $title = ""; @@ -334,10 +334,10 @@ sub get_bug_link { $options->{user} ||= Bugzilla->user; my $dbh = Bugzilla->dbh; - if (defined $bug) { + if (defined $bug && $bug ne '') { if (!blessed($bug)) { require Bugzilla::Bug; - $bug = new Bugzilla::Bug($bug); + $bug = new Bugzilla::Bug({ id => $bug, cache => 1 }); } return $link_text if $bug->{error}; } -- cgit v1.2.3-24-g4f1b