Bug 636676 - Utils.queryAsync: reuse mozIStorageStatementCallback object. r=rnewman a=blocking-fennec

This commit is contained in:
Philipp von Weitershausen 2011-03-01 14:29:52 -08:00
Родитель fbb1ae2b7e
Коммит 70dd415ddf
5 изменённых файлов: 79 добавлений и 49 удалений

Просмотреть файл

@ -992,11 +992,12 @@ BookmarksStore.prototype = {
}
return this.__childGUIDsStm = stmt;
},
_childGUIDsCols: ["item_id", "guid"],
_getChildGUIDsForId: function _getChildGUIDsForId(itemid) {
let stmt = this._childGUIDsStm;
stmt.params.parent = itemid;
let rows = Utils.queryAsync(stmt, ["item_id", "guid"]);
let rows = Utils.queryAsync(stmt, this._childGUIDsCols);
return rows.map(function (row) {
if (row.guid) {
return row.guid;
@ -1144,6 +1145,7 @@ BookmarksStore.prototype = {
"WHERE url = :url " +
"LIMIT 1");
},
_frecencyCols: ["frecency"],
get _addGUIDAnnotationNameStm() {
let stmt = this._getStmt(
@ -1165,6 +1167,7 @@ BookmarksStore.prototype = {
stmt.params.anno_name = GUID_ANNO;
return stmt;
},
_checkGUIDItemAnnotationCols: ["item_id", "name_id", "anno_id", "anno_date"],
get _addItemAnnotationStm() {
return this._getStmt(
@ -1214,8 +1217,7 @@ BookmarksStore.prototype = {
let stmt = this._checkGUIDItemAnnotationStm;
stmt.params.item_id = id;
let result = Utils.queryAsync(stmt, ["item_id", "name_id", "anno_id",
"anno_date"])[0];
let result = Utils.queryAsync(stmt, this._checkGUIDItemAnnotationCols)[0];
if (!result) {
this._log.warn("Couldn't annotate bookmark id " + id);
return guid;
@ -1268,6 +1270,7 @@ BookmarksStore.prototype = {
return this.__guidForIdStm = stmt;
},
_guidForIdCols: ["guid"],
GUIDForId: function GUIDForId(id) {
let special = kSpecialIds.specialGUIDForId(id);
@ -1278,7 +1281,7 @@ BookmarksStore.prototype = {
stmt.params.item_id = id;
// Use the existing GUID if it exists
let result = Utils.queryAsync(stmt, ["guid"])[0];
let result = Utils.queryAsync(stmt, this._guidForIdCols)[0];
if (result && result.guid)
return result.guid;
@ -1318,6 +1321,7 @@ BookmarksStore.prototype = {
return this.__idForGUIDStm = stmt;
},
_idForGUIDCols: ["item_id"],
// noCreate is provided as an optional argument to prevent the creation of
// non-existent special records, such as "mobile".
@ -1329,7 +1333,7 @@ BookmarksStore.prototype = {
// guid might be a String object rather than a string.
stmt.params.guid = guid.toString();
let results = Utils.queryAsync(stmt, ["item_id"]);
let results = Utils.queryAsync(stmt, this._idForGUIDCols);
this._log.trace("Rows matching GUID " + guid + ": " +
results.map(function(x) x.item_id));
@ -1372,7 +1376,7 @@ BookmarksStore.prototype = {
// Add in the bookmark's frecency if we have something
if (record.bmkUri != null) {
this._frecencyStm.params.url = record.bmkUri;
let result = Utils.queryAsync(this._frecencyStm, ["frecency"]);
let result = Utils.queryAsync(this._frecencyStm, this._frecencyCols);
if (result.length)
index += result[0].frecency;
}

Просмотреть файл

@ -91,7 +91,7 @@ let FormWrapper = {
getQuery.params.value = value;
// Give the guid if we found one
let item = Utils.queryAsync(getQuery, "guid")[0];
let item = Utils.queryAsync(getQuery, ["guid"])[0];
if (!item) {
// Shouldn't happen, but Bug 597400...
@ -120,9 +120,9 @@ let FormWrapper = {
hasGUID: function hasGUID(guid) {
let query = this.createStatement(
"SELECT 1 FROM moz_formhistory WHERE guid = :guid");
"SELECT guid FROM moz_formhistory WHERE guid = :guid LIMIT 1");
query.params.guid = guid;
return Utils.queryAsync(query).length == 1;
return Utils.queryAsync(query, ["guid"]).length == 1;
},
replaceGUID: function replaceGUID(oldGUID, newGUID) {

Просмотреть файл

@ -138,12 +138,14 @@ HistoryStore.prototype = {
"SELECT name FROM sqlite_temp_master " +
"WHERE name IN ('moz_places_temp', 'moz_historyvisits_temp')");
},
_haveTempTablesCols: ["name"],
__haveTempTables: null,
get _haveTempTables() {
if (this.__haveTempTables === null)
this.__haveTempTables = !!Utils.queryAsync(this._haveTempTablesStm,
["name"]).length;
if (this.__haveTempTables === null) {
this.__haveTempTables = !!Utils.queryAsync(
this._haveTempTablesStm, this._haveTempTablesCols).length;
}
return this.__haveTempTables;
},
@ -184,6 +186,8 @@ HistoryStore.prototype = {
stmt.params.anno_name = GUID_ANNO;
return stmt;
},
_checkGUIDPageAnnotationCols: ["place_id", "name_id", "anno_id",
"anno_date"],
get _addPageAnnotationStm() {
// Gecko <2.0 only
@ -237,8 +241,7 @@ HistoryStore.prototype = {
let stmt = this._checkGUIDPageAnnotationStm;
stmt.params.page_url = uri;
let result = Utils.queryAsync(stmt, ["place_id", "name_id", "anno_id",
"anno_date"])[0];
let result = Utils.queryAsync(stmt, this._checkGUIDPageAnnotationCols)[0];
if (!result) {
let log = Log4Moz.repository.getLogger("Engine.History");
log.warn("Couldn't annotate URI " + uri);
@ -295,13 +298,14 @@ HistoryStore.prototype = {
return this.__guidStmt = stmt;
},
_guidCols: ["guid"],
GUIDForUri: function GUIDForUri(uri, create) {
let stm = this._guidStm;
stm.params.page_url = uri.spec ? uri.spec : uri;
// Use the existing GUID if it exists
let result = Utils.queryAsync(stm, ["guid"])[0];
let result = Utils.queryAsync(stm, this._guidCols)[0];
if (result && result.guid)
return result.guid;
@ -332,6 +336,7 @@ HistoryStore.prototype = {
"WHERE place_id = (SELECT id FROM moz_places WHERE url = :url) " +
"ORDER BY date DESC LIMIT 10");
},
_visitCols: ["date", "type"],
__urlStmt: null,
get _urlStm() {
@ -365,6 +370,7 @@ HistoryStore.prototype = {
return this.__urlStmt = stmt;
},
_urlCols: ["url", "title", "frecency"],
get _allUrlStm() {
// Gecko <2.0
@ -386,17 +392,18 @@ HistoryStore.prototype = {
"ORDER BY frecency DESC " +
"LIMIT :max_results");
},
_allUrlCols: ["url"],
// See bug 320831 for why we use SQL here
_getVisits: function HistStore__getVisits(uri) {
this._visitStm.params.url = uri;
return Utils.queryAsync(this._visitStm, ["date", "type"]);
return Utils.queryAsync(this._visitStm, this._visitCols);
},
// See bug 468732 for why we use SQL here
_findURLByGUID: function HistStore__findURLByGUID(guid) {
this._urlStm.params.guid = guid;
return Utils.queryAsync(this._urlStm, ["url", "title", "frecency"])[0];
return Utils.queryAsync(this._urlStm, this._urlCols)[0];
},
changeItemID: function HStore_changeItemID(oldID, newID) {
@ -409,7 +416,7 @@ HistoryStore.prototype = {
this._allUrlStm.params.cutoff_date = (Date.now() - 2592000000) * 1000;
this._allUrlStm.params.max_results = MAX_HISTORY_UPLOAD;
let urls = Utils.queryAsync(this._allUrlStm, "url");
let urls = Utils.queryAsync(this._allUrlStm, this._allUrlCols);
let self = this;
return urls.reduce(function(ids, item) {
ids[self.GUIDForUri(item.url, true)] = item.url;

Просмотреть файл

@ -229,32 +229,51 @@ let Utils = {
return db.createStatement(query);
},
queryAsync: function(query, names) {
// Allow array of names, single name, and no name
if (!Utils.isArray(names))
names = names == null ? [] : [names];
// Prototype for mozIStorageCallback, used in queryAsync below.
// This allows us to define the handle* functions just once rather
// than on every queryAsync invocation.
_storageCallbackPrototype: {
results: null,
// These are set by queryAsync
names: null,
syncCb: null,
// Synchronously asyncExecute fetching all results by name
let execCb = Utils.makeSyncCallback();
query.executeAsync({
items: [],
handleResult: function handleResult(results) {
let row;
while ((row = results.getNextRow()) != null) {
this.items.push(names.reduce(function(item, name) {
item[name] = row.getResultByName(name);
return item;
}, {}));
}
},
handleError: function handleError(error) {
execCb.throw(error);
},
handleCompletion: function handleCompletion(reason) {
execCb(this.items);
handleResult: function handleResult(results) {
if (!this.names) {
return;
}
});
return Utils.waitForSyncCallback(execCb);
if (!this.results) {
this.results = [];
}
let row;
while ((row = results.getNextRow()) != null) {
let item = {};
for each (name in this.names) {
item[name] = row.getResultByName(name);
}
this.results.push(item);
}
},
handleError: function handleError(error) {
this.syncCb.throw(error);
},
handleCompletion: function handleCompletion(reason) {
// If we were called with column names but didn't find any results,
// the calling code probably still expects an array as a return value.
if (this.names && !this.results) {
this.results = [];
}
this.syncCb(this.results);
}
},
queryAsync: function(query, names) {
// Synchronously asyncExecute fetching all results by name
let storageCallback = {names: names,
syncCb: Utils.makeSyncCallback()};
storageCallback.__proto__ = Utils._storageCallbackPrototype;
query.executeAsync(storageCallback);
return Utils.waitForSyncCallback(storageCallback.syncCb);
},
byteArrayToString: function byteArrayToString(bytes) {

Просмотреть файл

@ -12,18 +12,18 @@ function run_test() {
_("Empty out the formhistory table");
let r0 = Utils.queryAsync(c("DELETE FROM moz_formhistory"));
do_check_eq(r0.length, 0);
do_check_eq(r0, null);
_("Make sure there's nothing there");
let r1 = Utils.queryAsync(c("SELECT 1 FROM moz_formhistory"));
do_check_eq(r1.length, 0);
do_check_eq(r1, null);
_("Insert a row");
let r2 = Utils.queryAsync(c("INSERT INTO moz_formhistory (fieldname, value) VALUES ('foo', 'bar')"));
do_check_eq(r2.length, 0);
do_check_eq(r2, null);
_("Request a known value for the one row");
let r3 = Utils.queryAsync(c("SELECT 42 num FROM moz_formhistory"), "num");
let r3 = Utils.queryAsync(c("SELECT 42 num FROM moz_formhistory"), ["num"]);
do_check_eq(r3.length, 1);
do_check_eq(r3[0].num, 42);
@ -41,7 +41,7 @@ function run_test() {
_("Add multiple entries (sqlite doesn't support multiple VALUES)");
let r6 = Utils.queryAsync(c("INSERT INTO moz_formhistory (fieldname, value) SELECT 'foo', 'baz' UNION SELECT 'more', 'values'"));
do_check_eq(r6.length, 0);
do_check_eq(r6, null);
_("Get multiple rows");
let r7 = Utils.queryAsync(c("SELECT fieldname, value FROM moz_formhistory WHERE fieldname = 'foo'"), ["fieldname", "value"]);
@ -51,7 +51,7 @@ function run_test() {
_("Make sure updates work");
let r8 = Utils.queryAsync(c("UPDATE moz_formhistory SET value = 'updated' WHERE fieldname = 'more'"));
do_check_eq(r8.length, 0);
do_check_eq(r8, null);
_("Get the updated");
let r9 = Utils.queryAsync(c("SELECT value, fieldname FROM moz_formhistory WHERE fieldname = 'more'"), ["fieldname", "value"]);
@ -60,7 +60,7 @@ function run_test() {
do_check_eq(r9[0].value, "updated");
_("Grabbing fewer fields than queried is fine");
let r10 = Utils.queryAsync(c("SELECT value, fieldname FROM moz_formhistory"), "fieldname");
let r10 = Utils.queryAsync(c("SELECT value, fieldname FROM moz_formhistory"), ["fieldname"]);
do_check_eq(r10.length, 3);
_("Generate an execution error");