- 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:
Dan Stillman 2007-04-10 07:27:03 +00:00
parent fa440368b9
commit 50f516d7f1
12 changed files with 589 additions and 103 deletions

View 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>

View File

@ -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);

View File

@ -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) {

View 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>

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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
*

View File

@ -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">

View File

@ -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

View 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;
}

View File

@ -0,0 +1,7 @@
description {
margin-bottom: 1.5em;
}
#zotero-change-log-link {
margin: 0;
}

View File

@ -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