111 lines
3.4 KiB
Python
111 lines
3.4 KiB
Python
from abc import ABC
|
|
from logging import Logger
|
|
from typing import Optional, Any, Dict
|
|
|
|
from bson import ObjectId
|
|
from libbot.cache.classes import Cache
|
|
|
|
from classes.abstract import Cacheable
|
|
from modules.utils import get_logger
|
|
|
|
logger: Logger = get_logger(__name__)
|
|
|
|
|
|
class BaseCacheable(Cacheable, ABC):
|
|
"""Base implementation of Cacheable used by all cachable classes."""
|
|
|
|
_id: ObjectId
|
|
|
|
async def _set(self, cache: Optional[Cache] = None, **kwargs: Any) -> None:
|
|
for key, value in kwargs.items():
|
|
if not hasattr(self, key):
|
|
raise AttributeError()
|
|
|
|
setattr(self, key, value)
|
|
|
|
await self.__collection__.update_one({"_id": self._id}, {"$set": kwargs})
|
|
|
|
self._update_cache(cache)
|
|
|
|
logger.info("Set attributes of %s to %s", self._id, kwargs)
|
|
|
|
async def _remove(self, *args: str, cache: Optional[Cache] = None) -> None:
|
|
attributes: Dict[str, Any] = {}
|
|
|
|
for key in args:
|
|
if not hasattr(self, key):
|
|
raise AttributeError()
|
|
|
|
default_value: Any = self.get_default_value(key)
|
|
|
|
setattr(self, key, default_value)
|
|
|
|
attributes[key] = default_value
|
|
|
|
await self.__collection__.update_one({"_id": self._id}, {"$set": attributes})
|
|
|
|
self._update_cache(cache)
|
|
|
|
logger.info("Reset attributes %s of %s to default values", args, self._id)
|
|
|
|
def _update_cache(self, cache: Optional[Cache] = None) -> None:
|
|
if cache is None:
|
|
return
|
|
|
|
object_dict: Dict[str, Any] = self.to_dict(json_compatible=True)
|
|
|
|
if object_dict is not None:
|
|
cache.set_json(self._get_cache_key(), object_dict)
|
|
else:
|
|
self._delete_cache(cache)
|
|
|
|
def _delete_cache(self, cache: Optional[Cache] = None) -> None:
|
|
if cache is None:
|
|
return
|
|
|
|
cache.delete(self._get_cache_key())
|
|
|
|
async def update(
|
|
self,
|
|
cache: Optional[Cache] = None,
|
|
**kwargs: Any,
|
|
) -> None:
|
|
"""Update attribute(s) on the object and save the updated entry into the database.
|
|
|
|
Args:
|
|
cache (:obj:`Cache`, optional): Cache engine that will be used to update the cache.
|
|
**kwargs (Any): Mapping of attributes in format `attribute_name=attribute_value` to update.
|
|
|
|
Raises:
|
|
AttributeError: Provided attribute does not exist in the class.
|
|
"""
|
|
await self._set(cache=cache, **kwargs)
|
|
|
|
async def reset(
|
|
self,
|
|
*args: str,
|
|
cache: Optional[Cache] = None,
|
|
) -> None:
|
|
"""Remove attribute(s) on the object, replace them with a default value and save the updated entry into the database.
|
|
|
|
Args:
|
|
*args (str): List of attributes to remove.
|
|
cache (:obj:`Cache`, optional): Cache engine that will be used to update the cache.
|
|
|
|
Raises:
|
|
AttributeError: Provided attribute does not exist in the class.
|
|
"""
|
|
await self._remove(*args, cache=cache)
|
|
|
|
async def purge(self, cache: Optional[Cache] = None) -> None:
|
|
"""Completely remove object data from database. Currently only removes the record from a respective collection.
|
|
|
|
Args:
|
|
cache (:obj:`Cache`, optional): Cache engine that will be used to update the cache.
|
|
"""
|
|
await self.__collection__.delete_one({"_id": self._id})
|
|
|
|
self._delete_cache(cache)
|
|
|
|
logger.info("Purged %s from the database", self._id)
|