--- a/toolkit/components/downloads/nsDownloadManager.cpp
+++ b/toolkit/components/downloads/nsDownloadManager.cpp
@@ -1846,35 +1846,36 @@ nsDownloadManager::OnEndUpdateBatch()
mHistoryTransaction = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsDownloadManager::OnVisit(nsIURI *aURI, PRInt64 aVisitID, PRTime aTime,
PRInt64 aSessionID, PRInt64 aReferringID,
- PRUint32 aTransitionType, PRUint32 *aAdded)
+ PRUint32 aTransitionType, const nsACString& aGUID,
+ PRUint32 *aAdded)
{
return NS_OK;
}
NS_IMETHODIMP
nsDownloadManager::OnTitleChanged(nsIURI *aURI, const nsAString &aPageTitle)
{
return NS_OK;
}
NS_IMETHODIMP
-nsDownloadManager::OnBeforeDeleteURI(nsIURI *aURI)
+nsDownloadManager::OnBeforeDeleteURI(nsIURI *aURI, const nsACString& aGUID)
{
return NS_OK;
}
NS_IMETHODIMP
-nsDownloadManager::OnDeleteURI(nsIURI *aURI)
+nsDownloadManager::OnDeleteURI(nsIURI *aURI, const nsACString& aGUID)
{
return RemoveDownloadsForURI(aURI);
}
NS_IMETHODIMP
nsDownloadManager::OnClearHistory()
{
return CleanUp();
@@ -1883,17 +1884,18 @@ nsDownloadManager::OnClearHistory()
NS_IMETHODIMP
nsDownloadManager::OnPageChanged(nsIURI *aURI, PRUint32 aWhat,
const nsAString &aValue)
{
return NS_OK;
}
NS_IMETHODIMP
-nsDownloadManager::OnDeleteVisits(nsIURI *aURI, PRTime aVisitTime)
+nsDownloadManager::OnDeleteVisits(nsIURI *aURI, PRTime aVisitTime,
+ const nsACString& aGUID)
{
// Don't bother removing downloads until the page is removed.
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
//// nsIObserver
--- a/toolkit/components/places/History.cpp
+++ b/toolkit/components/places/History.cpp
@@ -459,17 +459,17 @@ public:
// Notify nsNavHistory observers of visit, but only for certain types of
// visits to maintain consistency with nsNavHistory::GetQueryResults.
if (!mPlace.hidden &&
mPlace.transitionType != nsINavHistoryService::TRANSITION_EMBED &&
mPlace.transitionType != nsINavHistoryService::TRANSITION_FRAMED_LINK) {
navHistory->NotifyOnVisit(uri, mPlace.visitId, mPlace.visitTime,
mPlace.sessionId, mReferrer.visitId,
- mPlace.transitionType);
+ mPlace.transitionType, mPlace.guid);
}
nsCOMPtr<nsIObserverService> obsService =
mozilla::services::GetObserverService();
if (obsService) {
DebugOnly<nsresult> rv =
obsService->NotifyObservers(uri, URI_VISIT_SAVED, nsnull);
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Could not notify observers");
@@ -796,18 +796,19 @@ private:
NS_ENSURE_SUCCESS(rv, rv);
}
// Otherwise, the page was not in moz_places, so now we have to add it.
else {
rv = mHistory->InsertPlace(aPlace);
NS_ENSURE_SUCCESS(rv, rv);
// We need the place id and guid of the page we just inserted when we
- // have a callback. No point in doing the disk I/O if we do not need it.
- if (mCallback) {
+ // have a callback or when the GUID isn't known. No point in doing the
+ // disk I/O if we do not need it.
+ if (mCallback || aPlace.guid.IsEmpty()) {
bool exists = mHistory->FetchPageInfo(aPlace);
if (!exists) {
NS_NOTREACHED("should have an entry in moz_places");
}
}
}
rv = AddVisit(aPlace, aReferrer);
--- a/toolkit/components/places/nsNavBookmarks.cpp
+++ b/toolkit/components/places/nsNavBookmarks.cpp
@@ -3040,17 +3040,18 @@ nsNavBookmarks::OnEndUpdateBatch()
nsINavBookmarkObserver, OnEndUpdateBatch());
return NS_OK;
}
NS_IMETHODIMP
nsNavBookmarks::OnVisit(nsIURI* aURI, PRInt64 aVisitId, PRTime aTime,
PRInt64 aSessionID, PRInt64 aReferringID,
- PRUint32 aTransitionType, PRUint32* aAdded)
+ PRUint32 aTransitionType, const nsACString& aGUID,
+ PRUint32* aAdded)
{
// If the page is bookmarked, notify observers for each associated bookmark.
ItemVisitData visitData;
nsresult rv = aURI->GetSpec(visitData.bookmark.url);
NS_ENSURE_SUCCESS(rv, rv);
visitData.visitId = aVisitId;
visitData.time = aTime;
visitData.transitionType = aTransitionType;
@@ -3058,24 +3059,24 @@ nsNavBookmarks::OnVisit(nsIURI* aURI, PR
nsRefPtr< AsyncGetBookmarksForURI<ItemVisitMethod, ItemVisitData> > notifier =
new AsyncGetBookmarksForURI<ItemVisitMethod, ItemVisitData>(this, &nsNavBookmarks::NotifyItemVisited, visitData);
notifier->Init();
return NS_OK;
}
NS_IMETHODIMP
-nsNavBookmarks::OnBeforeDeleteURI(nsIURI* aURI)
+nsNavBookmarks::OnBeforeDeleteURI(nsIURI* aURI, const nsACString& aGUID)
{
return NS_OK;
}
NS_IMETHODIMP
-nsNavBookmarks::OnDeleteURI(nsIURI* aURI)
+nsNavBookmarks::OnDeleteURI(nsIURI* aURI, const nsACString& aGUID)
{
#ifdef DEBUG
nsNavHistory* history = nsNavHistory::GetHistoryService();
PRInt64 placeId;
NS_ABORT_IF_FALSE(
history && NS_SUCCEEDED(history->GetUrlIdFor(aURI, &placeId, PR_FALSE)) && !placeId,
"OnDeleteURI was notified for a page that still exists?"
);
@@ -3143,17 +3144,18 @@ nsNavBookmarks::OnPageChanged(nsIURI* aU
notifier->Init();
}
}
return NS_OK;
}
NS_IMETHODIMP
-nsNavBookmarks::OnDeleteVisits(nsIURI* aURI, PRTime aVisitTime)
+nsNavBookmarks::OnDeleteVisits(nsIURI* aURI, PRTime aVisitTime,
+ const nsACString& aGUID)
{
// Notify "cleartime" only if all visits to the page have been removed.
if (!aVisitTime) {
// If the page is bookmarked, notify observers for each associated bookmark.
ItemChangeData changeData;
nsresult rv = aURI->GetSpec(changeData.bookmark.url);
NS_ENSURE_SUCCESS(rv, rv);
changeData.property = NS_LITERAL_CSTRING("cleartime");
--- a/toolkit/components/places/nsNavHistory.cpp
+++ b/toolkit/components/places/nsNavHistory.cpp
@@ -23,16 +23,17 @@
* Dietrich Ayala <dietrich@mozilla.com>
* Seth Spitzer <sspitzer@mozilla.com>
* Asaf Romano <mano@mozilla.com>
* Marco Bonardo <mak77@bonardo.net>
* Edward Lee <edward.lee@engineering.uiuc.edu>
* Michael Ventnor <m.ventnor@gmail.com>
* Ehsan Akhgari <ehsan.akhgari@gmail.com>
* Drew Willcoxon <adw@mozilla.com>
+ * Philipp von Weitershausen <philipp@weitershausen.de>
*
* 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
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
@@ -1188,18 +1189,20 @@ nsNavHistory::InitTriggers()
mozIStorageStatement*
nsNavHistory::GetStatement(const nsCOMPtr<mozIStorageStatement>& aStmt)
{
// mCanNotify is set to false on shutdown.
if (!mCanNotify)
return nsnull;
+ // Note that this query violates the kGetInfoIndex_* convention in
+ // the last column.
RETURN_IF_STMT(mDBGetURLPageInfo, NS_LITERAL_CSTRING(
- "SELECT id, url, title, rev_host, visit_count "
+ "SELECT id, url, title, rev_host, visit_count, guid "
"FROM moz_places "
"WHERE url = :page_url "
));
RETURN_IF_STMT(mDBGetIdPageInfo, NS_LITERAL_CSTRING(
"SELECT id, url, title, rev_host, visit_count "
"FROM moz_places "
"WHERE id = :page_id "
@@ -1221,17 +1224,17 @@ nsNavHistory::GetStatement(const nsCOMPt
RETURN_IF_STMT(mDBInsertVisit, NS_LITERAL_CSTRING(
"INSERT INTO moz_historyvisits "
"(from_visit, place_id, visit_date, visit_type, session) "
"VALUES (:from_visit, :page_id, :visit_date, :visit_type, :session) "
));
RETURN_IF_STMT(mDBGetPageVisitStats, NS_LITERAL_CSTRING(
- "SELECT id, visit_count, typed, hidden "
+ "SELECT id, visit_count, typed, hidden, guid "
"FROM moz_places "
"WHERE url = :page_url "
));
RETURN_IF_STMT(mDBIsPageVisited, NS_LITERAL_CSTRING(
"SELECT h.id "
"FROM moz_places h "
"WHERE url = ?1 "
@@ -1717,17 +1720,18 @@ nsNavHistory::GetUrlIdFor(nsIURI* aURI,
if (hasEntry)
return stmt->GetInt64(kGetInfoIndex_PageID, aEntryID);
}
if (aAutoCreate) {
// create a new hidden, untyped, unvisited entry
nsAutoString voidString;
voidString.SetIsVoid(PR_TRUE);
- return InternalAddNewPage(aURI, voidString, PR_TRUE, PR_FALSE, 0, PR_TRUE, aEntryID);
+ nsCAutoString guid;
+ return InternalAddNewPage(aURI, voidString, PR_TRUE, PR_FALSE, 0, PR_TRUE, aEntryID, guid);
}
// Doesn't exist: don't do anything, entry ID was already set to 0 above
return NS_OK;
}
// nsNavHistory::InternalAddNewPage
@@ -1743,17 +1747,18 @@ nsNavHistory::GetUrlIdFor(nsIURI* aURI,
nsresult
nsNavHistory::InternalAddNewPage(nsIURI* aURI,
const nsAString& aTitle,
PRBool aHidden,
PRBool aTyped,
PRInt32 aVisitCount,
PRBool aCalculateFrecency,
- PRInt64* aPageID)
+ PRInt64* aPageID,
+ nsACString& guid)
{
DECLARE_AND_ASSIGN_SCOPED_LAZY_STMT(stmt, mDBAddNewPage);
nsresult rv = URIBinder::Bind(stmt, NS_LITERAL_CSTRING("page_url"), aURI);
NS_ENSURE_SUCCESS(rv, rv);
if (aTitle.IsVoid()) {
rv = stmt->BindNullByName(NS_LITERAL_CSTRING("page_title"));
}
@@ -1795,16 +1800,18 @@ nsNavHistory::InternalAddNewPage(nsIURI*
rv = URIBinder::Bind(getIdStmt, NS_LITERAL_CSTRING("page_url"), aURI);
NS_ENSURE_SUCCESS(rv, rv);
PRBool hasResult = PR_FALSE;
rv = getIdStmt->ExecuteStep(&hasResult);
NS_ENSURE_SUCCESS(rv, rv);
NS_ASSERTION(hasResult, "hasResult is false but the call succeeded?");
pageId = getIdStmt->AsInt64(0);
+ rv = getIdStmt->GetUTF8String(5, guid);
+ NS_ENSURE_SUCCESS(rv, rv);
}
if (aCalculateFrecency) {
rv = UpdateFrecency(pageId);
NS_ENSURE_SUCCESS(rv, rv);
}
// If the caller wants the page ID, return it.
@@ -2019,23 +2026,25 @@ nsNavHistory::GetNewSessionID()
void
nsNavHistory::NotifyOnVisit(nsIURI* aURI,
PRInt64 aVisitID,
PRTime aTime,
PRInt64 aSessionID,
PRInt64 referringVisitID,
- PRInt32 aTransitionType)
+ PRInt32 aTransitionType,
+ const nsACString& aGUID)
{
PRUint32 added = 0;
+ MOZ_ASSERT(!aGUID.IsEmpty());
NOTIFY_OBSERVERS(mCanNotify, mCacheObservers, mObservers,
nsINavHistoryObserver,
OnVisit(aURI, aVisitID, aTime, aSessionID,
- referringVisitID, aTransitionType, &added));
+ referringVisitID, aTransitionType, aGUID, &added));
}
void
nsNavHistory::NotifyTitleChange(nsIURI* aURI, const nsString& aTitle)
{
NOTIFY_OBSERVERS(mCanNotify, mCacheObservers, mObservers,
nsINavHistoryObserver, OnTitleChanged(aURI, aTitle));
}
@@ -2601,16 +2610,17 @@ nsNavHistory::AddVisit(nsIURI* aURI, PRT
// see if this is an update (revisit) or a new page
DECLARE_AND_ASSIGN_SCOPED_LAZY_STMT(stmt, mDBGetPageVisitStats);
rv = URIBinder::Bind(stmt, NS_LITERAL_CSTRING("page_url"), aURI);
NS_ENSURE_SUCCESS(rv, rv);
PRBool alreadyVisited = PR_FALSE;
rv = stmt->ExecuteStep(&alreadyVisited);
NS_ENSURE_SUCCESS(rv, rv);
+ nsCAutoString guid;
PRInt64 pageID = 0;
PRInt32 hidden;
PRInt32 typed;
PRBool newItem = PR_FALSE; // used to send out notifications at the end
if (alreadyVisited) {
// Update the existing entry...
rv = stmt->GetInt64(0, &pageID);
NS_ENSURE_SUCCESS(rv, rv);
@@ -2622,16 +2632,19 @@ nsNavHistory::AddVisit(nsIURI* aURI, PRT
PRInt32 oldTypedState = 0;
rv = stmt->GetInt32(2, &oldTypedState);
NS_ENSURE_SUCCESS(rv, rv);
PRBool oldHiddenState = 0;
rv = stmt->GetInt32(3, &oldHiddenState);
NS_ENSURE_SUCCESS(rv, rv);
+ rv = stmt->GetUTF8String(4, guid);
+ NS_ENSURE_SUCCESS(rv, rv);
+
// free the previous statement before we make a new one
stmt->Reset();
scoper.Abandon();
// Note that we want to unhide any hidden pages that the user explicitly
// types (aTransitionType == TRANSITION_TYPED) so that they will appear in
// the history UI (sidebar, history menu, url bar autocomplete, etc).
// Additionally, we don't want to hide any pages that are already unhidden.
@@ -2676,17 +2689,17 @@ nsNavHistory::AddVisit(nsIURI* aURI, PRT
aIsRedirect);
typed = (PRInt32)(aTransitionType == TRANSITION_TYPED);
// set as visited once, no title
nsString voidString;
voidString.SetIsVoid(PR_TRUE);
rv = InternalAddNewPage(aURI, voidString, hidden == 1, typed == 1, 1,
- PR_TRUE, &pageID);
+ PR_TRUE, &pageID, guid);
NS_ENSURE_SUCCESS(rv, rv);
}
// Get the visit id for the referrer, if it exists.
PRInt64 referringVisitID = 0;
PRInt64 referringSessionID;
PRTime referringTime;
PRBool referrerIsSame;
@@ -2711,17 +2724,17 @@ nsNavHistory::AddVisit(nsIURI* aURI, PRT
// important to notify the observers below.
(void)UpdateFrecency(pageID);
// Notify observers: The hidden detection code must match that in
// GetQueryResults to maintain consistency.
// FIXME bug 325241: make a way to observe hidden URLs
if (!hidden) {
NotifyOnVisit(aURI, *aVisitID, aTime, aSessionID, referringVisitID,
- aTransitionType);
+ aTransitionType, guid);
}
// Normally docshell sends the link visited observer notification for us (this
// will tell all the documents to update their visited link coloring).
// However, for redirects (since we implement nsIGlobalHistory3) and downloads
// (since we implement nsIDownloadHistory) this will not happen and we need to
// send it ourselves.
if (newItem && (aIsRedirect || aTransitionType == TRANSITION_DOWNLOAD)) {
@@ -4164,53 +4177,57 @@ nsNavHistory::CleanupPlacesOnVisitsDelet
{
// Return early if there is nothing to delete.
if (aPlaceIdsQueryString.IsEmpty())
return NS_OK;
// Collect about-to-be-deleted URIs to notify onDeleteURI.
nsCOMPtr<mozIStorageStatement> stmt;
mDBConn->CreateStatement(NS_LITERAL_CSTRING(
- "SELECT h.id, h.url, (SUBSTR(h.url, 1, 6) <> 'place:' "
- "AND NOT EXISTS (SELECT b.id FROM moz_bookmarks b "
- "WHERE b.fk = h.id LIMIT 1)"
- ") as whole_entry "
+ "SELECT h.id, h.url, h.guid, "
+ "(SUBSTR(h.url, 1, 6) <> 'place:' "
+ " AND NOT EXISTS (SELECT b.id FROM moz_bookmarks b "
+ "WHERE b.fk = h.id LIMIT 1)) as whole_entry "
"FROM moz_places h "
"WHERE h.id IN ( ") + aPlaceIdsQueryString + NS_LITERAL_CSTRING(") "
), getter_AddRefs(stmt));
NS_ENSURE_STATE(stmt);
nsCString filteredPlaceIds;
nsCOMArray<nsIURI> URIs;
+ nsTArray<nsCString> GUIDs;
PRBool hasMore;
while (NS_SUCCEEDED(stmt->ExecuteStep(&hasMore)) && hasMore) {
PRInt64 placeId;
nsresult rv = stmt->GetInt64(0, &placeId);
NS_ENSURE_SUCCESS(rv, rv);
nsCAutoString URLString;
rv = stmt->GetUTF8String(1, URLString);
+ nsCString guid;
+ rv = stmt->GetUTF8String(2, guid);
PRInt32 wholeEntry;
- rv = stmt->GetInt32(2, &wholeEntry);
+ rv = stmt->GetInt32(3, &wholeEntry);
nsCOMPtr<nsIURI> uri;
rv = NS_NewURI(getter_AddRefs(uri), URLString);
NS_ENSURE_SUCCESS(rv, rv);
if (wholeEntry) {
if (!filteredPlaceIds.IsEmpty()) {
filteredPlaceIds.AppendLiteral(",");
}
filteredPlaceIds.AppendInt(placeId);
URIs.AppendObject(uri);
+ GUIDs.AppendElement(guid);
// Notify we are about to remove this uri.
NOTIFY_OBSERVERS(mCanNotify, mCacheObservers, mObservers,
- nsINavHistoryObserver, OnBeforeDeleteURI(uri));
+ nsINavHistoryObserver, OnBeforeDeleteURI(uri, guid));
}
else {
// Notify that we will delete all visits for this page, but not the page
// itself, since it's bookmarked or a place: query.
NOTIFY_OBSERVERS(mCanNotify, mCacheObservers, mObservers,
- nsINavHistoryObserver, OnDeleteVisits(uri, 0));
+ nsINavHistoryObserver, OnDeleteVisits(uri, 0, guid));
}
}
// if the entry is not bookmarked and is not a place: uri
// then we can remove it from moz_places.
// Note that we do NOT delete favicons. Any unreferenced favicons will be
// deleted next time the browser is shut down.
nsresult rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
@@ -4223,17 +4240,17 @@ nsNavHistory::CleanupPlacesOnVisitsDelet
// frecency, or it would appear in the url bar autocomplete.
// XXX this might be dog slow, further degrading delete perf.
rv = FixInvalidFrecenciesForExcludedPlaces();
NS_ENSURE_SUCCESS(rv, rv);
// Finally notify about the removed URIs.
for (PRInt32 i = 0; i < URIs.Count(); ++i) {
NOTIFY_OBSERVERS(mCanNotify, mCacheObservers, mObservers,
- nsINavHistoryObserver, OnDeleteURI(URIs[i]));
+ nsINavHistoryObserver, OnDeleteURI(URIs[i], GUIDs[i]));
}
return NS_OK;
}
// nsNavHistory::RemovePages
//
@@ -5346,30 +5363,31 @@ nsNavHistory::AsyncExecuteLegacyQueries(
return NS_OK;
}
// nsPIPlacesHistoryListenersNotifier ******************************************
NS_IMETHODIMP
nsNavHistory::NotifyOnPageExpired(nsIURI *aURI, PRTime aVisitTime,
- PRBool aWholeEntry)
+ PRBool aWholeEntry, const nsACString& aGUID)
{
// Invalidate the cached value for whether there's history or not.
mHasHistoryEntries = -1;
+ MOZ_ASSERT(!aGUID.IsEmpty());
if (aWholeEntry) {
// Notify our observers that the page has been removed.
NOTIFY_OBSERVERS(mCanNotify, mCacheObservers, mObservers,
- nsINavHistoryObserver, OnDeleteURI(aURI));
+ nsINavHistoryObserver, OnDeleteURI(aURI, aGUID));
}
else {
// Notify our observers that some visits for the page have been removed.
NOTIFY_OBSERVERS(mCanNotify, mCacheObservers, mObservers,
- nsINavHistoryObserver, OnDeleteVisits(aURI, aVisitTime));
+ nsINavHistoryObserver, OnDeleteVisits(aURI, aVisitTime, aGUID));
}
return NS_OK;
}
// nsIObserver *****************************************************************
NS_IMETHODIMP
@@ -6835,25 +6853,28 @@ nsNavHistory::AddPageWithVisits(nsIURI *
PRBool alreadyVisited = PR_FALSE;
rv = stmt->ExecuteStep(&alreadyVisited);
NS_ENSURE_SUCCESS(rv, rv);
PRInt64 placeId = 0;
PRInt32 typed = 0;
PRInt32 hidden = 0;
+ nsCAutoString guid;
if (alreadyVisited) {
// Update the existing entry
rv = stmt->GetInt64(0, &placeId);
NS_ENSURE_SUCCESS(rv, rv);
// We don't mind visit_count
rv = stmt->GetInt32(2, &typed);
NS_ENSURE_SUCCESS(rv, rv);
rv = stmt->GetInt32(3, &hidden);
NS_ENSURE_SUCCESS(rv, rv);
+ rv = stmt->GetUTF8String(4, guid);
+ NS_ENSURE_SUCCESS(rv, rv);
if (typed == 0 && aTransitionType == TRANSITION_TYPED) {
typed = 1;
// Update with new stats
DECLARE_AND_ASSIGN_SCOPED_LAZY_STMT(updateStmt, mDBUpdatePageVisitStats);
rv = updateStmt->BindInt64ByName(NS_LITERAL_CSTRING("page_id"), placeId);
NS_ENSURE_SUCCESS(rv, rv);
rv = updateStmt->BindInt32ByName(NS_LITERAL_CSTRING("hidden"), hidden);
@@ -6863,17 +6884,17 @@ nsNavHistory::AddPageWithVisits(nsIURI *
rv = updateStmt->Execute();
NS_ENSURE_SUCCESS(rv, rv);
}
} else {
// Insert the new place entry
rv = InternalAddNewPage(aURI, aTitle, hidden == 1,
aTransitionType == TRANSITION_TYPED, 0,
- PR_FALSE, &placeId);
+ PR_FALSE, &placeId, guid);
NS_ENSURE_SUCCESS(rv, rv);
}
NS_ASSERTION(placeId != 0, "Cannot add a visit to a nonexistent page");
if (aFirstVisitDate != -1) {
// Add the first visit
PRInt64 visitId;
--- a/toolkit/components/places/nsNavHistory.h
+++ b/toolkit/components/places/nsNavHistory.h
@@ -590,22 +590,24 @@ public:
/**
* Fires onVisit event to nsINavHistoryService observers
*/
void NotifyOnVisit(nsIURI* aURI,
PRInt64 aVisitID,
PRTime aTime,
PRInt64 aSessionID,
PRInt64 referringVisitID,
- PRInt32 aTransitionType);
+ PRInt32 aTransitionType,
+ const nsACString& aGUID);
/**
* Fires onTitleChanged event to nsINavHistoryService observers
*/
- void NotifyTitleChange(nsIURI* aURI, const nsString& title);
+ void NotifyTitleChange(nsIURI* aURI,
+ const nsString& title);
bool isBatching() {
return mBatchLevel > 0;
}
private:
~nsNavHistory();
@@ -727,17 +729,17 @@ protected:
nsresult AddVisitChain(nsIURI* aURI, PRTime aTime,
PRBool aToplevel, PRBool aRedirect,
nsIURI* aReferrer, PRInt64* aVisitID,
PRInt64* aSessionID);
nsresult InternalAddNewPage(nsIURI* aURI, const nsAString& aTitle,
PRBool aHidden, PRBool aTyped,
PRInt32 aVisitCount, PRBool aCalculateFrecency,
- PRInt64* aPageID);
+ PRInt64* aPageID, nsACString& guid);
nsresult InternalAddVisit(PRInt64 aPageID, PRInt64 aReferringVisit,
PRInt64 aSessionID, PRTime aTime,
PRInt32 aTransitionType, PRInt64* aVisitID);
PRBool FindLastVisit(nsIURI* aURI,
PRInt64* aVisitID,
PRTime* aTime,
PRInt64* aSessionID);
PRBool IsURIStringVisited(const nsACString& url);
--- a/toolkit/components/places/nsNavHistoryResult.cpp
+++ b/toolkit/components/places/nsNavHistoryResult.cpp
@@ -2874,16 +2874,17 @@ nsNavHistoryQueryResultNode::OnEndUpdate
* common update operation and it is important that it be as efficient as
* possible.
*/
NS_IMETHODIMP
nsNavHistoryQueryResultNode::OnVisit(nsIURI* aURI, PRInt64 aVisitId,
PRTime aTime, PRInt64 aSessionId,
PRInt64 aReferringId,
PRUint32 aTransitionType,
+ const nsACString& aGUID,
PRUint32* aAdded)
{
nsNavHistory* history = nsNavHistory::GetHistoryService();
NS_ENSURE_TRUE(history, NS_ERROR_OUT_OF_MEMORY);
nsresult rv;
nsRefPtr<nsNavHistoryResultNode> addition;
switch(mLiveUpdate) {
@@ -3056,27 +3057,29 @@ nsNavHistoryQueryResultNode::OnTitleChan
}
}
return ChangeTitles(aURI, newTitle, PR_TRUE, onlyOneEntry);
}
NS_IMETHODIMP
-nsNavHistoryQueryResultNode::OnBeforeDeleteURI(nsIURI *aURI)
+nsNavHistoryQueryResultNode::OnBeforeDeleteURI(nsIURI *aURI,
+ const nsACString& aGUID)
{
return NS_OK;
}
/**
* Here, we can always live update by just deleting all occurrences of
* the given URI.
*/
NS_IMETHODIMP
-nsNavHistoryQueryResultNode::OnDeleteURI(nsIURI *aURI)
+nsNavHistoryQueryResultNode::OnDeleteURI(nsIURI *aURI,
+ const nsACString& aGUID)
{
if (IsContainersQuery()) {
// Incremental updates of query returning queries are pretty much
// complicated. In this case it's possible one of the child queries has
// no more children and it should be removed. Unfortunately there is no
// way to know that without executing the child query and counting results.
nsresult rv = Refresh();
NS_ENSURE_SUCCESS(rv, rv);
@@ -3160,25 +3163,26 @@ nsNavHistoryQueryResultNode::OnPageChang
default:
NS_WARNING("Unknown page changed notification");
}
return NS_OK;
}
NS_IMETHODIMP
-nsNavHistoryQueryResultNode::OnDeleteVisits(nsIURI* aURI, PRTime aVisitTime)
+nsNavHistoryQueryResultNode::OnDeleteVisits(nsIURI* aURI, PRTime aVisitTime,
+ const nsACString& aGUID)
{
NS_PRECONDITION(mOptions->QueryType() == nsINavHistoryQueryOptions::QUERY_TYPE_HISTORY,
"Bookmarks queries should not get a OnDeleteVisits notification");
if (aVisitTime == 0) {
// All visits for this uri have been removed, but the uri won't be removed
// from the databse, most likely because it's a bookmark. For a history
// query this is equivalent to a onDeleteURI notification.
- nsresult rv = OnDeleteURI(aURI);
+ nsresult rv = OnDeleteURI(aURI, aGUID);
NS_ENSURE_SUCCESS(rv, rv);
}
return NS_OK;
}
nsresult
nsNavHistoryQueryResultNode::NotifyIfTagsChanged(nsIURI* aURI)
@@ -5059,22 +5063,24 @@ nsNavHistoryResult::OnItemMoved(PRInt64
aNewParentGUID));
return NS_OK;
}
NS_IMETHODIMP
nsNavHistoryResult::OnVisit(nsIURI* aURI, PRInt64 aVisitId, PRTime aTime,
PRInt64 aSessionId, PRInt64 aReferringId,
- PRUint32 aTransitionType, PRUint32* aAdded)
+ PRUint32 aTransitionType, const nsACString& aGUID,
+ PRUint32* aAdded)
{
PRUint32 added = 0;
ENUMERATE_HISTORY_OBSERVERS(OnVisit(aURI, aVisitId, aTime, aSessionId,
- aReferringId, aTransitionType, &added));
+ aReferringId, aTransitionType, aGUID,
+ &added));
if (!mRootNode->mExpanded)
return NS_OK;
// If this visit is accepted by an overlapped container, and not all
// overlapped containers are visible, we should still call Refresh if the
// visit falls into any of them.
PRBool todayIsMissing = PR_FALSE;
@@ -5125,26 +5131,26 @@ NS_IMETHODIMP
nsNavHistoryResult::OnTitleChanged(nsIURI* aURI, const nsAString& aPageTitle)
{
ENUMERATE_HISTORY_OBSERVERS(OnTitleChanged(aURI, aPageTitle));
return NS_OK;
}
NS_IMETHODIMP
-nsNavHistoryResult::OnBeforeDeleteURI(nsIURI *aURI)
+nsNavHistoryResult::OnBeforeDeleteURI(nsIURI *aURI, const nsACString& aGUID)
{
return NS_OK;
}
NS_IMETHODIMP
-nsNavHistoryResult::OnDeleteURI(nsIURI *aURI)
+nsNavHistoryResult::OnDeleteURI(nsIURI *aURI, const nsACString& aGUID)
{
- ENUMERATE_HISTORY_OBSERVERS(OnDeleteURI(aURI));
+ ENUMERATE_HISTORY_OBSERVERS(OnDeleteURI(aURI, aGUID));
return NS_OK;
}
NS_IMETHODIMP
nsNavHistoryResult::OnClearHistory()
{
ENUMERATE_HISTORY_OBSERVERS(OnClearHistory());
@@ -5160,13 +5166,14 @@ nsNavHistoryResult::OnPageChanged(nsIURI
return NS_OK;
}
/**
* Don't do anything when visits expire.
*/
NS_IMETHODIMP
-nsNavHistoryResult::OnDeleteVisits(nsIURI* aURI, PRTime aVisitTime)
+nsNavHistoryResult::OnDeleteVisits(nsIURI* aURI, PRTime aVisitTime,
+ const nsACString& aGUID)
{
- ENUMERATE_HISTORY_OBSERVERS(OnDeleteVisits(aURI, aVisitTime));
+ ENUMERATE_HISTORY_OBSERVERS(OnDeleteVisits(aURI, aVisitTime, aGUID));
return NS_OK;
}
--- a/toolkit/components/places/nsNavHistoryResult.h
+++ b/toolkit/components/places/nsNavHistoryResult.h
@@ -93,24 +93,26 @@ private:
// Declare methods for implementing nsINavBookmarkObserver
// and nsINavHistoryObserver (some methods, such as BeginUpdateBatch overlap)
#define NS_DECL_BOOKMARK_HISTORY_OBSERVER \
NS_DECL_NSINAVBOOKMARKOBSERVER \
NS_IMETHOD OnVisit(nsIURI* aURI, PRInt64 aVisitId, PRTime aTime, \
PRInt64 aSessionId, PRInt64 aReferringId, \
- PRUint32 aTransitionType, PRUint32* aAdded); \
+ PRUint32 aTransitionType, const nsACString& aGUID, \
+ PRUint32* aAdded); \
NS_IMETHOD OnTitleChanged(nsIURI* aURI, const nsAString& aPageTitle); \
- NS_IMETHOD OnBeforeDeleteURI(nsIURI *aURI); \
- NS_IMETHOD OnDeleteURI(nsIURI *aURI); \
+ NS_IMETHOD OnBeforeDeleteURI(nsIURI *aURI, const nsACString& aGUID); \
+ NS_IMETHOD OnDeleteURI(nsIURI *aURI, const nsACString& aGUID); \
NS_IMETHOD OnClearHistory(); \
NS_IMETHOD OnPageChanged(nsIURI *aURI, PRUint32 aWhat, \
const nsAString &aValue); \
- NS_IMETHOD OnDeleteVisits(nsIURI* aURI, PRTime aVisitTime);
+ NS_IMETHOD OnDeleteVisits(nsIURI* aURI, PRTime aVisitTime, \
+ const nsACString& aGUID);
// nsNavHistoryResult
//
// nsNavHistory creates this object and fills in mChildren (by getting
// it through GetTopLevel()). Then FilledAllResults() is called to finish
// object initialization.
#define NS_NAVHISTORYRESULT_IID \
--- a/toolkit/components/places/nsPlacesExpiration.js
+++ b/toolkit/components/places/nsPlacesExpiration.js
@@ -207,18 +207,18 @@ const ACTION = {
// The queries we use to expire.
const EXPIRATION_QUERIES = {
// Finds visits to be expired. Will return nothing if we are not over the
// unique URIs limit.
QUERY_FIND_VISITS_TO_EXPIRE: {
sql: "INSERT INTO expiration_notify "
- + "(v_id, url, visit_date, expected_results) "
- + "SELECT v.id, h.url, v.visit_date, :limit_visits "
+ + "(v_id, url, guid, visit_date, expected_results) "
+ + "SELECT v.id, h.url, h.guid, v.visit_date, :limit_visits "
+ "FROM moz_historyvisits v "
+ "JOIN moz_places h ON h.id = v.place_id "
+ "WHERE (SELECT COUNT(*) FROM moz_places) > :max_uris "
+ "ORDER BY v.visit_date ASC "
+ "LIMIT :limit_visits",
actions: ACTION.TIMED_OVERLIMIT | ACTION.SHUTDOWN | ACTION.IDLE |
ACTION.DEBUG
},
@@ -232,18 +232,18 @@ const EXPIRATION_QUERIES = {
ACTION.DEBUG
},
// Finds orphan URIs in the database.
// Notice we won't notify single removed URIs on removeAllPages, so we don't
// run this query in such a case, but just delete URIs.
QUERY_FIND_URIS_TO_EXPIRE: {
sql: "INSERT INTO expiration_notify "
- + "(p_id, url, visit_date, expected_results) "
- + "SELECT h.id, h.url, h.last_visit_date, :limit_uris "
+ + "(p_id, url, guid, visit_date, expected_results) "
+ + "SELECT h.id, h.url, h.guid, h.last_visit_date, :limit_uris "
+ "FROM moz_places h "
+ "LEFT JOIN moz_historyvisits v ON h.id = v.place_id "
+ "LEFT JOIN moz_bookmarks b ON h.id = b.fk "
+ "WHERE v.id IS NULL "
+ "AND b.id IS NULL "
+ "AND h.ROWID <> IFNULL(:null_skips_last, (SELECT MAX(ROWID) FROM moz_places)) "
+ "LIMIT :limit_uris",
actions: ACTION.TIMED | ACTION.TIMED_OVERLIMIT | ACTION.SHUTDOWN |
@@ -383,17 +383,17 @@ const EXPIRATION_QUERIES = {
actions: ACTION.CLEAR_HISTORY | ACTION.SHUTDOWN | ACTION.CLEAN_SHUTDOWN |
ACTION.DEBUG
},
// Select entries for notifications.
// If p_id is set whole_entry = 1, then we have expired the full page.
// Either p_id or v_id are always set.
QUERY_SELECT_NOTIFICATIONS: {
- sql: "SELECT url, MAX(visit_date) AS visit_date, "
+ sql: "SELECT url, guid, MAX(visit_date) AS visit_date, "
+ "MAX(IFNULL(MIN(p_id, 1), MIN(v_id, 0))) AS whole_entry, "
+ "expected_results "
+ "FROM expiration_notify "
+ "GROUP BY url",
actions: ACTION.TIMED | ACTION.TIMED_OVERLIMIT | ACTION.SHUTDOWN |
ACTION.IDLE | ACTION.DEBUG
},
@@ -444,16 +444,17 @@ function nsPlacesExpiration()
// Create the temporary notifications table.
let stmt = db.createAsyncStatement(
"CREATE TEMP TABLE expiration_notify ( "
+ " id INTEGER PRIMARY KEY "
+ ", v_id INTEGER "
+ ", p_id INTEGER "
+ ", url TEXT NOT NULL "
+ + ", guid TEXT NOT NULL "
+ ", visit_date INTEGER "
+ ", expected_results INTEGER NOT NULL "
+ ") ");
stmt.executeAsync();
stmt.finalize();
return db;
});
@@ -627,20 +628,21 @@ nsPlacesExpiration.prototype = {
let row;
while (row = aResultSet.getNextRow()) {
if (!("_expectedResultsCount" in this))
this._expectedResultsCount = row.getResultByName("expected_results");
if (this._expectedResultsCount > 0)
this._expectedResultsCount--;
let uri = Services.io.newURI(row.getResultByName("url"), null, null);
+ let guid = row.getResultByName("guid");
let visitDate = row.getResultByName("visit_date");
let wholeEntry = row.getResultByName("whole_entry");
// Dispatch expiration notifications to history.
- this._hsn.notifyOnPageExpired(uri, visitDate, wholeEntry);
+ this._hsn.notifyOnPageExpired(uri, visitDate, wholeEntry, guid);
}
},
handleError: function PEX_handleError(aError)
{
Cu.reportError("Async statement execution returned with '" +
aError.result + "', '" + aError.message + "'");
},