ICRA26WM / database /__init__.py
qiukingballball's picture
squash history
c8b725d
import aiosqlite
import os
from pathlib import Path
DATABASE_PATH = Path(__file__).parent.parent / "database" / "submission.db"
DATABASE_PATH.parent.mkdir(exist_ok=True)
async def get_db():
"""获取数据库连接"""
db = await aiosqlite.connect(str(DATABASE_PATH))
db.row_factory = aiosqlite.Row
return db
async def init_db():
"""初始化数据库"""
db = await aiosqlite.connect(str(DATABASE_PATH))
with open(Path(__file__).parent / "schema.sql", "r") as f:
await db.executescript(f.read())
await db.commit()
await db.close()
async def get_or_create_team(db, team_name: str) -> int:
"""获取或创建队伍,返回 team_id"""
cursor = await db.execute(
"SELECT id FROM teams WHERE name = ?", (team_name,)
)
row = await cursor.fetchone()
if row:
return row["id"]
await db.execute(
"INSERT INTO teams (name) VALUES (?)", (team_name,)
)
await db.commit()
cursor = await db.execute(
"SELECT id FROM teams WHERE name = ?", (team_name,)
)
row = await cursor.fetchone()
return row["id"]
async def check_daily_limit(db, team_id: int) -> tuple[bool, int]:
"""
检查每日限制,返回 (是否超限, 当日提交数)
"""
today = date.today().isoformat()
cursor = await db.execute(
"SELECT count FROM daily_limits WHERE team_id = ? AND date = ?",
(team_id, today)
)
row = await cursor.fetchone()
if row:
return row["count"] >= 1, row["count"]
return False, 0
async def increment_daily_limit(db, team_id: int):
"""增加当日提交计数"""
today = date.today().isoformat()
await db.execute(
"""INSERT INTO daily_limits (team_id, date, count)
VALUES (?, ?, 1)
ON CONFLICT(team_id, date) DO UPDATE SET count = count + 1""",
(team_id, today)
)
await db.commit()
async def create_submission(db, team_id: int, file_path: str) -> int:
"""创建提交记录,返回 submission_id"""
cursor = await db.execute(
"""INSERT INTO submissions (team_id, file_path, status)
VALUES (?, ?, 'pending')""",
(team_id, file_path)
)
await db.commit()
return cursor.lastrowid
async def get_submission(submission_id: int):
"""获取单个提交记录"""
db = await get_db()
cursor = await db.execute(
"""SELECT s.*, t.name as team_name
FROM submissions s
JOIN teams t ON s.team_id = t.id
WHERE s.id = ?""",
(submission_id,)
)
row = await cursor.fetchone()
await db.close()
return dict(row) if row else None
async def update_submission_status(
submission_id: int,
status: str,
score: float = None,
error_message: str = None
):
"""更新提交状态"""
db = await get_db()
if score is not None:
await db.execute(
"UPDATE submissions SET status = ?, score = ?, error_message = ? WHERE id = ?",
(status, score, error_message, submission_id)
)
else:
await db.execute(
"UPDATE submissions SET status = ?, error_message = ? WHERE id = ?",
(status, error_message, submission_id)
)
await db.commit()
await db.close()
async def get_oldest_pending_submission():
"""获取最老的 pending 提交"""
db = await get_db()
cursor = await db.execute(
"""SELECT s.*, t.name as team_name
FROM submissions s
JOIN teams t ON s.team_id = t.id
WHERE s.status = 'pending'
ORDER BY s.submit_time ASC
LIMIT 1"""
)
row = await cursor.fetchone()
await db.close()
return dict(row) if row else None
async def get_team_submissions(team_id: int):
"""获取队伍的所有提交记录"""
db = await get_db()
cursor = await db.execute(
"""SELECT s.*, t.name as team_name
FROM submissions s
JOIN teams t ON s.team_id = t.id
WHERE s.team_id = ?
ORDER BY s.submit_time DESC""",
(team_id,)
)
rows = await cursor.fetchall()
await db.close()
return [dict(row) for row in rows]
async def get_leaderboard():
"""获取排行榜数据(每队最优成绩)"""
db = await get_db()
cursor = await db.execute(
"""SELECT t.name as team_name,
MAX(s.score) as best_score,
MAX(s.submit_time) as last_submit_time
FROM teams t
LEFT JOIN submissions s ON t.id = s.team_id AND s.status = 'completed'
GROUP BY t.id
ORDER BY best_score DESC NULLS LAST,
last_submit_time ASC"""
)
rows = await cursor.fetchall()
await db.close()
return [dict(row) for row in rows]
async def get_team_by_name(team_name: str):
"""根据队名获取队伍信息"""
db = await get_db()
cursor = await db.execute(
"SELECT * FROM teams WHERE name = ?", (team_name,)
)
row = await cursor.fetchone()
await db.close()
return dict(row) if row else None
from datetime import date