zigbee-herdsman
Version:
An open source Zigbee gateway solution with node.js.
114 lines • 4.07 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Database = void 0;
const node_fs_1 = __importDefault(require("node:fs"));
const logger_1 = require("../utils/logger");
const NS = "zh:controller:database";
class Database {
entries;
path;
maxId;
constructor(entries, path, maxId) {
this.entries = entries;
this.path = path;
this.maxId = maxId;
}
static open(path) {
const entries = new Map();
let maxId = 0;
if (node_fs_1.default.existsSync(path)) {
const file = node_fs_1.default.readFileSync(path, "utf-8");
for (const row of file.split("\n")) {
if (!row) {
continue;
}
try {
const json = JSON.parse(row);
if (Number.isFinite(json.id)) {
entries.set(json.id, json);
if (json.id > maxId) {
maxId = json.id;
}
}
}
catch (error) {
logger_1.logger.error(`Corrupted database line, ignoring. ${error}`, NS);
}
}
}
return new Database(entries, path, maxId);
}
*getEntriesIterator(type) {
for (const entry of this.entries.values()) {
if (type.includes(entry.type)) {
yield entry;
}
}
}
insert(databaseEntry) {
if (this.entries.has(databaseEntry.id)) {
throw new Error(`DatabaseEntry with ID '${databaseEntry.id}' already exists`);
}
this.entries.set(databaseEntry.id, databaseEntry);
this.write();
}
update(databaseEntry, write) {
if (!this.entries.has(databaseEntry.id)) {
throw new Error(`DatabaseEntry with ID '${databaseEntry.id}' does not exist`);
}
this.entries.set(databaseEntry.id, databaseEntry);
if (write) {
this.write();
}
}
remove(id) {
if (this.entries.delete(id)) {
this.write();
}
else {
throw new Error(`DatabaseEntry with ID '${id}' does not exist`);
}
}
has(id) {
return this.entries.has(id);
}
newID() {
this.maxId += 1;
return this.maxId;
}
write() {
logger_1.logger.debug(`Writing database to '${this.path}'`, NS);
let lines = "";
for (const entry of this.entries.values()) {
lines += `${JSON.stringify(entry)}\n`;
}
const tmpPath = `${this.path}.tmp`;
try {
// If there already exsits a database.db.tmp, rename it to database.db.tmp.<now>
const dateTmpPath = `${tmpPath}.${new Date().toISOString().replaceAll(":", "-")}`;
node_fs_1.default.renameSync(tmpPath, dateTmpPath);
// If we got this far, we succeeded! Warn the user about this
logger_1.logger.warning(`Found '${tmpPath}' when writing database, indicating past write failure; renamed it to '${dateTmpPath}'`, NS);
}
catch {
// Nothing to catch; if the renameSync fails, we ignore that exception
}
const fd = node_fs_1.default.openSync(tmpPath, "w");
node_fs_1.default.writeFileSync(fd, lines.slice(0, -1)); // remove last newline, no effect if empty string
// Ensure file is on disk https://github.com/Koenkk/zigbee2mqtt/issues/11759
node_fs_1.default.fsyncSync(fd);
node_fs_1.default.closeSync(fd);
node_fs_1.default.renameSync(tmpPath, this.path);
}
clear() {
logger_1.logger.debug(`Clearing database '${this.path}'...`, NS);
this.entries.clear();
this.write();
}
}
exports.Database = Database;
exports.default = Database;
//# sourceMappingURL=database.js.map