зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
9bc8273562
Коммит
fb6f18615e
|
@ -261,98 +261,6 @@ function makeQueryPredicates(aQueryData, delimiter = " AND ") {
|
||||||
}).join(delimiter);
|
}).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() {
|
function generateGUID() {
|
||||||
// string like: "{f60d9eac-9421-4abc-8491-8e8322b063d4}"
|
// string like: "{f60d9eac-9421-4abc-8491-8e8322b063d4}"
|
||||||
let uuid = uuidService.generateUUID().toString();
|
let uuid = uuidService.generateUUID().toString();
|
||||||
|
@ -370,115 +278,11 @@ function generateGUID() {
|
||||||
return btoa(raw);
|
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 = {
|
var Migrators = {
|
||||||
/*
|
/*
|
||||||
* Updates the DB schema to v3 (bug 506402).
|
* Updates the DB schema to v3 (bug 506402).
|
||||||
* Adds deleted form history table.
|
* 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) {
|
async dbAsyncMigrateToVersion4(conn) {
|
||||||
const TABLE_NAME = "moz_deleted_formhistory";
|
const TABLE_NAME = "moz_deleted_formhistory";
|
||||||
let tableExists = await conn.tableExists(TABLE_NAME);
|
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
|
* @typedef {Object} InsertQueryData
|
||||||
* @property {Object} updatedChange
|
* @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
|
// pass 'now' down so that every entry in the batch has the same timestamp
|
||||||
let now = Date.now() * 1000;
|
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 queries = [];
|
||||||
let notifications = [];
|
let notifications = [];
|
||||||
let conn = await FormHistory.db;
|
let conn = await FormHistory.db;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче