Bug 1074817 - Handle content preference downgrades for the timestamp column migration. r=MattN f=mak
authorTomasz Kołodziejski <tkolodziejski@mozilla.com>
Thu, 16 Oct 2014 00:36:44 -0700
changeset 210594 42a182f0431fb873eeba2bde9ec240db78680cbe
parent 210593 9794e8f22ac8566ed9342472388c20d5a940d9a5
child 210595 400b8c7a7f0157290be1064f7ae1f3df459f936b
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersMattN
bugs1074817
milestone36.0a1
Bug 1074817 - Handle content preference downgrades for the timestamp column migration. r=MattN f=mak
toolkit/components/contentprefs/nsContentPrefService.js
--- a/toolkit/components/contentprefs/nsContentPrefService.js
+++ b/toolkit/components/contentprefs/nsContentPrefService.js
@@ -1162,16 +1162,23 @@ ContentPrefService.prototype = {
     aDBFile.remove(false);
 
     let dbConnection = this._dbCreate(aDBService, aDBFile);
 
     return dbConnection;
   },
 
   _dbMigrate: function ContentPrefService__dbMigrate(aDBConnection, aOldVersion, aNewVersion) {
+    /**
+     * Migrations should follow the template rules in bug 1074817 comment 3 which are:
+     * 1. Migration should be incremental and non-breaking.
+     * 2. It should be idempotent because one can downgrade an upgrade again.
+     * On downgrade:
+     * 1. Decrement schema version so that upgrade runs the migrations again.
+     */
     aDBConnection.beginTransaction();
 
     try {
        /**
        * If the schema version is 0, that means it was never set, which means
        * the database was somehow created without the schema being applied, perhaps
        * because the system ran out of disk space (although we check for this
        * in _createDB) or because some other code created the database file without
@@ -1208,17 +1215,24 @@ ContentPrefService.prototype = {
     aDBConnection.executeSimpleSQL("DROP TABLE groupsOld");
   },
 
   _dbMigrate2To3: function ContentPrefService__dbMigrate2To3(aDBConnection) {
     this._dbCreateIndices(aDBConnection);
   },
 
   _dbMigrate3To4: function ContentPrefService__dbMigrate3To4(aDBConnection) {
-    aDBConnection.executeSimpleSQL("ALTER TABLE prefs ADD COLUMN timestamp INTEGER NOT NULL DEFAULT 0");
+    // Add timestamp column if it does not exist yet. This operation is idempotent.
+    try {
+      let stmt = aDBConnection.createStatement("SELECT timestamp FROM prefs");
+      stmt.finalize();
+    } catch (e) {
+      aDBConnection.executeSimpleSQL("ALTER TABLE prefs ADD COLUMN timestamp INTEGER NOT NULL DEFAULT 0");
+    }
+
     // To modify prefs_idx drop it and create again.
     aDBConnection.executeSimpleSQL("DROP INDEX IF EXISTS prefs_idx");
     this._dbCreateIndices(aDBConnection);
   },
 
   _parseGroupParam: function ContentPrefService__parseGroupParam(aGroup) {
     if (aGroup == null)
       return null;