File Coverage

blib/lib/Rose/DBx/CannedQuery/SimpleQueryCache.pm
Criterion Covered Total %
statement 57 57 100.0
branch 9 12 75.0
condition 2 3 66.6
subroutine 18 18 100.0
pod 4 4 100.0
total 90 94 95.7


line stmt bran cond sub pod time code
1             #!perl
2             #
3              
4 1     1   646 use strict;
  1         1  
  1         33  
5 1     1   4 use warnings;
  1         1  
  1         55  
6              
7             package Rose::DBx::CannedQuery::SimpleQueryCache;
8              
9             our ($VERSION) = '1.00';
10              
11 1     1   144362 use Data::Dumper;
  1         5117  
  1         126  
12 1     1   11 use Digest::MD5 qw(md5_hex);
  1         1  
  1         65  
13              
14 1     1   693 use Moo 2;
  1         8965  
  1         5  
15 1     1   1437 use Types::Standard qw/ CodeRef Object /;
  1         44476  
  1         9  
16              
17             has backend => (
18             isa => Object,
19             is => 'ro',
20             required => 1,
21             lazy => 1,
22             builder => '_build_backend'
23             );
24              
25             has args_to_key => (
26             isa => CodeRef,
27             is => 'ro',
28             required => 1,
29             lazy => 1,
30             builder => '_build_args_to_key'
31             );
32              
33             sub _build_backend {
34 1     1   389 Rose::DBx::CannedQuery::SimpleQueryCache::_PlainOldHash->new();
35             }
36              
37             {
38             my $dumper = Data::Dumper->new( [] )->Sortkeys(1);
39              
40             sub _make_digest_key {
41 14 50   14   80 my (%args) = ref $_[0] ? %{ $_[0] } : @_;
  14         42  
42 27         127 my $key =
43 14         30 $dumper->Reset->Values( [ map { $_ => $args{$_} } sort keys %args ] )
44             ->Dump;
45 14         403 $key =~ s/\s+/ /g;
46 14         23 $key = lc $key;
47 14 50       23 $key = md5_hex($key) if length($key) > 512;
48 14         25 return $key;
49             }
50             }
51              
52             sub _build_args_to_key {
53 1     1   408 return \&_make_digest_key;
54             }
55              
56             sub get_query_from_cache {
57 9     9 1 11 my $self = shift;
58 9         165 my $key = $self->args_to_key->(@_);
59 9         137 my $qry = $self->backend->get($key);
60              
61 9 100       15 if ($qry) {
62 5         8 my $sth = $qry->sth;
63              
64             # We take this roundabout path to check on connectedness because
65             # $sth's own Active attribute may be false if prepared but not yet
66             # executed, and we don't want to go through Rose::DB->dbh to get
67             # DBI's database handle, since it'll reconnect under the hood if
68             # it's been disconnected, which doesn't help $sth
69 5 100 66     30 return $qry if $sth->{Active} or $sth->{Database}->{Active};
70 1         13 $self->backend->remove($key);
71             }
72 5         15 return;
73             }
74              
75             sub add_query_to_cache {
76 4     4 1 2018 my $self = shift;
77 4         5 my $query = shift;
78 4         51 my $key = $self->args_to_key->(@_);
79 4         66 my $ret = $self->backend->set( $key, $query );
80 4 50       13 return $ret ? $query : $ret;
81             }
82              
83             sub remove_query_from_cache {
84 1     1 1 2 my $self = shift;
85 1         19 my $key = $self->args_to_key->(@_);
86 1         16 return $self->backend->remove($key);
87             }
88              
89             sub clear_query_cache {
90 1     1 1 20 shift->backend->clear();
91             }
92              
93             {
94              
95             package Rose::DBx::CannedQuery::SimpleQueryCache::_PlainOldHash;
96              
97             sub new {
98 1     1   14 bless {}, shift;
99             }
100              
101             sub get {
102 9     9   41 my ( $self, $key ) = @_;
103 9 100       20 return $self->{$key} if exists $self->{$key};
104 4         4 return;
105             }
106              
107             sub set {
108 4     4   32 my ( $self, $key, $query ) = @_;
109 4         9 $self->{$key} = $query;
110 4         5 return $query;
111             }
112              
113             sub remove {
114 2     2   10 my ( $self, $key ) = @_;
115 2         7 delete $self->{$key};
116             }
117              
118             sub clear {
119 1     1   8 my $self = shift;
120 1         2 undef %$self;
121 1         4 return 1;
122             }
123             }
124              
125             1;
126              
127             __END__