Don't back up an unchanged database

currentDBTime and lastBackupTime became Date objects when the backup was
made asynchronous in 2014, so comparing them with == has tested object
identity and returned false ever since. The interval check that follows
measures from the backup file's mtime, which a copy inherits from the
database file, so an unchanged database was backed up on every idle.

Fixes #6027
This commit is contained in:
Dan Stillman 2026-08-21 16:06:09 -04:00
parent ad98e84d24
commit 85e1cbc75c

View file

@ -1350,7 +1350,10 @@ Zotero.DBConnection.prototype.backUpDatabase = async function ({ force, suffix,
if (await OS.File.exists(backupFile)) {
let currentDBTime = (await OS.File.stat(file)).lastModificationDate;
let lastBackupTime = (await OS.File.stat(backupFile)).lastModificationDate;
if (currentDBTime == lastBackupTime) {
// In WAL mode the database file's mtime advances only when the WAL is
// checkpointed, so changes still in the WAL leave it matching the backup
if (currentDBTime.getTime() == lastBackupTime.getTime()
&& !(await this._hasWALContents(file))) {
Zotero.debug("Database '" + this._dbName + "' hasn't changed -- skipping backup");
return false;
}
@ -1702,6 +1705,25 @@ Zotero.DBConnection.prototype._getConnectionAsync = async function () {
};
/**
* Check whether the database's WAL file contains data not yet in the database file
*
* @param {String} file - Path to the database file
* @return {Promise<Boolean>}
*/
Zotero.DBConnection.prototype._hasWALContents = async function (file) {
try {
return (await IOUtils.stat(file + '-wal')).size > 0;
}
catch (e) {
if (e.name != 'NotFoundError') {
throw e;
}
return false;
}
};
/**
* Determine whether the database file can use WAL journal mode
*