- reset() 清空时一并剥离 share 参数,否则重载后分享代码会被写回 - share() 以去掉 query/share 的地址为基址,避免预设代码在 init 里覆盖分享内容 - 打开分享链接前比对本地已存代码,会覆盖用户改动时先弹窗确认 - SQL 分享带上选中的数据表 id,接收方运行结果与分享者一致 - 分享负载的 code/table 字段补类型校验 - 链接损坏或预设加载失败时给出提示,不再静默吞掉 - 剪贴板写入失败时不再提示"已复制" 组件外的 init 阶段拿不到 useMessage(),新增 composables/notice.ts 用 createDiscreteApi 提供提示与确认框,主题跟随 useDark()。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CWT2cy7mkZevZR4WVVfAVu
62 lines
1.9 KiB
TypeScript
62 lines
1.9 KiB
TypeScript
import { ref } from "vue"
|
|
import { buildSetupSql, defaultSqlTableId, sqlTables } from "../data/sqlTables"
|
|
|
|
export const selectedTableId = ref(defaultSqlTableId)
|
|
|
|
export function resetSqlTableSelection() {
|
|
selectedTableId.value = defaultSqlTableId
|
|
}
|
|
|
|
// 分享链接里的表 id 不可信,认不出来就退回默认表
|
|
export function selectSqlTable(id: unknown) {
|
|
selectedTableId.value = sqlTables.some((item) => item.id === id)
|
|
? (id as string)
|
|
: defaultSqlTableId
|
|
}
|
|
|
|
// SELECT / WITH 属于查询,直接展示查询结果的列;其余(增删改)回显整张表
|
|
function isQuery(sql: string): boolean {
|
|
return /^\s*(SELECT|WITH)\b/i.test(sql)
|
|
}
|
|
|
|
export function buildSqlScript(studentSql: string) {
|
|
const table =
|
|
sqlTables.find((item) => item.id === selectedTableId.value) ?? sqlTables[0]
|
|
const normalizedSql = studentSql.trim().replace(/;?\s*$/, ";")
|
|
if (isQuery(studentSql.trim())) {
|
|
return [buildSetupSql(table), ".headers on", normalizedSql].join("\n\n")
|
|
}
|
|
return [
|
|
buildSetupSql(table),
|
|
".output /dev/null",
|
|
normalizedSql,
|
|
".output stdout",
|
|
".headers on",
|
|
`SELECT * FROM ${table.tableName};`,
|
|
].join("\n\n")
|
|
}
|
|
|
|
export interface SqlResult {
|
|
columns: string[]
|
|
rows: Record<string, string | number>[]
|
|
}
|
|
|
|
// 输出为 sqlite CLI 的 list 模式(| 分隔),开启 .headers on 后首行是列名
|
|
export function parseResult(output: string): SqlResult {
|
|
const lines = output
|
|
.split("\n")
|
|
.map((line) => line.trim())
|
|
.filter(Boolean)
|
|
if (lines.length === 0) return { columns: [], rows: [] }
|
|
const columns = lines[0].split("|")
|
|
const rows = lines.slice(1).map((line, index) => {
|
|
const cells = line.split("|")
|
|
const record: Record<string, string | number> = { __key: index }
|
|
columns.forEach((column, i) => {
|
|
record[column] = cells[i] ?? ""
|
|
})
|
|
return record
|
|
})
|
|
return { columns, rows }
|
|
}
|