import asyncio from typing import List, Dict, Any from app.models.instance import Instance from app.schemas.instance import ConnectionTestResult class InstanceService: @staticmethod async def test_connection(instance: Instance) -> ConnectionTestResult: try: if instance.db_type == "mysql": import aiomysql conn = await asyncio.wait_for( aiomysql.connect( host=instance.host, port=instance.port, user=instance.username, password=instance.password, database=instance.database or None, ), timeout=10, ) async with conn.cursor() as cur: await cur.execute("SELECT VERSION()") version = (await cur.fetchone())[0] conn.close() return ConnectionTestResult(success=True, message="连接成功", version=str(version)) return ConnectionTestResult(success=False, message=f"暂不支持 {instance.db_type} 连接测试") except asyncio.TimeoutError: return ConnectionTestResult(success=False, message="连接超时") except Exception as e: return ConnectionTestResult(success=False, message=f"连接失败: {str(e)}") @staticmethod async def list_databases(instance: Instance) -> List[str]: if instance.db_type != "mysql": return [] import aiomysql conn = await aiomysql.connect( host=instance.host, port=instance.port, user=instance.username, password=instance.password, ) async with conn.cursor() as cur: await cur.execute("SHOW DATABASES") rows = await cur.fetchall() conn.close() return [row[0] for row in rows if row[0] not in ("information_schema", "mysql", "performance_schema", "sys")] @staticmethod async def list_tables(instance: Instance, database: str) -> List[Dict[str, Any]]: if instance.db_type != "mysql": return [] import aiomysql conn = await aiomysql.connect( host=instance.host, port=instance.port, user=instance.username, password=instance.password, database=database, ) async with conn.cursor() as cur: await cur.execute("SHOW TABLES") tables = [row[0] for row in await cur.fetchall()] result = [] for table in tables: await cur.execute(f"SHOW TABLE STATUS LIKE '{table}'") status = await cur.fetchone() result.append({ "name": table, "engine": status[1], "rows": status[4], "size": status[6], "comment": status[17], }) conn.close() return result