- Added wizards for userdata schema upgrade (to give feedback during upgrades) and error reporting (to send errors to the Zotero server)
- New Actions menu option, "Report Errors...", to send chrome errors from the Error Console to the Zotero server via the error reporting wizard -- no more Advanced Instructions from the Reporting Bugs page - Disabled unresponsive script indicator during schema upgrades, since that seems to be what caused problems during the Beta 4 upgrade - Added repair steps for interrupted Beta 4 upgrades - Speed up b4.r2 itemNotes repair step, which may have been what was causing the unresponsive script warning on large libraries - Moved some Zotero.UnresponsiveScriptIndicator.enable() calls into finally{} blocks to make sure they get triggered - New method Zotero.getSystemInfo() to get some info on the environment (platform, version, app, app version, locale) as a string for inclusion in bug reports - Added public property skipBackup to Zotero.DB so a startup error can cancel the shutdown backup Closes #321, Notification window to show when rebuilding cache
This commit is contained in:
parent
fa440368b9
commit
50f516d7f1
136
chrome/content/zotero/errorReport.xul
Normal file
136
chrome/content/zotero/errorReport.xul
Normal file
|
@ -0,0 +1,136 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://zotero/skin/errorReport.css" type="text/css"?>
|
||||
|
||||
<!DOCTYPE window SYSTEM "chrome://zotero/locale/zotero.dtd">
|
||||
|
||||
<wizard xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
id="zotero-error-report" title="Zotero">
|
||||
|
||||
<script>
|
||||
<![CDATA[
|
||||
var Zotero_Error_Report = new function() {
|
||||
this.init = init;
|
||||
this.sendErrorReport = sendErrorReport;
|
||||
|
||||
var obj = window.arguments[0].wrappedJSObject;
|
||||
var Zotero = obj.Zotero;
|
||||
var data = obj.data;
|
||||
var msg = data.msg;
|
||||
var e = data.e;
|
||||
var askForSteps = data.askForSteps;
|
||||
var extraData = data.extraData ? data.extraData : '';
|
||||
|
||||
function init() {
|
||||
var wizard = document.getElementById('zotero-error-report');
|
||||
|
||||
document.getElementById('zotero-failure-message').appendChild(document.createTextNode(msg));
|
||||
document.getElementById('zotero-error-message').value = e;
|
||||
|
||||
var continueButtonName = wizard.getButton('next').getAttribute('label');
|
||||
var str = Zotero.getString('errorReport.advanceMessage', continueButtonName);
|
||||
document.getElementById('zotero-advance-message').setAttribute('value', str);
|
||||
|
||||
if (askForSteps) {
|
||||
var str = Zotero.getString('errorReport.stepsToReproduce') + "\n\n1.\n2.\n3.\n\n"
|
||||
+ Zotero.getString('errorReport.expectedResult') + "\n\n"
|
||||
+ Zotero.getString('errorReport.actualResult') + "\n";
|
||||
document.getElementById('zotero-error-steps').value = str;
|
||||
document.getElementById('zotero-error-steps-box').setAttribute('hidden', false)
|
||||
}
|
||||
}
|
||||
|
||||
function sendErrorReport() {
|
||||
var parts = {
|
||||
error: "true",
|
||||
email: document.getElementById('zotero-email-address').value,
|
||||
errorSteps: document.getElementById('zotero-error-steps').value,
|
||||
errorData: Zotero.getErrors(true).join('\n'),
|
||||
extraData: extraData,
|
||||
diagnostic: Zotero.getSystemInfo()
|
||||
};
|
||||
|
||||
var body = '';
|
||||
for (var key in parts) {
|
||||
body += key + '=' + encodeURIComponent(parts[key]) + '&';
|
||||
}
|
||||
body = body.substr(0, body.length - 1);
|
||||
Zotero.Utilities.HTTP.doPost("http://www.zotero.org/repo/report", body,
|
||||
_sendErrorReportCallback);
|
||||
}
|
||||
|
||||
|
||||
function _sendErrorReportCallback(xmlhttp) {
|
||||
var wizard = document.getElementById('zotero-error-report');
|
||||
if (!wizard) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!xmlhttp.responseXML){
|
||||
try {
|
||||
if (xmlhttp.status>1000){
|
||||
alert('No network connection');
|
||||
}
|
||||
else {
|
||||
alert('Invalid response from repository');
|
||||
}
|
||||
}
|
||||
catch (e){
|
||||
alert('Repository cannot be contacted');
|
||||
}
|
||||
|
||||
wizard.rewind();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var reported = xmlhttp.responseXML.getElementsByTagName('reported');
|
||||
if (reported.length != 1) {
|
||||
alert('Invalid response from repository');
|
||||
wizard.rewind();
|
||||
return;
|
||||
}
|
||||
|
||||
wizard.advance();
|
||||
wizard.getButton('cancel').setAttribute('disabled', true);
|
||||
wizard.canRewind = false;
|
||||
var reportID = reported[0].getAttribute('reportID');
|
||||
document.getElementById('zotero-report-id').setAttribute('value', reportID);
|
||||
document.getElementById('zotero-report-result').setAttribute('hidden', false);
|
||||
}
|
||||
}
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<wizardpage onpageshow="Zotero_Error_Report.init()">
|
||||
<description id="zotero-failure-message"/>
|
||||
<textbox id="zotero-error-message" class="plain" readonly="true" multiline="true" rows="6"/>
|
||||
<description id="zotero-advance-message"/>
|
||||
</wizardpage>
|
||||
|
||||
<wizardpage label="&zotero.errorReport.additionalInfo; &zotero.general.optional;">
|
||||
<hbox id="zotero-email-address-box">
|
||||
<label value="&zotero.errorReport.emailAddress;" control="zotero-email-address"/>
|
||||
<textbox id="zotero-email-address" flex="1"/>
|
||||
</hbox>
|
||||
|
||||
<vbox id="zotero-error-steps-box" hidden="true">
|
||||
<description control="zotero-error-steps">&zotero.errorReport.errorSteps;</description>
|
||||
<textbox id="zotero-error-steps" multiline="true" rows="6"/>
|
||||
</vbox>
|
||||
</wizardpage>
|
||||
|
||||
<wizardpage onpageshow="Zotero_Error_Report.sendErrorReport()">
|
||||
<description>&zotero.errorReport.submissionInProgress;</description>
|
||||
</wizardpage>
|
||||
|
||||
<wizardpage>
|
||||
<description>&zotero.errorReport.submitted;</description>
|
||||
<description id="zotero-report-result" hidden="true">
|
||||
&zotero.errorReport.reportID;
|
||||
<textbox id="zotero-report-id" class="plain" readonly="true"/>
|
||||
</description>
|
||||
<description>&zotero.errorReport.includeReportID;</description>
|
||||
</wizardpage>
|
||||
</wizard>
|
|
@ -81,6 +81,7 @@ var ZoteroPane = new function()
|
|||
this.showSelectedAttachmentInFilesystem = showSelectedAttachmentInFilesystem;
|
||||
this.showAttachmentNotFoundDialog = showAttachmentNotFoundDialog;
|
||||
this.relinkAttachment = relinkAttachment;
|
||||
this.reportErrors = reportErrors;
|
||||
|
||||
var self = this;
|
||||
|
||||
|
@ -582,12 +583,16 @@ var ZoteroPane = new function()
|
|||
itemgroup.setSearch('');
|
||||
itemgroup.setTags(getTagSelection());
|
||||
|
||||
Zotero.UnresponsiveScriptIndicator.disable();
|
||||
this.itemsView = new Zotero.ItemTreeView(itemgroup);
|
||||
this.itemsView.addCallback(_setTagScope);
|
||||
document.getElementById('zotero-items-tree').view = this.itemsView;
|
||||
this.itemsView.selection.clearSelection();
|
||||
Zotero.UnresponsiveScriptIndicator.enable();
|
||||
try {
|
||||
Zotero.UnresponsiveScriptIndicator.disable();
|
||||
this.itemsView = new Zotero.ItemTreeView(itemgroup);
|
||||
this.itemsView.addCallback(_setTagScope);
|
||||
document.getElementById('zotero-items-tree').view = this.itemsView;
|
||||
this.itemsView.selection.clearSelection();
|
||||
}
|
||||
finally {
|
||||
Zotero.UnresponsiveScriptIndicator.enable();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1707,6 +1712,21 @@ var ZoteroPane = new function()
|
|||
item.relinkAttachmentFile(file);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function reportErrors() {
|
||||
var errors = Zotero.getErrors(true);
|
||||
var ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
|
||||
.getService(Components.interfaces.nsIWindowWatcher);
|
||||
var data = {
|
||||
msg: Zotero.getString('errorReport.followingErrors'),
|
||||
e: errors.join('\n\n'),
|
||||
askForSteps: true
|
||||
};
|
||||
var io = { wrappedJSObject: { Zotero: Zotero, data: data } };
|
||||
var win = ww.openWindow(null, "chrome://zotero/content/errorReport.xul",
|
||||
"zotero-error-report", "chrome,centerscreen,modal", io);
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener("load", function(e) { ZoteroPane.onLoad(e); }, false);
|
||||
|
|
|
@ -37,7 +37,9 @@
|
|||
|
||||
<commandset id="mainCommandSet">
|
||||
<command id="cmd_zotero_search" oncommand="ZoteroPane.search();"/>
|
||||
<command id="cmd_zotero_reportErrors" oncommand="ZoteroPane.reportErrors();"/>
|
||||
</commandset>
|
||||
|
||||
<toolbarpalette id="BrowserToolbarPalette">
|
||||
<toolbarbutton id="scholar-toolbar-button"/> <!-- May be necessary to keep pre-1.0b2 installs from breaking -->
|
||||
<toolbarbutton id="zotero-toolbar-button" class="toolbarbutton-1"
|
||||
|
@ -109,13 +111,14 @@
|
|||
<spacer flex="1"/>
|
||||
<toolbarbutton id="zotero-tb-tag-selector" tooltiptext="&zotero.toolbar.tagSelector.label;" oncommand="ZoteroPane.toggleTagSelector()"/>
|
||||
<toolbarbutton id="zotero-tb-actions-menu" tooltiptext="&zotero.toolbar.actions.label;" type="menu">
|
||||
<menupopup id="zotero-tb-actions-popup">
|
||||
<menupopup id="zotero-tb-actions-popup" onpopupshowing="document.getElementById('cmd_zotero_reportErrors').setAttribute('disabled', Zotero.getErrors().length == 0)">
|
||||
<menuitem id="zotero-tb-actions-import" label="&zotero.toolbar.import.label;" oncommand="Zotero_File_Interface.importFile();"/>
|
||||
<menuitem id="zotero-tb-actions-export" label="&zotero.toolbar.export.label;" oncommand="Zotero_File_Interface.exportFile();"/>
|
||||
<menuseparator id="zotero-tb-actions-utilities-separator" hidden="true"/>
|
||||
<menuseparator id="zotero-tb-actions-separator"/>
|
||||
<menuitem id="zotero-tb-actions-prefs" label="&zotero.toolbar.preferences.label;"
|
||||
oncommand="window.openDialog('chrome://zotero/content/preferences/preferences.xul', 'zotero-prefs', 'chrome,titlebar,toolbar,' + Zotero.Prefs.get('browser.preferences.instantApply', true) ? 'dialog=no' : 'modal')"/>
|
||||
<menuitem id="zotero-tb-actions-reportErrors" label="&zotero.toolbar.reportErrors;" command="cmd_zotero_reportErrors" disabled="true"/>
|
||||
<menuitem id="zotero-tb-actions-documentation" label="&zotero.toolbar.documentation.label;" oncommand="window.open('http://www.zotero.org/documentation/', '', 'menubar=yes,location=yes,toolbar=yes,personalbar=yes,resizable=yes,scrollbars=yes,status=yes');"/>
|
||||
<menuitem id="zotero-tb-actions-about" label="&zotero.toolbar.about.label;" oncommand="window.openDialog('chrome://zotero/content/about.xul', 'about', 'chrome')"/>
|
||||
</menupopup>
|
||||
|
@ -348,6 +351,12 @@
|
|||
icon.setAttribute('compact', true);
|
||||
break;
|
||||
}
|
||||
|
||||
// Used for loading the changelog after upgrades
|
||||
if (Zotero.initialURL) {
|
||||
gBrowser.selectedTab = gBrowser.addTab(Zotero.initialURL);
|
||||
Zotero.initialURL = null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (Zotero) {
|
||||
|
|
93
chrome/content/zotero/upgrade.xul
Normal file
93
chrome/content/zotero/upgrade.xul
Normal file
|
@ -0,0 +1,93 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://zotero/skin/upgrade.css" type="text/css"?>
|
||||
|
||||
<!DOCTYPE window SYSTEM "chrome://zotero/locale/zotero.dtd">
|
||||
|
||||
<wizard id="zotero-schema-upgrade" title="Zotero"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<script>
|
||||
<![CDATA[
|
||||
var Zotero_Schema_Upgrade = new function() {
|
||||
this.init = init;
|
||||
this.onAdvance = onAdvance;
|
||||
this.doUpgrade = doUpgrade;
|
||||
this.onChangeLogLinkClick = onChangeLogLinkClick;
|
||||
|
||||
var obj = window.arguments[0].wrappedJSObject;
|
||||
var Zotero = obj.Zotero;
|
||||
var data = obj.data;
|
||||
|
||||
function init() {
|
||||
var wizard = document.getElementById('zotero-schema-upgrade');
|
||||
|
||||
var continueButtonName = wizard.getButton('next').getAttribute('label');
|
||||
var str = Zotero.getString('upgrade.advanceMessage', continueButtonName);
|
||||
document.getElementById('zotero-advance-message').setAttribute('value', str);
|
||||
}
|
||||
|
||||
|
||||
function onAdvance() {
|
||||
var wizard = document.getElementById('zotero-schema-upgrade');
|
||||
wizard.getButton('cancel').setAttribute('disabled', true);
|
||||
wizard.canRewind = false;
|
||||
}
|
||||
|
||||
|
||||
function doUpgrade() {
|
||||
var wizard = document.getElementById('zotero-schema-upgrade');
|
||||
|
||||
onAdvance();
|
||||
|
||||
try {
|
||||
Zotero.Schema.updateSchema();
|
||||
}
|
||||
catch (e) {
|
||||
data.msg = Zotero.getString('upgrade.failed');
|
||||
data.e = e;
|
||||
|
||||
Components.utils.reportError(e);
|
||||
|
||||
var cancelButton = wizard.getButton('cancel');
|
||||
cancelButton.setAttribute('disabled', false);
|
||||
cancelButton.click();
|
||||
return;
|
||||
}
|
||||
|
||||
data.success = true;
|
||||
|
||||
wizard.advance();
|
||||
}
|
||||
|
||||
|
||||
function onChangeLogLinkClick() {
|
||||
Zotero.initialURL = 'http://www.zotero.org/documentation/changelog';
|
||||
document.getElementById('zotero-schema-upgrade').getButton('finish').click();
|
||||
}
|
||||
}
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<wizardpage onpageshow="Zotero_Schema_Upgrade.init()">
|
||||
<description>&zotero.upgrade.newVersionInstalled;</description>
|
||||
<description>&zotero.upgrade.upgradeRequired; &zotero.upgrade.autoBackup;</description>
|
||||
<description id="zotero-advance-message"/>
|
||||
</wizardpage>
|
||||
|
||||
<wizardpage onpageshow="setTimeout('Zotero_Schema_Upgrade.doUpgrade()', 100)">
|
||||
<description>&zotero.upgrade.upgradeInProgress;</description>
|
||||
<progressmeter mode="undetermined"/>
|
||||
</wizardpage>
|
||||
|
||||
<wizardpage onpageshow="Zotero_Schema_Upgrade.onAdvance()">
|
||||
<description>&zotero.upgrade.upgradeSucceeded;</description>
|
||||
<description>
|
||||
&zotero.upgrade.changeLogBeforeLink;
|
||||
<label id="zotero-change-log-link" class="text-link" value="&zotero.upgrade.changeLogLink;"
|
||||
onclick="Zotero_Schema_Upgrade.onChangeLogLinkClick()"/>
|
||||
&zotero.upgrade.changeLogAfterLink;
|
||||
</description>
|
||||
</wizardpage>
|
||||
</wizard>
|
|
@ -25,6 +25,8 @@ Zotero.DBConnection = function(dbName) {
|
|||
throw ('DB name not provided in Zotero.DBConnection()');
|
||||
}
|
||||
|
||||
this.skipBackup = false;
|
||||
|
||||
// Private members
|
||||
this._dbName = dbName;
|
||||
this._shutdown = false;
|
||||
|
@ -32,7 +34,7 @@ Zotero.DBConnection = function(dbName) {
|
|||
this._transactionRollback = null;
|
||||
this._transactionNestingLevel = 0;
|
||||
this._callbacks = { begin: [], commit: [], rollback: [] };
|
||||
this._skipBackup = false;
|
||||
this._dbIsCorrupt = null
|
||||
this._self = this;
|
||||
}
|
||||
|
||||
|
@ -543,7 +545,7 @@ Zotero.DBConnection.prototype.observe = function(subject, topic, data) {
|
|||
|
||||
|
||||
Zotero.DBConnection.prototype.checkException = function (e) {
|
||||
if (e.name == 'NS_ERROR_FILE_CORRUPTED') {
|
||||
if (e.name && e.name == 'NS_ERROR_FILE_CORRUPTED') {
|
||||
var file = Zotero.getZoteroDatabase(this._dbName, 'is.corrupt');
|
||||
var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"]
|
||||
.createInstance(Components.interfaces.nsIFileOutputStream);
|
||||
|
@ -551,7 +553,7 @@ Zotero.DBConnection.prototype.checkException = function (e) {
|
|||
foStream.write('', 0);
|
||||
foStream.close();
|
||||
|
||||
this._skipBackup = true;
|
||||
this._dbIsCorrupt = true;
|
||||
|
||||
var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
|
||||
.getService(Components.interfaces.nsIPromptService);
|
||||
|
@ -589,7 +591,11 @@ Zotero.DBConnection.prototype.backupDatabase = function (suffix) {
|
|||
|
||||
var corruptMarker = Zotero.getZoteroDatabase(this._dbName, 'is.corrupt').exists();
|
||||
|
||||
if (this._skipBackup || corruptMarker) {
|
||||
if (this.skipBackup) {
|
||||
this._debug("Skipping backup of database '" + this._dbName + "'", 1);
|
||||
return false;
|
||||
}
|
||||
else if (this._dbIsCorrupt || corruptMarker) {
|
||||
this._debug("Database '" + this._dbName + "' is marked as corrupt--skipping backup", 1);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -21,14 +21,56 @@
|
|||
*/
|
||||
|
||||
Zotero.Schema = new function(){
|
||||
this.userDataUpgradeRequired = userDataUpgradeRequired;
|
||||
this.showUpgradeWizard = showUpgradeWizard;
|
||||
this.updateSchema = updateSchema;
|
||||
this.updateScrapersRemote = updateScrapersRemote;
|
||||
this.stopRepositoryTimer = stopRepositoryTimer;
|
||||
|
||||
this.upgradeFinished = false;
|
||||
this.goToChangeLog = false;
|
||||
|
||||
var _dbVersions = [];
|
||||
var _schemaVersions = [];
|
||||
var _repositoryTimer;
|
||||
var _remoteUpdateInProgress = false;
|
||||
|
||||
this.updateSchema = updateSchema;
|
||||
this.updateScrapersRemote = updateScrapersRemote;
|
||||
this.stopRepositoryTimer = stopRepositoryTimer;
|
||||
|
||||
function userDataUpgradeRequired() {
|
||||
var dbVersion = _getDBVersion('userdata');
|
||||
var schemaVersion = _getSchemaSQLVersion('userdata');
|
||||
|
||||
return dbVersion && (dbVersion < schemaVersion);
|
||||
}
|
||||
|
||||
|
||||
function showUpgradeWizard() {
|
||||
var dbVersion = _getDBVersion('userdata');
|
||||
var schemaVersion = _getSchemaSQLVersion('userdata');
|
||||
|
||||
var ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
|
||||
.getService(Components.interfaces.nsIWindowWatcher);
|
||||
var obj = { Zotero: Zotero, data: { success: false } };
|
||||
var io = { wrappedJSObject: obj };
|
||||
var win = ww.openWindow(null, "chrome://zotero/content/upgrade.xul",
|
||||
"zotero-schema-upgrade", "chrome,centerscreen,modal", io);
|
||||
|
||||
if (obj.data.e) {
|
||||
var ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
|
||||
.getService(Components.interfaces.nsIWindowWatcher);
|
||||
var data = {
|
||||
msg: obj.data.msg,
|
||||
e: obj.data.e,
|
||||
extraData: "Schema upgrade from " + dbVersion + " to " + schemaVersion
|
||||
};
|
||||
var io = { wrappedJSObject: { Zotero: Zotero, data: data } };
|
||||
var win = ww.openWindow(null, "chrome://zotero/content/errorReport.xul",
|
||||
"zotero-error-report", "chrome,centerscreen,modal", io);
|
||||
}
|
||||
|
||||
return obj.data.success;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Checks if the DB schema exists and is up-to-date, updating if necessary
|
||||
|
@ -46,75 +88,77 @@ Zotero.Schema = new function(){
|
|||
|
||||
var schemaVersion = _getSchemaSQLVersion('userdata');
|
||||
|
||||
Zotero.UnresponsiveScriptIndicator.disable();
|
||||
|
||||
// If upgrading userdata, make backup of database first
|
||||
if (dbVersion < schemaVersion){
|
||||
Zotero.DB.backupDatabase(dbVersion);
|
||||
}
|
||||
|
||||
Zotero.DB.beginTransaction();
|
||||
|
||||
try {
|
||||
// Old schema system
|
||||
if (!dbVersion){
|
||||
// Check for pre-1.0b2 'user' table
|
||||
var user = _getDBVersion('user');
|
||||
if (user)
|
||||
{
|
||||
dbVersion = user;
|
||||
var sql = "UPDATE version SET schema=? WHERE schema=?";
|
||||
Zotero.DB.query(sql, ['userdata', 'user']);
|
||||
}
|
||||
else
|
||||
{
|
||||
dbVersion = 0;
|
||||
}
|
||||
Zotero.UnresponsiveScriptIndicator.disable();
|
||||
|
||||
// If upgrading userdata, make backup of database first
|
||||
if (dbVersion < schemaVersion){
|
||||
Zotero.DB.backupDatabase(dbVersion);
|
||||
}
|
||||
|
||||
var up1 = _migrateUserDataSchema(dbVersion);
|
||||
var up2 = _updateSchema('system');
|
||||
var up3 = _updateSchema('scrapers');
|
||||
Zotero.DB.beginTransaction();
|
||||
|
||||
// Rebuild fulltext cache if necessary
|
||||
if (Zotero.Fulltext.cacheIsOutdated()){
|
||||
Zotero.Fulltext.rebuildCache();
|
||||
}
|
||||
Zotero.DB.commitTransaction();
|
||||
}
|
||||
catch(e){
|
||||
Zotero.debug(e);
|
||||
Zotero.DB.rollbackTransaction();
|
||||
Zotero.UnresponsiveScriptIndicator.enable();
|
||||
throw(e);
|
||||
}
|
||||
|
||||
if (up1) {
|
||||
// Upgrade seems to have been a success -- delete any previous backups
|
||||
var maxPrevious = dbVersion - 1;
|
||||
var file = Zotero.getZoteroDirectory();
|
||||
// directoryEntries.hasMoreElements() throws an error (possibly
|
||||
// because of the temporary SQLite journal file?), so we just look
|
||||
// for all versions
|
||||
for (var i=maxPrevious; i>=29; i--) {
|
||||
var fileName = 'zotero.sqlite.' + i + '.bak';
|
||||
file.append(fileName);
|
||||
if (file.exists()) {
|
||||
Zotero.debug('Removing previous backup file ' + fileName);
|
||||
file.remove(null);
|
||||
try {
|
||||
// Old schema system
|
||||
if (!dbVersion){
|
||||
// Check for pre-1.0b2 'user' table
|
||||
var user = _getDBVersion('user');
|
||||
if (user)
|
||||
{
|
||||
dbVersion = user;
|
||||
var sql = "UPDATE version SET schema=? WHERE schema=?";
|
||||
Zotero.DB.query(sql, ['userdata', 'user']);
|
||||
}
|
||||
else
|
||||
{
|
||||
dbVersion = 0;
|
||||
}
|
||||
}
|
||||
|
||||
var up1 = _migrateUserDataSchema(dbVersion);
|
||||
var up2 = _updateSchema('system');
|
||||
var up3 = _updateSchema('scrapers');
|
||||
|
||||
// Rebuild fulltext cache if necessary
|
||||
if (Zotero.Fulltext.cacheIsOutdated()){
|
||||
Zotero.Fulltext.rebuildCache();
|
||||
}
|
||||
Zotero.DB.commitTransaction();
|
||||
}
|
||||
catch(e){
|
||||
Zotero.debug(e);
|
||||
Zotero.DB.rollbackTransaction();
|
||||
throw(e);
|
||||
}
|
||||
|
||||
if (up1) {
|
||||
// Upgrade seems to have been a success -- delete any previous backups
|
||||
var maxPrevious = dbVersion - 1;
|
||||
var file = Zotero.getZoteroDirectory();
|
||||
// directoryEntries.hasMoreElements() throws an error (possibly
|
||||
// because of the temporary SQLite journal file?), so we just look
|
||||
// for all versions
|
||||
for (var i=maxPrevious; i>=29; i--) {
|
||||
var fileName = 'zotero.sqlite.' + i + '.bak';
|
||||
file.append(fileName);
|
||||
if (file.exists()) {
|
||||
Zotero.debug('Removing previous backup file ' + fileName);
|
||||
file.remove(null);
|
||||
}
|
||||
file = file.parent;
|
||||
}
|
||||
}
|
||||
|
||||
if (up2 || up3) {
|
||||
// Run a manual scraper update if upgraded and pref set
|
||||
if (Zotero.Prefs.get('automaticScraperUpdates')){
|
||||
this.updateScrapersRemote(2);
|
||||
}
|
||||
file = file.parent;
|
||||
}
|
||||
}
|
||||
|
||||
if (up2 || up3) {
|
||||
// Run a manual scraper update if upgraded and pref set
|
||||
if (Zotero.Prefs.get('automaticScraperUpdates')){
|
||||
this.updateScrapersRemote(2);
|
||||
}
|
||||
finally {
|
||||
Zotero.UnresponsiveScriptIndicator.enable();
|
||||
}
|
||||
|
||||
Zotero.UnresponsiveScriptIndicator.enable();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -399,6 +443,7 @@ Zotero.Schema = new function(){
|
|||
}
|
||||
catch(e){
|
||||
Zotero.debug(e, 1);
|
||||
Components.utils.reportError(e);
|
||||
Zotero.DB.rollbackTransaction();
|
||||
alert('Error initializing Zotero database'); // TODO: localize
|
||||
throw(e);
|
||||
|
@ -433,7 +478,6 @@ Zotero.Schema = new function(){
|
|||
catch (e){
|
||||
Zotero.debug(e, 1);
|
||||
Zotero.DB.rollbackTransaction();
|
||||
alert('Error updating Zotero database'); // TODO: localize
|
||||
throw(e);
|
||||
}
|
||||
return true;
|
||||
|
@ -640,7 +684,7 @@ Zotero.Schema = new function(){
|
|||
* Migrate user data schema from an older version, preserving data
|
||||
*/
|
||||
function _migrateUserDataSchema(fromVersion){
|
||||
toVersion = _getSchemaSQLVersion('userdata');
|
||||
var toVersion = _getSchemaSQLVersion('userdata');
|
||||
|
||||
if (fromVersion==toVersion){
|
||||
return false;
|
||||
|
@ -761,6 +805,58 @@ Zotero.Schema = new function(){
|
|||
|
||||
// 1.0.0b3.r1
|
||||
|
||||
// Repair for interrupted B4 upgrades
|
||||
if (i==14) {
|
||||
var hash = Zotero.DB.getColumnHash('itemNotes');
|
||||
if (!hash.isAbstract) {
|
||||
// See if itemDataValues exists
|
||||
if (!Zotero.DB.tableExists('itemDataValues')) {
|
||||
// Copied from step 23
|
||||
var notes = Zotero.DB.query("SELECT itemID, note FROM itemNotes WHERE itemID IN (SELECT itemID FROM items WHERE itemTypeID=1)");
|
||||
if (notes) {
|
||||
var f = function(text) { var t = text.substring(0, 80); var ln = t.indexOf("\n"); if (ln>-1 && ln<80) { t = t.substring(0, ln); } return t; }
|
||||
for (var j=0; j<notes.length; j++) {
|
||||
Zotero.DB.query("REPLACE INTO itemNoteTitles VALUES (?,?)", [notes[j]['itemID'], f(notes[j]['note'])]);
|
||||
}
|
||||
}
|
||||
|
||||
Zotero.DB.query("CREATE TABLE itemDataValues (\n valueID INT,\n value,\n PRIMARY KEY (valueID)\n);");
|
||||
var values = Zotero.DB.columnQuery("SELECT DISTINCT value FROM itemData");
|
||||
if (values) {
|
||||
for (var j=0; j<values.length; j++) {
|
||||
var valueID = Zotero.getRandomID('itemDataValues', 'valueID', 2097152); // Stored in 3 bytes
|
||||
Zotero.DB.query("INSERT INTO itemDataValues VALUES (?,?)", [valueID, values[j]]);
|
||||
}
|
||||
}
|
||||
|
||||
Zotero.DB.query("CREATE TEMPORARY TABLE itemDataTemp AS SELECT itemID, fieldID, (SELECT valueID FROM itemDataValues WHERE value=ID.value) AS valueID FROM itemData ID");
|
||||
Zotero.DB.query("DROP TABLE itemData");
|
||||
Zotero.DB.query("CREATE TABLE itemData (\n itemID INT,\n fieldID INT,\n valueID INT,\n PRIMARY KEY (itemID, fieldID),\n FOREIGN KEY (itemID) REFERENCES items(itemID),\n FOREIGN KEY (fieldID) REFERENCES fields(fieldID)\n FOREIGN KEY (valueID) REFERENCES itemDataValues(valueID)\n);");
|
||||
Zotero.DB.query("INSERT INTO itemData SELECT * FROM itemDataTemp");
|
||||
Zotero.DB.query("DROP TABLE itemDataTemp");
|
||||
|
||||
i = 23;
|
||||
continue;
|
||||
}
|
||||
|
||||
var rows = Zotero.DB.query("SELECT * FROM itemData WHERE valueID NOT IN (SELECT valueID FROM itemDataValues)");
|
||||
if (rows) {
|
||||
for (var j=0; j<rows.length; j++) {
|
||||
for (var j=0; j<values.length; j++) {
|
||||
var valueID = Zotero.getRandomID('itemDataValues', 'valueID', 2097152); // Stored in 3 bytes
|
||||
Zotero.DB.query("INSERT INTO itemDataValues VALUES (?,?)", [valueID, values[j]]);
|
||||
Zotero.DB.query("UPDATE itemData SET valueID=? WHERE itemID=? AND fieldID=?", [valueID, rows[j]['itemID'], rows[j]['fieldID']]);
|
||||
}
|
||||
}
|
||||
i = 23;
|
||||
continue;
|
||||
}
|
||||
|
||||
i = 27;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (i==15) {
|
||||
Zotero.DB.query("DROP TABLE IF EXISTS annotations");
|
||||
}
|
||||
|
@ -852,16 +948,20 @@ Zotero.Schema = new function(){
|
|||
if (i==23) {
|
||||
Zotero.DB.query("CREATE TABLE IF NOT EXISTS itemNoteTitles (\n itemID INT,\n title TEXT,\n PRIMARY KEY (itemID),\n FOREIGN KEY (itemID) REFERENCES itemNotes(itemID)\n);");
|
||||
var notes = Zotero.DB.query("SELECT itemID, note FROM itemNotes WHERE itemID IN (SELECT itemID FROM items WHERE itemTypeID=1)");
|
||||
if (notes) {
|
||||
var f = function(text) { var t = text.substring(0, 80); var ln = t.indexOf("\n"); if (ln>-1 && ln<80) { t = t.substring(0, ln); } return t; }
|
||||
for each(var note in notes) {
|
||||
Zotero.DB.query("INSERT INTO itemNoteTitles VALUES (?,?)", [note['itemID'], f(note['note'])]);
|
||||
for (var j=0; j<notes.length; j++) {
|
||||
Zotero.DB.query("INSERT INTO itemNoteTitles VALUES (?,?)", [notes[j]['itemID'], f(notes[j]['note'])]);
|
||||
}
|
||||
}
|
||||
|
||||
Zotero.DB.query("CREATE TABLE IF NOT EXISTS itemDataValues (\n valueID INT,\n value,\n PRIMARY KEY (valueID)\n);");
|
||||
var values = Zotero.DB.columnQuery("SELECT DISTINCT value FROM itemData");
|
||||
for each(var value in values) {
|
||||
var valueID = Zotero.getRandomID('itemDataValues', 'valueID', 2097152); // Stored in 3 bytes
|
||||
Zotero.DB.query("INSERT INTO itemDataValues VALUES (?,?)", [valueID, value]);
|
||||
if (values) {
|
||||
for (var j=0; j<values.length; j++) {
|
||||
var valueID = Zotero.getRandomID('itemDataValues', 'valueID', 2097152); // Stored in 3 bytes
|
||||
Zotero.DB.query("INSERT INTO itemDataValues VALUES (?,?)", [valueID, values[j]]);
|
||||
}
|
||||
}
|
||||
|
||||
Zotero.DB.query("CREATE TEMPORARY TABLE itemDataTemp AS SELECT itemID, fieldID, (SELECT valueID FROM itemDataValues WHERE value=ID.value) AS valueID FROM itemData ID");
|
||||
|
@ -873,15 +973,17 @@ Zotero.Schema = new function(){
|
|||
|
||||
if (i==24) {
|
||||
var rows = Zotero.DB.query("SELECT * FROM itemData NATURAL JOIN itemDataValues WHERE fieldID IN (52,96,100)");
|
||||
for each(var row in rows) {
|
||||
if (!Zotero.Date.isMultipart(row['value'])) {
|
||||
var value = Zotero.Date.strToMultipart(row['value']);
|
||||
var valueID = Zotero.DB.valueQuery("SELECT valueID FROM itemDataValues WHERE value=?", value);
|
||||
if (!valueID) {
|
||||
var valueID = Zotero.getRandomID('itemDataValues', 'valueID', 2097152);
|
||||
Zotero.DB.query("INSERT INTO itemDataValues VALUES (?,?)", [valueID, value]);
|
||||
if (rows) {
|
||||
for (var j=0; j<rows.length; j++) {
|
||||
if (!Zotero.Date.isMultipart(rows[j]['value'])) {
|
||||
var value = Zotero.Date.strToMultipart(rows[j]['value']);
|
||||
var valueID = Zotero.DB.valueQuery("SELECT valueID FROM itemDataValues WHERE value=?", rows[j]['value']);
|
||||
if (!valueID) {
|
||||
var valueID = Zotero.getRandomID('itemDataValues', 'valueID', 2097152);
|
||||
Zotero.DB.query("INSERT INTO itemDataValues VALUES (?,?)", [valueID, value]);
|
||||
}
|
||||
Zotero.DB.query("UPDATE itemData SET valueID=? WHERE itemID=? AND fieldID=?", [valueID, rows[j]['itemID'], rows[j]['fieldID']]);
|
||||
}
|
||||
Zotero.DB.query("UPDATE itemData SET valueID=? WHERE itemID=? AND fieldID=?", [valueID, row['itemID'], row['fieldID']]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -902,8 +1004,17 @@ Zotero.Schema = new function(){
|
|||
|
||||
if (i==28) {
|
||||
var childNotes = Zotero.DB.query("SELECT * FROM itemNotes WHERE itemID IN (SELECT itemID FROM items) AND sourceItemID IS NOT NULL");
|
||||
if (!childNotes.length) {
|
||||
continue;
|
||||
}
|
||||
Zotero.DB.query("CREATE TEMPORARY TABLE itemNotesTemp AS SELECT * FROM itemNotes WHERE note IN (SELECT itemID FROM items) AND sourceItemID IS NOT NULL");
|
||||
Zotero.DB.query("CREATE INDEX tmp_itemNotes_pk ON itemNotesTemp(note, sourceItemID);");
|
||||
var num = Zotero.DB.valueQuery("SELECT COUNT(*) FROM itemNotesTemp");
|
||||
if (!num) {
|
||||
continue;
|
||||
}
|
||||
for (var j=0; j<childNotes.length; j++) {
|
||||
var reversed = Zotero.DB.query("SELECT * FROM itemNotes WHERE note=? AND sourceItemID=?", [childNotes[j].itemID, childNotes[j].sourceItemID]);
|
||||
var reversed = Zotero.DB.query("SELECT * FROM itemNotesTemp WHERE note=? AND sourceItemID=?", [childNotes[j].itemID, childNotes[j].sourceItemID]);
|
||||
if (!reversed.length) {
|
||||
continue;
|
||||
}
|
||||
|
@ -926,7 +1037,7 @@ Zotero.Schema = new function(){
|
|||
// 1.0.0b4.r2
|
||||
|
||||
if (i==29) {
|
||||
Zotero.DB.query("CREATE TABLE settings (\n setting TEXT,\n key TEXT,\n value,\n PRIMARY KEY (setting, key)\n);");
|
||||
Zotero.DB.query("CREATE TABLE IF NOT EXISTS settings (\n setting TEXT,\n key TEXT,\n value,\n PRIMARY KEY (setting, key)\n);");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -936,9 +1047,7 @@ Zotero.Schema = new function(){
|
|||
Zotero.DB.commitTransaction();
|
||||
}
|
||||
catch(e){
|
||||
Zotero.debug(e);
|
||||
Zotero.DB.rollbackTransaction();
|
||||
alert('Error migrating Zotero database');
|
||||
throw(e);
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@ var Zotero = new function(){
|
|||
this.debug = debug;
|
||||
this.log = log;
|
||||
this.getErrors = getErrors;
|
||||
this.getSystemInfo = getSystemInfo;
|
||||
this.varDump = varDump;
|
||||
this.safeDebug = safeDebug;
|
||||
this.getString = getString;
|
||||
|
@ -68,6 +69,7 @@ var Zotero = new function(){
|
|||
this.locale;
|
||||
this.isMac;
|
||||
this.isWin;
|
||||
this.initialURL; // used by Schema to show the changelog on upgrades
|
||||
|
||||
var _startupError;
|
||||
var _startupErrorHandler;
|
||||
|
@ -195,7 +197,19 @@ var Zotero = new function(){
|
|||
Zotero.Fulltext.init();
|
||||
|
||||
// Trigger updating of schema and scrapers
|
||||
Zotero.Schema.updateSchema();
|
||||
if (Zotero.Schema.userDataUpgradeRequired()) {
|
||||
var upgraded = Zotero.Schema.showUpgradeWizard();
|
||||
if (!upgraded) {
|
||||
this.skipLoading = true;
|
||||
Zotero.DB.skipBackup = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// If no userdata upgrade, still might need to process system/scrapers
|
||||
else {
|
||||
Zotero.Schema.updateSchema();
|
||||
}
|
||||
|
||||
Zotero.Schema.updateScrapersRemote();
|
||||
|
||||
// Initialize integration web server
|
||||
|
@ -203,6 +217,7 @@ var Zotero = new function(){
|
|||
Zotero.Integration.init();
|
||||
|
||||
this.initialized = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -412,7 +427,7 @@ var Zotero = new function(){
|
|||
}
|
||||
|
||||
|
||||
function getErrors() {
|
||||
function getErrors(asStrings) {
|
||||
var errors = [];
|
||||
var cs = Components.classes["@mozilla.org/consoleservice;1"].
|
||||
getService(Components.interfaces.nsIConsoleService);
|
||||
|
@ -421,23 +436,49 @@ var Zotero = new function(){
|
|||
|
||||
var skip = ['CSS Parser', 'content javascript'];
|
||||
|
||||
for each(var msg in messages) {
|
||||
Zotero.debug(msg);
|
||||
for each(var msg in messages.value) {
|
||||
//Zotero.debug(msg);
|
||||
try {
|
||||
msg.QueryInterface(Components.interfaces.nsIScriptError);
|
||||
if (skip.indexOf(msg.category) != -1) {
|
||||
//Zotero.debug(msg);
|
||||
if (skip.indexOf(msg.category) != -1 || msg.flags & msg.warningFlag) {
|
||||
continue;
|
||||
}
|
||||
errors.push(msg.errorMessage);
|
||||
}
|
||||
catch(e) {
|
||||
errors.push(msg.message);
|
||||
catch (e) { }
|
||||
|
||||
if (asStrings) {
|
||||
errors.push(msg.message)
|
||||
}
|
||||
else {
|
||||
errors.push(msg);
|
||||
}
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
|
||||
function getSystemInfo() {
|
||||
var appInfo = Components.classes["@mozilla.org/xre/app-info;1"].
|
||||
getService(Components.interfaces.nsIXULAppInfo);
|
||||
|
||||
var info = {
|
||||
version: Zotero.version,
|
||||
platform: Zotero.platform,
|
||||
locale: Zotero.locale,
|
||||
appName: appInfo.name,
|
||||
appVersion: appInfo.version
|
||||
};
|
||||
|
||||
var str = '';
|
||||
for (var key in info) {
|
||||
str += key + ' => ' + info[key] + ', ';
|
||||
}
|
||||
str = str.substr(0, str.length - 2);
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* PHP var_dump equivalent for JS
|
||||
*
|
||||
|
|
|
@ -1,3 +1,22 @@
|
|||
<!ENTITY zotero.general.optional "(Optional)">
|
||||
|
||||
<!ENTITY zotero.errorReport.additionalInfo "Additional Information">
|
||||
<!ENTITY zotero.errorReport.emailAddress "Your e-mail address:">
|
||||
<!ENTITY zotero.errorReport.errorSteps "What were you doing when the error occurred? If possible, please include steps to reproduce the error.">
|
||||
<!ENTITY zotero.errorReport.submissionInProgress "Please wait while the error report is submitted.">
|
||||
<!ENTITY zotero.errorReport.submitted "The error report has been submitted.">
|
||||
<!ENTITY zotero.errorReport.reportID "Report ID:">
|
||||
<!ENTITY zotero.errorReport.includeReportID "Please include the Report ID in any correspondence with the Zotero developers regarding this issue.">
|
||||
|
||||
<!ENTITY zotero.upgrade.newVersionInstalled "You have installed a new version of Zotero.">
|
||||
<!ENTITY zotero.upgrade.upgradeRequired "Your Zotero database must be upgraded to work with the new version.">
|
||||
<!ENTITY zotero.upgrade.autoBackup "Your existing database will be backed up automatically before any changes are made.">
|
||||
<!ENTITY zotero.upgrade.upgradeInProgress "Please wait for the upgrade process to finish.">
|
||||
<!ENTITY zotero.upgrade.upgradeSucceeded "Your Zotero database has been successfully upgraded.">
|
||||
<!ENTITY zotero.upgrade.changeLogBeforeLink "Please see">
|
||||
<!ENTITY zotero.upgrade.changeLogLink "the changelog">
|
||||
<!ENTITY zotero.upgrade.changeLogAfterLink "to find out what's new.">
|
||||
|
||||
<!ENTITY zotero.contextMenu.addTextToCurrentNote "Add Selection to Zotero Note">
|
||||
<!ENTITY zotero.contextMenu.addTextToNewNote "Create Zotero Item and Note from Selection">
|
||||
<!ENTITY zotero.contextMenu.saveLinkAsSnapshot "Save Link As Zotero Snapshot">
|
||||
|
@ -44,6 +63,7 @@
|
|||
<!ENTITY zotero.toolbar.import.label "Import...">
|
||||
<!ENTITY zotero.toolbar.export.label "Export Library...">
|
||||
<!ENTITY zotero.toolbar.preferences.label "Preferences...">
|
||||
<!ENTITY zotero.toolbar.reportErrors "Report Errors...">
|
||||
<!ENTITY zotero.toolbar.documentation.label "Documentation">
|
||||
<!ENTITY zotero.toolbar.about.label "About Zotero">
|
||||
<!ENTITY zotero.toolbar.advancedSearch "Advanced Search">
|
||||
|
|
|
@ -7,6 +7,15 @@ general.restartFirefox.plural = Firefox must be restarted for the changes to ta
|
|||
general.restartNow = Restart now
|
||||
general.restartLater = Restart later
|
||||
|
||||
upgrade.failed = Upgrading of the Zotero database failed:
|
||||
upgrade.advanceMessage = Press %S to upgrade now.
|
||||
|
||||
errorReport.followingErrors = The following errors have occurred:
|
||||
errorReport.advanceMessage = Press %S to send an error report to the Zotero developers.
|
||||
errorReport.stepsToReproduce = Steps to Reproduce:
|
||||
errorReport.expectedResult = Expected result:
|
||||
errorReport.actualResult = Actual result:
|
||||
|
||||
dataDir.notFound = The Zotero data directory could not be found.
|
||||
dataDir.previousDir = Previous directory:
|
||||
dataDir.useProfileDir = Use Firefox profile directory
|
||||
|
|
36
chrome/skin/default/zotero/errorReport.css
Normal file
36
chrome/skin/default/zotero/errorReport.css
Normal file
|
@ -0,0 +1,36 @@
|
|||
description {
|
||||
margin-bottom: 1.5em;
|
||||
}
|
||||
|
||||
/* Intro pane */
|
||||
#zotero-error-message {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
#zotero-advance-message {
|
||||
margin: 1.5em 0 .5em;
|
||||
}
|
||||
|
||||
/* Additional Info pane */
|
||||
#zotero-email-address-box {
|
||||
margin-bottom: 1.5em;
|
||||
}
|
||||
|
||||
#zotero-email-address-box {
|
||||
-moz-box-align: center;
|
||||
}
|
||||
|
||||
#zotero-email-address-box label {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
#zotero-error-steps-box description {
|
||||
margin-bottom: .25em;
|
||||
}
|
||||
|
||||
/* Submitted pane */
|
||||
|
||||
#zotero-report-id {
|
||||
color: red;
|
||||
font-weight: bold;
|
||||
}
|
7
chrome/skin/default/zotero/upgrade.css
Normal file
7
chrome/skin/default/zotero/upgrade.css
Normal file
|
@ -0,0 +1,7 @@
|
|||
description {
|
||||
margin-bottom: 1.5em;
|
||||
}
|
||||
|
||||
#zotero-change-log-link {
|
||||
margin: 0;
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
-- 29
|
||||
-- 30
|
||||
|
||||
-- This file creates tables containing user-specific data -- any changes
|
||||
-- to existing tables made here must be mirrored in transition steps in
|
||||
|
|
Loading…
Reference in New Issue
Block a user