优化
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
// Offline SQL-test helpers. No database access or command-line entry point.
|
||||
import { readFileSync } from 'node:fs'
|
||||
|
||||
export function readInitialization(region = 'CN') {
|
||||
const name = region === 'CN' ? '头程数据库统一增量-MySQL8.sql' : '海外区域统一增量-MySQL8.sql'
|
||||
return readFileSync(new URL(`../deploy/sql/${name}`, import.meta.url), 'utf8')
|
||||
}
|
||||
|
||||
export function tableDefinitions(sql) {
|
||||
const result = new Map()
|
||||
let schema
|
||||
for (const match of sql.matchAll(/^USE (\w+);|^CREATE TABLE (\w+) \([\s\S]*?^\) ENGINE=[^\n]+;/gm)) {
|
||||
if (match[1]) schema = match[1]
|
||||
else {
|
||||
const key = `${schema}.${match[2]}`
|
||||
if (result.has(key)) throw new Error(`Duplicate table definition: ${key}`)
|
||||
result.set(key, match[0])
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
export function table(sql, schema, name) {
|
||||
const value = tableDefinitions(sql).get(`${schema}.${name}`)
|
||||
if (!value) throw new Error(`Missing table: ${schema}.${name}`)
|
||||
return value
|
||||
}
|
||||
|
||||
function splitValues(value) {
|
||||
const items = []
|
||||
let start = 0, depth = 0, quoted = false
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
const c = value[i]
|
||||
if (quoted && c === '\\') { i++; continue }
|
||||
if (c === "'") {
|
||||
if (quoted && value[i + 1] === "'") { i++; continue }
|
||||
quoted = !quoted
|
||||
}
|
||||
if (quoted) continue
|
||||
if (c === '(') depth++
|
||||
if (c === ')') depth--
|
||||
if (c === ',' && depth === 0) { items.push(value.slice(start, i).trim()); start = i + 1 }
|
||||
}
|
||||
if (quoted || depth) throw new Error('Unbalanced SQL seed value')
|
||||
items.push(value.slice(start).trim())
|
||||
return items.map(item => item === 'NULL' ? null : item.startsWith("'")
|
||||
? item.slice(1, -1).replace(/''/g, "'").replace(/\\([\\'"nrt0])/g, (_, c) => ({ n: '\n', r: '\r', t: '\t', 0: '\0' }[c] ?? c))
|
||||
: item)
|
||||
}
|
||||
|
||||
export function seedRows(sql, name) {
|
||||
const pattern = new RegExp(`^INSERT INTO ${name} \\(([^\\n]+?)\\) VALUES \\(([^\\n]+)\\);$`, 'gm')
|
||||
return [...sql.matchAll(pattern)].map(match => {
|
||||
const keys = match[1].split(',').map(key => key.trim())
|
||||
const values = splitValues(match[2])
|
||||
if (keys.length !== values.length) throw new Error(`Invalid seed columns: ${name}`)
|
||||
return Object.fromEntries(keys.map((key, i) => [key, values[i]]))
|
||||
})
|
||||
}
|
||||
|
||||
export function roleAuthorities(sql, roleCode) {
|
||||
const role = seedRows(sql, 'iam_role').find(row => row.role_code === roleCode)
|
||||
if (!role) throw new Error(`Missing role: ${roleCode}`)
|
||||
const granted = new Set(seedRows(sql, 'iam_role_permission').filter(row => row.role_id === role.id).map(row => row.permission_id))
|
||||
return new Set(seedRows(sql, 'iam_permission').filter(row => granted.has(row.id)).map(row => row.permission_code))
|
||||
}
|
||||
Reference in New Issue
Block a user