Bug 512914 - Gloda gets upset when attributes that used to exist no longer exist [datastore.js:3055 TypeError: parentID is null]. v1 fix current problem and anticipated future problems. r=bienvenu
authorAndrew Sutherland <asutherland@asutherland.org>
Fri, 28 Aug 2009 01:17:23 -0700
changeset 3441 394de8e9f212e5a584454a92f1f138eb512b46ac
parent 3440 d92896496cf2454bd053c1455e207549fe3fe13f
child 3442 14db5b7f0dbf0fc25936daf5990782c98d17959d
push idunknown
push userunknown
push dateunknown
reviewersbienvenu
bugs512914
Bug 512914 - Gloda gets upset when attributes that used to exist no longer exist [datastore.js:3055 TypeError: parentID is null]. v1 fix current problem and anticipated future problems. r=bienvenu
mailnews/db/gloda/modules/datastore.js
--- a/mailnews/db/gloda/modules/datastore.js
+++ b/mailnews/db/gloda/modules/datastore.js
@@ -3053,23 +3053,33 @@ var GlodaDatastore = {
     }
 
     //this._log.debug(" load json: " + aItem._jsonText);
     let jsonDict = this._json.decode(aItem._jsonText);
     delete aItem._jsonText;
 
     // Iterate over the attributes on the item
     for each (let [attribId, jsonValue] in Iterator(jsonDict)) {
+      // It is technically impossible for attribute ids to go away at this
+      //  point in time.  This would require someone to monkey around with
+      //  our schema.  But we will introduce this functionality one day, so
+      //  prepare for it now.
+      if (!(attribId in attribIDToDBDefAndParam))
+        continue;
       // find the attribute definition that corresponds to this key
       let dbAttrib = attribIDToDBDefAndParam[attribId][0];
-      // the attribute should only fail to exist if an extension was removed
-      if (dbAttrib === undefined)
-        continue;
 
       let attrib = dbAttrib.attrDef;
+      // The attribute definition will fail to exist if no one defines the
+      //  attribute anymore.  This can happen for many reasons: an extension
+      //  was uninstalled, an extension was changed and no longer defines the
+      //  attribute, or patches are being applied/unapplied.  Ignore this
+      //  attribute if missing.
+      if (attrib == null)
+        continue;
       let objectNounDef = attrib.objectNounDef;
 
       // If it has a tableName member but no fromJSON, then it's a persistent
       //  object that needs to be loaded, which also means we need to hold it in
       //  a collection owned by our collection.
       // (If it has a fromJSON method, then it's a special case like
       //  MimeTypeNoun where it is authoritatively backed by a table but caches
       //  everything into memory.  There is no case where fromJSON would be