Bug 888784 - Get rid of dead mozIStorageService code in FormHistory.jsm. r?mak draft
authorMike Conley <mconley@mozilla.com>
Fri, 01 Dec 2017 14:55:24 -0500
changeset 723116 9695f645a9e79b9b885701974e8699975fcd5f17
parent 723115 2fd5fec679ceda908e183eb7dac131934e65b38e
child 723117 402a7c0cbd467b52841f7ae8a2e08a104572d0bb
push id96341
push usermconley@mozilla.com
push dateMon, 22 Jan 2018 16:46:17 +0000
reviewersmak
bugs888784
milestone60.0a1
Bug 888784 - Get rid of dead mozIStorageService code in FormHistory.jsm. r?mak MozReview-Commit-ID: XLOFLpMsPv
toolkit/components/satchel/FormHistory.jsm
--- a/toolkit/components/satchel/FormHistory.jsm
+++ b/toolkit/components/satchel/FormHistory.jsm
@@ -256,108 +256,16 @@ function makeQueryPredicates(aQueryData,
         return "lastUsed <= :" + field;
       }
     }
 
     return field + " = :" + field;
   }).join(delimiter);
 }
 
-/**
- * Storage statement creation and parameter binding
- */
-
-function makeSearchStatement(aSearchData, aSelectTerms) {
-  let query = "SELECT " + aSelectTerms.join(", ") + " FROM moz_formhistory";
-  let queryTerms = makeQueryPredicates(aSearchData);
-  if (queryTerms) {
-    query += " WHERE " + queryTerms;
-  }
-
-  return dbCreateAsyncStatement(query, aSearchData);
-}
-
-function makeAddStatement(aNewData, aNow, aBindingArrays) {
-  let query = "INSERT INTO moz_formhistory " +
-              "(fieldname, value, timesUsed, firstUsed, lastUsed, guid) " +
-              "VALUES (:fieldname, :value, :timesUsed, :firstUsed, :lastUsed, :guid)";
-
-  aNewData.timesUsed = aNewData.timesUsed || 1;
-  aNewData.firstUsed = aNewData.firstUsed || aNow;
-  aNewData.lastUsed = aNewData.lastUsed || aNow;
-  return dbCreateAsyncStatement(query, aNewData, aBindingArrays);
-}
-
-function makeBumpStatement(aGuid, aNow, aBindingArrays) {
-  let query = "UPDATE moz_formhistory " +
-              "SET timesUsed = timesUsed + 1, lastUsed = :lastUsed WHERE guid = :guid";
-  let queryParams = {
-    lastUsed: aNow,
-    guid: aGuid,
-  };
-
-  return dbCreateAsyncStatement(query, queryParams, aBindingArrays);
-}
-
-function makeRemoveStatement(aSearchData, aBindingArrays) {
-  let query = "DELETE FROM moz_formhistory";
-  let queryTerms = makeQueryPredicates(aSearchData);
-
-  if (queryTerms) {
-    log("removeEntries");
-    query += " WHERE " + queryTerms;
-  } else {
-    log("removeAllEntries");
-    // Not specifying any fields means we should remove all entries. We
-    // won't need to modify the query in this case.
-  }
-
-  return dbCreateAsyncStatement(query, aSearchData, aBindingArrays);
-}
-
-function makeUpdateStatement(aGuid, aNewData, aBindingArrays) {
-  let query = "UPDATE moz_formhistory SET ";
-  let queryTerms = makeQueryPredicates(aNewData, ", ");
-
-  if (!queryTerms) {
-    throw Components.Exception("Update query must define fields to modify.",
-                               Cr.NS_ERROR_ILLEGAL_VALUE);
-  }
-
-  query += queryTerms + " WHERE guid = :existing_guid";
-  aNewData.existing_guid = aGuid;
-
-  return dbCreateAsyncStatement(query, aNewData, aBindingArrays);
-}
-
-function makeMoveToDeletedStatement(aGuid, aNow, aData, aBindingArrays) {
-  if (supportsDeletedTable) {
-    let query = "INSERT INTO moz_deleted_formhistory (guid, timeDeleted)";
-    let queryTerms = makeQueryPredicates(aData);
-
-    if (aGuid) {
-      query += " VALUES (:guid, :timeDeleted)";
-    } else {
-      // TODO: Add these items to the deleted items table once we've sorted
-      //       out the issues from bug 756701
-      if (!queryTerms) {
-        return undefined;
-      }
-
-      query += " SELECT guid, :timeDeleted FROM moz_formhistory WHERE " + queryTerms;
-    }
-
-    aData.timeDeleted = aNow;
-
-    return dbCreateAsyncStatement(query, aData, aBindingArrays);
-  }
-
-  return null;
-}
-
 function generateGUID() {
   // string like: "{f60d9eac-9421-4abc-8491-8e8322b063d4}"
   let uuid = uuidService.generateUUID().toString();
   let raw = ""; // A string with the low bytes set to random values
   let bytes = 0;
   for (let i = 1; bytes < 12; i += 2) {
     // Skip dashes
     if (uuid[i] == "-") {
@@ -365,267 +273,32 @@ function generateGUID() {
     }
     let hexVal = parseInt(uuid[i] + uuid[i + 1], 16);
     raw += String.fromCharCode(hexVal);
     bytes++;
   }
   return btoa(raw);
 }
 
-/**
- * Database creation and access
- */
-
-var _dbConnection = null;
-XPCOMUtils.defineLazyGetter(this, "dbConnection", function() {
-  let dbFile;
-
-  try {
-    dbFile = Services.dirsvc.get("ProfD", Ci.nsIFile).clone();
-    dbFile.append(DB_FILENAME);
-    log("Opening database at " + dbFile.path);
-
-    _dbConnection = Services.storage.openDatabase(dbFile);
-    dbInit();
-  } catch (e) {
-    if (e.result != Cr.NS_ERROR_FILE_CORRUPTED) {
-      throw e;
-    }
-    dbCleanup(dbFile);
-    _dbConnection = Services.storage.openDatabase(dbFile);
-    dbInit();
-  }
-
-  return _dbConnection;
-});
-
-
-var dbStmts = new Map();
-
-/*
- * dbCreateAsyncStatement
- *
- * Creates a statement, wraps it, and then does parameter replacement
- */
-function dbCreateAsyncStatement(aQuery, aParams, aBindingArrays) {
-  if (!aQuery) {
-    return null;
-  }
-
-  let stmt = dbStmts.get(aQuery);
-  if (!stmt) {
-    log("Creating new statement for query: " + aQuery);
-    stmt = dbConnection.createAsyncStatement(aQuery);
-    dbStmts.set(aQuery, stmt);
-  }
-
-  if (aBindingArrays) {
-    let bindingArray = aBindingArrays.get(stmt);
-    if (!bindingArray) {
-      // first time using a particular statement in update
-      bindingArray = stmt.newBindingParamsArray();
-      aBindingArrays.set(stmt, bindingArray);
-    }
-
-    if (aParams) {
-      let bindingParams = bindingArray.newBindingParams();
-      for (let field in aParams) {
-        bindingParams.bindByName(field, aParams[field]);
-      }
-      bindingArray.addParams(bindingParams);
-    }
-  } else if (aParams) {
-    for (let field in aParams) {
-      stmt.params[field] = aParams[field];
-    }
-  }
-
-  return stmt;
-}
-
-var dbMigrate;
-
-/**
- * Attempts to initialize the database. This creates the file if it doesn't
- * exist, performs any migrations, etc.
- */
-function dbInit() {
-  log("Initializing Database");
-
-  if (!_dbConnection.tableExists("moz_formhistory")) {
-    dbCreate();
-    return;
-  }
-
-  // When FormHistory is released, we will no longer support the various schema versions prior to
-  // this release that nsIFormHistory2 once did.
-  let version = _dbConnection.schemaVersion;
-  if (version < 3) {
-    throw Components.Exception("DB version is unsupported.",
-                               Cr.NS_ERROR_FILE_CORRUPTED);
-  } else if (version != DB_SCHEMA_VERSION) {
-    dbMigrate(version);
-  }
-}
-
 var Migrators = {
   /*
    * Updates the DB schema to v3 (bug 506402).
    * Adds deleted form history table.
    */
-  dbMigrateToVersion4() {
-    if (!_dbConnection.tableExists("moz_deleted_formhistory")) {
-      let table = dbSchema.tables.moz_deleted_formhistory;
-      let tSQL = Object.keys(table).map(col => [col, table[col]].join(" ")).join(", ");
-      _dbConnection.createTable("moz_deleted_formhistory", tSQL);
-    }
-  },
-
   async dbAsyncMigrateToVersion4(conn) {
     const TABLE_NAME = "moz_deleted_formhistory";
     let tableExists = await conn.tableExists(TABLE_NAME);
     if (!tableExists) {
       let table = dbSchema.tables[TABLE_NAME];
       let tSQL = Object.keys(table).map(col => [col, table[col]].join(" ")).join(", ");
       await conn.execute(`CREATE TABLE ${TABLE_NAME} (${tSQL})`);
     }
   },
 };
 
-function dbCreate() {
-  log("Creating DB -- tables");
-  for (let name in dbSchema.tables) {
-    let table = dbSchema.tables[name];
-    let tSQL = Object.keys(table).map(col => [col, table[col]].join(" ")).join(", ");
-    log("Creating table " + name + " with " + tSQL);
-    _dbConnection.createTable(name, tSQL);
-  }
-
-  log("Creating DB -- indices");
-  for (let name in dbSchema.indices) {
-    let index = dbSchema.indices[name];
-    let statement = "CREATE INDEX IF NOT EXISTS " + name + " ON " + index.table +
-                    "(" + index.columns.join(", ") + ")";
-    _dbConnection.executeSimpleSQL(statement);
-  }
-
-  _dbConnection.schemaVersion = DB_SCHEMA_VERSION;
-}
-
-dbMigrate = (oldVersion) => {
-  log("Attempting to migrate from version " + oldVersion);
-
-  if (oldVersion > DB_SCHEMA_VERSION) {
-    log("Downgrading to version " + DB_SCHEMA_VERSION);
-    // User's DB is newer. Sanity check that our expected columns are
-    // present, and if so mark the lower version and merrily continue
-    // on. If the columns are borked, something is wrong so blow away
-    // the DB and start from scratch. [Future incompatible upgrades
-    // should switch to a different table or file.]
-
-    if (!dbAreExpectedColumnsPresent()) {
-      throw Components.Exception("DB is missing expected columns",
-                                 Cr.NS_ERROR_FILE_CORRUPTED);
-    }
-
-    // Change the stored version to the current version. If the user
-    // runs the newer code again, it will see the lower version number
-    // and re-upgrade (to fixup any entries the old code added).
-    _dbConnection.schemaVersion = DB_SCHEMA_VERSION;
-    return;
-  }
-
-  // Note that migration is currently performed synchronously.
-  _dbConnection.beginTransaction();
-
-  try {
-    for (let v = oldVersion + 1; v <= DB_SCHEMA_VERSION; v++) {
-      this.log("Upgrading to version " + v + "...");
-      Migrators["dbMigrateToVersion" + v]();
-    }
-  } catch (e) {
-    this.log("Migration failed: " + e);
-    this.dbConnection.rollbackTransaction();
-    throw e;
-  }
-
-  _dbConnection.schemaVersion = DB_SCHEMA_VERSION;
-  _dbConnection.commitTransaction();
-
-  log("DB migration completed.");
-};
-
-/**
- * Sanity check to ensure that the columns this version of the code expects
- * are present in the DB we're using.
- * @returns {boolean} whether expected columns are present
- */
-function dbAreExpectedColumnsPresent() {
-  for (let name in dbSchema.tables) {
-    let table = dbSchema.tables[name];
-    let query = "SELECT " +
-                Object.keys(table).join(", ") +
-                " FROM " + name;
-    try {
-      let stmt = _dbConnection.createStatement(query);
-      // (no need to execute statement, if it compiled we're good)
-      stmt.finalize();
-    } catch (e) {
-      return false;
-    }
-  }
-
-  log("verified that expected columns are present in DB.");
-  return true;
-}
-
-/**
- * Called when database creation fails. Finalizes database statements,
- * closes the database connection, deletes the database file.
- * @param {Object} dbFile database file to close
- */
-function dbCleanup(dbFile) {
-  log("Cleaning up DB file - close & remove & backup");
-
-  // Create backup file
-  let backupFile = dbFile.leafName + ".corrupt";
-  Services.storage.backupDatabaseFile(dbFile, backupFile);
-
-  dbClose(false);
-  dbFile.remove(false);
-}
-
-function dbClose(aShutdown) {
-  log("dbClose(" + aShutdown + ")");
-
-  if (aShutdown) {
-    sendNotification("formhistory-shutdown", null);
-  }
-
-  // Connection may never have been created if say open failed but we still
-  // end up calling dbClose as part of the rest of dbCleanup.
-  if (!_dbConnection) {
-    return;
-  }
-
-  log("dbClose finalize statements");
-  for (let stmt of dbStmts.values()) {
-    stmt.finalize();
-  }
-
-  dbStmts = new Map();
-
-  let closed = false;
-  _dbConnection.asyncClose(() => closed = true);
-
-  if (!aShutdown) {
-    Services.tm.spinEventLoopUntil(() => closed);
-  }
-}
-
 /**
  * @typedef {Object} InsertQueryData
  * @property {Object} updatedChange
  *           A change requested by FormHistory.
  * @property {String} query
  *           The insert query string.
  */
 
@@ -664,21 +337,16 @@ function prepareInsertQuery(change, now)
  */
 // XXX This should be split up and the complexity reduced.
 // eslint-disable-next-line complexity
 async function updateFormHistoryWrite(aChanges, aPreparedHandlers) {
   log("updateFormHistoryWrite  " + aChanges.length);
 
   // pass 'now' down so that every entry in the batch has the same timestamp
   let now = Date.now() * 1000;
-
-  // for each change, we either create and append a new storage statement to
-  // stmts or bind a new set of parameters to an existing storage statement.
-  // stmts and bindingArrays are updated when makeXXXStatement eventually
-  // calls dbCreateAsyncStatement.
   let queries = [];
   let notifications = [];
   let conn = await FormHistory.db;
 
   for (let change of aChanges) {
     let operation = change.op;
     delete change.op;
     switch (operation) {