Skip to content

Commit

Permalink
Merge pull request #15 from amirreza8002/api
Browse files Browse the repository at this point in the history
completed the hash operation API
  • Loading branch information
amirreza8002 authored Dec 17, 2024
2 parents d97f56e + c295f5f commit 052d21b
Show file tree
Hide file tree
Showing 8 changed files with 685 additions and 9 deletions.
10 changes: 10 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
Version 1.0.0
-------------

Breaking change:
- floats are no longer serialized when passing to valkey (in theory shouldn't break anything)

New features:
- Added the missing hash methods, now all hash methods are supported except for ``hmset`` which is deprecated.
- hset: added ``mapping`` and ``items`` parameters for bulk operations.

Version 0.1.8
-------------

Expand Down
15 changes: 15 additions & 0 deletions django_valkey/async_cache/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,30 @@ class AsyncValkeyCache(BaseValkeyCache[AsyncDefaultClient, AValkey]):
sunionstore = BaseValkeyCache.asunionstore

hset = BaseValkeyCache.ahset
hsetnx = BaseValkeyCache.ahsetnx

hdel = BaseValkeyCache.ahdel
hdel_many = BaseValkeyCache.ahdel_many

hget = BaseValkeyCache.ahget
hgetall = BaseValkeyCache.ahgetall
hmget = BaseValkeyCache.ahmget

hincrby = BaseValkeyCache.ahincrby
hincrbyfloat = BaseValkeyCache.ahincrbyfloat

hlen = BaseValkeyCache.ahlen

hkeys = BaseValkeyCache.ahkeys

hexists = BaseValkeyCache.ahexists

hvals = BaseValkeyCache.ahvals

hstrlen = BaseValkeyCache.ahstrlen

hrandfield = BaseValkeyCache.ahrandfield

@omit_exception
async def set(self, *args, **kwargs):
return await self.client.aset(*args, **kwargs)
Expand Down
199 changes: 193 additions & 6 deletions django_valkey/async_cache/client/default.py
Original file line number Diff line number Diff line change
Expand Up @@ -1054,8 +1054,10 @@ async def touch(
async def hset(
self,
name: str,
key,
value,
key=None,
value=None,
mapping: dict | None = None,
items: list | None = None,
version: int | None = None,
client: AValkey | Any | None = None,
) -> int:
Expand All @@ -1064,13 +1066,38 @@ async def hset(
Returns the number of fields added to the hash.
"""
client = await self._get_client(write=True, client=client)
if key and value:
key = await self.make_key(key, version=version)
value = await self.encode(value)
if mapping:
mapping = {
await self.make_key(key): await self.encode(value)
for key, value in mapping.items()
}
if items:
items = [
await (self.encode if index & 1 else self.make_key)(item)
for index, item in enumerate(items)
]

return await client.hset(name, key, value, mapping=mapping, items=items)

nkey = await self.make_key(key, version)
nvalue = await self.encode(value)
ahset = hset

return await client.hset(name, nkey, nvalue)
async def hsetnx(
self,
name: str,
key,
value,
version: int | None = None,
client: AValkey | Any | None = None,
) -> int:
client = await self._get_client(write=True, client=client)
nkey = await self.make_key(key, version=version)
nvalue = await self.encode(value)
return await client.hsetnx(name, nkey, nvalue)

ahset = hset
ahsetnx = hsetnx

async def hdel(
self,
Expand All @@ -1089,6 +1116,109 @@ async def hdel(

ahdel = hdel

async def hdel_many(
self,
name: str,
keys: list,
version: int | None = None,
client: AValkey | Any | None = None,
) -> int:
client = await self._get_client(write=True, client=client)
nkeys = [await self.make_key(key) for key in keys]
return await client.hdel(name, *nkeys)

ahdel_many = hdel_many

async def hget(
self,
name: str,
key: str,
version: int | None = None,
client: AValkey | Any | None = None,
) -> str | None:
client = await self._get_client(write=False, client=client)
key = await self.make_key(key, version=version)
try:
value = await client.hget(name, key)
except _main_exceptions as e:
raise ConnectionInterrupted(connection=client) from e
if value is None:
return None
return await self.decode(value)

ahget = hget

async def hgetall(
self, name: str, client: AValkey | Any | None = None
) -> dict[str, str] | dict:
client = await self._get_client(write=False, client=client)
try:
_values = await client.hgetall(name)
except _main_exceptions as e:
raise ConnectionInterrupted(connection=client) from e

values = {}
for key, value in _values.items():
values[key.decode()] = await self.decode(value)
return values

ahgetall = hgetall

async def hmget(
self,
name: str,
keys: list,
version: int | None = None,
client: AValkey | Any | None = None,
) -> list:
client = await self._get_client(write=False, client=client)
nkeys = [await self.make_key(key, version=version) for key in keys]
try:
values = await client.hmget(name, nkeys)
except _main_exceptions as e:
raise ConnectionInterrupted(connection=client) from e

values = [await self.decode(val) for val in values]
return values

ahmget = hmget

async def hincrby(
self,
name: str,
key: str,
amount: int = 1,
version: int | None = None,
client: AValkey | Any | None = None,
) -> int:
client = await self._get_client(write=True, client=client)
nkey = await self.make_key(key, version=version)
try:
value = await client.hincrby(name, nkey, amount)
except _main_exceptions as e:
raise ConnectionInterrupted(connection=client) from e
return value

ahincrby = hincrby

async def hincrbyfloat(
self,
name: str,
key: str,
amount: float = 1.0,
version: int | None = None,
client: AValkey | Any | None = None,
) -> float:
client = await self._get_client(write=True, client=client)
nkey = await self.make_key(key, version=version)
try:
value = await client.hincrbyfloat(name, nkey, amount)
except _main_exceptions as e:
raise ConnectionInterrupted(connection=client) from e
return value

ahincrbyfloat = hincrbyfloat

async def hlen(self, name: str, client: AValkey | Any | None = None) -> int:
"""
Return the number of items in hash name.
Expand Down Expand Up @@ -1123,3 +1253,60 @@ async def hexists(
return await client.hexists(name, nkey)

ahexists = hexists

async def hvals(self, name: str, client: AValkey | Any | None = None) -> list:
client = await self._get_client(write=False, client=client)
try:
return [await self.decode(val) for val in await client.hvals(name)]
except _main_exceptions as e:
raise ConnectionInterrupted(connection=client) from e

ahvals = hvals

async def hstrlen(
self,
name: str,
key: KeyT,
version: int | None = None,
client: AValkey | Any | None = None,
) -> int:
client = await self._get_client(write=False, client=client)
nkey = await self.make_key(key, version=version)
try:
return await client.hstrlen(name, nkey)
except _main_exceptions as e:
raise ConnectionInterrupted(connection=client) from e

ahstrlen = hstrlen

async def hrandfield(
self,
name: str,
count: int | None = None,
withvalues: bool = False,
client: AValkey | None = None,
) -> str | list | None:
client = await self._get_client(write=False, client=client)
try:
result = await client.hrandfield(
key=name, count=count, withvalues=withvalues
)
except _main_exceptions as e:
raise ConnectionInterrupted(connection=client) from e

if not result:
return None
elif count and withvalues:
return [
(
await self.decode(val)
if index & 1
else self.reverse_key(val.decode())
)
for index, val in enumerate(result)
]
elif count:
return [self.reverse_key(val.decode()) for val in result]
return self.reverse_key(result.decode())

ahrandfield = hrandfield
80 changes: 80 additions & 0 deletions django_valkey/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,14 @@ def hset(self, *args, **kwargs) -> int:
async def ahset(self, *args, **kwargs) -> int:
return await self.client.hset(*args, **kwargs)

@omit_exception
def hsetnx(self, *args, **kwargs) -> int:
return self.client.hsetnx(*args, **kwargs)

@omit_exception
async def ahsetnx(self, *args, **kwargs) -> int:
return await self.client.hsetnx(*args, **kwargs)

@omit_exception
def hdel(self, *args, **kwargs) -> int:
return self.client.hdel(*args, **kwargs)
Expand All @@ -356,6 +364,54 @@ def hdel(self, *args, **kwargs) -> int:
async def ahdel(self, *args, **kwargs) -> int:
return await self.client.hdel(*args, **kwargs)

@omit_exception
def hdel_many(self, *args, **kwargs) -> int:
return self.client.hdel_many(*args, **kwargs)

@omit_exception
async def ahdel_many(self, *args, **kwargs) -> int:
return await self.client.ahdel_many(*args, **kwargs)

@omit_exception
def hget(self, *args, **kwargs) -> bytes | None:
return self.client.hget(*args, **kwargs)

@omit_exception
async def ahget(self, *args, **kwargs) -> str | None:
return await self.client.ahget(*args, **kwargs)

@omit_exception
def hgetall(self, *args, **kwargs) -> dict:
return self.client.hgetall(*args, **kwargs)

@omit_exception
async def ahgetall(self, *args, **kwargs) -> dict:
return await self.client.ahgetall(*args, **kwargs)

@omit_exception
def hmget(self, *args, **kwargs) -> dict:
return self.client.hmget(*args, **kwargs)

@omit_exception
async def ahmget(self, *args, **kwargs) -> dict:
return await self.client.ahmget(*args, **kwargs)

@omit_exception
def hincrby(self, *args, **kwargs) -> int:
return self.client.hincrby(*args, **kwargs)

@omit_exception
async def ahincrby(self, *args, **kwargs) -> int:
return await self.client.ahincrby(*args, **kwargs)

@omit_exception
def hincrbyfloat(self, *args, **kwargs) -> float:
return self.client.hincrbyfloat(*args, **kwargs)

@omit_exception
async def ahincrbyfloat(self, *args, **kwargs) -> float:
return await self.client.ahincrbyfloat(*args, **kwargs)

@omit_exception
def hlen(self, *args, **kwargs) -> int:
return self.client.hlen(*args, **kwargs)
Expand All @@ -379,3 +435,27 @@ def hexists(self, *args, **kwargs) -> bool:
@omit_exception
async def ahexists(self, *args, **kwargs) -> bool:
return await self.client.ahexists(*args, **kwargs)

@omit_exception
def hvals(self, *args, **kwargs) -> list:
return self.client.hvals(*args, **kwargs)

@omit_exception
async def ahvals(self, *args, **kwargs) -> list:
return await self.client.ahvals(*args, **kwargs)

@omit_exception
def hstrlen(self, *args, **kwargs) -> int:
return self.client.hstrlen(*args, **kwargs)

@omit_exception
async def ahstrlen(self, *args, **kwargs) -> int:
return await self.client.ahstrlen(*args, **kwargs)

@omit_exception
def hrandfield(self, *args, **kwargs) -> str | list:
return self.client.hrandfield(*args, **kwargs)

@omit_exception
async def ahrandfield(self, *args, **kwargs) -> str | list:
return await self.client.ahrandfield(*args, **kwargs)
Loading

0 comments on commit 052d21b

Please sign in to comment.