Notes/src/services/backup.ts

94 lines
2.6 KiB
TypeScript
Raw Normal View History

2017-10-21 21:10:33 -04:00
"use strict";
import dateUtils from "./date_utils.js";
2025-01-03 17:54:05 +02:00
import optionService, { OptionNames } from "./options.js";
import fs from "fs-extra";
import dataDir from "./data_dir.js";
import log from "./log.js";
import syncMutexService from "./sync_mutex.js";
import cls from "./cls.js";
import sql from "./sql.js";
import path from "path";
2024-02-17 19:33:29 +02:00
type BackupType = ("daily" | "weekly" | "monthly");
function getExistingBackups() {
if (!fs.existsSync(dataDir.BACKUP_DIR)) {
return [];
}
return fs.readdirSync(dataDir.BACKUP_DIR)
.filter(fileName => fileName.includes("backup"))
2023-10-19 00:51:38 +02:00
.map(fileName => {
const filePath = path.resolve(dataDir.BACKUP_DIR, fileName);
const stat = fs.statSync(filePath)
return {fileName, filePath, mtime: stat.mtime};
2023-10-19 00:51:38 +02:00
});
}
2020-06-20 12:31:38 +02:00
function regularBackup() {
2020-07-04 00:20:23 +02:00
cls.init(() => {
periodBackup('lastDailyBackupDate', 'daily', 24 * 3600);
2020-07-04 00:20:23 +02:00
periodBackup('lastWeeklyBackupDate', 'weekly', 7 * 24 * 3600);
2020-07-04 00:20:23 +02:00
periodBackup('lastMonthlyBackupDate', 'monthly', 30 * 24 * 3600);
});
}
2024-02-17 19:33:29 +02:00
function isBackupEnabled(backupType: BackupType) {
2025-01-03 17:54:05 +02:00
let optionName: OptionNames;
switch (backupType) {
case "daily":
optionName = "dailyBackupEnabled";
break;
case "weekly":
optionName = "weeklyBackupEnabled";
break;
case "monthly":
optionName = "monthlyBackupEnabled";
break;
}
2021-10-11 22:30:23 +02:00
return optionService.getOptionBool(optionName);
}
2025-01-03 17:54:05 +02:00
function periodBackup(optionName: "lastDailyBackupDate" | "lastWeeklyBackupDate" | "lastMonthlyBackupDate", backupType: BackupType, periodInSeconds: number) {
2021-10-11 22:30:23 +02:00
if (!isBackupEnabled(backupType)) {
return;
}
const now = new Date();
2021-10-11 22:30:23 +02:00
const lastBackupDate = dateUtils.parseDateTime(optionService.getOption(optionName));
2021-10-11 22:30:23 +02:00
if (now.getTime() - lastBackupDate.getTime() > periodInSeconds * 1000) {
backupNow(backupType);
2020-06-20 12:31:38 +02:00
optionService.setOption(optionName, dateUtils.utcNowDateTime());
}
}
2024-02-17 19:33:29 +02:00
async function backupNow(name: string) {
// we don't want to back up DB in the middle of sync with potentially inconsistent DB state
return await syncMutexService.doExclusively(async () => {
const backupFile = `${dataDir.BACKUP_DIR}/backup-${name}.db`;
2017-10-24 22:17:48 -04:00
await sql.copyDatabase(backupFile);
log.info(`Created backup at ${backupFile}`);
return backupFile;
});
}
if (!fs.existsSync(dataDir.BACKUP_DIR)) {
fs.mkdirSync(dataDir.BACKUP_DIR, 0o700);
}
export default {
getExistingBackups,
2020-06-02 23:13:55 +02:00
backupNow,
2020-07-02 22:57:17 +02:00
regularBackup
};