diff --git a/toolkit/components/places/src/nsNavHistory.h b/toolkit/components/places/src/nsNavHistory.h index 3de9b8a9ee99..17e7c67f8604 100644 --- a/toolkit/components/places/src/nsNavHistory.h +++ b/toolkit/components/places/src/nsNavHistory.h @@ -654,12 +654,16 @@ protected: static const PRInt32 kAutoCompleteIndex_VisitCount; nsCOMPtr mDBCurrentQuery; // kAutoCompleteIndex_* results nsCOMPtr mDBAutoCompleteQuery; // kAutoCompleteIndex_* results + mozIStorageStatement* GetDBAutoCompleteHistoryQuery(); nsCOMPtr mDBAutoCompleteHistoryQuery; // kAutoCompleteIndex_* results + mozIStorageStatement* GetDBAutoCompleteStarQuery(); nsCOMPtr mDBAutoCompleteStarQuery; // kAutoCompleteIndex_* results + mozIStorageStatement* GetDBAutoCompleteTagsQuery(); nsCOMPtr mDBAutoCompleteTagsQuery; // kAutoCompleteIndex_* results nsCOMPtr mDBPreviousQuery; // kAutoCompleteIndex_* results nsCOMPtr mDBAdaptiveQuery; // kAutoCompleteIndex_* results nsCOMPtr mDBKeywordQuery; // kAutoCompleteIndex_* results + mozIStorageStatement* GetDBFeedbackIncrease(); nsCOMPtr mDBFeedbackIncrease; /** diff --git a/toolkit/components/places/src/nsNavHistoryAutoComplete.cpp b/toolkit/components/places/src/nsNavHistoryAutoComplete.cpp index 2d6e6cd74319..5bf8741708e8 100644 --- a/toolkit/components/places/src/nsNavHistoryAutoComplete.cpp +++ b/toolkit/components/places/src/nsNavHistoryAutoComplete.cpp @@ -26,6 +26,7 @@ * Seth Spitzer * Dietrich Ayala * Edward Lee + * Marco Bonardo * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or @@ -116,6 +117,38 @@ const PRUnichar kTitleTagsSeparatorChars[] = { ' ', 0x2013, ' ', 0 }; "(SELECT rev_host FROM moz_places WHERE id = b.fk)) " \ "ORDER BY frecency DESC LIMIT 1) " +// Define common pieces of various queries +// XXX bug 412736 +// in the case of a frecency tie, break it with h.typed and h.visit_count +// which is better than nothing. but this is slow, so not doing it yet. + +// Try to reduce size of compound table since with partitioning this became +// slower. Limiting moz_places with OFFSET+LIMIT will mostly help speed +// of first chunks, that are usually most wanted. +// Can do this only if there aren't additional conditions on final resultset. + +// Note: h.frecency is selected because we need it for ordering, but will +// not be read later and we don't have an associated kAutoCompleteIndex_ +const nsCString kAutoCompleteBaseQuery = NS_LITERAL_CSTRING( + "SELECT h.url, h.title, f.url") + BOOK_TAG_SQL + NS_LITERAL_CSTRING(", " + "h.visit_count, h.frecency " + "FROM moz_places_temp h " + "LEFT OUTER JOIN moz_favicons f ON f.id = h.favicon_id " + "WHERE h.frecency <> 0 " + "{ADDITIONAL_CONDITIONS} " + "UNION ALL " + "SELECT * FROM ( " + "SELECT h.url, h.title, f.url") + BOOK_TAG_SQL + NS_LITERAL_CSTRING(", " + "h.visit_count, h.frecency " + "FROM moz_places h " + "LEFT OUTER JOIN moz_favicons f ON f.id = h.favicon_id " + "WHERE h.id NOT IN (SELECT id FROM moz_places_temp) " + "AND h.frecency <> 0 " + "{ADDITIONAL_CONDITIONS} " + "ORDER BY h.frecency DESC LIMIT (?2 + ?3) " + ") " + "ORDER BY 8 DESC LIMIT ?2 OFFSET ?3"); + //////////////////////////////////////////////////////////////////////////////// //// nsNavHistoryAutoComplete Helper Functions @@ -262,49 +295,106 @@ nsNavHistory::InitAutoComplete() return NS_OK; } +// nsNavHistory::GetDBAutoCompleteHistoryQuery() +// +// Returns the auto complete statement used when autocomplete results are +// restricted to history entries. +mozIStorageStatement* +nsNavHistory::GetDBAutoCompleteHistoryQuery() +{ + if (mDBAutoCompleteHistoryQuery) + return mDBAutoCompleteHistoryQuery; + + nsCString AutoCompleteHistoryQuery = kAutoCompleteBaseQuery; + AutoCompleteHistoryQuery.ReplaceSubstring("{ADDITIONAL_CONDITIONS}", + "AND h.visit_count > 0"); + nsresult rv = mDBConn->CreateStatement(AutoCompleteHistoryQuery, + getter_AddRefs(mDBAutoCompleteHistoryQuery)); + NS_ENSURE_SUCCESS(rv, nsnull); + + return mDBAutoCompleteHistoryQuery; +} + +// nsNavHistory::GetDBAutoCompleteStarQuery() +// +// Returns the auto complete statement used when autocomplete results are +// restricted to bookmarked entries. +mozIStorageStatement* +nsNavHistory::GetDBAutoCompleteStarQuery() +{ + if (mDBAutoCompleteStarQuery) + return mDBAutoCompleteStarQuery; + + nsCString AutoCompleteStarQuery = kAutoCompleteBaseQuery; + AutoCompleteStarQuery.ReplaceSubstring("{ADDITIONAL_CONDITIONS}", + "AND bookmark IS NOT NULL"); + nsresult rv = mDBConn->CreateStatement(AutoCompleteStarQuery, + getter_AddRefs(mDBAutoCompleteStarQuery)); + NS_ENSURE_SUCCESS(rv, nsnull); + + return mDBAutoCompleteStarQuery; +} + +// nsNavHistory::GetDBAutoCompleteTagsQuery() +// +// Returns the auto complete statement used when autocomplete results are +// restricted to tagged entries. +mozIStorageStatement* +nsNavHistory::GetDBAutoCompleteTagsQuery() +{ + if (mDBAutoCompleteTagsQuery) + return mDBAutoCompleteTagsQuery; + + nsCString AutoCompleteTagsQuery = kAutoCompleteBaseQuery; + AutoCompleteTagsQuery.ReplaceSubstring("{ADDITIONAL_CONDITIONS}", + "AND tags IS NOT NULL"); + nsresult rv = mDBConn->CreateStatement(AutoCompleteTagsQuery, + getter_AddRefs(mDBAutoCompleteTagsQuery)); + NS_ENSURE_SUCCESS(rv, nsnull); + + return mDBAutoCompleteTagsQuery; +} + +// nsNavHistory::GetDBFeedbackIncrease() +// +// Returns the statement to update the input history that keeps track of +// selections in the locationbar. Input history is used for adaptive query. +mozIStorageStatement* +nsNavHistory::GetDBFeedbackIncrease() +{ + if (mDBFeedbackIncrease) + return mDBFeedbackIncrease; + + nsresult rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( + // Leverage the PRIMARY KEY (place_id, input) to insert/update entries + "INSERT OR REPLACE INTO moz_inputhistory " + // use_count will asymptotically approach the max of 10 + "SELECT h.id, IFNULL(i.input, ?1), IFNULL(i.use_count, 0) * .9 + 1 " + "FROM moz_places_temp h " + "LEFT JOIN moz_inputhistory i ON i.place_id = h.id AND i.input = ?1 " + "WHERE url = ?2 " + "UNION ALL " + "SELECT h.id, IFNULL(i.input, ?1), IFNULL(i.use_count, 0) * .9 + 1 " + "FROM moz_places h " + "LEFT JOIN moz_inputhistory i ON i.place_id = h.id AND i.input = ?1 " + "WHERE url = ?2 " + "AND h.id NOT IN (SELECT id FROM moz_places_temp)"), + getter_AddRefs(mDBFeedbackIncrease)); + NS_ENSURE_SUCCESS(rv, nsnull); + + return mDBFeedbackIncrease; +} // nsNavHistory::CreateAutoCompleteQueries // // The auto complete queries we use depend on options, so we have them in // a separate function so it can be re-created when the option changes. - +// We are not lazy creating these queries because they will be most likely +// used on first search, and we don't want to lag on first autocomplete use. nsresult nsNavHistory::CreateAutoCompleteQueries() { - // Define common pieces of various queries - // XXX bug 412736 - // in the case of a frecency tie, break it with h.typed and h.visit_count - // which is better than nothing. but this is slow, so not doing it yet. - - // Try to reduce size of compound table since with partitioning this became - // slower. Limiting moz_places with OFFSET+LIMIT will mostly help speed - // of first chunks, that are usually most wanted. - // Can do this only if there aren't additional conditions on final resultset. - - // Note: h.frecency is selected because we need it for ordering, but will - // not be read later and we don't have an associated kAutoCompleteIndex_ - - nsCString sqlBase = NS_LITERAL_CSTRING( - "SELECT h.url, h.title, f.url") + BOOK_TAG_SQL + NS_LITERAL_CSTRING(", " - "h.visit_count, h.frecency " - "FROM moz_places_temp h " - "LEFT OUTER JOIN moz_favicons f ON f.id = h.favicon_id " - "WHERE h.frecency <> 0 " - "{ADDITIONAL_CONDITIONS} " - "UNION ALL " - "SELECT * FROM ( " - "SELECT h.url, h.title, f.url") + BOOK_TAG_SQL + NS_LITERAL_CSTRING(", " - "h.visit_count, h.frecency " - "FROM moz_places h " - "LEFT OUTER JOIN moz_favicons f ON f.id = h.favicon_id " - "WHERE h.id NOT IN (SELECT id FROM moz_places_temp) " - "AND h.frecency <> 0 " - "{ADDITIONAL_CONDITIONS} " - "ORDER BY h.frecency DESC LIMIT (?2 + ?3) " - ") " - "ORDER BY 8 DESC LIMIT ?2 OFFSET ?3"); // ORDER BY frecency - - nsCString AutoCompleteQuery = sqlBase; + nsCString AutoCompleteQuery = kAutoCompleteBaseQuery; AutoCompleteQuery.ReplaceSubstring("{ADDITIONAL_CONDITIONS}", (mAutoCompleteOnlyTyped ? "AND h.typed = 1" : "")); @@ -312,27 +402,6 @@ nsNavHistory::CreateAutoCompleteQueries() getter_AddRefs(mDBAutoCompleteQuery)); NS_ENSURE_SUCCESS(rv, rv); - nsCString AutoCompleteHistoryQuery = sqlBase; - AutoCompleteHistoryQuery.ReplaceSubstring("{ADDITIONAL_CONDITIONS}", - "AND h.visit_count > 0"); - rv = mDBConn->CreateStatement(AutoCompleteHistoryQuery, - getter_AddRefs(mDBAutoCompleteHistoryQuery)); - NS_ENSURE_SUCCESS(rv, rv); - - nsCString AutoCompleteStarQuery = sqlBase; - AutoCompleteStarQuery.ReplaceSubstring("{ADDITIONAL_CONDITIONS}", - "AND bookmark IS NOT NULL"); - rv = mDBConn->CreateStatement(AutoCompleteStarQuery, - getter_AddRefs(mDBAutoCompleteStarQuery)); - NS_ENSURE_SUCCESS(rv, rv); - - nsCString AutoCompleteTagsQuery = sqlBase; - AutoCompleteTagsQuery.ReplaceSubstring("{ADDITIONAL_CONDITIONS}", - "AND tags IS NOT NULL"); - rv = mDBConn->CreateStatement(AutoCompleteTagsQuery, - getter_AddRefs(mDBAutoCompleteTagsQuery)); - NS_ENSURE_SUCCESS(rv, rv); - // In this query we are taking BOOK_TAG_SQL only for h.id because it // uses data from moz_bookmarks table and we sync tables on bookmark insert. // So, most likely, h.id will always be populated when we have any bookmark. @@ -375,23 +444,6 @@ nsNavHistory::CreateAutoCompleteQueries() rv = mDBConn->CreateStatement(sql, getter_AddRefs(mDBKeywordQuery)); NS_ENSURE_SUCCESS(rv, rv); - sql = NS_LITERAL_CSTRING( - // Leverage the PRIMARY KEY (place_id, input) to insert/update entries - "INSERT OR REPLACE INTO moz_inputhistory " - // use_count will asymptotically approach the max of 10 - "SELECT h.id, IFNULL(i.input, ?1), IFNULL(i.use_count, 0) * .9 + 1 " - "FROM moz_places_temp h " - "LEFT JOIN moz_inputhistory i ON i.place_id = h.id AND i.input = ?1 " - "WHERE url = ?2 " - "UNION ALL " - "SELECT h.id, IFNULL(i.input, ?1), IFNULL(i.use_count, 0) * .9 + 1 " - "FROM moz_places h " - "LEFT JOIN moz_inputhistory i ON i.place_id = h.id AND i.input = ?1 " - "WHERE url = ?2 " - "AND h.id NOT IN (SELECT id FROM moz_places_temp)"); - rv = mDBConn->CreateStatement(sql, getter_AddRefs(mDBFeedbackIncrease)); - NS_ENSURE_SUCCESS(rv, rv); - return NS_OK; } @@ -761,10 +813,10 @@ nsNavHistory::ProcessTokensForSpecialSearch() // We can use optimized queries for restricts, so check for the most // restrictive query first - mDBCurrentQuery = mRestrictTag ? mDBAutoCompleteTagsQuery : - mRestrictBookmark ? mDBAutoCompleteStarQuery : - mRestrictHistory ? mDBAutoCompleteHistoryQuery : - mDBAutoCompleteQuery; + mDBCurrentQuery = mRestrictTag ? GetDBAutoCompleteTagsQuery() : + mRestrictBookmark ? GetDBAutoCompleteStarQuery() : + mRestrictHistory ? GetDBAutoCompleteHistoryQuery() : + static_cast(mDBAutoCompleteQuery); } nsresult @@ -1067,21 +1119,22 @@ nsresult nsNavHistory::AutoCompleteFeedback(PRInt32 aIndex, nsIAutoCompleteController *aController) { - mozStorageStatementScoper scope(mDBFeedbackIncrease); + mozIStorageStatement* statement = GetDBFeedbackIncrease(); + mozStorageStatementScoper scope(statement); nsAutoString input; nsresult rv = aController->GetSearchString(input); NS_ENSURE_SUCCESS(rv, rv); - rv = mDBFeedbackIncrease->BindStringParameter(0, input); + rv = statement->BindStringParameter(0, input); NS_ENSURE_SUCCESS(rv, rv); nsAutoString url; rv = aController->GetValueAt(aIndex, url); NS_ENSURE_SUCCESS(rv, rv); - rv = mDBFeedbackIncrease->BindStringParameter(1, url); + rv = statement->BindStringParameter(1, url); NS_ENSURE_SUCCESS(rv, rv); - rv = mDBFeedbackIncrease->Execute(); + rv = statement->Execute(); NS_ENSURE_SUCCESS(rv, rv); return NS_OK;