import os import aiosqlite from datetime import datetime from typing import Optional, List, Dict, Any, Tuple from logs.custom_logger import logger class AsyncBotDB: """Асинхронный класс для работы с базой данных.""" 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: # Используем connect вместо connect с контекстным менеджером 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 create_tables(self): """Создание таблиц в базе данных.""" conn = None try: conn = await self._get_connection() # Таблица пользователей await conn.execute(''' CREATE TABLE IF NOT EXISTS our_users ( id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER UNIQUE NOT NULL, first_name TEXT NOT NULL, full_name TEXT NOT NULL, username TEXT, is_bot BOOLEAN DEFAULT FALSE, language_code TEXT DEFAULT 'ru', emoji TEXT DEFAULT '😊', has_stickers BOOLEAN DEFAULT FALSE, date_added TEXT NOT NULL, date_changed TEXT NOT NULL ) ''') # Таблица черного списка await conn.execute(''' CREATE TABLE IF NOT EXISTS blacklist ( id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER UNIQUE NOT NULL, user_name TEXT, message_for_user TEXT, date_to_unban TEXT, created_at TEXT DEFAULT CURRENT_TIMESTAMP ) ''') # Таблица сообщений пользователей await conn.execute(''' CREATE TABLE IF NOT EXISTS user_messages ( id INTEGER PRIMARY KEY AUTOINCREMENT, message_text TEXT NOT NULL, user_id INTEGER NOT NULL, message_id INTEGER UNIQUE NOT NULL, date TEXT NOT NULL, FOREIGN KEY (user_id) REFERENCES our_users (user_id) ) ''') # Таблица постов из Telegram await conn.execute(''' CREATE TABLE IF NOT EXISTS post_from_telegram_suggest ( id INTEGER PRIMARY KEY AUTOINCREMENT, message_id INTEGER UNIQUE NOT NULL, text TEXT NOT NULL, author_id INTEGER NOT NULL, helper_text_message_id INTEGER, created_at TEXT NOT NULL, FOREIGN KEY (author_id) REFERENCES our_users (user_id) ) ''') # Таблица контента постов (создаем ПЕРЕД таблицей связей) await conn.execute(''' CREATE TABLE IF NOT EXISTS content_post_from_telegram ( id INTEGER PRIMARY KEY AUTOINCREMENT, message_id INTEGER UNIQUE NOT NULL, content_name TEXT NOT NULL, content_type TEXT NOT NULL ) ''') # Таблица связи сообщений с контентом await conn.execute(''' CREATE TABLE IF NOT EXISTS message_link_to_content ( id INTEGER PRIMARY KEY AUTOINCREMENT, post_id INTEGER NOT NULL, message_id INTEGER NOT NULL, FOREIGN KEY (post_id) REFERENCES post_from_telegram_suggest (message_id), FOREIGN KEY (message_id) REFERENCES content_post_from_telegram (message_id) ) ''') # Таблица администраторов await conn.execute(''' CREATE TABLE IF NOT EXISTS admins ( id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER UNIQUE NOT NULL, role TEXT NOT NULL DEFAULT 'admin', created_at TEXT DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (user_id) REFERENCES our_users (user_id) ) ''') # Таблица миграций await conn.execute(''' CREATE TABLE IF NOT EXISTS migrations ( id INTEGER PRIMARY KEY AUTOINCREMENT, version INTEGER UNIQUE NOT NULL, script_name TEXT NOT NULL, created_at TEXT DEFAULT CURRENT_TIMESTAMP ) ''') # Таблица аудио сообщений await conn.execute(''' CREATE TABLE IF NOT EXISTS audio_message_reference ( id INTEGER PRIMARY KEY AUTOINCREMENT, file_name TEXT NOT NULL, author_id INTEGER NOT NULL, date_added TEXT NOT NULL, listen_count INTEGER DEFAULT 0, file_id TEXT NOT NULL, FOREIGN KEY (author_id) REFERENCES our_users (user_id) ) ''') # Таблица прослушивания аудио await conn.execute(''' CREATE TABLE IF NOT EXISTS listen_audio_users ( id INTEGER PRIMARY KEY AUTOINCREMENT, file_name TEXT NOT NULL, user_id INTEGER NOT NULL, is_listen BOOLEAN DEFAULT FALSE, FOREIGN KEY (user_id) REFERENCES our_users (user_id) ) ''') # Таблица для voice bot await conn.execute(''' CREATE TABLE IF NOT EXISTS audio_moderate ( id INTEGER PRIMARY KEY AUTOINCREMENT, message_id INTEGER UNIQUE NOT NULL, user_id INTEGER NOT NULL, FOREIGN KEY (user_id) REFERENCES our_users (user_id) ) ''') await conn.commit() self.logger.info("Таблицы успешно созданы") except Exception as e: self.logger.error(f"Ошибка при создании таблиц: {e}") raise finally: if conn: await conn.close() async def user_exists(self, user_id: int) -> bool: """Проверка существования пользователя.""" conn = None try: conn = await self._get_connection() async with conn.execute("SELECT 1 FROM our_users WHERE user_id = ?", (user_id,)) as cursor: result = await cursor.fetchone() return bool(result) except Exception as e: self.logger.error(f"Ошибка при проверке существования пользователя: {e}") raise finally: if conn: await conn.close() async def add_new_user(self, user_id: int, first_name: str, full_name: str, username: str = None, is_bot: bool = False, language_code: str = "ru", emoji: str = "😊"): """Добавление нового пользователя.""" conn = None try: date_added = datetime.now().strftime("%d-%m-%Y %H:%M:%S") date_changed = datetime.now().strftime("%d-%m-%Y %H:%M:%S") conn = await self._get_connection() await conn.execute( "INSERT INTO our_users (user_id, first_name, full_name, username, is_bot, " "language_code, emoji, date_added, date_changed) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", (user_id, first_name, full_name, username, is_bot, language_code, emoji, date_added, date_changed) ) await conn.commit() self.logger.info(f"Новый пользователь добавлен: {user_id}") except Exception as e: self.logger.error(f"Ошибка при добавлении пользователя: {e}") raise finally: if conn: await conn.close() async def get_user_info(self, user_id: int) -> Optional[Dict[str, Any]]: """Получение информации о пользователе.""" conn = None try: conn = await self._get_connection() async with conn.execute( "SELECT username, full_name, has_stickers, emoji FROM our_users WHERE user_id = ?", (user_id,) ) as cursor: result = await cursor.fetchone() if result: return { 'username': result[0], 'full_name': result[1], 'has_stickers': bool(result[2]) if result[2] is not None else False, 'emoji': result[3] } return None except Exception as e: self.logger.error(f"Ошибка при получении информации о пользователе: {e}") raise finally: if conn: await conn.close() async def update_user_date(self, user_id: int): """Обновление даты последнего изменения пользователя.""" conn = None try: date_changed = datetime.now().strftime("%d-%m-%Y %H:%M:%S") conn = await self._get_connection() await conn.execute( "UPDATE our_users SET date_changed = ? WHERE user_id = ?", (date_changed, user_id) ) await conn.commit() except Exception as e: self.logger.error(f"Ошибка при обновлении даты пользователя: {e}") raise finally: if conn: await conn.close() async def update_user_info(self, user_id: int, username: str = None, full_name: str = None): """Обновление информации о пользователе.""" conn = None try: conn = await self._get_connection() if username and full_name: await conn.execute( "UPDATE our_users SET username = ?, full_name = ? WHERE user_id = ?", (username, full_name, user_id) ) elif username: await conn.execute( "UPDATE our_users SET username = ? WHERE user_id = ?", (username, user_id) ) elif full_name: await conn.execute( "UPDATE our_users SET full_name = ? WHERE user_id = ?", (full_name, user_id) ) await conn.commit() except Exception as e: self.logger.error(f"Ошибка при обновлении информации о пользователе: {e}") raise finally: if conn: await conn.close() async def update_user_emoji(self, user_id: int, emoji: str): """Обновление эмодзи пользователя.""" conn = None try: conn = await self._get_connection() await conn.execute( "UPDATE our_users SET emoji = ? WHERE user_id = ?", (emoji, user_id) ) await conn.commit() except Exception as e: self.logger.error(f"Ошибка при обновлении эмодзи: {e}") raise finally: if conn: await conn.close() async def get_user_emoji(self, user_id: int) -> Optional[str]: """Получение эмодзи пользователя.""" conn = None try: conn = await self._get_connection() async with conn.execute( "SELECT emoji FROM our_users WHERE user_id = ?", (user_id,) ) as cursor: result = await cursor.fetchone() return result[0] if result else None except Exception as e: self.logger.error(f"Ошибка при получении эмодзи: {e}") raise finally: if conn: await conn.close() async def check_emoji_exists(self, emoji: str) -> bool: """Проверка существования эмодзи.""" conn = None try: conn = await self._get_connection() async with conn.execute( "SELECT 1 FROM our_users WHERE emoji = ?", (emoji,) ) as cursor: result = await cursor.fetchone() return bool(result) except Exception as e: self.logger.error(f"Ошибка при проверке эмодзи: {e}") raise finally: if conn: await conn.close() async def update_stickers_info(self, user_id: int): """Обновление информации о стикерах.""" conn = None try: conn = await self._get_connection() await conn.execute( "UPDATE our_users SET has_stickers = 1 WHERE user_id = ?", (user_id,) ) await conn.commit() except Exception as e: self.logger.error(f"Ошибка при обновлении информации о стикерах: {e}") raise finally: if conn: await conn.close() async def get_stickers_info(self, user_id: int) -> bool: """Получение информации о стикерах.""" conn = None try: conn = await self._get_connection() async with conn.execute( "SELECT has_stickers FROM our_users WHERE user_id = ?", (user_id,) ) as cursor: result = await cursor.fetchone() return bool(result[0]) if result and result[0] is not None else False except Exception as e: self.logger.error(f"Ошибка при получении информации о стикерах: {e}") return False finally: if conn: await conn.close() async def add_message(self, message_text: str, user_id: int, message_id: int): """Добавление сообщения пользователя.""" conn = None try: date = datetime.now().strftime("%d-%m-%Y %H:%M:%S") conn = await self._get_connection() await conn.execute( "INSERT INTO user_messages (message_text, user_id, message_id, date) VALUES (?, ?, ?, ?)", (message_text, user_id, message_id, date) ) await conn.commit() except Exception as e: self.logger.error(f"Ошибка при добавлении сообщения: {e}") raise finally: if conn: await conn.close() async def add_post(self, message_id: int, text: str, author_id: int): """Добавление поста.""" conn = None try: created_at = datetime.now().strftime("%d-%m-%Y %H:%M:%S") conn = await self._get_connection() await conn.execute( "INSERT INTO post_from_telegram_suggest (message_id, text, author_id, created_at) VALUES (?, ?, ?, ?)", (message_id, text, author_id, created_at) ) await conn.commit() except Exception as e: self.logger.error(f"Ошибка при добавлении поста: {e}") raise finally: if conn: await conn.close() async def update_helper_message(self, message_id: int, helper_message_id: int): """Обновление helper сообщения.""" conn = None try: conn = await self._get_connection() await conn.execute( "UPDATE post_from_telegram_suggest SET helper_text_message_id = ? WHERE message_id = ?", (helper_message_id, message_id) ) await conn.commit() except Exception as e: self.logger.error(f"Ошибка при обновлении helper сообщения: {e}") raise finally: if conn: await conn.close() async def add_post_content(self, post_id: int, message_id: int, content_name: str, content_type: str): """Добавление контента поста.""" conn = None try: conn = await self._get_connection() # Сначала добавляем связь await conn.execute( "INSERT INTO message_link_to_content (post_id, message_id) VALUES (?, ?)", (post_id, message_id) ) # Затем добавляем контент await conn.execute( "INSERT INTO content_post_from_telegram (message_id, content_name, content_type) VALUES (?, ?, ?)", (message_id, content_name, content_type) ) await conn.commit() except Exception as e: self.logger.error(f"Ошибка при добавлении контента поста: {e}") raise finally: if conn: await conn.close() async def get_post_content(self, last_post_id: int) -> List: """Получение контента поста.""" conn = None try: conn = await self._get_connection() async with conn.execute(""" SELECT cpft.content_name, cpft.content_type FROM post_from_telegram_suggest pft JOIN message_link_to_content mltc ON pft.message_id = mltc.post_id JOIN content_post_from_telegram cpft ON cpft.message_id = mltc.message_id WHERE pft.helper_text_message_id = ? """, (last_post_id,)) as cursor: return await cursor.fetchall() except Exception as e: self.logger.error(f"Ошибка при получении контента поста: {e}") raise finally: if conn: await conn.close() async def get_post_text(self, last_post_id: int) -> Optional[str]: """Получение текста поста.""" conn = None try: conn = await self._get_connection() async with conn.execute( "SELECT text FROM post_from_telegram_suggest WHERE helper_text_message_id = ?", (last_post_id,) ) as cursor: result = await cursor.fetchone() return result[0] if result else None except Exception as e: self.logger.error(f"Ошибка при получении текста поста: {e}") raise finally: if conn: await conn.close() async def get_post_ids(self, last_post_id: int) -> List: """Получение ID постов.""" conn = None try: conn = await self._get_connection() async with conn.execute(""" SELECT mltc.message_id FROM post_from_telegram_suggest pft JOIN message_link_to_content mltc ON pft.message_id = mltc.post_id WHERE pft.helper_text_message_id = ? """, (last_post_id,)) as cursor: result = await cursor.fetchall() return [row[0] for row in result] except Exception as e: self.logger.error(f"Ошибка при получении ID постов: {e}") raise finally: if conn: await conn.close() async def get_author_id_by_message(self, message_id: int) -> Optional[int]: """Получение ID автора по message_id.""" conn = None try: conn = await self._get_connection() async with conn.execute( "SELECT author_id FROM post_from_telegram_suggest WHERE message_id = ?", (message_id,) ) as cursor: result = await cursor.fetchone() return result[0] if result else None except Exception as e: self.logger.error(f"Ошибка при получении ID автора: {e}") raise finally: if conn: await conn.close() async def get_author_id_by_helper_message(self, helper_message_id: int) -> Optional[int]: """Получение ID автора по helper_message_id.""" conn = None try: conn = await self._get_connection() async with conn.execute( "SELECT author_id FROM post_from_telegram_suggest WHERE helper_text_message_id = ?", (helper_message_id,) ) as cursor: result = await cursor.fetchone() return result[0] if result else None except Exception as e: self.logger.error(f"Ошибка при получении ID автора по helper сообщению: {e}") raise finally: if conn: await conn.close() async def get_last_users(self, limit: int = 30) -> List: """Получение последних пользователей.""" conn = None try: conn = await self._get_connection() async with conn.execute( "SELECT full_name, user_id FROM our_users ORDER BY date_changed DESC LIMIT ?", (limit,) ) as cursor: return await cursor.fetchall() except Exception as e: self.logger.error(f"Ошибка при получении последних пользователей: {e}") raise finally: if conn: await conn.close() async def get_user_by_message_id(self, message_id: int) -> Optional[int]: """Получение пользователя по message_id.""" conn = None try: conn = await self._get_connection() async with conn.execute( "SELECT user_id FROM user_messages WHERE message_id = ?", (message_id,) ) as cursor: result = await cursor.fetchone() return result[0] if result else None except Exception as e: self.logger.error(f"Ошибка при получении пользователя по message_id: {e}") raise finally: if conn: await conn.close() # Методы для работы с черным списком async def add_to_blacklist(self, user_id: int, user_name: str = None, message_for_user: str = None, date_to_unban: str = None): """Добавление пользователя в черный список.""" conn = None try: conn = await self._get_connection() await conn.execute( "INSERT INTO blacklist (user_id, user_name, message_for_user, date_to_unban) VALUES (?, ?, ?, ?)", (user_id, user_name, message_for_user, date_to_unban) ) await conn.commit() except Exception as e: self.logger.error(f"Ошибка при добавлении в черный список: {e}") raise finally: if conn: await conn.close() async def remove_from_blacklist(self, user_id: int) -> bool: """Удаление пользователя из черного списка.""" conn = None try: conn = await self._get_connection() await conn.execute("DELETE FROM blacklist WHERE user_id = ?", (user_id,)) await conn.commit() return True except Exception as e: self.logger.error(f"Ошибка при удалении из черного списка: {e}") return False finally: if conn: await conn.close() async def check_blacklist(self, user_id: int) -> bool: """Проверка пользователя в черном списке.""" conn = None try: conn = await self._get_connection() async with conn.execute( "SELECT 1 FROM blacklist WHERE user_id = ?", (user_id,) ) as cursor: result = await cursor.fetchone() return bool(result) except Exception as e: self.logger.error(f"Ошибка при проверке черного списка: {e}") raise finally: if conn: await conn.close() async def get_blacklist_users(self, offset: int = 0, limit: int = 10) -> List: """Получение пользователей из черного списка.""" conn = None try: conn = await self._get_connection() async with conn.execute( "SELECT user_name, user_id, message_for_user, date_to_unban FROM blacklist LIMIT ?, ?", (offset, limit) ) as cursor: return await cursor.fetchall() except Exception as e: self.logger.error(f"Ошибка при получении пользователей из черного списка: {e}") raise finally: if conn: await conn.close() async def get_blacklist_count(self) -> int: """Получение количества пользователей в черном списке.""" conn = None try: conn = await self._get_connection() async with conn.execute("SELECT COUNT(*) FROM blacklist") as cursor: result = await cursor.fetchone() return result[0] if result else 0 except Exception as e: self.logger.error(f"Ошибка при получении количества пользователей в черном списке: {e}") raise finally: if conn: await conn.close() async def get_users_for_unban_today(self, date_to_unban: str) -> List: """Получение пользователей для разблокировки сегодня.""" conn = None try: conn = await self._get_connection() async with conn.execute( "SELECT user_id, user_name FROM blacklist WHERE date_to_unban = ?", (date_to_unban,) ) as cursor: return await cursor.fetchall() except Exception as e: self.logger.error(f"Ошибка при получении пользователей для разблокировки: {e}") raise finally: if conn: await conn.close() # Методы для работы с администраторами async def add_admin(self, user_id: int, role: str = "admin"): """Добавление администратора.""" conn = None try: conn = await self._get_connection() await conn.execute( "INSERT INTO admins (user_id, role) VALUES (?, ?)", (user_id, role) ) await conn.commit() except Exception as e: self.logger.error(f"Ошибка при добавлении администратора: {e}") raise finally: if conn: await conn.close() async def remove_admin(self, user_id: int): """Удаление администратора.""" conn = None try: conn = await self._get_connection() await conn.execute("DELETE FROM admins WHERE user_id = ?", (user_id,)) await conn.commit() except Exception as e: self.logger.error(f"Ошибка при удалении администратора: {e}") raise finally: if conn: await conn.close() async def is_admin(self, user_id: int) -> bool: """Проверка, является ли пользователь администратором.""" conn = None try: conn = await self._get_connection() async with conn.execute( "SELECT 1 FROM admins WHERE user_id = ?", (user_id,) ) as cursor: result = await cursor.fetchone() return bool(result) except Exception as e: self.logger.error(f"Ошибка при проверке прав администратора: {e}") return False finally: if conn: await conn.close() # Методы для работы с аудио async def add_audio_record(self, file_name: str, author_id: int, file_id: str): """Добавление аудио записи.""" conn = None try: date_added = datetime.now().strftime("%d-%m-%Y %H:%M:%S") conn = await self._get_connection() await conn.execute( "INSERT INTO audio_message_reference (file_name, author_id, date_added, file_id) VALUES (?, ?, ?, ?)", (file_name, author_id, date_added, file_id) ) await conn.commit() except Exception as e: self.logger.error(f"Ошибка при добавлении аудио записи: {e}") raise finally: if conn: await conn.close() async def get_last_audio_date(self) -> Optional[str]: """Получение даты последнего аудио.""" conn = None try: conn = await self._get_connection() async with conn.execute( "SELECT date_added FROM audio_message_reference ORDER BY date_added DESC LIMIT 1" ) as cursor: result = await cursor.fetchone() return result[0] if result else None except Exception as e: self.logger.error(f"Ошибка при получении даты последнего аудио: {e}") raise finally: if conn: await conn.close() async def get_user_audio_records(self, user_id: int) -> bool: """Проверка наличия аудио записей у пользователя.""" conn = None try: conn = await self._get_connection() async with conn.execute( "SELECT 1 FROM audio_message_reference WHERE author_id = ? LIMIT 1", (user_id,) ) as cursor: result = await cursor.fetchone() return bool(result) except Exception as e: self.logger.error(f"Ошибка при проверке аудио записей пользователя: {e}") raise finally: if conn: await conn.close() async def get_audio_file_id(self, user_id: int) -> Optional[str]: """Получение file_id последнего аудио пользователя.""" conn = None try: conn = await self._get_connection() async with conn.execute( "SELECT file_id FROM audio_message_reference WHERE author_id = ? ORDER BY date_added DESC LIMIT 1", (user_id,) ) as cursor: result = await cursor.fetchone() return result[0] if result else None except Exception as e: self.logger.error(f"Ошибка при получении file_id аудио: {e}") raise finally: if conn: await conn.close() async def get_audio_file_name(self, user_id: int) -> Optional[str]: """Получение имени файла последнего аудио пользователя.""" conn = None try: conn = await self._get_connection() async with conn.execute( "SELECT file_name FROM audio_message_reference WHERE author_id = ? ORDER BY date_added DESC LIMIT 1", (user_id,) ) as cursor: result = await cursor.fetchone() return result[0] if result else None except Exception as e: self.logger.error(f"Ошибка при получении имени файла аудио: {e}") raise finally: if conn: await conn.close() async def check_audio_listened(self, user_id: int) -> List[str]: """Проверка прослушанных аудио пользователем.""" conn = None try: conn = await self._get_connection() # Получаем все аудио файлы async with conn.execute( "SELECT file_name FROM audio_message_reference WHERE author_id != ?", (user_id,) ) as cursor: all_audio = await cursor.fetchall() # Получаем прослушанные пользователем async with conn.execute(""" SELECT l.file_name FROM audio_message_reference a LEFT JOIN listen_audio_users l ON l.file_name = a.file_name WHERE l.user_id = ? AND l.file_name IS NOT NULL """, (user_id,)) as cursor: listened_audio = await cursor.fetchall() # Находим непрослушанные all_audio_names = {row[0] for row in all_audio} listened_names = {row[0] for row in listened_audio} return list(all_audio_names - listened_names) except Exception as e: self.logger.error(f"Ошибка при проверке прослушанных аудио: {e}") raise finally: if conn: await conn.close() async def mark_audio_listened(self, file_name: str, user_id: int): """Отметка аудио как прослушанного.""" conn = None try: conn = await self._get_connection() await conn.execute( "INSERT INTO listen_audio_users (file_name, user_id, is_listen) VALUES (?, ?, ?)", (file_name, user_id, 1) ) await conn.commit() except Exception as e: self.logger.error(f"Ошибка при отметке аудио как прослушанного: {e}") raise finally: if conn: await conn.close() async def clear_user_audio_listen(self, user_id: int): """Очистка данных о прослушивании аудио пользователем.""" conn = None try: conn = await self._get_connection() await conn.execute( "DELETE FROM listen_audio_users WHERE user_id = ?", (user_id,) ) await conn.commit() except Exception as e: self.logger.error(f"Ошибка при очистке данных о прослушивании: {e}") raise finally: if conn: await conn.close() async def get_user_by_audio_file(self, file_name: str) -> Optional[int]: """Получение пользователя по имени аудио файла.""" conn = None try: conn = await self._get_connection() async with conn.execute( "SELECT author_id FROM audio_message_reference WHERE file_name = ?", (file_name,) ) as cursor: result = await cursor.fetchone() return result[0] if result else None except Exception as e: self.logger.error(f"Ошибка при получении пользователя по имени файла: {e}") raise finally: if conn: await conn.close() async def get_audio_date(self, file_name: str) -> Optional[str]: """Получение даты аудио файла.""" conn = None try: conn = await self._get_connection() async with conn.execute( "SELECT date_added FROM audio_message_reference WHERE file_name = ?", (file_name,) ) as cursor: result = await cursor.fetchone() return result[0] if result else None except Exception as e: self.logger.error(f"Ошибка при получении даты аудио файла: {e}") raise finally: if conn: await conn.close() # Методы для voice bot async def set_voice_bot_message(self, message_id: int, user_id: int): """Установка связи message_id и user_id для voice bot.""" conn = None try: conn = await self._get_connection() await conn.execute( "INSERT INTO audio_moderate (message_id, user_id) VALUES (?, ?)", (message_id, user_id) ) await conn.commit() except Exception as e: self.logger.error(f"Ошибка при установке связи для voice bot: {e}") raise finally: if conn: await conn.close() async def get_voice_bot_user(self, message_id: int) -> Optional[int]: """Получение пользователя voice bot по message_id.""" conn = None try: conn = await self._get_connection() async with conn.execute( "SELECT user_id FROM audio_moderate WHERE message_id = ?", (message_id,) ) as cursor: result = await cursor.fetchone() return result[0] if result else None except Exception as e: self.logger.error(f"Ошибка при получении пользователя voice bot: {e}") raise finally: if conn: await conn.close() # Методы для миграций async def get_migration_version(self) -> int: """Получение текущей версии миграции.""" conn = None try: conn = await self._get_connection() async with conn.execute( "SELECT version FROM migrations ORDER BY version DESC LIMIT 1" ) as cursor: result = await cursor.fetchone() return result[0] if result else 0 except Exception as e: self.logger.error(f"Ошибка при получении версии миграции: {e}") raise finally: if conn: await conn.close() async def update_migration_version(self, version: int, script_name: str): """Обновление версии миграции.""" conn = None try: created_at = datetime.now().strftime("%d-%m-%Y %H:%M:%S") conn = await self._get_connection() await conn.execute( "INSERT INTO migrations (version, script_name, created_at) VALUES (?, ?, ?)", (version, script_name, created_at) ) await conn.commit() except Exception as e: self.logger.error(f"Ошибка при обновлении версии миграции: {e}") raise finally: if conn: await conn.close() async def close(self): """Закрытие соединений.""" # Соединения закрываются в каждом методе pass