Bug 1074817 - Handle content preference downgrades for the timestamp column migration. r=MattN f=mak
--- 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;