Use Node SQLite libraries for backup verification, if available
Some checks failed
CI/CD Pipeline / Test on Node.js 16.x and ubuntu-latest (release) Successful in 1m37s
CI/CD Pipeline / Test on Node.js 18.x and ubuntu-latest (release) Successful in 43s
CI/CD Pipeline / Test on Node.js 20.x and ubuntu-latest (release) Successful in 45s
CI/CD Pipeline / Test on Node.js 22.x and ubuntu-latest (release) Successful in 50s
CI/CD Pipeline / Lint and Code Quality (release) Failing after 11s
CI/CD Pipeline / Security Scan (release) Failing after 11s
CI/CD Pipeline / Test on Node.js 16.x and windows-latest (release) Has been cancelled
CI/CD Pipeline / Test on Node.js 18.x and macos-latest (release) Has been cancelled
CI/CD Pipeline / Test on Node.js 18.x and windows-latest (release) Has been cancelled
CI/CD Pipeline / Test on Node.js 20.x and macos-latest (release) Has been cancelled
CI/CD Pipeline / Test on Node.js 20.x and windows-latest (release) Has been cancelled
CI/CD Pipeline / Test on Node.js 22.x and macos-latest (release) Has been cancelled
CI/CD Pipeline / Test on Node.js 22.x and windows-latest (release) Has been cancelled
CI/CD Pipeline / Publish to npm (release) Has been cancelled
CI/CD Pipeline / Auto-increment version on main (release) Has been cancelled
Some checks failed
CI/CD Pipeline / Test on Node.js 16.x and ubuntu-latest (release) Successful in 1m37s
CI/CD Pipeline / Test on Node.js 18.x and ubuntu-latest (release) Successful in 43s
CI/CD Pipeline / Test on Node.js 20.x and ubuntu-latest (release) Successful in 45s
CI/CD Pipeline / Test on Node.js 22.x and ubuntu-latest (release) Successful in 50s
CI/CD Pipeline / Lint and Code Quality (release) Failing after 11s
CI/CD Pipeline / Security Scan (release) Failing after 11s
CI/CD Pipeline / Test on Node.js 16.x and windows-latest (release) Has been cancelled
CI/CD Pipeline / Test on Node.js 18.x and macos-latest (release) Has been cancelled
CI/CD Pipeline / Test on Node.js 18.x and windows-latest (release) Has been cancelled
CI/CD Pipeline / Test on Node.js 20.x and macos-latest (release) Has been cancelled
CI/CD Pipeline / Test on Node.js 20.x and windows-latest (release) Has been cancelled
CI/CD Pipeline / Test on Node.js 22.x and macos-latest (release) Has been cancelled
CI/CD Pipeline / Test on Node.js 22.x and windows-latest (release) Has been cancelled
CI/CD Pipeline / Publish to npm (release) Has been cancelled
CI/CD Pipeline / Auto-increment version on main (release) Has been cancelled
This commit is contained in:
parent
b34e4b5d83
commit
c2b4a8eca3
64
lib/index.js
64
lib/index.js
@ -1,7 +1,7 @@
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const { spawn, exec } = require('child_process');
|
const {spawn, exec} = require('child_process');
|
||||||
const { promisify } = require('util');
|
const {promisify} = require('util');
|
||||||
const execAsync = promisify(exec);
|
const execAsync = promisify(exec);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -35,7 +35,7 @@ class SQLiteBackup {
|
|||||||
|
|
||||||
// Create backup directory if needed
|
// Create backup directory if needed
|
||||||
if (this.createBackupDir && !fs.existsSync(this.backupDirectory)) {
|
if (this.createBackupDir && !fs.existsSync(this.backupDirectory)) {
|
||||||
fs.mkdirSync(this.backupDirectory, { recursive: true });
|
fs.mkdirSync(this.backupDirectory, {recursive: true});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,9 +114,27 @@ class SQLiteBackup {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const dbDriver = this._getDatabaseDriver();
|
||||||
|
|
||||||
|
var result = "";
|
||||||
|
|
||||||
|
switch (dbDriver.type) {
|
||||||
|
case "cli":
|
||||||
const command = `sqlite3 "${backupPath}" "PRAGMA integrity_check;"`;
|
const command = `sqlite3 "${backupPath}" "PRAGMA integrity_check;"`;
|
||||||
const { stdout } = await execAsync(command);
|
const {stdout} = await execAsync(command);
|
||||||
return stdout.trim() === 'ok';
|
result = stdout.trim();
|
||||||
|
break;
|
||||||
|
case "better-sqlite3":
|
||||||
|
const db = dbDriver.driver(backupPath);
|
||||||
|
result = await db.pragma('integrity_check', {simple: true});
|
||||||
|
break;
|
||||||
|
case "sqlite3":
|
||||||
|
result = await this._validateUsingSQLite3Package(dbDriver.driver, backupPath);
|
||||||
|
console.log(result);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result === 'ok';
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -212,7 +230,6 @@ class SQLiteBackup {
|
|||||||
isValid: null,
|
isValid: null,
|
||||||
checksum: null
|
checksum: null
|
||||||
};
|
};
|
||||||
|
|
||||||
if (includeChecksums) {
|
if (includeChecksums) {
|
||||||
backup.checksum = await this._calculateChecksum(file.path);
|
backup.checksum = await this._calculateChecksum(file.path);
|
||||||
backup.isValid = await this.verifyBackup(file.path);
|
backup.isValid = await this.verifyBackup(file.path);
|
||||||
@ -390,6 +407,25 @@ class SQLiteBackup {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async _validateUsingSQLite3Package(driver, databasePath) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const db = new driver.Database(databasePath, driver.OPEN_READONLY, err => {
|
||||||
|
if (err) {
|
||||||
|
return resolve("fail");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
db.get("PRAGMA integrity_check", function (err, res) {
|
||||||
|
console.log(res);
|
||||||
|
if (typeof res == 'undefined') {
|
||||||
|
resolve("fail");
|
||||||
|
} else {
|
||||||
|
resolve(res.integrity_check ?? "fail");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async _backupUsingCopy(backupPath) {
|
async _backupUsingCopy(backupPath) {
|
||||||
fs.copyFileSync(this.databasePath, backupPath);
|
fs.copyFileSync(this.databasePath, backupPath);
|
||||||
}
|
}
|
||||||
@ -401,7 +437,7 @@ class SQLiteBackup {
|
|||||||
|
|
||||||
async _calculateChecksum(filePath) {
|
async _calculateChecksum(filePath) {
|
||||||
try {
|
try {
|
||||||
const { stdout } = await execAsync(`shasum -a 256 "${filePath}"`);
|
const {stdout} = await execAsync(`shasum -a 256 "${filePath}"`);
|
||||||
return stdout.split(' ')[0];
|
return stdout.split(' ')[0];
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return null;
|
return null;
|
||||||
@ -434,7 +470,8 @@ class SQLiteBackup {
|
|||||||
|
|
||||||
_matchesPattern(filename, pattern) {
|
_matchesPattern(filename, pattern) {
|
||||||
// Simple pattern matching - could be enhanced with a proper glob library
|
// Simple pattern matching - could be enhanced with a proper glob library
|
||||||
if (pattern === '*' || pattern === '*.*') return true;
|
if (pattern === '*' || pattern === '*.*')
|
||||||
|
return true;
|
||||||
if (pattern.startsWith('*.')) {
|
if (pattern.startsWith('*.')) {
|
||||||
const extension = pattern.slice(2);
|
const extension = pattern.slice(2);
|
||||||
return filename.endsWith('.' + extension);
|
return filename.endsWith('.' + extension);
|
||||||
@ -454,7 +491,8 @@ class BackupUtils {
|
|||||||
*/
|
*/
|
||||||
static formatSize(bytes) {
|
static formatSize(bytes) {
|
||||||
const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
|
const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
|
||||||
if (bytes === 0) return '0 B';
|
if (bytes === 0)
|
||||||
|
return '0 B';
|
||||||
const i = Math.floor(Math.log(bytes) / Math.log(1024));
|
const i = Math.floor(Math.log(bytes) / Math.log(1024));
|
||||||
return `${(bytes / Math.pow(1024, i)).toFixed(2)} ${sizes[i]}`;
|
return `${(bytes / Math.pow(1024, i)).toFixed(2)} ${sizes[i]}`;
|
||||||
}
|
}
|
||||||
@ -465,8 +503,10 @@ class BackupUtils {
|
|||||||
* @returns {string} Formatted duration string
|
* @returns {string} Formatted duration string
|
||||||
*/
|
*/
|
||||||
static formatDuration(milliseconds) {
|
static formatDuration(milliseconds) {
|
||||||
if (milliseconds < 1000) return `${milliseconds}ms`;
|
if (milliseconds < 1000)
|
||||||
if (milliseconds < 60000) return `${(milliseconds / 1000).toFixed(2)}s`;
|
return `${milliseconds}ms`;
|
||||||
|
if (milliseconds < 60000)
|
||||||
|
return `${(milliseconds / 1000).toFixed(2)}s`;
|
||||||
return `${(milliseconds / 60000).toFixed(2)}m`;
|
return `${(milliseconds / 60000).toFixed(2)}m`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -483,7 +523,7 @@ class BackupUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const command = `sqlite3 "${databasePath}" "PRAGMA integrity_check;"`;
|
const command = `sqlite3 "${databasePath}" "PRAGMA integrity_check;"`;
|
||||||
const { stdout } = await execAsync(command);
|
const {stdout} = await execAsync(command);
|
||||||
return stdout.trim() === 'ok';
|
return stdout.trim() === 'ok';
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user