13 Redis - perl binding for Redis database
17 our $VERSION = '1.2001';
22 Pure perl bindings for L<http://code.google.com/p/redis/>
24 This version supports protocol 1.2 or later of Redis available at
26 L<git://github.com/antirez/redis>
29 lists commands which are exercised in test suite, but
30 additinal commands will work correctly since protocol
31 specifies enough information to support almost all commands
32 with same peace of code with a little help of C<AUTOLOAD>.
38 my $r = Redis->new; # $ENV{REDIS_SERVER} or 127.0.0.1:6379
40 my $r = Redis->new( server => '192.168.0.1:6379', debug = 0 );
48 $self->{debug} ||= $ENV{REDIS_DEBUG};
49 $self->{encoding} ||= 'utf8'; ## default to lax utf8
51 $self->{server} ||= $ENV{REDIS_SERVER} || '127.0.0.1:6379';
52 $self->{sock} = IO::Socket::INET->new(
53 PeerAddr => $self->{server},
55 ) || confess("Could not connect to Redis server at $self->{server}: $!");
58 $self->{is_subscriber} = 0;
60 return bless($self, $class);
64 ### we don't want DESTROY to fallback into AUTOLOAD
68 ### Deal with common, general case, Redis commands
72 my $sock = $self->{sock} || confess("Not connected to any server");
73 my $enc = $self->{encoding};
74 my $deb = $self->{debug};
76 my $command = $AUTOLOAD;
78 $self->__is_valid_command($command);
80 $self->__send_command($command, @_);
82 return $self->__read_response($command);
86 ### Commands with extra logic
90 $self->__send_command('QUIT');
92 close(delete $self->{sock}) || confess("Can't close socket: $!");
100 $self->__is_valid_command('INFO');
102 $self->__send_command('INFO');
104 my $info = $self->__read_response('INFO');
107 map { split(/:/, $_, 2) } split(/\r\n/, $info)
113 $self->__is_valid_command('KEYS');
115 $self->__send_command('KEYS', @_);
117 my @keys = $self->__read_response('INFO', \my $type);
118 return @keys if $type eq '*';
120 ## Support redis <= 1.2.6
121 return split(/\s/, $keys[0]) if $keys[0];
127 sub __is_valid_command {
128 my ($self, $cmd) = @_;
130 return unless $self->{is_subscriber};
131 return if $cmd =~ /^P?(UN)?SUBSCRIBE$/;
132 confess("Cannot use command '$cmd' while in SUBSCRIBE mode, ");
136 ### Socket operations
140 my $enc = $self->{encoding};
141 my $deb = $self->{debug};
143 warn "[SEND] $cmd ", Dumper([@_]) if $deb;
145 ## Encode command using multi-bulk format
146 my $n_elems = scalar(@_) + 1;
147 my $buf = "\*$n_elems\r\n";
148 for my $elem ($cmd, @_) {
149 my $bin = $enc ? encode($enc, $elem) : $elem;
150 $buf .= defined($bin) ? '$' . length($bin) . "\r\n$bin\r\n" : "\$-1\r\n";
153 ## Send command, take care for partial writes
154 warn "[SEND RAW] $buf" if $deb;
155 my $sock = $self->{sock} || confess("Not connected to any server");
157 my $len = syswrite $sock, $buf, length $buf;
158 confess("Could not write to Redis server: $!")
160 substr $buf, 0, $len, "";
166 sub __read_response {
167 my ($self, $command, $type_r) = @_;
169 my ($type, $result) = $self->__read_sock;
170 $$type_r = $type if $type_r;
173 confess "[$command] $result, ";
175 elsif ($type eq '+') {
178 elsif ($type eq '$') {
179 return if $result < 0;
180 return $self->__read_sock($result);
182 elsif ($type eq '*') {
185 push @list, $self->__read_response($command);
189 elsif ($type eq ':') {
193 confess "unknown answer type: $type ($result), "
198 my ($self, $len) = @_;
199 my $sock = $self->{sock} || confess("Not connected to any server");
200 my $enc = $self->{encoding};
201 my $deb = $self->{debug};
202 my $rbuf = \($self->{rbuf});
204 my ($data, $type) = ('', '');
205 my $read_size = defined $len? $len+2 : 8192;
207 ## Read NN bytes, strip \r\n at the end
209 if (length($$rbuf) >= $len + 2) {
210 $data = substr(substr($$rbuf, 0, $len + 2, ''), 0, -2);
214 ## No len, means line more, read until \r\n
215 elsif ($$rbuf =~ s/^(.)([^\015\012]*)\015\012//) {
216 ($type, $data) = ($1, $2);
220 my $bytes = sysread $sock, $$rbuf, $read_size, length $$rbuf;
221 confess("Error while reading from Redis server: $!") unless defined $bytes;
222 confess("Redis server closed connection") unless $bytes;
225 $data = decode($enc, $data) if $enc;
226 warn "[RECV] '$type$data'" if $self->{debug};
228 return ($type, $data) if $type;
237 =head1 Connection Handling
245 $r->ping || die "no server?";
247 =head1 Commands operating on string values
251 $r->set( foo => 'bar' );
253 $r->setnx( foo => 42 );
257 my $value = $r->get( 'foo' );
261 my @values = $r->mget( 'foo', 'bar', 'baz' );
267 $r->incrby('tripplets', 3);
273 $r->decrby('tripplets', 3);
277 $r->exists( 'key' ) && print "got key!";
281 $r->del( 'key' ) || warn "key doesn't exist";
285 $r->type( 'key' ); # = string
287 =head1 Commands operating on the key space
291 my @keys = $r->keys( '*glob_pattern*' );
295 my $key = $r->randomkey;
299 my $ok = $r->rename( 'old-key', 'new-key', $new );
303 my $nr_keys = $r->dbsize;
305 =head1 Commands operating on lists
307 See also L<Redis::List> for tie interface.
311 $r->rpush( $key, $value );
315 $r->lpush( $key, $value );
323 my @list = $r->lrange( $key, $start, $end );
327 my $ok = $r->ltrim( $key, $start, $end );
331 $r->lindex( $key, $index );
335 $r->lset( $key, $index, $value );
339 my $modified_count = $r->lrem( $key, $count, $value );
343 my $value = $r->lpop( $key );
347 my $value = $r->rpop( $key );
349 =head1 Commands operating on sets
353 $r->sadd( $key, $member );
357 $r->srem( $key, $member );
361 my $elements = $r->scard( $key );
365 $r->sismember( $key, $member );
369 $r->sinter( $key1, $key2, ... );
373 my $ok = $r->sinterstore( $dstkey, $key1, $key2, ... );
375 =head1 Multiple databases handling commands
379 $r->select( $dbindex ); # 0 for new clients
383 $r->move( $key, $dbindex );
397 $r->sort("key BY pattern LIMIT start end GET pattern ASC|DESC ALPHA');
399 =head1 Persistence control commands
417 =head1 Remote server control commands
421 my $info_hash = $r->info;
425 Since Redis knows nothing about encoding, we are forcing utf-8 flag on all data received from Redis.
426 This change is introduced in 1.2001 version.
428 This allows us to round-trip utf-8 encoded characters correctly, but might be problem if you push
429 binary junk into Redis and expect to get it back without utf-8 flag turned on.
433 Dobrica Pavlinusic, C<< <dpavlin at rot13.org> >>
437 Please report any bugs or feature requests to C<bug-redis at rt.cpan.org>, or through
438 the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Redis>. I will be notified, and then you'll
439 automatically be notified of progress on your bug as I make changes.
446 You can find documentation for this module with the perldoc command.
453 You can also look for information at:
457 =item * RT: CPAN's request tracker
459 L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Redis>
461 =item * AnnoCPAN: Annotated CPAN documentation
463 L<http://annocpan.org/dist/Redis>
467 L<http://cpanratings.perl.org/d/Redis>
471 L<http://search.cpan.org/dist/Redis>
476 =head1 ACKNOWLEDGEMENTS
479 =head1 COPYRIGHT & LICENSE
481 Copyright 2009-2010 Dobrica Pavlinusic, all rights reserved.
483 This program is free software; you can redistribute it and/or modify it
484 under the same terms as Perl itself.