先核來源與已訂規則
本例舊 A 沒類別依據,加 category DEFAULT New 卻令現有行出現 New。搬移應先加可空欄,只按所附歷史依據補值;舊紀錄未曾證實屬 New。
| 紀錄 | 輸入 JSON |
|---|---|
| 原例輸入 | {"records":[{"id":1,"name":"A"}],"evidence":[]} |
比較兩條實際路徑
更正 A 的 category 仍 null。差異來自實際 ALTER 及回讀,不是匯入程序代作新類別決定。
| 路徑 | 輸出 JSON |
|---|---|
| 錯誤路徑 | [{"id":1,"name":"A","category":"New"}] |
| 更正路徑 | [{"id":1,"name":"A","category":null}] |
import {DatabaseSync} from 'node:sqlite';
import {TextDecoder} from 'node:util';
import {inflateSync} from 'node:zlib';
import {posix} from 'node:path';
import {createHash} from 'node:crypto';
const rows=(db,sql)=>db.prepare(sql).all().map(r=>({...r}));
const failed=(action)=>{try{action();return null;}catch(e){return {code:e.errcode??e.code??e.name};}};
import assert from 'node:assert/strict';
const run=function run(i,corrected=true){
const db=new DatabaseSync(':memory:');try{db.exec('CREATE TABLE target(id INTEGER PRIMARY KEY,name TEXT);');
for(const r of i.records)db.prepare('INSERT INTO target VALUES(?,?)').run(r.id,r.name);
db.exec(corrected?'ALTER TABLE target ADD COLUMN category TEXT':"ALTER TABLE target ADD COLUMN category TEXT DEFAULT 'New'");
if(corrected)for(const e of i.evidence)db.prepare('UPDATE target SET category=? WHERE id=?').run(e.category,e.id);
return rows(db,'SELECT * FROM target ORDER BY id');
}finally{db.close();}
};
const cases=[{"label":"misleading base","input":{"records":[{"id":1,"name":"A"}],"evidence":[]},"expected":[{"id":1,"name":"A","category":"New"}],"corrected":false},{"label":"corrected base","input":{"records":[{"id":1,"name":"A"}],"evidence":[]},"expected":[{"id":1,"name":"A","category":null}],"corrected":true},{"label":"evidenced historical category","input":{"records":[{"id":1,"name":"A"}],"evidence":[{"id":1,"category":"Old"}]},"expected":[{"id":1,"name":"A","category":"Old"}],"corrected":true},{"label":"no historical rows","input":{"records":[],"evidence":[]},"expected":[],"corrected":true}];
for(const test of cases){
const actual=run(test.input,test.corrected);
assert.deepEqual(actual,test.expected,test.label);
console.log(test.label,actual);
}
下次載入前核邊界
依據明訂 Old 就填 Old;舊表沒有紀錄則照空。
| 情況 | 輸入 JSON | 預期輸出 JSON |
|---|---|---|
| 明確歷史類別依據 | {"records":[{"id":1,"name":"A"}],"evidence":[{"id":1,"category":"Old"}]} | [{"id":1,"name":"A","category":"Old"}] |
| 沒有舊紀錄 | {"records":[],"evidence":[]} | [] |
新加預設值可否確立舊紀錄歷史類別?
查看參考答案
不可,此處 A 仍未知。只有對應歷史依據已列 Old,才補 Old。