Use async DB for Zotero.Translators.init()

Zotero.Translators.init() now returns a promise. This will temporarily break
all the Zotero.Translators.get* calls.
This commit is contained in:
Dan Stillman 2013-08-15 23:21:57 -04:00
parent a901b47d87
commit 5040fba8bb
3 changed files with 112 additions and 133 deletions

View file

@ -128,11 +128,13 @@ Zotero_Preferences.Advanced = {
null, null, null, {});
if (index == 0) {
Zotero.Schema.resetTranslatorsAndStyles(function (xmlhttp, updated) {
Zotero.Schema.resetTranslatorsAndStyles()
.then(function () {
if (Zotero_Preferences.Export) {
Zotero_Preferences.Export.populateQuickCopyList();
}
});
})
.done();
}
},
@ -152,11 +154,13 @@ Zotero_Preferences.Advanced = {
null, null, null, {});
if (index == 0) {
Zotero.Schema.resetTranslators(function () {
Zotero.Schema.resetTranslators()
.then(function () {
if (Zotero_Preferences.Export) {
Zotero_Preferences.Export.populateQuickCopyList();
}
});
})
.done();
}
},
@ -176,11 +180,13 @@ Zotero_Preferences.Advanced = {
null, null, null, {});
if (index == 0) {
Zotero.Schema.resetStyles(function (xmlhttp, updated) {
Zotero.Schema.resetStyles()
.then(function () {
if (Zotero_Preferences.Export) {
Zotero_Preferences.Export.populateQuickCopyList();
}
});
})
.done();
}
},

View file

