Bug 16699: Remove requirement from borrowernumberQueryParam
[koha.git] / Koha / Cache / Object.pm
blobb5f947cd08577d36a94f3119c5d47b2568d78c03
1 package Koha::Cache::Object;
3 # Copyright 2013 C & P Bibliography Services
5 # This file is part of Koha.
7 # Koha is free software; you can redistribute it and/or modify it under the
8 # terms of the GNU General Public License as published by the Free Software
9 # Foundation; either version 3 of the License, or (at your option) any later
10 # version.
12 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License along
17 # with Koha; if not, write to the Free Software Foundation, Inc.,
18 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 =head1 NAME
22 Koha::Cache::Object - Tie-able class for caching objects
24 =head1 SYNOPSIS
26 my $cache = Koha::Cache->new();
27 my $scalar = Koha::Cache->create_scalar(
29 'key' => 'whatever',
30 'timeout' => 2,
31 'constructor' => sub { return 'stuff'; },
34 my %hash = Koha::Cache->create_hash(
36 'key' => 'whateverelse',
37 'timeout' => 2,
38 'constructor' => sub { return { 'stuff' => 'nonsense' }; },
42 =head1 DESCRIPTION
44 Do not use this class directly. It is tied to variables by Koha::Cache
45 for transparent cache access. If you choose to ignore this warning, you
46 should be aware that it is disturbingly polymorphic and supports both
47 scalars and hashes, with arrays a potential future addition.
49 =head1 TIE METHODS
51 =cut
53 use strict;
54 use warnings;
55 use Carp;
57 use base qw(Class::Accessor);
59 __PACKAGE__->mk_ro_accessors(
60 qw( allowupdate arguments cache cache_type constructor destructor inprocess key lastupdate timeout unset value )
63 # General/SCALAR routines
65 sub TIESCALAR {
66 my ( $class, $self ) = @_;
68 $self->{'datatype'} ||= 'SCALAR';
69 $self->{'arguments'} ||= [];
70 if ( defined $self->{'preload'} ) {
71 $self->{'value'} = &{ $self->{'preload'} }( @{ $self->{'arguments'} } );
72 if ( defined( $self->{'cache'} ) ) {
73 $self->{'cache'}->set_in_cache( $self->{'key'}, $self->{'value'},
74 { expiry => $self->{'timeout'} } );
76 $self->{'lastupdate'} = time;
78 return bless $self, $class;
81 sub FETCH {
82 my ( $self, $index ) = @_;
84 $ENV{DEBUG}
85 && $index
86 && carp "Retrieving cached hash member $index of $self->{'key'}";
88 my $now = time;
90 if ( !( $self->{'inprocess'} && defined( $self->{'value'} ) )
91 && $self->{'cache'} )
93 $self->{'value'} = $self->{'cache'}->get_from_cache( $self->{'key'} );
94 $self->{'lastupdate'} = $now;
97 if ( !defined $self->{'value'}
98 || ( defined $index && !exists $self->{'value'}->{$index} )
99 || !defined $self->{'lastupdate'}
100 || ( $now - $self->{'lastupdate'} > $self->{'timeout'} ) )
102 $self->{'value'} =
103 &{ $self->{'constructor'} }( @{ $self->{'arguments'} },
104 $self->{'value'}, $index );
105 if ( defined( $self->{'cache'} ) ) {
106 $self->{'cache'}->set_in_cache( $self->{'key'}, $self->{'value'},
107 { expiry => $self->{'timeout'} } );
109 $self->{'lastupdate'} = $now;
111 if ( $self->{'datatype'} eq 'HASH' && defined $index ) {
112 return $self->{'value'}->{$index};
114 return $self->{'value'};
117 sub STORE {
118 my $value = pop @_;
119 my ( $self, $index ) = @_;
121 if ( $self->{'datatype'} eq 'HASH' && defined($index) ) {
122 $self->{'value'}->{$index} = $value;
124 else {
125 $self->{'value'} = $value;
127 if ( defined( $self->{'allowupdate'} )
128 && $self->{'allowupdate'}
129 && defined( $self->{'cache'} ) )
131 $self->{'cache'}->set_in_cache( $self->{'key'}, $self->{'value'},
132 { expiry => $self->{'timeout'} },
136 return $self->{'value'};
139 sub DESTROY {
140 my ($self) = @_;
142 if ( defined( $self->{'destructor'} ) ) {
143 &{ $self->{'destructor'} }( @{ $self->{'arguments'} } );
146 if ( defined( $self->{'unset'} )
147 && $self->{'unset'}
148 && defined( $self->{'cache'} ) )
150 $self->{'cache'}->clear_from_cache( $self->{'key'} );
153 undef $self->{'value'};
155 return $self;
158 # HASH-specific routines
160 sub TIEHASH {
161 my ( $class, $self, @args ) = @_;
162 $self->{'datatype'} = 'HASH';
163 return TIESCALAR( $class, $self, @args );
166 sub DELETE {
167 my ( $self, $index ) = @_;
168 delete $self->{'value'}->{$index};
169 return $self->STORE( $self->{'value'} );
172 sub EXISTS {
173 my ( $self, $index ) = @_;
174 $self->FETCH($index);
175 return exists $self->{'value'}->{$index};
178 sub FIRSTKEY {
179 my ($self) = @_;
180 $self->FETCH;
181 $self->{'iterator'} = [ keys %{ $self->{'value'} } ];
182 return $self->NEXTKEY;
185 sub NEXTKEY {
186 my ($self) = @_;
187 return shift @{ $self->{'iterator'} };
190 sub SCALAR {
191 my ($self) = @_;
192 $self->FETCH;
193 return scalar %{ $self->{'value'} }
194 if ( ref( $self->{'value'} ) eq 'HASH' );
195 return;
198 sub CLEAR {
199 my ($self) = @_;
200 return $self->DESTROY;
203 # ARRAY-specific routines
205 =head1 SEE ALSO
207 Koha::Cache, tie, perltie
209 =head1 AUTHOR
211 Jared Camins-Esakov, E<lt>jcamins@cpbibliography.comE<gt>
213 =cut
217 __END__