rename 'delete' to 'remove' so that the interface matches Cache::Cache
[catagits/Catalyst-Plugin-Cache.git] / lib / Catalyst / Plugin / Cache.pm
CommitLineData
c28ee69c 1#!/usr/bin/perl
2
3package Catalyst::Plugin::Cache;
2e4bde89 4use base qw/Class::Data::Inheritable Class::Accessor::Fast/;
c28ee69c 5
6use strict;
7use warnings;
8
9use Scalar::Util ();
10use Carp ();
11use NEXT;
12
2e4bde89 13use Catalyst::Plugin::Cache::Curried;
14
c28ee69c 15__PACKAGE__->mk_classdata( "_cache_backends" );
2e4bde89 16__PACKAGE__->mk_accessors( "_default_curried_cache" );
c28ee69c 17
18sub setup {
19 my $app = shift;
20
21 # set it once per app, not once per plugin,
22 # and don't overwrite if some plugin was wicked
23 $app->_cache_backends({}) unless $app->_cache_backends;
24
25 my $ret = $app->NEXT::setup( @_ );
26
27 $app->setup_cache_backends;
28
29 $ret;
30}
31
2e4bde89 32# don't die even if we don't have cache backends
c28ee69c 33sub setup_cache_backends { shift->NEXT::setup_cache_backends(@_) }
34
35sub cache {
2e4bde89 36 my ( $c, @meta ) = @_;
37
38 if ( @meta == 1 ) {
39 my $name = $meta[0];
40 return ( $c->get_preset_curried($name) || $c->get_cache_backend($name) );
41 } elsif ( !@meta ) {
42 # be nice and always return the same one for the simplest case
43 return ( $c->_default_curried_cache || $c->_default_curried_cache( $c->curry_cache( @meta ) ) );
c28ee69c 44 } else {
2e4bde89 45 return $c->curry_cache( @meta );
c28ee69c 46 }
47}
48
2e4bde89 49sub curry_cache {
50 my ( $c, @meta ) = @_;
51 return Catalyst::Plugin::Cache::Curried->new( $c, @meta );
52}
53
54sub get_preset_curried {
55 my ( $c, $name ) = @_;
56
57 if ( ref( my $preset = $c->config->{cache}{profiles}{$name} ) ) {
58 return $preset if Scalar::Util::blessed($preset);
59
60 my @meta = ( ( ref $preset eq "HASH" ) ? %$preset : @$preset );
61 return $c->curry_cache( @meta );
62 }
63
64 return;
65}
66
c28ee69c 67sub get_cache_backend {
68 my ( $c, $name ) = @_;
69 $c->_cache_backends->{$name};
70}
71
72sub register_cache_backend {
73 my ( $c, $name, $backend ) = @_;
74
75 no warnings 'uninitialized';
76 Carp::croak("$backend does not look like a cache backend - "
aed484da 77 . "it must be an object supporting get, set and remove")
78 unless eval { $backend->can("get") && $backend->can("set") && $backend->can("remove") };
c28ee69c 79
80 $c->_cache_backends->{$name} = $backend;
81}
82
83sub unregister_cache_backend {
84 my ( $c, $name ) = @_;
85 delete $c->_cache_backends->{$name};
86}
87
88sub default_cache_backend {
89 my $c = shift;
90 $c->get_cache_backend( "default" ) || $c->temporary_cache_backend;
91}
92
93sub temporary_cache_backend {
94 my $c = shift;
95 die "FIXME - make up an in memory cache backend, that hopefully works well for the current engine";
96}
97
98# this gets a shit name so that the plugins can override a good name
99sub choose_cache_backend_wrapper {
100 my ( $c, @meta ) = @_;
101
102 Carp::croak("meta data must be an even sized list") unless @meta % 2 == 0;
103
104 my %meta = @meta;
105
106 # allow the cache client to specify who it wants to cache with (but loeave room for a hook)
107 if ( exists $meta{backend} ) {
108 if ( Scalar::Util::blessed($meta{backend}) ) {
109 return $meta{backend};
110 } else {
111 return $c->get_cache_backend( $meta{backend} ) || $c->default_cache_backend;
112 }
113 };
114
115
116 $meta{caller} = [ caller(2) ] unless exists $meta{caller}; # might be interesting
117
118 if ( my $chosen = $c->choose_cache_backend( %meta ) ) {
119 $chosen = $c->get_cache_backend( $chosen ) unless Scalar::Util::blessed($chosen); # if it's a name find it
120 return $chosen if Scalar::Util::blessed($chosen); # only return if it was an object or name lookup worked
121
122 # FIXME
123 # die "no such backend"?
124 # currently, we fall back to default
125 }
126
127 return $c->default_cache_backend;
128}
129
130sub choose_cache_backend { shift->NEXT::choose_cache_backend( @_ ) } # a convenient fallback
131
132sub cache_set {
133 my ( $c, $key, $value, @meta ) = @_;
134 $c->choose_cache_backend_wrapper( key => $key, value => $value, @meta )->set( $key, $value );
135}
136
137sub cache_get {
138 my ( $c, $key, @meta ) = @_;
139 $c->choose_cache_backend_wrapper( key => $key, @meta )->get( $key );
140}
141
aed484da 142sub cache_remove {
c28ee69c 143 my ( $c, $key, @meta ) = @_;
aed484da 144 $c->choose_cache_backend_wrapper( key => $key, @meta )->remove( $key );
c28ee69c 145}
146
147__PACKAGE__;
148
149__END__
150
151=pod
152
153=head1 NAME
154
155Catalyst::Plugin::Cache -
156
157=head1 SYNOPSIS
158
159 use Catalyst::Plugin::Cache;
160
161=head1 DESCRIPTION
162
163=cut
164
165