1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
|
from typing import Iterable, Tuple, Optional, Any, Dict
from fakeredis import _msgs as msgs
from fakeredis._helpers import current_time
class Hash:
DECODE_ERROR = msgs.INVALID_HASH_MSG
redis_type = b"hash"
def __init__(self, *args: Any, **kwargs: Any) -> None:
super().__init__(*args, **kwargs)
self._expirations: Dict[bytes, int] = dict()
self._values: Dict[bytes, Any] = dict()
def _expire_keys(self) -> None:
removed = []
now = current_time()
for k in self._expirations:
if self._expirations[k] < now:
self._values.pop(k, None)
removed.append(k)
for k in removed:
self._expirations.pop(k, None)
def set_key_expireat(self, key: bytes, when_ms: int) -> int:
now = current_time()
if when_ms <= now:
self._values.pop(key, None)
self._expirations.pop(key, None)
return 2
self._expirations[key] = when_ms
return 1
def clear_key_expireat(self, key: bytes) -> bool:
return self._expirations.pop(key, None) is not None
def get_key_expireat(self, key: bytes) -> Optional[int]:
self._expire_keys()
return self._expirations.get(key, None)
def __getitem__(self, key: bytes) -> Any:
self._expire_keys()
return self._values.get(key)
def __contains__(self, key: bytes) -> bool:
self._expire_keys()
return self._values.__contains__(key)
def __setitem__(self, key: bytes, value: Any) -> None:
self._expirations.pop(key, None)
self._values[key] = value
def __delitem__(self, key: bytes) -> None:
self._values.pop(key, None)
self._expirations.pop(key, None)
def __len__(self) -> int:
return len(self._values)
def __iter__(self) -> Iterable[bytes]:
return iter(self._values)
def get(self, key: bytes, default: Any = None) -> Any:
self._expire_keys()
return self._values.get(key, default)
def keys(self) -> Iterable[bytes]:
self._expire_keys()
return self._values.keys()
def values(self) -> Iterable[Any]:
return [v for k, v in self.items()]
def items(self) -> Iterable[Tuple[bytes, Any]]:
self._expire_keys()
return self._values.items()
def update(self, values: Dict[bytes, Any], clear_expiration: bool) -> None:
self._expire_keys()
if clear_expiration:
for k in values.keys():
self.clear_key_expireat(k)
self._values.update(values)
def getall(self) -> Dict[bytes, Any]:
self._expire_keys()
return self._values.copy()
def pop(self, key: bytes, d: Any = None) -> Any:
self._expire_keys()
return self._values.pop(key, d)
|