File Coverage

blib/lib/Tie/Redis.pm
Criterion Covered Total %
statement 22 83 26.5
branch 1 28 3.5
condition 0 5 0.0
subroutine 7 23 30.4
pod n/a
total 30 139 21.5


line stmt bran cond sub pod time code
1             package Tie::Redis;
2             {
3             $Tie::Redis::VERSION = '0.26';
4             }
5             # ABSTRACT: Connect perl data structures to Redis
6 4     4   94747 use strict;
  4         9  
  4         133  
7 4     4   24 use Carp ();
  4         5  
  4         63  
8              
9 4     4   2217 use Tie::Redis::Connection;
  4         12  
  4         132  
10 4     4   3987 use Tie::Redis::Hash;
  4         11  
  4         113  
11 4     4   4185 use Tie::Redis::List;
  4         15  
  4         131  
12 4     4   2663 use Tie::Redis::Scalar;
  4         11  
  4         4262  
13              
14             sub TIEHASH {
15 1     1   12 my($class, %args) = @_;
16 1         4 my $serialize = delete $args{serialize};
17            
18 1         30 my $conn = Tie::Redis::Connection->new(%args);
19 1 50       1725 Carp::croak "Unable to connect to Redis server: $!" unless $conn;
20              
21 0           bless {
22             _conn => $conn,
23             serialize => $class->_serializer($serialize),
24             }, $class;
25             }
26              
27             sub _serializer {
28 0     0     my($self, $serialize) = @_;
29              
30             my %serializers = (
31             json => [
32 0     0     sub { require JSON },
33             \&JSON::to_json,
34             \&JSON::from_json
35             ],
36             storable => [
37 0     0     sub { require Storable },
38             \&Storable::nfreeze,
39             \&Storaable::thaw
40             ],
41             msgpack => [
42 0     0     sub { require Data::MessagePack },
43 0     0     sub { unshift @_, "Data::MessagePack"; goto &Data::MessagePack::pack },
  0            
44 0     0     sub { unshift @_, "Data::MessagePack"; goto &Data::MessagePack::unpack }
  0            
45 0           ],
46             );
47              
48             my $serializer = $serializers{$serialize || ''} || [undef, (sub {
49 0     0     Carp::croak("No serializer specified for Tie::Redis; unable to handle nested structures");
50 0   0       }) x 2];
51              
52             # Load; will error if required module isn't present
53 0 0         $serializer->[0] && $serializer->[0]->();
54              
55 0           return $serializer;
56             }
57              
58             sub _cmd {
59 0     0     my($self, $cmd, @args) = @_;
60              
61 0 0 0       if($self->{prefix} && defined $args[0]) {
62 0           $args[0] = "$self->{prefix}$args[0]";
63             }
64              
65 0           $self->{_conn}->$cmd(@args);
66             }
67              
68             sub STORE {
69 0     0     my($self, $key, $value) = @_;
70              
71 0 0         if(!ref $value) {
    0          
    0          
    0          
72 0           $self->_cmd(set => $key, $value);
73              
74             } elsif(ref $value eq 'HASH') {
75             # TODO: Should pipeline somehow
76 0           $self->_cmd("multi");
77 0           $self->_cmd(del => $key);
78 0           $self->_cmd(hmset => $key,
79             map +($_ => $value->{$_}), keys %$value);
80 0           $self->_cmd("exec");
81 0           $self->{_type_cache}->{$key} = 'hash';
82              
83             } elsif(ref $value eq 'ARRAY') {
84 0           $self->_cmd("multi");
85 0           $self->_cmd(del => $key);
86 0           for my $v(@$value) {
87 0           $self->_cmd(rpush => $key, $v);
88             }
89 0           $self->_cmd("exec");
90 0           $self->{_type_cache}->{$key} = 'list';
91              
92             } elsif(ref $value) {
93 0           $self->_cmd(set => $key, $self->{serialize}->[1]->($value));
94             }
95             }
96              
97             sub FETCH {
98 0     0     my($self, $key) = @_;
99 0 0         my $type = exists $self->{_type_cache}->{$key}
100             ? $self->{_type_cache}->{$key}
101             : $self->_cmd(type => $key);
102              
103 0 0         if($type eq 'hash') {
    0          
    0          
    0          
    0          
104 0           tie my %h, "Tie::Redis::Hash", redis => $self, key => $key;
105 0           return \%h;
106             } elsif($type eq 'list') {
107 0           tie my @l, "Tie::Redis::List", redis => $self, key => $key;
108 0           return \@l;
109             } elsif($type eq 'set') {
110 0           die "Sets yet to be implemented...";
111             } elsif($type eq 'zset') {
112 0           die "Zsets yet to be implemented...";
113             } elsif($type eq 'string') {
114 0           $self->_cmd(get => $key);
115             } else {
116 0           return undef;
117             }
118             }
119              
120             sub FIRSTKEY {
121 0     0     my($self) = @_;
122 0           my $keys = $self->_cmd(keys => "*");
123 0           $self->{keys} = $keys;
124 0           $self->NEXTKEY;
125             }
126              
127             sub NEXTKEY {
128 0     0     my($self) = @_;
129 0           shift @{$self->{keys}};
  0            
130             }
131              
132             sub EXISTS {
133 0     0     my($self, $key) = @_;
134 0           $self->_cmd(exists => $key);
135             }
136              
137             sub DELETE {
138 0     0     my($self, $key) = @_;
139 0           $self->_cmd(del => $key);
140             }
141              
142             sub CLEAR {
143 0     0     my($self, $key) = @_;
144 0 0         if($self->{prefix}) {
145 0           $self->_cmd(del => $self->_cmd(keys => "*"));
146             } else {
147 0           $self->_cmd("flushdb");
148             }
149             }
150              
151             sub SCALAR {
152 0     0     my($self) = @_;
153 0           $self->_cmd("dbsize");
154             }
155              
156             1;
157              
158              
159              
160             __END__