Use a DOMDocument instead of E4X for uploaded XML generation -- this is almost an order of magnitude faster and hopefully fixes data corruption issues with E4X on large uploads that were causing validation errors on the server.
Individual objects are still created as E4X (e.g., in itemToXML()) and reparsed into the DOM. Generating individual objects with the DOM would produce roughly another order-of-magnitude speedup.
This commit is contained in:
parent
462d9ab199
commit
2e41266c03
1 changed files with 37 additions and 17 deletions
|
@ -3286,11 +3286,13 @@ Zotero.Sync.Server.Data = new function() {
|
|||
//Zotero.debug(syncSession);
|
||||
var keys = syncSession.uploadKeys;
|
||||
|
||||
var xml = <data/>
|
||||
var parser = Components.classes["@mozilla.org/xmlextras/domparser;1"]
|
||||
.createInstance(Components.interfaces.nsIDOMParser);
|
||||
var doc = parser.parseFromString("<data/>", "text/xml");
|
||||
var docElem = doc.documentElement;
|
||||
|
||||
// Add API version attribute
|
||||
xml.@version = Zotero.Sync.Server.apiVersion;
|
||||
|
||||
docElem.setAttribute('version', Zotero.Sync.Server.apiVersion);
|
||||
|
||||
// Updates
|
||||
for each(var syncObject in Zotero.Sync.syncObjects) {
|
||||
|
@ -3298,16 +3300,16 @@ Zotero.Sync.Server.Data = new function() {
|
|||
var Types = syncObject.plural; // 'Items'
|
||||
var type = Type.toLowerCase(); // 'item'
|
||||
var types = Types.toLowerCase(); // 'items'
|
||||
var xmlObjectsNode = false;
|
||||
|
||||
Zotero.debug("Processing locally changed " + types);
|
||||
|
||||
var elementCreated = false;
|
||||
var libraryID, key;
|
||||
for (var libraryID in keys.updated[types]) {
|
||||
for (var key in keys.updated[types][libraryID]) {
|
||||
if (!elementCreated) {
|
||||
xml[types] = new XML("<" + types + "/>");
|
||||
elementCreated = true;
|
||||
// Insert the <[types]> node
|
||||
if (!xmlObjectsNode) {
|
||||
xmlObjectsNode = docElem.appendChild(doc.createElement(types));
|
||||
}
|
||||
|
||||
var l = parseInt(libraryID);
|
||||
|
@ -3322,23 +3324,30 @@ Zotero.Sync.Server.Data = new function() {
|
|||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
if (type == 'item') {
|
||||
// itemToXML needs the sync session
|
||||
xml.items.appendChild(this.itemToXML(obj, syncSession));
|
||||
var str = this.itemToXML(obj, syncSession).toXMLString();
|
||||
}
|
||||
else {
|
||||
xml[types].appendChild(this[type + 'ToXML'](obj));
|
||||
var str = this[type + 'ToXML'](obj).toXMLString();
|
||||
}
|
||||
|
||||
xmlObjectsNode.appendChild(doc.createRange().createContextualFragment(str));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Deletions
|
||||
var xmlDeletedNode = doc.createElement('deleted');
|
||||
var inserted = false;
|
||||
|
||||
for each(var syncObject in Zotero.Sync.syncObjects) {
|
||||
var Type = syncObject.singular; // 'Item'
|
||||
var Types = syncObject.plural; // 'Items'
|
||||
var type = Type.toLowerCase(); // 'item'
|
||||
var types = Types.toLowerCase(); // 'items'
|
||||
var xmlDeletedObjectsNode = false;
|
||||
|
||||
Zotero.debug('Processing locally deleted ' + types);
|
||||
|
||||
|
@ -3346,19 +3355,30 @@ Zotero.Sync.Server.Data = new function() {
|
|||
var libraryID, key;
|
||||
for (var libraryID in keys.deleted[types]) {
|
||||
for (var key in keys.deleted[types][libraryID]) {
|
||||
if (!elementCreated) {
|
||||
xml.deleted[types] = new XML("<" + types + "/>");
|
||||
elementCreated = true;
|
||||
// Insert the <deleted> node
|
||||
if (!inserted) {
|
||||
docElem.appendChild(xmlDeletedNode);
|
||||
inserted = true;
|
||||
}
|
||||
var deletexml = new XML('<' + type + '/>');
|
||||
deletexml.@libraryID = parseInt(libraryID) ? parseInt(libraryID) : Zotero.libraryID;
|
||||
deletexml.@key = key;
|
||||
xml.deleted[types].appendChild(deletexml);
|
||||
// Insert the <deleted><[types]></deleted> node
|
||||
if (!xmlDeletedObjectsNode) {
|
||||
xmlDeletedObjectsNode = xmlDeletedNode.appendChild(doc.createElement(types));
|
||||
}
|
||||
|
||||
var n = doc.createElement(type);
|
||||
n.setAttribute('libraryID', parseInt(libraryID) ? parseInt(libraryID) : Zotero.libraryID);
|
||||
n.setAttribute('key', key);
|
||||
xmlDeletedObjectsNode.appendChild(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var xmlstr = xml.toXMLString();
|
||||
|
||||
var s = Components.classes["@mozilla.org/xmlextras/xmlserializer;1"]
|
||||
.createInstance(Components.interfaces.nsIDOMSerializer);
|
||||
var xmlstr = s.serializeToString(doc);
|
||||
|
||||
// No updated data
|
||||
if (xmlstr.match('<data version="[0-9]+"/>')) {
|
||||
return '';
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue