File Coverage

blib/lib/CHI.pm
Criterion Covered Total %
statement 39 89 43.8
branch 2 28 7.1
condition 0 21 0.0
subroutine 14 19 73.6
pod 2 6 33.3
total 57 163 34.9


line stmt bran cond sub pod time code
1             package CHI;
2             $CHI::VERSION = '0.59';
3 1     1   15327 use 5.006;
  1         2  
  1         35  
4 1     1   4 use Carp;
  1         2  
  1         74  
5 1     1   404 use CHI::Stats;
  1         3  
  1         32  
6 1     1   440 use String::RewritePrefix;
  1         10413  
  1         6  
7 1     1   133 use Module::Runtime qw(require_module);
  1         2  
  1         7  
8 1     1   519 use Moo::Role ();
  1         19510  
  1         37  
9 1     1   10 use strict;
  1         1  
  1         42  
10 1     1   6 use warnings;
  1         2  
  1         179  
11              
12             my ( %final_class_seen, %memoized_cache_objects, %stats );
13             my %valid_config_keys =
14             map { ( $_, 1 ) } qw(defaults memoize_cache_objects namespace storage);
15              
16             sub logger {
17 0     0 0 0 warn
18             "CHI now uses Log::Any for logging - see Log::Any documentation for details";
19             }
20              
21             sub config {
22 1     1 1 2 my $class = shift;
23 1 50       5 $class->_set_config(@_) if @_;
24 1         6 return $class->_get_config();
25             }
26              
27             sub _set_config {
28 1     1   1 my ( $class, $config ) = @_;
29 1 50       4 if ( my @bad_keys = grep { !$valid_config_keys{$_} } keys(%$config) ) {
  0         0  
30 0         0 croak "unknown keys in config hash: " . join( ", ", @bad_keys );
31             }
32              
33             # set class specific configuration
34 1     1   31 no strict 'refs';
  1         2  
  1         26  
35 1     1   4 no warnings 'redefine';
  1         1  
  1         106  
36 1     1   3 *{"$class\::_get_config"} = sub { $config };
  1         4  
  1         484  
37             }
38              
39 1     1   4 BEGIN { __PACKAGE__->config( {} ) }
40              
41             sub memoized_cache_objects {
42 0     0 0   my ($class) = @_;
43              
44             # Each CHI root class gets its hash of memoized objects
45             #
46 0   0       $memoized_cache_objects{$class} ||= {};
47 0           return $memoized_cache_objects{$class};
48             }
49              
50             sub clear_memoized_cache_objects {
51 0     0 0   my ($class) = @_;
52              
53 0           $memoized_cache_objects{$class} = {};
54             }
55              
56             sub stats {
57 0     0 0   my ($class) = @_;
58              
59             # Each CHI root class gets its own stats object
60             #
61 0   0       $stats{$class} ||= CHI::Stats->new( chi_root_class => $class );
62 0           return $stats{$class};
63             }
64              
65             sub new {
66 0     0 1   my ( $chi_root_class, %params ) = @_;
67              
68 0           my $config = $chi_root_class->config;
69              
70             # Cache object memoization: See if cache object with these parameters
71             # has already been created, and return it if so. Only for parameters
72             # with 0 or 1 keys.
73             #
74 0           my ( $cache_object_key, $cache_objects );
75 0 0 0       if ( $config->{memoize_cache_objects} && keys(%params) <= 1 ) {
76 0           $cache_object_key = join chr(28), %params;
77 0           $cache_objects = $chi_root_class->memoized_cache_objects;
78 0 0         if ( my $cache_object = $cache_objects->{$cache_object_key} ) {
79 0           return $cache_object;
80             }
81             }
82              
83             # Gather defaults
84             #
85 0   0       my $core_defaults = $config->{defaults} || {};
86 0   0       my $namespace_defaults =
87             $config->{namespace}->{ $params{namespace} || 'Default' } || {};
88 0   0       my $storage =
89             $params{storage}
90             || $namespace_defaults->{storage}
91             || $core_defaults->{storage};
92 0           my $storage_defaults = {};
93 0 0         if ( defined($storage) ) {
94 0 0         $storage_defaults = $config->{storage}->{$storage}
95             or croak "no config for storage type '$storage'";
96             }
97              
98             # Combine passed params with defaults
99             #
100             %params =
101 0           ( %$core_defaults, %$storage_defaults, %$namespace_defaults, %params );
102              
103             # Get driver class from driver or driver_class parameters
104             #
105 0           my $driver_class;
106 0 0         if ( my $driver = delete( $params{driver} ) ) {
107 0           ($driver_class) =
108             String::RewritePrefix->rewrite( { '' => 'CHI::Driver::', '+' => '' },
109             $driver );
110             }
111             else {
112 0           $driver_class = delete( $params{driver_class} );
113             }
114 0 0         croak "missing required param 'driver' or 'driver_class'"
115             unless defined $driver_class;
116              
117             # Load driver class if it hasn't been loaded or defined in-line already
118             #
119 0 0         unless ( $driver_class->can('fetch') ) {
120 0           require_module($driver_class);
121             }
122              
123             # Select roles depending on presence of certain arguments. Everyone gets
124             # the Universal role. Accept both 'roles' and 'traits' for backwards
125             # compatibility. Add CHI::Driver::Role:: unless prefixed with '+'.
126             #
127 0           my @roles = ('Universal');
128 0           foreach my $param_name (qw(roles traits)) {
129 0 0         if ( exists( $params{$param_name} ) ) {
130 0           push( @roles, @{ delete( $params{$param_name} ) } );
  0            
131             }
132             }
133 0 0 0       if ( exists( $params{max_size} ) || exists( $params{is_size_aware} ) ) {
134 0           push( @roles, 'IsSizeAware' );
135             }
136 0 0 0       if ( exists( $params{l1_cache} ) || exists( $params{mirror_cache} ) ) {
137 0           push( @roles, 'HasSubcaches' );
138             }
139 0 0         if ( $params{is_subcache} ) {
140 0           push( @roles, 'IsSubcache' );
141             }
142 0           @roles = String::RewritePrefix->rewrite(
143             { '' => 'CHI::Driver::Role::', '+' => '' }, @roles );
144              
145             # Select a final class based on the driver class and roles, creating it
146             # if necessary - adapted from MooseX::Traits
147             #
148 0           my $final_class =
149             Moo::Role->create_class_with_roles( $driver_class, @roles );
150              
151 0           my $cache_object = $final_class->new(
152             chi_root_class => $chi_root_class,
153             driver_class => $driver_class,
154             %params
155             );
156              
157             # Memoize if appropriate
158             #
159 0 0         if ($cache_object_key) {
160 0           $cache_objects->{$cache_object_key} = $cache_object;
161             }
162              
163 0           return $cache_object;
164             }
165              
166             1;
167              
168             __END__