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
73 my $sock = $self->{sock} || confess("Not connected to any server");
74 my $enc = $self->{encoding};
75 my $deb = $self->{debug};
77 my $command = $AUTOLOAD;
79 $self->__is_valid_command($command);
81 $self->__send_command($command, @_);
83 return $self->__read_response($command);
87 ### Commands with extra logic
91 $self->__send_command('QUIT');
93 close(delete $self->{sock}) || confess("Can't close socket: $!");
101 $self->__is_valid_command('INFO');
103 $self->__send_command('INFO');
105 my $info = $self->__read_response('INFO');
107 return {map { split(/:/, $_, 2) } split(/\r\n/, $info)};
112 $self->__is_valid_command('KEYS');
114 $self->__send_command('KEYS', @_);
116 my @keys = $self->__read_response('INFO', \my $type);
117 return @keys if $type eq '*';
119 ## Support redis <= 1.2.6
120 return split(/\s/, $keys[0]) if $keys[0];
126 sub __is_valid_command {
127 my ($self, $cmd) = @_;
129 return unless $self->{is_subscriber};
130 return if $cmd =~ /^P?(UN)?SUBSCRIBE$/;
131 confess("Cannot use command '$cmd' while in SUBSCRIBE mode, ");
135 ### Socket operations
139 my $enc = $self->{encoding};
140 my $deb = $self->{debug};
142 warn "[SEND] $cmd ", Dumper([@_]) if $deb;
144 ## Encode command using multi-bulk format
145 my $n_elems = scalar(@_) + 1;
146 my $buf = "\*$n_elems\r\n";
147 for my $elem ($cmd, @_) {
148 my $bin = $enc ? encode($enc, $elem) : $elem;
149 $buf .= defined($bin) ? '$' . length($bin) . "\r\n$bin\r\n" : "\$-1\r\n";
152 ## Send command, take care for partial writes
153 warn "[SEND RAW] $buf" if $deb;
154 my $sock = $self->{sock} || confess("Not connected to any server");
156 my $len = syswrite $sock, $buf, length $buf;
157 confess("Could not write to Redis server: $!")
159 substr $buf, 0, $len, "";
165 sub __read_response {
166 my ($self, $command, $type_r) = @_;
168 my ($type, $result) = $self->__read_sock;
169 $$type_r = $type if $type_r;
172 confess "[$command] $result, ";
174 elsif ($type eq '+') {
177 elsif ($type eq '$') {
178 return if $result < 0;
179 return $self->__read_sock($result);
181 elsif ($type eq '*') {
184 push @list, $self->__read_response($command);
188 elsif ($type eq ':') {
192 confess "unknown answer type: $type ($result), ";
197 my ($self, $len) = @_;
198 my $sock = $self->{sock} || confess("Not connected to any server");
199 my $enc = $self->{encoding};
200 my $deb = $self->{debug};
201 my $rbuf = \($self->{rbuf});
203 my ($data, $type) = ('', '');
204 my $read_size = defined $len ? $len + 2 : 8192;
206 ## Read NN bytes, strip \r\n at the end
208 if (length($$rbuf) >= $len + 2) {
209 $data = substr(substr($$rbuf, 0, $len + 2, ''), 0, -2);
213 ## No len, means line more, read until \r\n
214 elsif ($$rbuf =~ s/^(.)([^\015\012]*)\015\012//) {
215 ($type, $data) = ($1, $2);
219 my $bytes = sysread $sock, $$rbuf, $read_size, length $$rbuf;
220 confess("Error while reading from Redis server: $!")
221 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.