Bug 888784 - Get rid of dead mozIStorageService code in FormHistory.jsm. r=mak

MozReview-Commit-ID: XLOFLpMsPv

--HG--
extra : rebase_source : e25875eed9c190ba9d5b1bd2c9e435f431bf1db5
This commit is contained in:
Mike Conley 2017-12-01 14:55:24 -05:00
parent 9bc8273562
commit fb6f18615e

View File

@ -261,98 +261,6 @@ function makeQueryPredicates(aQueryData, delimiter = " AND ") {
}).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();
@ -370,115 +278,11 @@ function generateGUID() {
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);
@ -490,137 +294,6 @@ var Migrators = {
},
};
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
@ -667,11 +340,6 @@ async function updateFormHistoryWrite(aChanges, aPreparedHandlers) {
// 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;