FastAPI backend with auth, user, instance, ticket, query, dashboard APIs. React + TypeScript frontend with mock data UI (10 pages). SQLite + async SQLAlchemy, JWT auth, role-based access control. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
80 lines
2.9 KiB
Python
80 lines
2.9 KiB
Python
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
|