/
DATKAI
/
label_system
Обзор
Документация
Войти
/
DATKAI
/
label_system
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
main
convert.js
75 строк
4 KB
DATKAI
Перенос БД на SQLite (node:sqlite) + конвертер старой базы
30 июн 2026, 05:50
30 июн 2026, 05:50
9b01437
Код
Авторство
О чём код?
'use strict'; // Конвертер старой базы: db.json → label.db (SQLite). // Запуск: node convert.js — создаёт label.db рядом // node convert.js --force — перезаписать существующий label.db // // Не трогает db.json (только читает). После конвертации печатает отчёт // и проверяет целостность (счётчики + round-trip сравнение). const fs = require('fs'); const path = require('path'); const store = require('./lib/store'); const DB_JSON = path.join(__dirname, 'db.json'); const DB_FILE = store.DB_FILE; const force = process.argv.includes('--force'); function fail(msg){ console.error('❌ ' + msg); process.exit(1); } if(!fs.existsSync(DB_JSON)) fail('db.json не найден: ' + DB_JSON); if(fs.existsSync(DB_FILE) && !force) fail(`label.db уже существует. Запустите с --force, чтобы перезаписать:\n node convert.js --force`); if(fs.existsSync(DB_FILE) && force){ // на всякий случай — резервная копия старого label.db for(const ext of ['', '-wal', '-shm']){ if(fs.existsSync(DB_FILE+ext)) fs.renameSync(DB_FILE+ext, DB_FILE+ext+'.bak-'+Date.now()); } console.log('ℹ старый label.db переименован в *.bak-*'); } console.log('▸ Читаю db.json…'); let src; try { src = JSON.parse(fs.readFileSync(DB_JSON, 'utf8')); } catch(e){ fail('db.json повреждён: ' + e.message); } console.log('▸ Создаю label.db и переношу данные…'); store.open(DB_FILE); store.saveAll(src); // ── Отчёт ── const counts = store.rowCounts(); console.log('\n✅ Готово. Перенесено:'); const srcCounts = { decors:(src.decors||[]).length, operators:(src.operators||[]).length, users:(src.users||[]).length, templates:(src.templates||[]).length, products:(src.products||[]).length, cutting_orders:(src.cutting_orders||[]).length, tasks:(src.tasks||[]).length, log:(src.log||[]).length, feedback:(src.feedback||[]).length, }; let mismatch = 0; for(const k of Object.keys(srcCounts)){ const ok = srcCounts[k] === counts[k]; if(!ok) mismatch++; console.log(` ${ok?'✓':'✗'} ${k.padEnd(15)} json:${String(srcCounts[k]).padStart(5)} → sqlite:${String(counts[k]).padStart(5)}`); } // ── Round-trip проверка целостности ── const back = store.loadAll(); function norm(o){ return JSON.stringify(o); } const checks = []; checks.push(['adminPassword', norm(src.adminPassword) === norm(back.adminPassword)]); checks.push(['companyName', norm(src.companyName) === norm(back.companyName)]); checks.push(['users[0]', norm((src.users||[])[0]) === norm((back.users||[])[0])]); checks.push(['tasks set', JSON.stringify((src.tasks||[]).map(t=>t.id).sort()) === JSON.stringify((back.tasks||[]).map(t=>t.id).sort())]); checks.push(['log newest', !(src.log||[]).length || norm((src.log||[])[0]) === norm((back.log||[])[0])]); console.log('\n▸ Проверка целостности (round-trip):'); let bad = 0; for(const [name, ok] of checks){ console.log(` ${ok?'✓':'✗'} ${name}`); if(!ok) bad++; } const dbSize = fs.statSync(DB_FILE).size; console.log(`\n📦 label.db: ${(dbSize/1024).toFixed(0)} КБ`); if(mismatch || bad){ console.error(`\n⚠ Обнаружены расхождения (counts:${mismatch}, checks:${bad}). НЕ переключайте сервер, сообщите разработчику.`); process.exit(2); } console.log('\n🎉 Конвертация успешна и проверена. Можно переключать сервер на SQLite.');