Files
Toolbox/dev_test_scripts/debug/debug_sql_check_unknown_col.js
T
yangxiangyuan db7648eb4d feat(mp, web, calendar): 新增微信收藏夹与日历批量生成功能
- 新增微信小程序版个人收藏夹全套功能,包含聚合首页、收藏列表、编辑、详情页面与配套后端API
- 新增web版时光助手门户与个人收藏夹工具,支持与小程序共享后端数据
- 优化日历提醒工具:替换本地bootstrap资源为公共CDN版本,新增批量生成循环提醒的前端界面与后端逻辑,新增数据库batch_id字段,更新鉴权配置文件
- 补充项目配置、站点地图、调试诊断脚本等配套文件
- 完善各模块的页面配置与样式文件
2026-09-02 22:20:37 +08:00

65 lines
3.1 KiB
JavaScript

// 快速诊断:batch_sql_check 对含 xxx_col 的 INSERT 返回什么
// 用法:node 临时脚本放在项目根,直接 require
const fs = require('fs')
const path = require('path')
const os = require('os')
const TMP_DIR = fs.mkdtempSync(path.join(os.tmpdir(), 'cal_diag_'))
const BACKUP_DIR = path.join(process.cwd(), 'data', 'calendar_reminder_backups')
const latest = fs.readdirSync(BACKUP_DIR).filter(f => f.startsWith('calendar_reminder_2') && f.endsWith('.db')).sort().slice(-1)[0]
const SRC = path.join(BACKUP_DIR, latest)
const DST_DIR = path.join(process.cwd(), 'data', 'calendar_reminder_backups', '_diag')
fs.mkdirSync(DST_DIR, { recursive: true })
for (const suf of ['.db', '.db-wal', '.db-shm']) {
fs.copyFileSync(SRC.replace(/\.db$/,'') + suf, path.join(DST_DIR, 'calendar_reminder' + suf))
}
const modSrc = fs.readFileSync(path.join(process.cwd(), 'src','server','calendar_reminder.js'), 'utf8')
const NEEDLE = "const DB_PATH = path.join(process.cwd(), 'data', 'calendar_reminder.db')"
if (!modSrc.includes(NEEDLE)) { throw new Error('NEEDLE NOT FOUND') }
const modTmp = path.join(process.cwd(), 'dev_test_scripts','unit','_calendar_reminder_diag.js')
fs.writeFileSync(modTmp, modSrc.replace(NEEDLE,
'const DB_PATH = path.join(process.cwd(), "data/calendar_reminder_backups/_diag", "calendar_reminder.db")'))
const express = require('express')
const { createHash } = require('crypto')
const cookie = require('cookie')
const app = express()
app.use((req, res, next) => {
req.headers.cookie = (req.headers.cookie || '') + '; calendar_reminder_gate=1'
next()
})
const mod = require(modTmp)
mod.bindRoutes(app)
const PORT = 18795
const server = app.listen(PORT, '127.0.0.1', async () => {
try {
const badCol = `INSERT INTO events (title,xxx_col,start) VALUES ('t',1,'2026-09-02 09:00');`
const http = require('http')
const r = await new Promise((resolve, reject) => {
const body = JSON.stringify({ sql_text: badCol })
const req = http.request({ hostname: '127.0.0.1', port: PORT, path: '/api/calendar_reminder/batch_sql_check', method: 'POST', headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(body) } }, res => {
let buf = ''; res.on('data', d => buf += d); res.on('end', () => resolve({ status: res.statusCode, body: buf }))
})
req.on('error', reject); req.write(body); req.end()
})
console.log('STATUS', r.status)
console.log('BODY', r.body)
let j
try { j = JSON.parse(r.body) } catch (e) { j = null }
if (j) {
console.log('col_errors length:', j.col_errors && j.col_errors.length)
console.log('col_errors:', JSON.stringify(j.col_errors, null, 2))
console.log('syntax_errors:', JSON.stringify(j.syntax_errors, null, 2))
console.log('forbidden:', JSON.stringify(j.forbidden, null, 2))
console.log('ok?', j.ok)
}
server.close(() => {
fs.rmSync(DST_DIR, { recursive: true, force: true })
fs.unlinkSync(modTmp)
})
} catch (e) {
console.error(e)
try { server.close() } catch {}
try { fs.rmSync(DST_DIR, { recursive: true, force: true }) } catch {}
try { fs.unlinkSync(modTmp) } catch {}
}
})