Files
Solo_bot/database/settings_cache.py
T

81 lines
2.4 KiB
Python

from __future__ import annotations
import threading
from datetime import datetime
from typing import Any
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from .models import Setting
class SettingsCache:
_cache: dict[str, dict[str, Any]]
_lock: threading.Lock
def __init__(self) -> None:
self._cache = {}
self._lock = threading.Lock()
@staticmethod
def _row_to_item(s: Setting) -> dict[str, Any]:
return {
"key": s.key,
"value": s.value,
"description": s.description,
"created_at": getattr(s, "created_at", None),
"updated_at": getattr(s, "updated_at", None),
}
async def load(self, session: AsyncSession) -> None:
result = await session.execute(select(Setting))
rows = result.scalars().all()
with self._lock:
self._cache.clear()
for s in rows:
self._cache[s.key] = self._row_to_item(s)
def get_all(self) -> list[dict[str, Any]]:
with self._lock:
return [dict(x) for x in self._cache.values()]
def get(self, key: str) -> dict[str, Any] | None:
with self._lock:
return dict(self._cache[key]) if key in self._cache else None
def update(
self,
key: str,
value: Any,
description: str | None = None,
created_at: datetime | None = None,
updated_at: datetime | None = None,
) -> None:
now = datetime.utcnow()
with self._lock:
if key in self._cache:
self._cache[key]["value"] = value
self._cache[key]["updated_at"] = updated_at if updated_at is not None else now
if description is not None:
self._cache[key]["description"] = description
else:
self._cache[key] = {
"key": key,
"value": value,
"description": description,
"created_at": created_at if created_at is not None else now,
"updated_at": updated_at if updated_at is not None else now,
}
def delete(self, key: str) -> None:
with self._lock:
self._cache.pop(key, None)
settings_cache = SettingsCache()
async def load(session: AsyncSession) -> None:
await settings_cache.load(session)