Spaces:
Running on A100
Running on A100
File size: 5,137 Bytes
c8b725d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 | 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
|