Deploy / deploy (push) Canceled after 0s
原来每组数据都必须有被标准答案改到的行,所以「这组里没有研发部,看学生会不会把别的部门也改了」 这种测试数据建不了。现在只有第 1 组(题面上给学生看的那组)还要求改到行;其余组一行都没改时 出题页写「一行都没改」、预览写「执行后所有表都没有变化」。删掉第 1 组、别的组顶上来时自动按 新位置重查。判题本来就不管这一条,不受影响。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
63 lines
2.8 KiB
TypeScript
63 lines
2.8 KiB
TypeScript
import type { SqlDisplay } from "utils/types"
|
||
import { changedRowCount, tableChanges } from "oj/problem/utils/sqlChanges"
|
||
|
||
/** 出题页的一组测试数据:一份建表 + 插数据的脚本,和它跑出来的样子 */
|
||
export interface ScriptGroup {
|
||
key: number
|
||
sql: string
|
||
/** 跑出来的结果对应的是哪一版(标准答案 + 判题方式 + 脚本),和现在的对不上就是过期了 */
|
||
ranFor: string
|
||
display: SqlDisplay | null
|
||
/** 跑不起来的原因,常见的已经翻成中文(explainSqlError) */
|
||
error: string
|
||
/** 后端回的原话,翻译过的时候用小字附在后面 */
|
||
errorRaw: string
|
||
/** 正在跑的那一版 */
|
||
running: string
|
||
}
|
||
|
||
export type GroupStatus = "empty" | "no-answer" | "running" | "ok" | "error"
|
||
|
||
/**
|
||
* SQLite 的报错是英文,出题的老师未必看得懂。常见的几种翻成一句中文,
|
||
* 认不出来的原样给(后端已经加了「初始化脚本执行失败」这类中文前缀)
|
||
*/
|
||
export function explainSqlError(message: string) {
|
||
const rules: [RegExp, (m: RegExpMatchArray) => string][] = [
|
||
[/no such table: (\S+)/, (m) => `没有 ${m[1]} 这张表`],
|
||
[/no such column: (\S+)/, (m) => `没有 ${m[1]} 这一列`],
|
||
[/table (\S+) already exists/, (m) => `${m[1]} 这张表建了两次`],
|
||
[/near "([^"]*)": syntax error/, (m) => `语法有错,在「${m[1]}」附近`],
|
||
[/incomplete input/, () => "语句没写完(少了右括号或分号?)"],
|
||
[/UNIQUE constraint failed: (\S+)/, (m) => `${m[1]} 有重复的值`],
|
||
[/(\d+) values for (\d+) columns/, (m) => `一行给了 ${m[1]} 个值,但表有 ${m[2]} 列`],
|
||
]
|
||
if (message.includes("标准答案未修改任何表数据")) {
|
||
return "标准答案在这组数据上一行都没改:第 1 组是题面上给学生看的,里面要有会被改到的行"
|
||
}
|
||
for (const [pattern, say] of rules) {
|
||
const match = message.match(pattern)
|
||
if (match) {
|
||
const where = message.startsWith("标准答案") ? "标准答案在这组数据上" : "这组的脚本"
|
||
return `${where}跑不起来:${say(match)}`
|
||
}
|
||
}
|
||
return message
|
||
}
|
||
|
||
/** 列表里那一行的小结:几张表各几行 → 期望几行 / 改了几行 */
|
||
export function groupSummary(display: SqlDisplay) {
|
||
const rows = display.tables.map((t) => t.total_rows).join(" + ")
|
||
const expected = display.expected
|
||
if ("columns" in expected) return `${rows} 行 → 期望 ${expected.total_rows} 行`
|
||
const changed = expected.changed_tables.reduce((sum, table) => {
|
||
if (table.dropped) return sum + 1
|
||
const changes = tableChanges(
|
||
display.tables.find((t) => t.name === table.name),
|
||
table,
|
||
)
|
||
return sum + (changes ? changedRowCount(changes) : 0)
|
||
}, 0)
|
||
return changed ? `${rows} 行 → 改了 ${changed} 行` : `${rows} 行 → 一行都没改`
|
||
}
|