@ -142,13 +142,7 @@ Zotero.Schema = new function(){
// After a delay, start update of bundled files and repo updates
Zotero.initializationPromise
.delay(5000)
.then(function () {
Zotero.UnresponsiveScriptIndicator.disable();
return Zotero.Schema.updateBundledFiles(null, false, true)
.finally(function () {
Zotero.UnresponsiveScriptIndicator.enable();
});
})
.then(function () Zotero.Schema.updateBundledFiles(null, false, true))
.done();
return updated;
@ -375,6 +369,7 @@ Zotero.Schema = new function(){
* @param {Boolean} [skipDeleteUpdated] Skip updating of the file deleting version --
* since deleting uses a single version table key,
* it should only be updated the last time through
* @return {Promise}
*/
this.updateBundledFiles = function(mode, skipDeleteUpdate, runRemoteUpdateWhenComplete) {
if (_localUpdateInProgress) return Q();
@ -1038,20 +1033,16 @@ Zotero.Schema = new function(){
var translatorsDir = Zotero.getTranslatorsDirectory();
translatorsDir.remove(true);
Zotero.getTranslatorsDirectory(); // recreate directory
Zotero.Translators.init();
this.updateBundledFiles('translators', null, false);
var stylesDir = Zotero.getStylesDirectory();
stylesDir.remove(true);
Zotero.getStylesDirectory(); // recreate directory
Zotero.Styles.init();
this.updateBundledFiles('styles', null, true)
return Zotero.Translators.init()
.then(function () self.updateBundledFiles('translators', null, false))
.then(function () {
if (callback) {
callback();
}
var stylesDir = Zotero.getStylesDirectory();
stylesDir.remove(true);
Zotero.getStylesDirectory(); // recreate directory
Zotero.Styles.init();
return self.updateBundledFiles('styles', null, true);
})
.done();
.then(callback);
}
@ -1067,14 +1058,9 @@ Zotero.Schema = new function(){
var translatorsDir = Zotero.getTranslatorsDirectory();
translatorsDir.remove(true);
Zotero.getTranslatorsDirectory(); // recreate directory
Zotero.Translators.init();
this.updateBundledFiles('translators', null, true)
.then(function () {
if (callback) {
callback();
}
})
.done();
return Zotero.Translators.init()
.then(function () self.updateBundledFiles('translators', null, true))
.then(callback);
}
@ -1090,14 +1076,9 @@ Zotero.Schema = new function(){
var stylesDir = Zotero.getStylesDirectory();
stylesDir.remove(true);
Zotero.getStylesDirectory(); // recreate directory
Zotero.Styles.init();
this.updateBundledFiles('styles', null, true)
.then(function () {
if (callback) {
callback();
}
})
.done();
return Zotero.Styles.init()
.then(function () self.updateBundledFiles('styles', null, true))
.then(callback);
}
@ -1554,7 +1535,7 @@ Zotero.Schema = new function(){
}
// Rebuild caches
Zotero.Translators.init();
yield Zotero.Translators.init();
Zotero.Styles.init();
}
catch (e) {

View file

@ -37,115 +37,105 @@ Zotero.Translators = new function() {
/**
* Initializes translator cache, loading all relevant translators into memory
*/
this.init = function() {
this.init = Q.async(function() {
_initialized = true;
var start = (new Date()).getTime();
var transactionStarted = false;
Zotero.UnresponsiveScriptIndicator.disable();
_cache = {"import":[], "export":[], "web":[], "search":[]};
_translators = {};
// Use try/finally so that we always reset the unresponsive script warning
try {
_cache = {"import":[], "export":[], "web":[], "search":[]};
_translators = {};
var dbCacheResults = yield Zotero.DB.queryAsync("SELECT leafName, translatorJSON, "+
"code, lastModifiedTime FROM translatorCache");
var dbCache = {};
for each(var cacheEntry in dbCacheResults) {
dbCache[cacheEntry.leafName] = cacheEntry;
}
var i = 0;
var filesInCache = {};
var contents = Zotero.getTranslatorsDirectory().directoryEntries;
while(contents.hasMoreElements()) {
var file = contents.getNext().QueryInterface(Components.interfaces.nsIFile);
var leafName = file.leafName;
if(!(/^[^.].*\.js$/.test(leafName))) continue;
var lastModifiedTime = file.lastModifiedTime;
var dbCacheResults = Zotero.DB.query("SELECT leafName, translatorJSON, "+
"code, lastModifiedTime FROM translatorCache");
var dbCache = {};
for each(var cacheEntry in dbCacheResults) {
dbCache[cacheEntry.leafName] = cacheEntry;
var dbCacheEntry = false;
if(dbCache[leafName]) {
filesInCache[leafName] = true;
if(dbCache[leafName].lastModifiedTime == lastModifiedTime) {
dbCacheEntry = dbCache[file.leafName];
}
}
var i = 0;
var filesInCache = {};
var contents = Zotero.getTranslatorsDirectory().directoryEntries;
while(contents.hasMoreElements()) {
var file = contents.getNext().QueryInterface(Components.interfaces.nsIFile);
var leafName = file.leafName;
if(!(/^[^.].*\.js$/.test(leafName))) continue;
var lastModifiedTime = file.lastModifiedTime;
var dbCacheEntry = false;
if(dbCache[leafName]) {
filesInCache[leafName] = true;
if(dbCache[leafName].lastModifiedTime == lastModifiedTime) {
dbCacheEntry = dbCache[file.leafName];
}
}
if(dbCacheEntry) {
// get JSON from cache if possible
var translator = new Zotero.Translator(file, dbCacheEntry.translatorJSON, dbCacheEntry.code);
filesInCache[leafName] = true;
// TODO: use async load method instead of constructor
if(dbCacheEntry) {
// get JSON from cache if possible
var translator = new Zotero.Translator(file, dbCacheEntry.translatorJSON, dbCacheEntry.code);
filesInCache[leafName] = true;
} else {
// otherwise, load from file
var translator = new Zotero.Translator(file);
}
if(translator.translatorID) {
if(_translators[translator.translatorID]) {
// same translator is already cached
translator.logError('Translator with ID '+
translator.translatorID+' already loaded from "'+
_translators[translator.translatorID].file.leafName+'"');
} else {
// otherwise, load from file
var translator = new Zotero.Translator(file);
}
if(translator.translatorID) {
if(_translators[translator.translatorID]) {
// same translator is already cached
translator.logError('Translator with ID '+
translator.translatorID+' already loaded from "'+
_translators[translator.translatorID].file.leafName+'"');
} else {
// add to cache
_translators[translator.translatorID] = translator;
for(var type in TRANSLATOR_TYPES) {
if(translator.translatorType & TRANSLATOR_TYPES[type]) {
_cache[type].push(translator);
}
}
if(!dbCacheEntry) {
// Add cache misses to DB
if(!transactionStarted) {
transactionStarted = true;
Zotero.DB.beginTransaction();
}
Zotero.Translators.cacheInDB(leafName, translator.metadataString, translator.cacheCode ? translator.code : null, lastModifiedTime);
delete translator.metadataString;
// add to cache
_translators[translator.translatorID] = translator;
for(var type in TRANSLATOR_TYPES) {
if(translator.translatorType & TRANSLATOR_TYPES[type]) {
_cache[type].push(translator);
}
}
}
i++;
}
// Remove translators from DB as necessary
for(var leafName in dbCache) {
if(!filesInCache[leafName]) {
Zotero.DB.query("DELETE FROM translatorCache WHERE leafName = ?", [leafName]);
if(!dbCacheEntry) {
yield Zotero.Translators.cacheInDB(
leafName,
translator.metadataString,
translator.cacheCode ? translator.code : null,
lastModifiedTime
);
delete translator.metadataString;
}
}
}
// Close transaction
if(transactionStarted) {
Zotero.DB.commitTransaction();
}
// Sort by priority
var collation = Zotero.getLocaleCollation();
var cmp = function (a, b) {
if (a.priority > b.priority) {
return 1;
}
else if (a.priority < b.priority) {
return -1;
}
return collation.compareString(1, a.label, b.label);
}
for(var type in _cache) {
_cache[type].sort(cmp);
i++;
}
// Remove translators from DB as necessary
for(var leafName in dbCache) {
if(!filesInCache[leafName]) {
yield Zotero.DB.queryAsync(
"DELETE FROM translatorCache WHERE leafName = ?", [leafName]
);
}
}
finally {
Zotero.UnresponsiveScriptIndicator.enable();
// Sort by priority
var collation = Zotero.getLocaleCollation();
var cmp = function (a, b) {
if (a.priority > b.priority) {
return 1;
}
else if (a.priority < b.priority) {
return -1;
}
return collation.compareString(1, a.label, b.label);
}
for(var type in _cache) {
_cache[type].sort(cmp);
}
Zotero.debug("Cached "+i+" translators in "+((new Date()).getTime() - start)+" ms");
}
});
/**
* Gets the translator that corresponds to a given ID
@ -414,8 +404,10 @@ Zotero.Translators = new function() {
}
this.cacheInDB = function(fileName, metadataJSON, code, lastModifiedTime) {
Zotero.DB.query("REPLACE INTO translatorCache VALUES (?, ?, ?, ?)",
[fileName, metadataJSON, code, lastModifiedTime]);
return Zotero.DB.queryAsync(
"REPLACE INTO translatorCache VALUES (?, ?, ?, ?)",
[fileName, metadataJSON, code, lastModifiedTime]
);
}
}