Skip to content

Commit c148ede

Browse files
committed
* fix for #21, make only the "db" argument of select() required. If host and port aren't specified, the host/port options on the existing connection are used.
* added HINCRBY support
1 parent 97ed01d commit c148ede

File tree

4 files changed

+50
-11
lines changed

4 files changed

+50
-11
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
11
redis-py
2-
--------
2+
========
33

44
This is the Python interface to the Redis key-value store.
55

66

77
Usage
8-
=====
8+
-----
99

1010
>>> import redis
1111
>>> r = redis.Redis(host='localhost', port=6379, db=0)
1212
>>> r.set('foo', 'bar') # or r['foo'] = 'bar'
1313
True
14-
>>> r.get('foo')
14+
>>> r.get('foo') # or r['foo']
1515
'bar'
1616

1717
For a complete list of commands, check out the list of Redis commands here:
1818
http://code.google.com/p/redis/wiki/CommandReference
1919

2020

2121
Author
22-
======
22+
------
2323

2424
redis-py is developed and maintained by Andy McCurdy ([email protected]).
2525
It can be found here: http://github.com/andymccurdy/redis-py

redis/client.py

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,8 @@ def __init__(self, host='localhost', port=6379,
224224
charset='utf-8', errors='strict'):
225225
self.encoding = charset
226226
self.errors = errors
227-
self.select(host, port, db, password, socket_timeout)
227+
self.connection = None
228+
self.select(db, host, port, password, socket_timeout)
228229

229230
#### Legacty accessors of connection information ####
230231
def _get_host(self):
@@ -375,14 +376,28 @@ def _setup_connection(self):
375376
raise AuthenticationError("Invalid Password")
376377
self.format_inline('SELECT', self.connection.db)
377378

378-
def select(self, host, port, db, password=None, socket_timeout=None):
379+
def select(self, db, host=None, port=None, password=None,
380+
socket_timeout=None):
379381
"""
380-
Switch to a different database on the current host/port
382+
Switch to a different Redis connection.
383+
384+
If the host and port aren't provided and there's an existing
385+
connection, use the existing connection's host and port instead.
381386
382387
Note this method actually replaces the underlying connection object
383388
prior to issuing the SELECT command. This makes sure we protect
384389
the thread-safe connections
385390
"""
391+
if host is None:
392+
if self.connection is None:
393+
raise RedisError("A valid hostname or IP address "
394+
"must be specified")
395+
host = self.connection.host
396+
if port is None:
397+
if self.connection is None:
398+
raise RedisError("A valid port must be specified")
399+
port = self.connection.port
400+
386401
self.connection = self.get_connection(
387402
host, port, db, password, socket_timeout)
388403

@@ -939,6 +954,10 @@ def hgetall(self, name):
939954
"Return a Python dict of the hash's name/value pairs"
940955
return self.format_inline('HGETALL', name)
941956

957+
def hincrby(self, name, key, amount=1):
958+
"Increment the value of ``key`` in hash ``name`` by ``amount``"
959+
return self.format_inline('HINCRBY', name, key, amount)
960+
942961
def hkeys(self, name):
943962
"Return the list of keys within hash ``name``"
944963
return self.format_inline('HKEYS', name)
@@ -1045,6 +1064,6 @@ def execute(self):
10451064
self.connection.disconnect()
10461065
return self._execute(stack)
10471066

1048-
def select(self, host, port, db):
1067+
def select(self, *args, **kwargs):
10491068
raise RedisError("Cannot select a different database from a pipeline")
10501069

tests/connection_pool.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@ def test_multiple_connections(self):
1212

1313
# if one o them switches, they should have
1414
# separate conncetion objects
15-
r2.select('localhost', 6379, db=10)
15+
r2.select(db=10, host='localhost', port=6379)
1616
self.assertNotEqual(r1.connection, r2.connection)
1717

1818
conns = [r1.connection, r2.connection]
1919
conns.sort()
2020

2121
# but returning to the original state shares the object again
22-
r2.select('localhost', 6379, db=9)
22+
r2.select(db=9, host='localhost', port=6379)
2323
self.assertEquals(r1.connection, r2.connection)
2424

2525
# the connection manager should still have just 2 connections

tests/server_commands.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,8 @@ def test_lrem(self):
272272
self.assertEquals(self.client.lrem('a', 'a', 1), 1)
273273
self.assertEquals(self.client.lrange('a', 0, 3), ['a', 'a', 'a'])
274274
self.assertEquals(self.client.lrem('a', 'a'), 3)
275-
self.assertEquals(self.client.lrange('a', 0, 1), [])
275+
# remove all the elements in the list means the key is deleted
276+
self.assertEquals(self.client.lrange('a', 0, 1), None)
276277

277278
def test_lset(self):
278279
# no key
@@ -755,6 +756,25 @@ def test_hgetall(self):
755756
remote_hash = self.client.hgetall('a')
756757
self.assertEquals(h, remote_hash)
757758

759+
def test_hincrby(self):
760+
# key is not a hash
761+
self.client['a'] = 'a'
762+
self.assertRaises(redis.ResponseError, self.client.hincrby, 'a', 'a1')
763+
del self.client['a']
764+
# no key should create the hash and incr the key's value to 1
765+
self.assertEquals(self.client.hincrby('a', 'a1'), 1)
766+
# real logic
767+
self.assertEquals(self.client.hincrby('a', 'a1'), 2)
768+
self.assertEquals(self.client.hincrby('a', 'a1', amount=2), 4)
769+
# negative values decrement
770+
self.assertEquals(self.client.hincrby('a', 'a1', amount=-3), 1)
771+
# hash that exists, but key that doesn't
772+
self.assertEquals(self.client.hincrby('a', 'a2', amount=3), 3)
773+
# finally a key that's not an int
774+
self.client.hset('a', 'a3', 'foo')
775+
self.assertEquals(self.client.hincrby('a', 'a3'), 1)
776+
777+
758778

759779
def test_hkeys(self):
760780
# key is not a hash

0 commit comments

Comments
 (0)