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