Files
mikopbxbot/bot/services/database.py
2026-06-24 16:32:30 +03:00

177 lines
6.7 KiB
Python

import aiosqlite
import logging
from typing import List, Dict, Optional
from config import DB_PATH
logger = logging.getLogger(__name__)
class Database:
def __init__(self):
self.db_path = DB_PATH
async def init_db(self):
async with aiosqlite.connect(self.db_path) as db:
await db.execute("""
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
telegram_id INTEGER UNIQUE NOT NULL,
telegram_username TEXT,
full_name TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
""")
await db.execute("""
CREATE TABLE IF NOT EXISTS sip_accounts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL,
extension_number TEXT UNIQUE NOT NULL,
sip_secret TEXT,
username TEXT,
email TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users (id)
)
""")
await db.commit()
logger.info("Database initialized")
async def add_user(self, telegram_id: int, username: str = None, full_name: str = None) -> int:
async with aiosqlite.connect(self.db_path) as db:
cursor = await db.execute(
"INSERT OR IGNORE INTO users (telegram_id, telegram_username, full_name) VALUES (?, ?, ?)",
(telegram_id, username, full_name)
)
await db.commit()
if cursor.lastrowid == 0:
# User already exists, get their id
cursor = await db.execute(
"SELECT id FROM users WHERE telegram_id = ?",
(telegram_id,)
)
row = await cursor.fetchone()
return row[0] if row else None
return cursor.lastrowid
async def get_user(self, telegram_id: int) -> Optional[Dict]:
async with aiosqlite.connect(self.db_path) as db:
cursor = await db.execute(
"SELECT * FROM users WHERE telegram_id = ?",
(telegram_id,)
)
row = await cursor.fetchone()
if row:
return {
"id": row[0],
"telegram_id": row[1],
"telegram_username": row[2],
"full_name": row[3],
"created_at": row[4]
}
return None
async def add_sip_account(self, user_id: int, extension_number: str, sip_secret: str = None,
username: str = None, email: str = None) -> int:
async with aiosqlite.connect(self.db_path) as db:
cursor = await db.execute(
"""INSERT INTO sip_accounts
(user_id, extension_number, sip_secret, username, email)
VALUES (?, ?, ?, ?, ?)""",
(user_id, extension_number, sip_secret, username, email)
)
await db.commit()
return cursor.lastrowid
async def get_user_sip_accounts(self, telegram_id: int) -> List[Dict]:
async with aiosqlite.connect(self.db_path) as db:
cursor = await db.execute("""
SELECT sa.* FROM sip_accounts sa
JOIN users u ON sa.user_id = u.id
WHERE u.telegram_id = ?
ORDER BY sa.created_at DESC
""", (telegram_id,))
rows = await cursor.fetchall()
return [
{
"id": row[0],
"user_id": row[1],
"extension_number": row[2],
"sip_secret": row[3],
"username": row[4],
"email": row[5],
"created_at": row[6]
}
for row in rows
]
async def get_all_sip_accounts(self) -> List[Dict]:
async with aiosqlite.connect(self.db_path) as db:
cursor = await db.execute("""
SELECT sa.*, u.telegram_id, u.telegram_username, u.full_name
FROM sip_accounts sa
JOIN users u ON sa.user_id = u.id
ORDER BY sa.created_at DESC
""")
rows = await cursor.fetchall()
return [
{
"id": row[0],
"user_id": row[1],
"extension_number": row[2],
"sip_secret": row[3],
"username": row[4],
"email": row[5],
"created_at": row[6],
"telegram_id": row[7],
"telegram_username": row[8],
"full_name": row[9]
}
for row in rows
]
async def update_sip_secret(self, extension_number: str, new_secret: str) -> bool:
async with aiosqlite.connect(self.db_path) as db:
cursor = await db.execute(
"UPDATE sip_accounts SET sip_secret = ? WHERE extension_number = ?",
(new_secret, extension_number)
)
await db.commit()
return cursor.rowcount > 0
async def update_extension_number(self, old_number: str, new_number: str) -> bool:
async with aiosqlite.connect(self.db_path) as db:
cursor = await db.execute(
"UPDATE sip_accounts SET extension_number = ? WHERE extension_number = ?",
(new_number, old_number)
)
await db.commit()
return cursor.rowcount > 0
async def delete_sip_account(self, extension_number: str) -> bool:
async with aiosqlite.connect(self.db_path) as db:
cursor = await db.execute(
"DELETE FROM sip_accounts WHERE extension_number = ?",
(extension_number,)
)
await db.commit()
return cursor.rowcount > 0
async def get_sip_account_by_number(self, number: str) -> Optional[Dict]:
async with aiosqlite.connect(self.db_path) as db:
cursor = await db.execute(
"SELECT * FROM sip_accounts WHERE extension_number = ?",
(number,)
)
row = await cursor.fetchone()
if row:
return {
"id": row[0],
"user_id": row[1],
"extension_number": row[2],
"sip_secret": row[3],
"username": row[4],
"email": row[5],
"created_at": row[6]
}
return None