diff --git a/toolkit/components/satchel/nsFormHistory.js b/toolkit/components/satchel/nsFormHistory.js index 9a08389ee4d8..65609c7e47a1 100644 --- a/toolkit/components/satchel/nsFormHistory.js +++ b/toolkit/components/satchel/nsFormHistory.js @@ -89,7 +89,6 @@ FormHistory.prototype = { }, } }, - dbConnection : null, // The database connection dbStmts : null, // Database statements for memoization dbFile : null, @@ -141,26 +140,8 @@ FormHistory.prototype = { // Add observers Services.obs.addObserver(function() { self.expireOldEntries() }, "idle-daily", false); Services.obs.addObserver(function() { self.expireOldEntries() }, "formhistory-expire-now", false); - - try { - this.dbFile = Services.dirsvc.get("ProfD", Ci.nsIFile).clone(); - this.dbFile.append("formhistory.sqlite"); - this.log("Opening database at " + this.dbFile.path); - - this.dbInit(); - } catch (e) { - this.log("Initialization failed: " + e); - // If dbInit fails... - if (e.result == Cr.NS_ERROR_FILE_CORRUPTED) { - this.dbCleanup(true); - this.dbInit(); - } else { - throw "Initialization failed"; - } - } }, - /* ---- message listener ---- */ @@ -377,6 +358,33 @@ FormHistory.prototype = { }, + get dbConnection() { + let connection; + + // Make sure dbConnection can't be called from now to prevent infinite loops. + delete FormHistory.prototype.dbConnection; + + try { + this.dbFile = Services.dirsvc.get("ProfD", Ci.nsIFile).clone(); + this.dbFile.append("formhistory.sqlite"); + this.log("Opening database at " + this.dbFile.path); + + FormHistory.prototype.dbConnection = this.dbOpen(); + this.dbInit(); + } catch (e) { + this.log("Initialization failed: " + e); + // If dbInit fails... + if (e.result == Cr.NS_ERROR_FILE_CORRUPTED) { + this.dbCleanup(true); + FormHistory.prototype.dbConnection = this.dbOpen(); + this.dbInit(); + } else { + throw "Initialization failed"; + } + } + + return FormHistory.prototype.dbConnection; + }, get DBConnection() { return this.dbConnection; @@ -591,6 +599,20 @@ FormHistory.prototype = { return stmt; }, + /* + * dbOpen + * + * Open a connection with the database and returns it. + * + * @returns a db connection object. + */ + dbOpen : function () { + this.log("Open Database"); + + let storage = Cc["@mozilla.org/storage/service;1"]. + getService(Ci.mozIStorageService); + return storage.openDatabase(this.dbFile); + }, /* * dbInit @@ -601,9 +623,6 @@ FormHistory.prototype = { dbInit : function () { this.log("Initializing Database"); - let storage = Cc["@mozilla.org/storage/service;1"]. - getService(Ci.mozIStorageService); - this.dbConnection = storage.openDatabase(this.dbFile); let version = this.dbConnection.schemaVersion; // Note: Firefox 3 didn't set a schema value, so it started from 0. diff --git a/toolkit/components/satchel/test/unit/test_db_corrupt.js b/toolkit/components/satchel/test/unit/test_db_corrupt.js index e8dabdb35bea..fcc93278d67b 100644 --- a/toolkit/components/satchel/test/unit/test_db_corrupt.js +++ b/toolkit/components/satchel/test/unit/test_db_corrupt.js @@ -63,6 +63,10 @@ function run_test() do_check_false(bakFile.exists()); var fh = Cc["@mozilla.org/satchel/form-history;1"]. getService(Ci.nsIFormHistory2); + // DB init is done lazily so the DB shouldn't be created yet. + do_check_false(bakFile.exists()); + // Doing any request to the DB should create it. + fh.DBConnection; do_check_true(bakFile.exists()); bakFile.remove(false); diff --git a/toolkit/components/satchel/test/unit/test_db_update_v999b.js b/toolkit/components/satchel/test/unit/test_db_update_v999b.js index a36189e39959..c292fbbe9078 100644 --- a/toolkit/components/satchel/test/unit/test_db_update_v999b.js +++ b/toolkit/components/satchel/test/unit/test_db_update_v999b.js @@ -73,6 +73,10 @@ function run_test() do_check_false(bakFile.exists()); var fh = Cc["@mozilla.org/satchel/form-history;1"]. getService(Ci.nsIFormHistory2); + // DB init is done lazily so the DB shouldn't be created yet. + do_check_false(bakFile.exists()); + // Doing any request to the DB should create it. + fh.DBConnection; do_check_true(bakFile.exists()); bakFile.remove(false);