'use strict'; /* db-maintain.js — обслуживание SQLite-БД: проверка целостности + компактизация. * Шаги: PRAGMA integrity_check -> PRAGMA wal_checkpoint(TRUNCATE) -> VACUUM. * Путь к БД: env DB_PATH, либо argv[2], либо стандартный. * VACUUM требует, чтобы БД никто не писал — запускать на ОСТАНОВЛЕННОМ сервере. * Используется панелью управления (control-panel.ps1, пункт «Обслуживание БД»). */ const path = require('path'); const fs = require('fs'); const { DatabaseSync } = require('node:sqlite'); const DB = process.env.DB_PATH || process.argv[2] || path.join(__dirname, '..', 'data', 'learnspace.db'); function sizeMB(p) { try { return (fs.statSync(p).size / 1048576).toFixed(1) + ' МБ'; } catch (_) { return '?'; } } if (!fs.existsSync(DB)) { console.error('БД не найдена: ' + DB); process.exit(1); } const before = sizeMB(DB); const db = new DatabaseSync(DB); try { db.exec('PRAGMA busy_timeout=8000'); } catch (_) {} // 1) Проверка целостности let integ = '?'; try { const rows = db.prepare('PRAGMA integrity_check').all(); integ = rows.map(r => (r.integrity_check !== undefined ? r.integrity_check : Object.values(r)[0])).join('; '); } catch (e) { integ = 'ошибка: ' + e.message; } const integOk = (integ === 'ok'); console.log('Целостность: ' + (integOk ? 'ok' : integ)); // 2) Сброс WAL в основной файл try { db.exec('PRAGMA wal_checkpoint(TRUNCATE)'); console.log('WAL checkpoint: ok'); } catch (e) { console.log('WAL checkpoint: ' + e.message); } // 3) Компактизация (только если целостность в порядке — VACUUM на битой БД опасен) if (integOk) { try { db.exec('VACUUM'); console.log('VACUUM: ok'); } catch (e) { console.log('VACUUM: ' + e.message); } } else { console.log('VACUUM пропущен: сначала восстановите целостность (откат из бэкапа).'); } db.close(); console.log('Размер БД: ' + before + ' -> ' + sizeMB(DB));