Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@iobroker/db-base

Package Overview
Dependencies
Maintainers
5
Versions
417
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@iobroker/db-base - npm Package Compare versions

Comparing version 1.0.10 to 1.1.0

220

lib/inMemFileDB.js

@@ -74,8 +74,6 @@ /**

// Create data directory
if (!fs.existsSync(this.dataDir)) {
fs.mkdirSync(this.dataDir);
}
this.datasetName = path.join(this.dataDir, this.settings.fileDB.fileName);
const parts = path.dirname(this.datasetName);
fs.ensureDirSync(parts);
this.datasetName = path.join(this.dataDir, this.settings.fileDB.fileName);
this.stateTimer = null;

@@ -86,23 +84,3 @@

if (!this.settings.backup.disabled) {
this.zlib = this.zlib || require('zlib');
// Interval in minutes => to milliseconds
this.settings.backup.period = this.settings.backup.period === undefined ? 120 : parseInt(this.settings.backup.period);
if (isNaN(this.settings.backup.period)) {
this.settings.backup.period = 120;
}
this.settings.backup.period *= 60000;
this.settings.backup.files = this.settings.backup.files === undefined ? 24 : parseInt(this.settings.backup.files);
if (isNaN(this.settings.backup.files)) {
this.settings.backup.files = 24;
}
this.settings.backup.hours = this.settings.backup.hours === undefined ? 48 : parseInt(this.settings.backup.hours);
if (isNaN(this.settings.backup.hours)) {
this.settings.backup.hours = 48;
}
// Create backup directory
if (!fs.existsSync(this.backupDir)) {
fs.mkdirSync(this.backupDir);
}
this.initBackupDir();
}

@@ -113,37 +91,65 @@

this.log.debug(this.namespace + ' Data File: ' + this.datasetName);
}
/** @returns {Promise<void>} */
async open() {
// load values from file
if (fs.existsSync(this.datasetName)) {
this.dataset = await this.loadDataset(this.datasetName);
}
/**
* Loads a dataset file
*
* @param datasetName {string} Filename of the file to load
* @returns {Promise<Record<string, any>>} read data, normally as object
*/
async loadDatasetFile(datasetName) {
if (!(await fs.pathExists(datasetName))) {
throw new Error(`Database file ${datasetName} does not exists.`);
}
return fs.readJSON(datasetName);
}
/**
* Loads the dataset including pot. Fallback handling
*
* @param datasetName {string} Filename of the file to load
* @returns {Promise<Record<string, any>>} dataset read as object
*/
async loadDataset(datasetName) {
let ret = {};
try {
ret = await this.loadDatasetFile(datasetName);
} catch (err) {
this.log.error(`${this.namespace} Cannot load ${datasetName}: ${err.message}. Try last Backup!`);
try {
this.dataset = fs.readJSONSync(this.datasetName);
} catch (e) {
this.log.error(this.namespace + ' Cannot parse ' + this.datasetName + ': ' + e.message);
if (fs.existsSync(this.datasetName + '.bak')) {
try {
this.dataset = fs.readJSONSync(this.datasetName + '.bak');
} catch (e) {
this.log.error(this.namespace + ' Cannot parse ' + this.datasetName + '.bak: ' + e.message);
this.dataset = {};
}
} else {
this.dataset = {};
}
ret = await this.loadDatasetFile(datasetName + '.bak');
} catch (err) {
this.log.error(`${this.namespace} Cannot load ${datasetName}.bak: ${err.message}. Continue with empty dataset!`);
}
} else if (fs.existsSync(this.datasetName + '.bak')) {
try {
this.dataset = fs.readJSONSync(this.datasetName + '.bak');
} catch (e) {
this.log.error(this.namespace + ' Cannot parse ' + this.datasetName + '.bak: ' + e.message);
this.dataset = {};
}
} else {
this.dataset = {};
}
return ret;
}
// Check if directory exists
this.datasetName = this.datasetName.replace(/\\/g, '/');
initBackupDir() {
this.zlib = this.zlib || require('zlib');
// Interval in minutes => to milliseconds
this.settings.backup.period = this.settings.backup.period === undefined ? 120 : parseInt(this.settings.backup.period);
if (isNaN(this.settings.backup.period)) {
this.settings.backup.period = 120;
}
this.settings.backup.period *= 60000;
const parts = path.dirname(this.datasetName);
if (!fs.existsSync(parts)) {
fs.mkdirSync(parts);
this.settings.backup.files = this.settings.backup.files === undefined ? 24 : parseInt(this.settings.backup.files);
if (isNaN(this.settings.backup.files)) {
this.settings.backup.files = 24;
}
this.settings.backup.hours = this.settings.backup.hours === undefined ? 48 : parseInt(this.settings.backup.hours);
if (isNaN(this.settings.backup.hours)) {
this.settings.backup.hours = 48;
}
// Create backup directory
fs.ensureDirSync(this.backupDir);
}

@@ -270,47 +276,79 @@

saveState() {
/**
* Handle saving the dataset incl. backups
*/
async saveState() {
if (this.stateTimer) {
clearTimeout(this.stateTimer);
this.stateTimer = null;
}
const jsonString = await this.saveDataset();
if (!this.settings.backup.disabled && jsonString) {
this.saveBackup(jsonString);
}
}
/**
* Saves the dataset into File incl. handling of a fallback backup file
*
* @returns {Promise<string>} JSON string of the complete dataset to also be stored into a compressed backup file
*/
async saveDataset() {
const jsonString = JSON.stringify(this.dataset);
try {
if (fs.existsSync(this.datasetName)) {
const old = fs.readFileSync(this.datasetName);
fs.writeFileSync(this.datasetName + '.bak', old);
if (await fs.pathExists(this.datasetName)) {
await fs.move(this.datasetName, `${this.datasetName}.bak`, { overwrite: true });
}
} catch (e) {
this.log.error(`${this.namespace} Cannot save backup file ${this.datasetName}.bak: ${e.message}`);
}
const actual = JSON.stringify(this.dataset);
fs.writeFileSync(this.datasetName, actual);
try {
await fs.writeFile(this.datasetName, jsonString);
} catch (e) {
this.log.error(`${this.namespace} Cannot save ${this.datasetName}: ${e.message}`);
}
if (!this.settings.backup.disabled) {
// save files for the last x hours
const now = Date.now();
return jsonString;
}
// makes backups only if settings.backupInterval is not 0
if (this.settings.backup.period && (!this.lastSave || now - this.lastSave > this.settings.backup.period)) {
this.lastSave = now;
const backFileName = path.join(this.backupDir, this.getTimeStr(now) + '_' + this.settings.fileDB.fileName + '.gz');
/**
* Stores a compressed backup of the DB in definable intervals
*
* @param jsonString {string} JSON string of the complete dataset to also be stored into a compressed backup file
*/
saveBackup(jsonString) {
// save files for the last x hours
const now = Date.now();
if (!fs.existsSync(backFileName)) {
this.zlib = this.zlib || require('zlib');
const output = fs.createWriteStream(backFileName);
output.on('error', err => {
this.log.error(this.namespace + ' Cannot save ' + this.datasetName + ': ' + err);
});
const compress = this.zlib.createGzip();
/* The following line will pipe everything written into compress to the file stream */
compress.pipe(output);
/* Since we're piped through the file stream, the following line will do:
'Hello World!'->gzip compression->file which is the desired effect */
compress.write(actual);
compress.end();
// makes backups only if settings.backupInterval is not 0
if (this.settings.backup.period && (!this.lastSave || now - this.lastSave > this.settings.backup.period)) {
this.lastSave = now;
const backFileName = path.join(this.backupDir, this.getTimeStr(now) + '_' + this.settings.fileDB.fileName + '.gz');
// analyse older files
this.deleteOldBackupFiles();
}
try {
if (!fs.existsSync(backFileName)) {
this.zlib = this.zlib || require('zlib');
const output = fs.createWriteStream(backFileName);
output.on('error', err => {
this.log.error(this.namespace + ' Cannot save ' + this.datasetName + ': ' + err);
});
const compress = this.zlib.createGzip();
/* The following line will pipe everything written into compress to the file stream */
compress.pipe(output);
/* Since we're piped through the file stream, the following line will do:
'Hello World!'->gzip compression->file which is the desired effect */
compress.write(jsonString);
compress.end();
// analyse older files
this.deleteOldBackupFiles();
}
} catch (e) {
this.log.error(`${this.namespace} Cannot save backup ${backFileName}: ${e.message}`);
}
} catch (e) {
this.log.error(this.namespace + ' Cannot save ' + this.datasetName + ': ' + e.message);
}
if (this.stateTimer) {
clearTimeout(this.stateTimer);
this.stateTimer = null;
}
}

@@ -357,3 +395,5 @@

async destroy() {
this.stateTimer && this.saveState();
if (this.stateTimer) {
await this.saveState();
}
}

@@ -360,0 +400,0 @@ }

{
"name": "@iobroker/db-base",
"version": "1.0.10",
"version": "1.1.0",
"engines": {

@@ -34,3 +34,3 @@ "node": ">=10.0.0"

},
"gitHead": "758fd93aae496663dff8b9d8dbe38d06fdb739be"
"gitHead": "48a8b298f8c6bd10ca3da29f404fc4a0c756ba9c"
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc