switch to MX::Traits, document attributes
[catagits/Catalyst-Model-DBIC-Schema.git] / lib / Catalyst / Model / DBIC / Schema / Trait / Caching.pm
1 package Catalyst::Model::DBIC::Schema::Trait::Caching;
2
3 use Moose::Role;
4 use Carp::Clan '^Catalyst::Model::DBIC::Schema';
5 use Catalyst::Model::DBIC::Schema::Types 'CursorClass';
6 use MooseX::Types::Moose qw/Int Str/;
7
8 use namespace::clean -except => 'meta';
9
10 =head1 NAME
11
12 Catalyst::Model::DBIC::Schema::Trait::Caching - Query caching support for
13 Catalyst::Model::DBIC::Schema
14
15 =head1 SYNOPSIS
16
17     __PACKAGE__->config({
18         traits => ['Caching'],
19         connect_info => 
20             ['dbi:mysql:db', 'user', 'pass'],
21     });
22
23     $c->model('DB::Table')->search({ foo => 'bar' }, { cache_for => 18000 });
24
25 =head1 DESCRIPTION
26
27 Enable caching support using L<DBIx::Class::Cursor::Cached> and
28 L<Catalyst::Plugin::Cache>.
29
30 In order for this to work, L<Catalyst::Plugin::Cache> must be configured and
31 loaded. A possible configuration would look like this:
32
33   <Plugin::Cache>
34     <backend>       
35       class Cache::FastMmap
36       unlink_on_exit 1
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;