diff --git a/chrome/content/zotero/xpcom/data/itemFields.js b/chrome/content/zotero/xpcom/data/itemFields.js index 6c9681e03c..c655479505 100644 --- a/chrome/content/zotero/xpcom/data/itemFields.js +++ b/chrome/content/zotero/xpcom/data/itemFields.js @@ -36,6 +36,7 @@ Zotero.ItemFields = new function() { var _baseMappedFields = []; var _typeFieldIDsByBase = {}; var _typeFieldNamesByBase = {}; + var _baseFieldIDsByTypeAndField = {}; // Privileged methods this.getName = getName; @@ -288,13 +289,13 @@ Zotero.ItemFields = new function() { var typeFieldID = this.getID(typeField); if (!itemTypeID) { - throw ("Invalid item type '" + itemType + "' in ItemFields.getBaseIDFromTypeAndField()"); + throw new Error("Invalid item type '" + itemType + "'"); } _fieldCheck(typeField, 'getBaseIDFromTypeAndField'); if (!this.isValidForType(typeFieldID, itemTypeID)) { - throw ("'" + typeField + "' is not a valid field for '" + itemType + "' in ItemFields.getBaseIDFromTypeAndField()"); + throw new Error("'" + typeField + "' is not a valid field for '" + itemType + "'"); } // If typeField is already a base field, just return that @@ -302,8 +303,8 @@ Zotero.ItemFields = new function() { return typeFieldID; } - return Zotero.DB.valueQuery("SELECT baseFieldID FROM baseFieldMappingsCombined " - + "WHERE itemTypeID=? AND fieldID=?", [itemTypeID, typeFieldID]); + if (!_baseFieldIDsByTypeAndField[itemTypeID]) return false; + return _baseFieldIDsByTypeAndField[itemTypeID][typeFieldID] || false; } @@ -466,16 +467,25 @@ Zotero.ItemFields = new function() { } _baseTypeFields = fields; - var sql = "SELECT baseFieldID, fieldID, fieldName " + var sql = "SELECT itemTypeID, baseFieldID, fieldID, fieldName " + "FROM baseFieldMappingsCombined JOIN fieldsCombined USING (fieldID)"; var rows = yield Zotero.DB.queryAsync(sql); - for each(var row in rows) { + for (let i = 0; i < rows.length; i++) { + let row = rows[i]; + // Type fields by base if (!_typeFieldIDsByBase[row['baseFieldID']]) { _typeFieldIDsByBase[row['baseFieldID']] = []; _typeFieldNamesByBase[row['baseFieldID']] = []; } _typeFieldIDsByBase[row['baseFieldID']].push(row['fieldID']); _typeFieldNamesByBase[row['baseFieldID']].push(row['fieldName']); + + // Base fields by type and field + if (!_baseFieldIDsByTypeAndField[row.itemTypeID]) { + _baseFieldIDsByTypeAndField[row.itemTypeID] = {}; + } + _baseFieldIDsByTypeAndField[row.itemTypeID][row.fieldID] = row.baseFieldID; + } // Get all fields mapped to base types diff --git a/test/tests/itemFieldsTest.js b/test/tests/itemFieldsTest.js new file mode 100644 index 0000000000..0132a463d8 --- /dev/null +++ b/test/tests/itemFieldsTest.js @@ -0,0 +1,34 @@ +"use strict"; + +describe("Zotero.ItemFields", function () { + describe("#getBaseIDFromTypeAndField()", function () { + it("should return the base field id for an item type and base-mapped field", function* () { + assert.equal( + Zotero.ItemFields.getBaseIDFromTypeAndField('audioRecording', 'label'), + Zotero.ItemFields.getID('publisher') + ); + + // Accept ids too + assert.equal( + Zotero.ItemFields.getBaseIDFromTypeAndField( + Zotero.ItemTypes.getID('audioRecording'), + Zotero.ItemFields.getID('label') + ), + Zotero.ItemFields.getID('publisher') + ); + }) + + it("should return the base field id for an item type and base field", function* () { + assert.equal( + Zotero.ItemFields.getBaseIDFromTypeAndField('book', 'publisher'), + Zotero.ItemFields.getID('publisher') + ); + }) + + it("should return false for an item type and non-base-mapped field", function* () { + assert.isFalse( + Zotero.ItemFields.getBaseIDFromTypeAndField('audioRecording', 'runningTime') + ); + }) + }) +})