import os import aiosqlite from typing import Optional from logs.custom_logger import logger class DatabaseConnection: """Базовый класс для работы с базой данных.""" def __init__(self, db_path: str): self.db_path = os.path.abspath(db_path) self.logger = logger self.logger.info(f'Инициация базы данных: {self.db_path}') async def _get_connection(self): """Получение асинхронного соединения с базой данных.""" try: conn = await aiosqlite.connect(self.db_path) # Включаем поддержку внешних ключей await conn.execute("PRAGMA foreign_keys = ON") # Включаем WAL режим для лучшей производительности await conn.execute("PRAGMA journal_mode = WAL") await conn.execute("PRAGMA synchronous = NORMAL") await conn.execute("PRAGMA cache_size = 10000") await conn.execute("PRAGMA temp_store = MEMORY") return conn except Exception as e: self.logger.error(f"Ошибка при получении соединения: {e}") raise async def _execute_query(self, query: str, params: tuple = ()): """Выполнение запроса с автоматическим закрытием соединения.""" conn = None try: conn = await self._get_connection() result = await conn.execute(query, params) await conn.commit() return result except Exception as e: self.logger.error(f"Ошибка при выполнении запроса: {e}") raise finally: if conn: await conn.close() async def _execute_query_with_result(self, query: str, params: tuple = ()): """Выполнение запроса с результатом и автоматическим закрытием соединения.""" conn = None try: conn = await self._get_connection() result = await conn.execute(query, params) # Получаем все результаты сразу, чтобы можно было закрыть соединение rows = await result.fetchall() return rows except Exception as e: self.logger.error(f"Ошибка при выполнении запроса: {e}") raise finally: if conn: await conn.close() async def _execute_transaction(self, queries: list): """Выполнение транзакции с несколькими запросами.""" conn = None try: conn = await self._get_connection() for query, params in queries: await conn.execute(query, params) await conn.commit() except Exception as e: if conn: await conn.rollback() self.logger.error(f"Ошибка при выполнении транзакции: {e}") raise finally: if conn: await conn.close() async def check_database_integrity(self): """Проверяет целостность базы данных и очищает WAL файлы.""" conn = None try: conn = await self._get_connection() result = await conn.execute("PRAGMA integrity_check") integrity_result = await result.fetchone() if integrity_result and integrity_result[0] == "ok": self.logger.info("Проверка целостности базы данных прошла успешно") await conn.execute("PRAGMA wal_checkpoint(TRUNCATE)") self.logger.info("WAL файлы очищены") else: self.logger.warning(f"Проблемы с целостностью базы данных: {integrity_result}") except Exception as e: self.logger.error(f"Ошибка при проверке целостности базы данных: {e}") raise finally: if conn: await conn.close() async def cleanup_wal_files(self): """Очищает WAL файлы и переключает на DELETE режим для предотвращения проблем с I/O.""" conn = None try: conn = await self._get_connection() await conn.execute("PRAGMA journal_mode=DELETE") await conn.execute("PRAGMA journal_mode=WAL") self.logger.info("WAL файлы очищены и режим восстановлен") except Exception as e: self.logger.error(f"Ошибка при очистке WAL файлов: {e}") raise finally: if conn: await conn.close()