File Coverage

blib/lib/Starch/Store.pm
Criterion Covered Total %
statement 41 41 100.0
branch 4 4 100.0
condition n/a
subroutine 15 15 100.0
pod 7 8 87.5
total 67 68 98.5


line stmt bran cond sub pod time code
1             package Starch::Store;
2             our $VERSION = '0.14';
3              
4             =encoding utf8
5              
6             =head1 NAME
7              
8             Starch::Store - Base role for Starch stores.
9              
10             =head1 DESCRIPTION
11              
12             This role defines an interfaces for Starch store classes. Starch store
13             classes are meant to be thin wrappers around the store implementations
14             (such as DBI, CHI, etc).
15              
16             See L for instructions on using stores and a list of
17             available Starch stores.
18              
19             See L for instructions on writing your own stores.
20              
21             This role adds support for method proxies to consuming classes as
22             described in L.
23              
24             =cut
25              
26 13     13   6759 use Starch::Util qw( croak );
  13         30  
  13         884  
27 13     13   80 use Types::Common::Numeric -types;
  13         24  
  13         96  
28 13     13   15970 use Types::Common::String -types;
  13         29  
  13         127  
29 13     13   17464 use Types::Standard -types;
  13         28  
  13         74  
30              
31 13     13   53930 use Moo::Role;
  13         89  
  13         96  
32 13     13   6132 use strictures 2;
  13         85  
  13         458  
33 13     13   2083 use namespace::clean;
  13         27  
  13         75  
34              
35             with 'Starch::Role::Log';
36             with 'MooX::MethodProxyArgs';
37              
38             requires qw(
39             set
40             get
41             remove
42             );
43              
44             # Declare BUILD so roles can apply method modifiers to it.
45       144 0   sub BUILD { }
46              
47             around set => sub{
48             my ($orig, $self, $id, $keys, $data, $expires) = @_;
49              
50             # Short-circuit set operations if the data should not be stoed.
51             return if $data->{ $self->manager->no_store_state_key() };
52              
53             $expires = $self->calculate_expires( $expires );
54              
55             return $self->$orig( $id, $keys, $data, $expires );
56             };
57              
58             =head1 REQUIRED ARGUMENTS
59              
60             =head2 manager
61              
62             The L object which is used by stores to
63             access configuration and create sub-stores (such as the Layered
64             store's outer and inner stores). This is automatically set when
65             the stores are built by L.
66              
67             =cut
68              
69             has manager => (
70             is => 'ro',
71             isa => InstanceOf[ 'Starch::Manager' ],
72             required => 1,
73             weak_ref => 1,
74             handles => ['factory'],
75             );
76              
77             =head1 OPTIONAL ARGUMENTS
78              
79             =head2 max_expires
80              
81             Set the per-store maximum expires which will override the state's expires
82             if the state's expires is larger.
83              
84             =cut
85              
86             has max_expires => (
87             is => 'ro',
88             isa => (PositiveOrZeroInt) | Undef,
89             );
90              
91             =head2 key_separator
92              
93             Used by L to combine the state namespace
94             and ID. Defaults to C<:>.
95              
96             =cut
97              
98             has key_separator => (
99             is => 'ro',
100             isa => NonEmptySimpleStr,
101             default => ':',
102             );
103              
104             =head1 ATTRIBUTES
105              
106             =head2 can_reap_expired
107              
108             Return true if the stores supports the L method.
109              
110             =cut
111              
112 10     10 1 88 sub can_reap_expired { 0 }
113              
114             =head2 short_store_class_name
115              
116             Returns L with the
117             C prefix remove.
118              
119             =cut
120              
121             sub short_store_class_name {
122 74     74 1 1567 my ($self) = @_;
123 74         216 my $class = $self->short_class_name();
124 74         218 $class =~ s{^Store::}{};
125 74         307 return $class;
126             }
127              
128             =head1 METHODS
129              
130             =head2 new_sub_store
131              
132             Builds a new store object. Any arguments passed will be
133             combined with the L.
134              
135             =cut
136              
137             sub new_sub_store {
138 50     50 1 109 my $self = shift;
139              
140 50         269 my $args = $self->sub_store_args( @_ );
141              
142 50         889 return $self->factory->new_store( $args );
143             }
144              
145             =head2 sub_store_args
146              
147             Returns the arguments needed to create a sub-store. Any arguments
148             passed will be combined with the default arguments. The default
149             arguments will be L and L (if set). More
150             arguments may be present if any plugins extend this method.
151              
152             =cut
153              
154             sub sub_store_args {
155 50     50 1 159 my $self = shift;
156              
157 50         1228 my $args = $self->BUILDARGS( @_ );
158              
159             return {
160 50         10807 manager => $self->manager(),
161             max_expires => $self->max_expires(),
162             key_separator => $self->key_separator(),
163             %$args,
164             };
165             }
166              
167             =head2 calculate_expires
168              
169             Given an expires value this will calculate the expires that this store
170             should use considering what L is set to.
171              
172             =cut
173              
174             sub calculate_expires {
175 154     154 1 340 my ($self, $expires) = @_;
176              
177 154         403 my $max_expires = $self->max_expires();
178 154 100       508 return $expires if !defined $max_expires;
179              
180 16 100       75 return $max_expires if $expires > $max_expires;
181              
182 8         42 return $expires;
183             }
184              
185             =head2 stringify_key
186              
187             my $store_key = $starch->stringify_key(
188             $state_id,
189             \@namespace,
190             );
191              
192             This method is used by stores that store and lookup data by
193             a string (all of them at this time). It combines the state
194             ID with the L of the key data for the store
195             request.
196              
197             =cut
198              
199             sub stringify_key {
200 420     420 1 3888 my ($self, $id, $namespace) = @_;
201 420         2100 return join(
202             $self->key_separator(),
203             @$namespace,
204             $id,
205             );
206             }
207              
208             =head2 reap_expired
209              
210             This triggers the store to find and delete all expired states.
211             This is meant to be used in an offline process, such as a cronjob,
212             as finding and deleting the states could take hours depending
213             on the amount of data and the storage engine's speed.
214              
215             By default this method will throw an exception if the store does
216             not define its own reap method. You can check if a store supports
217             this method by calling L.
218              
219             =cut
220              
221             sub reap_expired {
222 8     8 1 26 my ($self) = @_;
223              
224 8         49 croak sprintf(
225             '%s does not support expired state reaping',
226             $self->short_class_name(),
227             );
228             }
229              
230             1;
231             __END__