# ╔══════════════════════════════════════════════════════════════════╗ # ║ ║ # ║ +-+-+-+-+-+-+-+-+ ║ # ║ |H|e|x|a|H|o|s|t| ║ # ║ +-+-+-+-+-+-+-+-+ ║ # ║ ║ # ║ © 2026 HexaHost — All Rights Reserved ║ # ║ ║ # ║ discord ── https://discord.gg/hexahost ║ # ║ github ── https://github.com/theoneandonlymace ║ # ║ ║ # ╚══════════════════════════════════════════════════════════════════╝ from utils.db_paths import db_path as resolve_db_path import aiosqlite import asyncio import random from typing import Optional class Database: _instance: Optional['Database'] = None _lock: asyncio.Lock db_path: str db: Optional[aiosqlite.Connection] def __new__(cls, database_path: str | None = None): if cls._instance is None: cls._instance = super().__new__(cls) cls._instance.db_path = database_path or resolve_db_path('anti.db') cls._instance.db = None cls._instance._lock = asyncio.Lock() return cls._instance async def connect(self, timeout=30): async with self._lock: if self.db is None: self.db = await aiosqlite.connect(self.db_path, timeout=timeout) await self.db.execute('PRAGMA journal_mode=WAL;') await self.db.commit() return self.db async def ensure_connection(self): if self.db is None or not self.db.is_open: await self.connect() return self.db async def execute_with_retries(self, func, retries=5, delay=1): for attempt in range(retries): try: return await func() except aiosqlite.OperationalError as e: if 'database is locked' in str(e).lower(): sleep_time = delay * (2 ** attempt) + random.uniform(0, 1) print(f"Database is locked. Retryng in {sleep_time:.2f} seconds.....") await asyncio.sleep(sleep_time) else: raise raise Exception("Max retrys.") async def close(self): async with self._lock: if self.db is not None: await self.db.close() self.db = None