diff --git a/lib/index.js b/lib/index.js index 21a8093..eb0bd38 100644 --- a/lib/index.js +++ b/lib/index.js @@ -325,9 +325,70 @@ class SQLiteBackup { } } + _getDatabaseDriver() { + var sqlite3 = null; + var sqliteType = "cli"; + try { + sqlite3 = require('better-sqlite3'); + sqliteType = "better-sqlite3"; + } catch (ex) { + try { + sqlite3 = require("sqlite3"); + sqliteType = "sqlite3"; + } catch (ex) { + sqlite3 = null; + sqliteType = "cli"; + } + } + return {type: sqliteType, driver: sqlite3}; + } + async _backupUsingBackupCommand(backupPath) { - const command = `sqlite3 "${this.databasePath}" ".backup '${backupPath}'"`; - await execAsync(command); + const dbDriver = this._getDatabaseDriver(); + + switch (dbDriver.type) { + case "cli": + const command = `sqlite3 "${this.databasePath}" ".backup '${backupPath}'"`; + await execAsync(command); + return; + case "better-sqlite3": + const db = dbDriver.driver(this.databasePath); + await db.backup(backupPath); + return; + case "sqlite3": + console.info("Using node-sqlite3"); + await this._backupUsingSQLite3Package(dbDriver.driver, this.databasePath, backupPath); + return; + } + } + + async _backupUsingSQLite3Package(driver, databasePath, backupPath) { + return new Promise((resolve, reject) => { + const db = new driver.Database(databasePath, driver.OPEN_READONLY, err => { + if (err) + return reject(err); + }); + + const backup = db.backup(backupPath); + + backup.step(-1, err => { + if (err) { + backup.finish(() => { + db.close(); + reject(err); + }); + return; + } + + backup.finish(err => { + db.close(); + if (err) + reject(err); + else + resolve(); + }); + }); + }); } async _backupUsingCopy(backupPath) {