release
[catagits/Catalyst-Model-DBIC-Schema.git] / lib / Catalyst / TraitFor / Model / DBIC / Schema / Caching.pm
1 package Catalyst::TraitFor::Model::DBIC::Schema::Caching;
2
3 use namespace::autoclean;
4 use Moose::Role;
5 use Carp::Clan '^Catalyst::Model::DBIC::Schema';
6 use Catalyst::Model::DBIC::Schema::Types 'CursorClass';
7 use MooseX::Types::Moose qw/Int Str/;
8
9 =head1 NAME
10
11 Catalyst::TraitFor::Model::DBIC::Schema::Caching - Query caching support for
12 Catalyst::Model::DBIC::Schema
13
14 =head1 SYNOPSIS
15
16     __PACKAGE__->config({
17         traits => ['Caching'],
18         connect_info => 
19             ['dbi:mysql:db', 'user', 'pass'],
20     });
21
22     $c->model('DB::Table')->search({ foo => 'bar' }, { cache_for => 18000 });
23
24 =head1 DESCRIPTION
25
26 Enable caching support using L<DBIx::Class::Cursor::Cached> and
27 L<Catalyst::Plugin::Cache>.
28
29 In order for this to work, L<Catalyst::Plugin::Cache> must be configured and
30 loaded. A possible configuration would look like this:
31
32   <Plugin::Cache>
33     <backend>       
34       class Cache::FastMmap
35       unlink_on_exit 1
36       share_file /tmp/myapp_share
37     </backend>
38   </Plugin::Cache>
39
40 Then in your queries, set the C<cache_for> ResultSet attribute to the number of
41 seconds you want the query results to be cached for, eg.:
42
43   $c->model('DB::Table')->search({ foo => 'bar' }, { cache_for => 18000 });
44
45 =head1 CONFIG PARAMETERS
46
47 =head2 caching
48
49 Turn caching on or off, you can use:
50
51     $c->model('DB')->caching(0);
52
53 =cut
54
55 has caching => (is => 'rw', isa => Int, default => 1);
56
57 after setup => sub {
58     my $self = shift;
59
60     return if !$self->caching;
61
62     $self->caching(0);
63
64     my $cursor_class = $self->connect_info->{cursor_class}
65         || 'DBIx::Class::Cursor::Cached';
66
67     unless (eval { Class::MOP::load_class($cursor_class) }) {
68         carp "Caching disabled, cannot load cursor class"
69             . " $cursor_class: $@";
70         return;
71     }
72
73     unless ($cursor_class->can('clear_cache')) {
74         carp "Caching disabled, cursor_class $cursor_class does not"
75              . " support it.";
76         return;
77     }
78
79     $self->connect_info->{cursor_class} = $cursor_class;
80     $self->caching(1);
81 };
82
83 before ACCEPT_CONTEXT => sub {
84     my ($self, $c) = @_;
85
86     return $self unless 
87         $self->caching;
88
89     unless ($c->can('cache') && ref $c->cache) {
90         $c->log->warn("DBIx::Class cursor caching disabled, you don't seem to"
91             . " have a working Cache plugin.");
92         $self->caching(0);
93         $self->_reset_cursor_class;
94         return $self;
95     }
96
97     if (ref $self->schema->default_resultset_attributes) {
98         $self->schema->default_resultset_attributes->{cache_object} =
99             $c->cache;
100     } else {
101         $self->schema->default_resultset_attributes({
102             cache_object => $c->cache
103         });
104     }
105 };
106
107 =head1 SEE ALSO
108
109 L<Catalyst::Model::DBIC::Schema>, L<DBIx::Class>, L<Catalyst::Plugin::Cache>,
110 L<Cache::FastMmap>, L<DBIx::Class::Cursor::Cached>
111
112 =head1 AUTHOR
113
114 Rafael Kitover, C<rkitover at cpan.org>
115
116 =head1 COPYRIGHT
117
118 This program is free software, you can redistribute it and/or modify it
119 under the same terms as Perl itself.
120
121 =cut
122
123 1;