Delay Extra field migration until after auto-sync and show progress

This avoids redundant field migration on other devices if it has already
run on one. Conflict resolution should automatically ignore identical
changes, so it's not the end of the world if it runs in multiple places,
but we might as well avoid it if we can.
This commit is contained in:
Dan Stillman 2025-12-29 15:55:18 -05:00
parent a5843d8e2d
commit fb20db9a58
3 changed files with 78 additions and 12 deletions

View file

@ -671,7 +671,7 @@ Zotero.Schema = new function () {
* This needs the data object architecture to be initialized, so it's called from zotero.js
* rather than in _updateGlobalSchema().
*/
this.migrateExtraFields = async function () {
this.migrateExtraFields = async function ({ onProgress }) {
// Check for a flag set by _updateGlobalSchema()
var needsUpdate = await Zotero.DB.valueQueryAsync(
"SELECT COUNT(*) FROM settings WHERE setting='globalSchema' AND key='migrateExtra'"
@ -680,11 +680,14 @@ Zotero.Schema = new function () {
return;
}
Zotero.debug("Migrating fields from Extra");
var fieldID = Zotero.ItemFields.getID('extra');
var sql = "SELECT itemID, value FROM itemData "
+ "JOIN itemDataValues USING (valueID) "
+ "WHERE fieldID=?";
var rows = await Zotero.DB.queryAsync(sql, fieldID);
var itemIDs = [];
for (let row of rows) {
let { itemType, fields, creators } = Zotero.Utilities.Internal.extractExtraFields(
@ -696,14 +699,35 @@ Zotero.Schema = new function () {
}
var items = await Zotero.Items.getAsync(itemIDs);
await Zotero.Items.loadDataTypes(items);
for (let item of items) {
let changed = item.migrateExtraFields();
if (!changed) continue;
await item.saveTx({
skipDateModifiedUpdate: true,
skipSelect: true
});
Zotero.debug(`${items.length} items to migrate`);
if (items.length) {
await Zotero.Items.loadDataTypes(items);
let progress = 0;
let progressMax = items.length;
if (onProgress) {
onProgress({ progress, progressMax });
}
let notifierQueue = new Zotero.Notifier.Queue;
try {
for (let item of items) {
let changed = item.migrateExtraFields();
if (changed) {
await item.saveTx({
skipDateModifiedUpdate: true,
skipSelect: true,
notifierQueue
});
}
onProgress({ progress: ++progress, progressMax });
}
}
finally {
await Zotero.Notifier.commit(notifierQueue);
}
}
await Zotero.DB.queryAsync(

View file

@ -745,9 +745,6 @@ const { CommandLineOptions } = ChromeUtils.importESModule("chrome://zotero/conte
}
});
// Migrate fields from Extra that can be moved to item fields after a schema update
await Zotero.Schema.migrateExtraFields();
Zotero.Items.startEmptyTrashTimer();
Zotero.QuickCopy.init();
@ -758,6 +755,49 @@ const { CommandLineOptions } = ChromeUtils.importESModule("chrome://zotero/conte
Zotero.Schema.schemaUpdatePromise.then(Zotero.purgeDataObjects.bind(Zotero));
// Migrate fields from Extra that can be moved to item fields after a schema update
//
// To test migration after the server has been updated, disable auto-sync and uncomment
// this line instead of the following one
//Zotero.Schema.schemaUpdatePromise.then(async () => {
Zotero.startupSyncPromise.then(async () => {
let progressWin;
let itemProgress;
// Feed updates (e.g., deleting old items) can interfere with this, so pause them
// until we're done
let feedPauser = await Zotero.Feeds.pause();
try {
await Zotero.Schema.migrateExtraFields({
onProgress: ({ progress, progressMax }) => {
if (!progressWin) {
progressWin = new Zotero.ProgressWindow({
closeOnClick: false
});
let title = Zotero.getString('upgrade.status');
progressWin.changeHeadline(title);
itemProgress = new progressWin.ItemProgress(
'journalArticle',
Zotero.getString('migrate-extra-fields-progress-message')
);
progressWin.show();
}
itemProgress.setProgress(progress / progressMax * 100);
}
});
}
catch (e) {
Zotero.logError(e);
itemProgress.setError();
}
finally {
feedPauser.resume();
}
if (progressWin) {
progressWin.startCloseTimer(3000);
}
});
return true;
}
catch (e) {

View file

@ -841,6 +841,8 @@ connector-version-warning = The { -app-name } Connector must be updated to work
userjs-pref-warning = Some { -app-name } settings have been overridden using an unsupported method. { -app-name } will revert them and restart.
migrate-extra-fields-progress-message = Migrating new fields from Extra field
long-tag-fixer-window-title =
.title = Split Tags
long-tag-fixer-button-dont-split =