Bug 1269398: Add visitType, visitId, and fromVisitId fields to history visit query results. r=mak

MozReview-Commit-ID: BCsztVsCH98
This commit is contained in:
Kris Maglione
2016-05-13 13:47:24 -07:00
parent 5671f05a69
commit bc973f9b6a
8 changed files with 196 additions and 24 deletions

View File

@@ -167,6 +167,25 @@ interface nsINavHistoryResultNode : nsISupports
* separator.
*/
readonly attribute ACString bookmarkGuid;
/**
* The unique ID associated with the history visit. For node types other than
* history visit nodes, this value is -1.
*/
readonly attribute long long visitId;
/**
* The unique ID associated with visit node which was the referrer of this
* history visit. For node types other than history visit nodes, or visits
* without any known referrer, this value is -1.
*/
readonly attribute long long fromVisitId;
/**
* The transition type associated with this visit. For node types other than
* history visit nodes, this value is 0.
*/
readonly attribute unsigned long visitType;
};

View File

@@ -22,10 +22,10 @@
using namespace mozilla;
// These columns sit to the right of the kGetInfoIndex_* columns.
const int32_t nsNavBookmarks::kGetChildrenIndex_Guid = 15;
const int32_t nsNavBookmarks::kGetChildrenIndex_Position = 16;
const int32_t nsNavBookmarks::kGetChildrenIndex_Type = 17;
const int32_t nsNavBookmarks::kGetChildrenIndex_PlaceID = 18;
const int32_t nsNavBookmarks::kGetChildrenIndex_Guid = 18;
const int32_t nsNavBookmarks::kGetChildrenIndex_Position = 19;
const int32_t nsNavBookmarks::kGetChildrenIndex_Type = 20;
const int32_t nsNavBookmarks::kGetChildrenIndex_PlaceID = 21;
using namespace mozilla::places;
@@ -962,8 +962,8 @@ nsNavBookmarks::GetDescendantChildren(int64_t aFolderId,
nsCOMPtr<mozIStorageStatement> stmt = mDB->GetStatement(
"SELECT h.id, h.url, IFNULL(b.title, h.title), h.rev_host, h.visit_count, "
"h.last_visit_date, f.url, b.id, b.dateAdded, b.lastModified, "
"b.parent, null, h.frecency, h.hidden, h.guid, b.guid, "
"b.position, b.type, b.fk "
"b.parent, null, h.frecency, h.hidden, h.guid, null, null, null, "
"b.guid, b.position, b.type, b.fk "
"FROM moz_bookmarks b "
"LEFT JOIN moz_places h ON b.fk = h.id "
"LEFT JOIN moz_favicons f ON h.favicon_id = f.id "
@@ -1635,8 +1635,8 @@ nsNavBookmarks::QueryFolderChildren(
nsCOMPtr<mozIStorageStatement> stmt = mDB->GetStatement(
"SELECT h.id, h.url, IFNULL(b.title, h.title), h.rev_host, h.visit_count, "
"h.last_visit_date, f.url, b.id, b.dateAdded, b.lastModified, "
"b.parent, null, h.frecency, h.hidden, h.guid, b.guid, "
"b.position, b.type, b.fk "
"b.parent, null, h.frecency, h.hidden, h.guid, null, null, null, "
"b.guid, b.position, b.type, b.fk "
"FROM moz_bookmarks b "
"LEFT JOIN moz_places h ON b.fk = h.id "
"LEFT JOIN moz_favicons f ON h.favicon_id = f.id "
@@ -1773,8 +1773,8 @@ nsNavBookmarks::QueryFolderChildrenAsync(
nsCOMPtr<mozIStorageAsyncStatement> stmt = mDB->GetAsyncStatement(
"SELECT h.id, h.url, IFNULL(b.title, h.title), h.rev_host, h.visit_count, "
"h.last_visit_date, f.url, b.id, b.dateAdded, b.lastModified, "
"b.parent, null, h.frecency, h.hidden, h.guid, b.guid, "
"b.position, b.type, b.fk "
"b.parent, null, h.frecency, h.hidden, h.guid, null, null, null, "
"b.guid, b.position, b.type, b.fk "
"FROM moz_bookmarks b "
"LEFT JOIN moz_places h ON b.fk = h.id "
"LEFT JOIN moz_favicons f ON h.favicon_id = f.id "

View File

@@ -248,6 +248,15 @@ const int32_t nsNavHistory::kGetInfoIndex_ItemTags = 11;
const int32_t nsNavHistory::kGetInfoIndex_Frecency = 12;
const int32_t nsNavHistory::kGetInfoIndex_Hidden = 13;
const int32_t nsNavHistory::kGetInfoIndex_Guid = 14;
const int32_t nsNavHistory::kGetInfoIndex_VisitId = 15;
const int32_t nsNavHistory::kGetInfoIndex_FromVisitId = 16;
const int32_t nsNavHistory::kGetInfoIndex_VisitType = 17;
// These columns are followed by corresponding constants in nsNavBookmarks.cpp,
// which must be kept in sync:
// nsNavBookmarks::kGetChildrenIndex_Guid = 18;
// nsNavBookmarks::kGetChildrenIndex_Position = 19;
// nsNavBookmarks::kGetChildrenIndex_Type = 20;
// nsNavBookmarks::kGetChildrenIndex_PlaceID = 21;
PLACES_FACTORY_SINGLETON_IMPLEMENTATION(nsNavHistory, gHistoryService)
@@ -1484,7 +1493,8 @@ PlacesSQLQueryBuilder::SelectAsURI()
mQueryString = NS_LITERAL_CSTRING(
"SELECT h.id, h.url, h.title AS page_title, h.rev_host, h.visit_count, "
"h.last_visit_date, f.url, null, null, null, null, ") +
tagsSqlFragment + NS_LITERAL_CSTRING(", h.frecency, h.hidden, h.guid "
tagsSqlFragment + NS_LITERAL_CSTRING(", h.frecency, h.hidden, h.guid, "
"null, null, null "
"FROM moz_places h "
"LEFT JOIN moz_favicons f ON h.favicon_id = f.id "
// WHERE 1 is a no-op since additonal conditions will start with AND.
@@ -1511,7 +1521,7 @@ PlacesSQLQueryBuilder::SelectAsURI()
"h.rev_host, h.visit_count, h.last_visit_date, f.url, b2.id, "
"b2.dateAdded, b2.lastModified, b2.parent, ") +
tagsSqlFragment + NS_LITERAL_CSTRING(", h.frecency, h.hidden, h.guid, "
"b2.guid, b2.position, b2.type, b2.fk "
"null, null, null, b2.guid, b2.position, b2.type, b2.fk "
"FROM moz_bookmarks b2 "
"JOIN (SELECT b.fk "
"FROM moz_bookmarks b "
@@ -1536,7 +1546,7 @@ PlacesSQLQueryBuilder::SelectAsURI()
"h.rev_host, h.visit_count, h.last_visit_date, f.url, b.id, "
"b.dateAdded, b.lastModified, b.parent, ") +
tagsSqlFragment + NS_LITERAL_CSTRING(", h.frecency, h.hidden, h.guid,"
"b.guid, b.position, b.type, b.fk "
"null, null, null, b.guid, b.position, b.type, b.fk "
"FROM moz_bookmarks b "
"JOIN moz_places h ON b.fk = h.id "
"LEFT OUTER JOIN moz_favicons f ON h.favicon_id = f.id "
@@ -1568,7 +1578,8 @@ PlacesSQLQueryBuilder::SelectAsVisit()
mQueryString = NS_LITERAL_CSTRING(
"SELECT h.id, h.url, h.title AS page_title, h.rev_host, h.visit_count, "
"v.visit_date, f.url, null, null, null, null, ") +
tagsSqlFragment + NS_LITERAL_CSTRING(", h.frecency, h.hidden, h.guid "
tagsSqlFragment + NS_LITERAL_CSTRING(", h.frecency, h.hidden, h.guid, "
"v.id, v.from_visit, v.visit_type "
"FROM moz_places h "
"JOIN moz_historyvisits v ON h.id = v.place_id "
"LEFT JOIN moz_favicons f ON h.favicon_id = f.id "
@@ -1603,7 +1614,8 @@ PlacesSQLQueryBuilder::SelectAsDay()
mQueryString = nsPrintfCString(
"SELECT null, "
"'place:type=%ld&sort=%ld&beginTime='||beginTime||'&endTime='||endTime, "
"dayTitle, null, null, beginTime, null, null, null, null, null, null "
"dayTitle, null, null, beginTime, null, null, null, null, null, null, "
"null, null, null "
"FROM (", // TOUTER BEGIN
resultType,
sortingMode);
@@ -1806,7 +1818,8 @@ PlacesSQLQueryBuilder::SelectAsSite()
mQueryString = nsPrintfCString(
"SELECT null, 'place:type=%ld&sort=%ld&domain=&domainIsHost=true'%s, "
":localhost, :localhost, null, null, null, null, null, null, null "
":localhost, :localhost, null, null, null, null, null, null, null, "
"null, null, null "
"WHERE EXISTS ( "
"SELECT h.id FROM moz_places h "
"%s "
@@ -1819,7 +1832,8 @@ PlacesSQLQueryBuilder::SelectAsSite()
"UNION ALL "
"SELECT null, "
"'place:type=%ld&sort=%ld&domain='||host||'&domainIsHost=true'%s, "
"host, host, null, null, null, null, null, null, null "
"host, host, null, null, null, null, null, null, null, "
"null, null, null "
"FROM ( "
"SELECT get_unreversed_host(h.rev_host) AS host "
"FROM moz_places h "
@@ -1859,7 +1873,7 @@ PlacesSQLQueryBuilder::SelectAsTag()
mQueryString = nsPrintfCString(
"SELECT null, 'place:folder=' || id || '&queryType=%d&type=%ld', "
"title, null, null, null, null, null, dateAdded, "
"lastModified, null, null, null "
"lastModified, null, null, null, null, null, null "
"FROM moz_bookmarks "
"WHERE parent = %lld",
nsINavHistoryQueryOptions::QUERY_TYPE_BOOKMARKS,
@@ -2093,7 +2107,8 @@ nsNavHistory::ConstructQueryString(
queryString = NS_LITERAL_CSTRING(
"SELECT h.id, h.url, h.title AS page_title, h.rev_host, h.visit_count, h.last_visit_date, "
"f.url, null, null, null, null, ") +
tagsSqlFragment + NS_LITERAL_CSTRING(", h.frecency, h.hidden, h.guid "
tagsSqlFragment + NS_LITERAL_CSTRING(", h.frecency, h.hidden, h.guid, "
"null, null, null "
"FROM moz_places h "
"LEFT OUTER JOIN moz_favicons f ON h.favicon_id = f.id "
"WHERE h.hidden = 0 "
@@ -3945,6 +3960,19 @@ nsNavHistory::RowToResult(mozIStorageValueArray* aRow,
rv = aRow->GetUTF8String(kGetInfoIndex_Guid, resultNode->mPageGuid);
NS_ENSURE_SUCCESS(rv, rv);
rv = aRow->GetInt64(kGetInfoIndex_VisitId, &resultNode->mVisitId);
NS_ENSURE_SUCCESS(rv, rv);
int64_t fromVisitId;
rv = aRow->GetInt64(kGetInfoIndex_FromVisitId, &fromVisitId);
NS_ENSURE_SUCCESS(rv, rv);
if (fromVisitId > 0) {
resultNode->mFromVisitId = fromVisitId;
}
resultNode->mTransitionType = aRow->AsInt32(kGetInfoIndex_VisitType);
resultNode.forget(aResult);
return NS_OK;
}
@@ -4053,7 +4081,8 @@ nsNavHistory::VisitIdToResultNode(int64_t visitId,
statement = mDB->GetStatement(NS_LITERAL_CSTRING(
"SELECT h.id, h.url, h.title, h.rev_host, h.visit_count, "
"v.visit_date, f.url, null, null, null, null, "
) + tagsFragment + NS_LITERAL_CSTRING(", h.frecency, h.hidden, h.guid "
) + tagsFragment + NS_LITERAL_CSTRING(", h.frecency, h.hidden, h.guid, "
"v.id, v.from_visit, v.visit_type "
"FROM moz_places h "
"JOIN moz_historyvisits v ON h.id = v.place_id "
"LEFT JOIN moz_favicons f ON h.favicon_id = f.id "
@@ -4067,7 +4096,8 @@ nsNavHistory::VisitIdToResultNode(int64_t visitId,
statement = mDB->GetStatement(NS_LITERAL_CSTRING(
"SELECT h.id, h.url, h.title, h.rev_host, h.visit_count, "
"h.last_visit_date, f.url, null, null, null, null, "
) + tagsFragment + NS_LITERAL_CSTRING(", h.frecency, h.hidden, h.guid "
) + tagsFragment + NS_LITERAL_CSTRING(", h.frecency, h.hidden, h.guid, "
"null, null, null "
"FROM moz_places h "
"JOIN moz_historyvisits v ON h.id = v.place_id "
"LEFT JOIN moz_favicons f ON h.favicon_id = f.id "
@@ -4114,7 +4144,7 @@ nsNavHistory::BookmarkIdToResultNode(int64_t aBookmarkId, nsNavHistoryQueryOptio
"h.rev_host, h.visit_count, h.last_visit_date, f.url, b.id, "
"b.dateAdded, b.lastModified, b.parent, "
) + tagsFragment + NS_LITERAL_CSTRING(", h.frecency, h.hidden, h.guid, "
"b.guid, b.position, b.type, b.fk "
"null, null, null, b.guid, b.position, b.type, b.fk "
"FROM moz_bookmarks b "
"JOIN moz_places h ON b.fk = h.id "
"LEFT JOIN moz_favicons f ON h.favicon_id = f.id "
@@ -4155,7 +4185,7 @@ nsNavHistory::URIToResultNode(nsIURI* aURI,
"h.rev_host, h.visit_count, h.last_visit_date, f.url, "
"b.id, b.dateAdded, b.lastModified, b.parent, "
) + tagsFragment + NS_LITERAL_CSTRING(", h.frecency, h.hidden, h.guid, "
"b.guid, b.position, b.type, b.fk "
"null, null, null, b.guid, b.position, b.type, b.fk "
"FROM moz_places h "
"LEFT JOIN moz_bookmarks b ON b.fk = h.id "
"LEFT JOIN moz_favicons f ON h.favicon_id = f.id "

View File

@@ -236,6 +236,9 @@ public:
static const int32_t kGetInfoIndex_Frecency;
static const int32_t kGetInfoIndex_Hidden;
static const int32_t kGetInfoIndex_Guid;
static const int32_t kGetInfoIndex_VisitId;
static const int32_t kGetInfoIndex_FromVisitId;
static const int32_t kGetInfoIndex_VisitType;
int64_t GetTagsFolder();

View File

@@ -100,6 +100,8 @@ nsNavHistoryResultNode::nsNavHistoryResultNode(
mBookmarkIndex(-1),
mItemId(-1),
mFolderId(-1),
mVisitId(-1),
mFromVisitId(-1),
mDateAdded(0),
mLastModified(0),
mIndentLevel(-1),
@@ -240,6 +242,27 @@ nsNavHistoryResultNode::GetBookmarkGuid(nsACString& aBookmarkGuid) {
}
NS_IMETHODIMP
nsNavHistoryResultNode::GetVisitId(int64_t* aVisitId) {
*aVisitId = mVisitId;
return NS_OK;
}
NS_IMETHODIMP
nsNavHistoryResultNode::GetFromVisitId(int64_t* aFromVisitId) {
*aFromVisitId = mFromVisitId;
return NS_OK;
}
NS_IMETHODIMP
nsNavHistoryResultNode::GetVisitType(uint32_t* aVisitType) {
*aVisitType = mTransitionType;
return NS_OK;
}
void
nsNavHistoryResultNode::OnRemoving()
{

View File

@@ -243,7 +243,13 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsNavHistoryResult, NS_NAVHISTORYRESULT_IID)
NS_IMETHOD GetPageGuid(nsACString& aPageGuid) override \
{ return nsNavHistoryResultNode::GetPageGuid(aPageGuid); } \
NS_IMETHOD GetBookmarkGuid(nsACString& aBookmarkGuid) override \
{ return nsNavHistoryResultNode::GetBookmarkGuid(aBookmarkGuid); }
{ return nsNavHistoryResultNode::GetBookmarkGuid(aBookmarkGuid); } \
NS_IMETHOD GetVisitId(int64_t* aVisitId) override \
{ return nsNavHistoryResultNode::GetVisitId(aVisitId); } \
NS_IMETHOD GetFromVisitId(int64_t* aFromVisitId) override \
{ return nsNavHistoryResultNode::GetFromVisitId(aFromVisitId); } \
NS_IMETHOD GetVisitType(uint32_t* aVisitType) override \
{ return nsNavHistoryResultNode::GetVisitType(aVisitType); }
class nsNavHistoryResultNode : public nsINavHistoryResultNode
{
@@ -268,6 +274,9 @@ public:
NS_IMETHOD GetTags(nsAString& aTags) override;
NS_IMETHOD GetPageGuid(nsACString& aPageGuid) override;
NS_IMETHOD GetBookmarkGuid(nsACString& aBookmarkGuid) override;
NS_IMETHOD GetVisitId(int64_t* aVisitId) override;
NS_IMETHOD GetFromVisitId(int64_t* aFromVisitId) override;
NS_IMETHOD GetVisitType(uint32_t* aVisitType) override;
virtual void OnRemoving();
@@ -359,6 +368,8 @@ public:
int32_t mBookmarkIndex;
int64_t mItemId;
int64_t mFolderId;
int64_t mVisitId;
int64_t mFromVisitId;
PRTime mDateAdded;
PRTime mLastModified;

View File

@@ -0,0 +1,85 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et: */
const {bookmarks, history} = PlacesUtils
add_task(function* test_addVisitCheckFields() {
let uri = NetUtil.newURI("http://test4.com/");
yield PlacesTestUtils.addVisits([
{ uri },
{ uri, referrer: uri },
{ uri, transition: history.TRANSITION_TYPED },
]);
let options = history.getNewQueryOptions();
let query = history.getNewQuery();
query.uri = uri;
// Check RESULTS_AS_VISIT node.
options.resultType = options.RESULTS_AS_VISIT;
let root = history.executeQuery(query, options).root;
root.containerOpen = true;
equal(root.childCount, 3);
let child = root.getChild(0);
equal(child.visitType, history.TRANSITION_LINK, "Visit type should be TRANSITION_LINK");
equal(child.visitId, 1, "Visit ID should be 1");
equal(child.fromVisitId, -1, "Should have no referrer visit ID");
child = root.getChild(1);
equal(child.visitType, history.TRANSITION_LINK, "Visit type should be TRANSITION_LINK");
equal(child.visitId, 2, "Visit ID should be 2");
equal(child.fromVisitId, 1, "First visit should be the referring visit");
child = root.getChild(2);
equal(child.visitType, history.TRANSITION_TYPED, "Visit type should be TRANSITION_TYPED");
equal(child.visitId, 3, "Visit ID should be 3");
equal(child.fromVisitId, -1, "Should have no referrer visit ID");
root.containerOpen = false;
// Check RESULTS_AS_URI node.
options.resultType = options.RESULTS_AS_URI;
root = history.executeQuery(query, options).root;
root.containerOpen = true;
equal(root.childCount, 1);
child = root.getChild(0);
equal(child.visitType, 0, "Visit type should be 0");
equal(child.visitId, -1, "Visit ID should be -1");
equal(child.fromVisitId, -1, "Referrer visit id should be -1");
root.containerOpen = false;
yield PlacesTestUtils.clearHistory();
});
add_task(function* test_bookmarkFields() {
let folder = bookmarks.createFolder(bookmarks.placesRoot, "test folder", bookmarks.DEFAULT_INDEX);
let bm = bookmarks.insertBookmark(folder, uri("http://test4.com/"),
bookmarks.DEFAULT_INDEX, "test4 title");
let root = PlacesUtils.getFolderContents(folder).root;
equal(root.childCount, 1);
equal(root.visitType, 0, "Visit type should be 0");
equal(root.visitId, -1, "Visit ID should be -1");
equal(root.fromVisitId, -1, "Referrer visit id should be -1");
let child = root.getChild(0);
equal(child.visitType, 0, "Visit type should be 0");
equal(child.visitId, -1, "Visit ID should be -1");
equal(child.fromVisitId, -1, "Referrer visit id should be -1");
root.containerOpen = false;
yield bookmarks.eraseEverything();
});

View File

@@ -139,6 +139,7 @@ skip-if = os == "android"
skip-if = os == "android"
[test_resolveNullBookmarkTitles.js]
[test_result_sort.js]
[test_resultsAsVisit_details.js]
[test_sql_guid_functions.js]
[test_svg_favicon.js]
[test_tag_autocomplete_search.js]