7 use Fcntl qw( O_NONBLOCK F_SETFL );
14 Redis - perl binding for Redis database
18 our $VERSION = '1.2001';
23 Pure perl bindings for L<http://code.google.com/p/redis/>
25 This version supports protocol 1.2 or later of Redis available at
27 L<git://github.com/antirez/redis>
30 lists commands which are exercised in test suite, but
31 additinal commands will work correctly since protocol
32 specifies enough information to support almost all commands
33 with same peace of code with a little help of C<AUTOLOAD>.
39 my $r = Redis->new; # $ENV{REDIS_SERVER} or 127.0.0.1:6379
41 my $r = Redis->new( server => '192.168.0.1:6379', debug = 0 );
49 $self->{debug} ||= $ENV{REDIS_DEBUG};
50 $self->{encoding} ||= 'utf8'; ## default to lax utf8
52 $self->{server} ||= $ENV{REDIS_SERVER} || '127.0.0.1:6379';
53 $self->{sock} = IO::Socket::INET->new(
54 PeerAddr => $self->{server},
56 ) || confess("Could not connect to Redis server at $self->{server}: $!");
58 $self->{read_size} = 8192;
61 $self->{is_subscriber} = 0;
63 return bless($self, $class);
67 ### we don't want DESTROY to fallback into AUTOLOAD
71 ### Deal with common, general case, Redis commands
76 my $sock = $self->{sock} || confess("Not connected to any server");
77 my $enc = $self->{encoding};
78 my $deb = $self->{debug};
80 my $command = $AUTOLOAD;
82 $self->__is_valid_command($command);
84 $self->__send_command($command, @_);
86 return $self->__read_response($command);
90 ### Commands with extra logic
94 $self->__send_command('QUIT');
97 close(delete $self->{sock}) || confess("Can't close socket: $!");
104 $self->__is_valid_command('INFO');
106 $self->__send_command('INFO');
108 my $info = $self->__read_response('INFO');
110 return {map { split(/:/, $_, 2) } split(/\r\n/, $info)};
115 $self->__is_valid_command('KEYS');
117 $self->__send_command('KEYS', @_);
119 my @keys = $self->__read_response('INFO', \my $type);
120 return @keys if $type eq '*';
122 ## Support redis <= 1.2.6
123 return split(/\s/, $keys[0]) if $keys[0];
129 sub __is_valid_command {
130 my ($self, $cmd) = @_;
132 return unless $self->{is_subscriber};
133 return if $cmd =~ /^P?(UN)?SUBSCRIBE$/i;
134 confess("Cannot use command '$cmd' while in SUBSCRIBE mode, ");
138 ### Socket operations
142 my $enc = $self->{encoding};
143 my $deb = $self->{debug};
145 warn "[SEND] $cmd ", Dumper([@_]) if $deb;
147 ## Encode command using multi-bulk format
148 my $n_elems = scalar(@_) + 1;
149 my $buf = "\*$n_elems\r\n";
150 for my $elem ($cmd, @_) {
151 my $bin = $enc ? encode($enc, $elem) : $elem;
152 $buf .= defined($bin) ? '$' . length($bin) . "\r\n$bin\r\n" : "\$-1\r\n";
155 ## Send command, take care for partial writes
156 warn "[SEND RAW] $buf" if $deb;
157 my $sock = $self->{sock} || confess("Not connected to any server");
159 my $len = syswrite $sock, $buf, length $buf;
160 confess("Could not write to Redis server: $!")
162 substr $buf, 0, $len, "";
168 sub __read_response {
169 my ($self, $command, $type_r) = @_;
171 my ($type, $result) = $self->__read_sock;
172 $$type_r = $type if $type_r;
175 confess "[$command] $result, ";
177 elsif ($type eq '+') {
180 elsif ($type eq '$') {
181 return if $result < 0;
182 return $self->__read_sock($result);
184 elsif ($type eq '*') {
187 push @list, $self->__read_response($command);
191 elsif ($type eq ':') {
195 confess "unknown answer type: $type ($result), ";
200 my ($self, $len) = @_;
201 my $sock = $self->{sock} || confess("Not connected to any server");
202 my $enc = $self->{encoding};
203 my $deb = $self->{debug};
204 my $rbuf = \($self->{rbuf});
206 my ($data, $type) = ('', '');
207 my $read_size = $self->{read_size};
208 $read_size = $len + 2 if defined $len && $len + 2 > $read_size;
211 ## Read NN bytes, strip \r\n at the end
213 if (length($$rbuf) >= $len + 2) {
214 $data = substr(substr($$rbuf, 0, $len + 2, ''), 0, -2);
218 ## No len, means line more, read until \r\n
219 elsif ($$rbuf =~ s/^(.)([^\015\012]*)\015\012//) {
220 ($type, $data) = ($1, $2);
224 my $bytes = sysread $sock, $$rbuf, $read_size, length $$rbuf;
225 confess("Error while reading from Redis server: $!")
226 unless defined $bytes;
227 confess("Redis server closed connection") unless $bytes;
230 $data = decode($enc, $data) if $enc;
231 warn "[RECV] '$type$data'" if $self->{debug};
233 return ($type, $data) if $type;
237 sub __can_read_sock {
239 my $sock = $self->{sock};
240 my $rbuf = \($self->{rbuf});
243 __fh_nonblocking($sock, 1);
244 my $bytes = sysread $sock, $$rbuf, $self->{read_size}, length $$rbuf;
245 __fh_nonblocking($sock, 0);
251 ### Copied from AnyEvent::Util
253 *__fh_nonblocking = ($^O eq 'MSWin32')
254 ? sub($$) { ioctl $_[0], 0x8004667e, pack "L", $_[1]; } # FIONBIO
255 : sub($$) { fcntl $_[0], F_SETFL, $_[1] ? O_NONBLOCK : 0; };
263 =head1 Connection Handling
271 $r->ping || die "no server?";
273 =head1 Commands operating on string values
277 $r->set( foo => 'bar' );
279 $r->setnx( foo => 42 );
283 my $value = $r->get( 'foo' );
287 my @values = $r->mget( 'foo', 'bar', 'baz' );
293 $r->incrby('tripplets', 3);
299 $r->decrby('tripplets', 3);
303 $r->exists( 'key' ) && print "got key!";
307 $r->del( 'key' ) || warn "key doesn't exist";
311 $r->type( 'key' ); # = string
313 =head1 Commands operating on the key space
317 my @keys = $r->keys( '*glob_pattern*' );
321 my $key = $r->randomkey;
325 my $ok = $r->rename( 'old-key', 'new-key', $new );
329 my $nr_keys = $r->dbsize;
331 =head1 Commands operating on lists
333 See also L<Redis::List> for tie interface.
337 $r->rpush( $key, $value );
341 $r->lpush( $key, $value );
349 my @list = $r->lrange( $key, $start, $end );
353 my $ok = $r->ltrim( $key, $start, $end );
357 $r->lindex( $key, $index );
361 $r->lset( $key, $index, $value );
365 my $modified_count = $r->lrem( $key, $count, $value );
369 my $value = $r->lpop( $key );
373 my $value = $r->rpop( $key );
375 =head1 Commands operating on sets
379 $r->sadd( $key, $member );
383 $r->srem( $key, $member );
387 my $elements = $r->scard( $key );
391 $r->sismember( $key, $member );
395 $r->sinter( $key1, $key2, ... );
399 my $ok = $r->sinterstore( $dstkey, $key1, $key2, ... );
401 =head1 Multiple databases handling commands
405 $r->select( $dbindex ); # 0 for new clients
409 $r->move( $key, $dbindex );
423 $r->sort("key BY pattern LIMIT start end GET pattern ASC|DESC ALPHA');
425 =head1 Persistence control commands
443 =head1 Remote server control commands
447 my $info_hash = $r->info;
451 Since Redis knows nothing about encoding, we are forcing utf-8 flag on all data received from Redis.
452 This change is introduced in 1.2001 version.
454 This allows us to round-trip utf-8 encoded characters correctly, but might be problem if you push
455 binary junk into Redis and expect to get it back without utf-8 flag turned on.
459 Dobrica Pavlinusic, C<< <dpavlin at rot13.org> >>
463 Please report any bugs or feature requests to C<bug-redis at rt.cpan.org>, or through
464 the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Redis>. I will be notified, and then you'll
465 automatically be notified of progress on your bug as I make changes.
472 You can find documentation for this module with the perldoc command.
479 You can also look for information at:
483 =item * RT: CPAN's request tracker
485 L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Redis>
487 =item * AnnoCPAN: Annotated CPAN documentation
489 L<http://annocpan.org/dist/Redis>
493 L<http://cpanratings.perl.org/d/Redis>
497 L<http://search.cpan.org/dist/Redis>
502 =head1 ACKNOWLEDGEMENTS
505 =head1 COPYRIGHT & LICENSE
507 Copyright 2009-2010 Dobrica Pavlinusic, all rights reserved.
509 This program is free software; you can redistribute it and/or modify it
510 under the same terms as Perl itself.