commit fa539356e80f908b949886a35d5c19490bc2147a
parent 92a3feb1ba75906ee6e9d983c41095e9bd8e6c5d
Author: Sandor Molnar <smolnar@mozilla.com>
Date: Fri, 21 Nov 2025 05:55:47 +0200
Revert "Bug 1846461: Remove FetchItemInfo(guid) from nsNavBookmarks r=places-reviewers,mak" for causing build bustages @ nsNavHistoryResult.h
This reverts commit c7e28148ef9bb237203596e0bc5dbba76e4dbb3c.
Revert "Bug 1846461: Move logic that appends children of folder to nsNavHistoryResult r=places-reviewers,mak"
This reverts commit e236d89e70544d8d4755c46b4a407b3ca599a030.
Diffstat:
4 files changed, 324 insertions(+), 191 deletions(-)
diff --git a/toolkit/components/places/nsNavBookmarks.cpp b/toolkit/components/places/nsNavBookmarks.cpp
@@ -1086,6 +1086,74 @@ nsresult nsNavBookmarks::FetchItemInfo(int64_t aItemId,
return NS_OK;
}
+nsresult nsNavBookmarks::FetchItemInfo(const nsCString& aGUID,
+ BookmarkData& _bookmark) {
+ // LEFT JOIN since not all bookmarks have an associated place.
+ nsCOMPtr<mozIStorageStatement> stmt = mDB->GetStatement(
+ "SELECT b.id, h.url, b.title, b.position, b.fk, b.parent, b.type, "
+ "b.dateAdded, b.lastModified, t.guid, t.parent, "
+ "b.syncStatus "
+ "FROM moz_bookmarks b "
+ "LEFT JOIN moz_bookmarks t ON t.id = b.parent "
+ "LEFT JOIN moz_places h ON h.id = b.fk "
+ "WHERE b.guid = :item_guid");
+ NS_ENSURE_STATE(stmt);
+ mozStorageStatementScoper scoper(stmt);
+
+ nsresult rv = stmt->BindUTF8StringByName("item_guid"_ns, aGUID);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ _bookmark.guid = aGUID;
+
+ bool hasResult;
+ rv = stmt->ExecuteStep(&hasResult);
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (!hasResult) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ rv = stmt->GetInt64(0, &_bookmark.id);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = stmt->GetUTF8String(1, _bookmark.url);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ bool isNull;
+ rv = stmt->GetIsNull(2, &isNull);
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (!isNull) {
+ rv = stmt->GetUTF8String(2, _bookmark.title);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+ rv = stmt->GetInt32(3, &_bookmark.position);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = stmt->GetInt64(4, &_bookmark.placeId);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = stmt->GetInt64(5, &_bookmark.parentId);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = stmt->GetInt32(6, &_bookmark.type);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = stmt->GetInt64(7, reinterpret_cast<int64_t*>(&_bookmark.dateAdded));
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = stmt->GetInt64(8, reinterpret_cast<int64_t*>(&_bookmark.lastModified));
+ NS_ENSURE_SUCCESS(rv, rv);
+ // Getting properties of the root would show no parent.
+ rv = stmt->GetIsNull(9, &isNull);
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (!isNull) {
+ rv = stmt->GetUTF8String(9, _bookmark.parentGuid);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = stmt->GetInt64(10, &_bookmark.grandParentId);
+ NS_ENSURE_SUCCESS(rv, rv);
+ } else {
+ _bookmark.grandParentId = -1;
+ }
+ rv = stmt->GetInt32(11, &_bookmark.syncStatus);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ return NS_OK;
+}
+
nsresult nsNavBookmarks::SetItemDateInternal(enum BookmarkDate aDateType,
int64_t aSyncChangeDelta,
int64_t aItemId, PRTime aValue) {
@@ -1436,6 +1504,182 @@ nsNavBookmarks::GetItemTitle(int64_t aItemId, nsACString& _title) {
return NS_OK;
}
+nsresult nsNavBookmarks::QueryFolderChildren(
+ int64_t aFolderId, nsNavHistoryQueryOptions* aOptions,
+ nsCOMArray<nsNavHistoryResultNode>* aChildren) {
+ NS_ENSURE_ARG_POINTER(aOptions);
+ NS_ENSURE_ARG_POINTER(aChildren);
+
+ // Select all children of a given folder, sorted by position.
+ // This is a LEFT JOIN because not all bookmarks types have a place.
+ // We construct a result where the first columns exactly match those returned
+ // by mDBGetURLPageInfo, and additionally contains columns for position,
+ // item_child, and folder_child from moz_bookmarks.
+ nsCOMPtr<mozIStorageStatement> stmt = mDB->GetStatement(
+ nsNavHistory::GetTagsSqlFragment(
+ nsINavHistoryQueryOptions::QUERY_TYPE_BOOKMARKS,
+ aOptions->ExcludeItems()) +
+ "SELECT "
+ " h.id, h.url, b.title, h.rev_host, h.visit_count, "
+ " h.last_visit_date, null, b.id, b.dateAdded, b.lastModified, b.parent, "
+ " (SELECT tags FROM tagged WHERE place_id = h.id) AS tags, "
+ " h.frecency, h.hidden, h.guid, null, null, null, "
+ " b.guid, b.position, b.type, b.fk, t.guid, t.id, t.title "
+ "FROM moz_bookmarks b "
+ "LEFT JOIN moz_places h ON b.fk = h.id "
+ "LEFT JOIN moz_bookmarks t ON t.guid = target_folder_guid(h.url) "
+ "WHERE b.parent = :parent "
+ "AND (NOT :excludeItems OR "
+ "b.type = :folder OR "
+ "h.url_hash BETWEEN hash('place', 'prefix_lo') "
+ " AND hash('place', 'prefix_hi')) "
+ "ORDER BY b.position ASC"_ns);
+ NS_ENSURE_STATE(stmt);
+ mozStorageStatementScoper scoper(stmt);
+
+ nsresult rv = stmt->BindInt64ByName("parent"_ns, aFolderId);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = stmt->BindInt32ByName("folder"_ns, TYPE_FOLDER);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = stmt->BindInt32ByName("excludeItems"_ns, aOptions->ExcludeItems());
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<mozIStorageValueArray> row = do_QueryInterface(stmt, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ int32_t index = -1;
+ bool hasResult;
+ while (NS_SUCCEEDED(stmt->ExecuteStep(&hasResult)) && hasResult) {
+ rv = ProcessFolderNodeRow(row, aOptions, aChildren, index);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ return NS_OK;
+}
+
+nsresult nsNavBookmarks::ProcessFolderNodeRow(
+ mozIStorageValueArray* aRow, nsNavHistoryQueryOptions* aOptions,
+ nsCOMArray<nsNavHistoryResultNode>* aChildren, int32_t& aCurrentIndex) {
+ NS_ENSURE_ARG_POINTER(aRow);
+ NS_ENSURE_ARG_POINTER(aOptions);
+ NS_ENSURE_ARG_POINTER(aChildren);
+
+ // The results will be in order of aCurrentIndex. Even if we don't add a node
+ // because it was excluded, we need to count its index, so do that before
+ // doing anything else.
+ aCurrentIndex++;
+
+ int32_t itemType;
+ nsresult rv = aRow->GetInt32(kGetChildrenIndex_Type, &itemType);
+ NS_ENSURE_SUCCESS(rv, rv);
+ int64_t id;
+ rv = aRow->GetInt64(nsNavHistory::kGetInfoIndex_ItemId, &id);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ RefPtr<nsNavHistoryResultNode> node;
+
+ if (itemType == TYPE_BOOKMARK) {
+ nsNavHistory* history = nsNavHistory::GetHistoryService();
+ NS_ENSURE_TRUE(history, NS_ERROR_OUT_OF_MEMORY);
+ rv = history->RowToResult(aRow, aOptions, getter_AddRefs(node));
+ NS_ENSURE_SUCCESS(rv, rv);
+ uint32_t nodeType;
+ node->GetType(&nodeType);
+ if (nodeType == nsINavHistoryResultNode::RESULT_TYPE_QUERY &&
+ aOptions->ExcludeQueries()) {
+ return NS_OK;
+ }
+ } else if (itemType == TYPE_FOLDER) {
+ nsAutoCString title;
+ bool isNull;
+ rv = aRow->GetIsNull(nsNavHistory::kGetInfoIndex_Title, &isNull);
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (!isNull) {
+ rv = aRow->GetUTF8String(nsNavHistory::kGetInfoIndex_Title, title);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ nsAutoCString guid;
+ rv = aRow->GetUTF8String(kGetChildrenIndex_Guid, guid);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // Don't use options from the parent to build the new folder node, it will
+ // inherit those later when it's inserted in the result.
+ node = new nsNavHistoryFolderResultNode(id, guid, id, guid, title,
+ new nsNavHistoryQueryOptions());
+
+ rv = aRow->GetInt64(nsNavHistory::kGetInfoIndex_ItemDateAdded,
+ reinterpret_cast<int64_t*>(&node->mDateAdded));
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = aRow->GetInt64(nsNavHistory::kGetInfoIndex_ItemLastModified,
+ reinterpret_cast<int64_t*>(&node->mLastModified));
+ NS_ENSURE_SUCCESS(rv, rv);
+ } else {
+ // This is a separator.
+ node = new nsNavHistorySeparatorResultNode();
+
+ node->mItemId = id;
+ rv = aRow->GetUTF8String(kGetChildrenIndex_Guid, node->mBookmarkGuid);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = aRow->GetInt64(nsNavHistory::kGetInfoIndex_ItemDateAdded,
+ reinterpret_cast<int64_t*>(&node->mDateAdded));
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = aRow->GetInt64(nsNavHistory::kGetInfoIndex_ItemLastModified,
+ reinterpret_cast<int64_t*>(&node->mLastModified));
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ // Store the index of the node within this container. Note that this is not
+ // moz_bookmarks.position.
+ node->mBookmarkIndex = aCurrentIndex;
+
+ NS_ENSURE_TRUE(aChildren->AppendObject(node), NS_ERROR_OUT_OF_MEMORY);
+ return NS_OK;
+}
+
+nsresult nsNavBookmarks::QueryFolderChildrenAsync(
+ nsNavHistoryFolderResultNode* aNode,
+ mozIStoragePendingStatement** _pendingStmt) {
+ NS_ENSURE_ARG_POINTER(aNode);
+ NS_ENSURE_ARG_POINTER(_pendingStmt);
+
+ // Select all children of a given folder, sorted by position.
+ // This is a LEFT JOIN because not all bookmarks types have a place.
+ // We construct a result where the first columns exactly match those returned
+ // by mDBGetURLPageInfo, and additionally contains columns for position,
+ // item_child, and folder_child from moz_bookmarks.
+ nsCOMPtr<mozIStorageAsyncStatement> stmt = mDB->GetAsyncStatement(
+ "SELECT h.id, h.url, b.title, h.rev_host, h.visit_count, "
+ "h.last_visit_date, null, b.id, b.dateAdded, b.lastModified, "
+ "b.parent, null, h.frecency, h.hidden, h.guid, null, null, null, "
+ "b.guid, b.position, b.type, b.fk, t.guid, t.id, t.title "
+ "FROM moz_bookmarks b "
+ "LEFT JOIN moz_places h ON b.fk = h.id "
+ "LEFT JOIN moz_bookmarks t ON t.guid = target_folder_guid(h.url) "
+ "WHERE b.parent = :parent "
+ "AND (NOT :excludeItems OR "
+ "b.type = :folder OR "
+ "h.url_hash BETWEEN hash('place', 'prefix_lo') AND hash('place', "
+ "'prefix_hi')) "
+ "ORDER BY b.position ASC");
+ NS_ENSURE_STATE(stmt);
+
+ nsresult rv = stmt->BindInt64ByName("parent"_ns, aNode->mTargetFolderItemId);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = stmt->BindInt32ByName("folder"_ns, TYPE_FOLDER);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv =
+ stmt->BindInt32ByName("excludeItems"_ns, aNode->mOptions->ExcludeItems());
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<mozIStoragePendingStatement> pendingStmt;
+ rv = stmt->ExecuteAsync(aNode, getter_AddRefs(pendingStmt));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ NS_IF_ADDREF(*_pendingStmt = pendingStmt);
+ return NS_OK;
+}
+
nsresult nsNavBookmarks::FetchFolderInfo(int64_t aFolderId,
int32_t* _folderCount,
nsACString& _guid,
diff --git a/toolkit/components/places/nsNavBookmarks.h b/toolkit/components/places/nsNavBookmarks.h
@@ -101,6 +101,46 @@ class nsNavBookmarks final : public nsINavBookmarksService,
bool aHidden, uint32_t aVisitCount, uint32_t aTyped,
const nsAString& aLastKnownTitle);
+ // Find all the children of a folder, using the given query and options.
+ // For each child, a ResultNode is created and added to |children|.
+ // The results are ordered by folder position.
+ nsresult QueryFolderChildren(int64_t aFolderId,
+ nsNavHistoryQueryOptions* aOptions,
+ nsCOMArray<nsNavHistoryResultNode>* children);
+
+ /**
+ * Turns aRow into a node and appends it to aChildren if it is appropriate to
+ * do so.
+ *
+ * @param aRow
+ * A Storage statement (in the case of synchronous execution) or row of
+ * a result set (in the case of asynchronous execution).
+ * @param aOptions
+ * The options of the parent folder node. These are the options used
+ * to fill the parent node.
+ * @param aChildren
+ * The children of the parent folder node.
+ * @param aCurrentIndex
+ * The index of aRow within the results. When called on the first row,
+ * this should be set to -1.
+ */
+ nsresult ProcessFolderNodeRow(mozIStorageValueArray* aRow,
+ nsNavHistoryQueryOptions* aOptions,
+ nsCOMArray<nsNavHistoryResultNode>* aChildren,
+ int32_t& aCurrentIndex);
+
+ /**
+ * The async version of QueryFolderChildren.
+ *
+ * @param aNode
+ * The folder node that will receive the children.
+ * @param _pendingStmt
+ * The Storage pending statement that will be used to control async
+ * execution.
+ */
+ nsresult QueryFolderChildrenAsync(nsNavHistoryFolderResultNode* aNode,
+ mozIStoragePendingStatement** _pendingStmt);
+
/**
* Fetches information about the specified id from the database.
*
@@ -112,6 +152,16 @@ class nsNavBookmarks final : public nsINavBookmarksService,
nsresult FetchItemInfo(int64_t aItemId, BookmarkData& _bookmark);
/**
+ * Fetches information about the specified GUID from the database.
+ *
+ * @param aGUID
+ * GUID of the item to fetch information for.
+ * @param aBookmark
+ * BookmarkData to store the information.
+ */
+ nsresult FetchItemInfo(const nsCString& aGUID, BookmarkData& _bookmark);
+
+ /**
* Notifies that a bookmark has been visited.
*
* @param aItemId
diff --git a/toolkit/components/places/nsNavHistoryResult.cpp b/toolkit/components/places/nsNavHistoryResult.cpp
@@ -2689,7 +2689,17 @@ nsNavHistoryFolderResultNode::GetQueryOptions(
}
nsresult nsNavHistoryFolderResultNode::FillChildren() {
- nsresult rv = FillChildrenInternal();
+ NS_ASSERTION(!mContentsValid,
+ "Don't call FillChildren when contents are valid");
+ NS_ASSERTION(mChildren.Count() == 0,
+ "We are trying to fill children when there already are some");
+
+ nsNavBookmarks* bookmarks = nsNavBookmarks::GetBookmarksService();
+ NS_ENSURE_TRUE(bookmarks, NS_ERROR_OUT_OF_MEMORY);
+
+ // Actually get the folder children from the bookmark service.
+ nsresult rv =
+ bookmarks->QueryFolderChildren(mTargetFolderItemId, mOptions, &mChildren);
NS_ENSURE_SUCCESS(rv, rv);
// PERFORMANCE: it may be better to also fill any child folders at this point
@@ -2751,16 +2761,23 @@ void nsNavHistoryFolderResultNode::EnsureRegisteredAsFolderObserver() {
}
/**
- * The async version of FillChildren. This begins asynchronous execution by
- * calling FillChildrenInternal. During execution, this node's async Storage
- * callbacks, HandleResult and HandleCompletion, will be called.
+ * The async version of FillChildren. This begins asynchronous execution by
+ * calling nsNavBookmarks::QueryFolderChildrenAsync. During execution, this
+ * node's async Storage callbacks, HandleResult and HandleCompletion, will be
+ * called.
*/
nsresult nsNavHistoryFolderResultNode::FillChildrenAsync() {
+ NS_ASSERTION(!mContentsValid, "FillChildrenAsync when contents are valid");
+ NS_ASSERTION(mChildren.Count() == 0, "FillChildrenAsync when children exist");
+
// ProcessFolderNodeChild, called in HandleResult, increments this for every
// result row it processes. Initialize it here as we begin async execution.
mAsyncBookmarkIndex = -1;
- nsresult rv = FillChildrenInternal(getter_AddRefs(mAsyncPendingStmt));
+ nsNavBookmarks* bmSvc = nsNavBookmarks::GetBookmarksService();
+ NS_ENSURE_TRUE(bmSvc, NS_ERROR_OUT_OF_MEMORY);
+ nsresult rv =
+ bmSvc->QueryFolderChildrenAsync(this, getter_AddRefs(mAsyncPendingStmt));
NS_ENSURE_SUCCESS(rv, rv);
// Register with the result for updates. All updates during async execution
@@ -2770,168 +2787,6 @@ nsresult nsNavHistoryFolderResultNode::FillChildrenAsync() {
return NS_OK;
}
-nsresult nsNavHistoryFolderResultNode::FillChildrenInternal(
- mozIStoragePendingStatement** aPendingStmt) {
- NS_ASSERTION(!mContentsValid,
- "Don't call FillChildrenInternal when contents are valid");
- NS_ASSERTION(mChildren.Count() == 0,
- "We are trying to fill children when there already are some");
-
- // Select all children of a given folder, sorted by position.
- // This is a LEFT JOIN because not all bookmarks types have a place.
- // We construct a result where the first columns exactly match those returned
- // by mDBGetURLPageInfo, and additionally contains columns for position,
- // item_child, and folder_child from moz_bookmarks.
- bool isAsync = !!aPendingStmt;
- nsCString sql =
- "SELECT "
- " h.id, h.url, b.title, h.rev_host, h.visit_count, h.last_visit_date, "
- " null, b.id, b.dateAdded, b.lastModified, b.parent, "_ns +
- nsCString(
- isAsync
- ? " null, "
- : " (SELECT tags FROM tagged WHERE place_id = h.id) AS tags, ") +
- " h.frecency, h.hidden, h.guid, null, null, null, b.guid, b.position, "
- " b.type, b.fk, t.guid, t.id, t.title "
- "FROM moz_bookmarks b "
- "LEFT JOIN moz_places h ON b.fk = h.id "
- "LEFT JOIN moz_bookmarks t ON t.guid = target_folder_guid(h.url) "
- "WHERE b.parent = :parent "
- " AND ("
- " NOT :excludeItems OR "
- " b.type = :folder OR "
- " h.url_hash BETWEEN "
- " hash('place', 'prefix_lo') AND hash('place', 'prefix_hi')"
- " ) "
- "ORDER BY b.position ASC"_ns;
-
- RefPtr<Database> db = Database::GetDatabase();
- NS_ENSURE_STATE(db);
- nsCOMPtr<mozIStorageBaseStatement> stmt;
- if (isAsync) {
- stmt = db->GetAsyncStatement(sql);
- NS_ENSURE_STATE(stmt);
- } else {
- stmt = db->GetStatement(nsNavHistory::GetTagsSqlFragment(
- nsINavHistoryQueryOptions::QUERY_TYPE_BOOKMARKS,
- mOptions->ExcludeItems()) +
- sql);
- NS_ENSURE_STATE(stmt);
- }
-
- nsresult rv = stmt->BindInt64ByName("parent"_ns, mTargetFolderItemId);
- NS_ENSURE_SUCCESS(rv, rv);
- rv = stmt->BindInt32ByName("folder"_ns, nsINavBookmarksService::TYPE_FOLDER);
- NS_ENSURE_SUCCESS(rv, rv);
- rv = stmt->BindInt32ByName("excludeItems"_ns, mOptions->ExcludeItems());
- NS_ENSURE_SUCCESS(rv, rv);
-
- if (isAsync) {
- nsCOMPtr<mozIStorageAsyncStatement> async = do_QueryInterface(stmt, &rv);
- NS_ENSURE_SUCCESS(rv, rv);
-
- nsCOMPtr<mozIStoragePendingStatement> pendingStmt;
- rv = async->ExecuteAsync(this, getter_AddRefs(pendingStmt));
- NS_ENSURE_SUCCESS(rv, rv);
-
- NS_IF_ADDREF(*aPendingStmt = pendingStmt);
- } else {
- nsCOMPtr<mozIStorageStatement> sync = do_QueryInterface(stmt, &rv);
- NS_ENSURE_SUCCESS(rv, rv);
- mozStorageStatementScoper scoper(sync);
- nsCOMPtr<mozIStorageValueArray> row = do_QueryInterface(sync, &rv);
- NS_ENSURE_SUCCESS(rv, rv);
-
- int32_t index = -1;
- bool hasResult;
- while (NS_SUCCEEDED(sync->ExecuteStep(&hasResult)) && hasResult) {
- rv = AppendRowAsChild(row, index);
- NS_ENSURE_SUCCESS(rv, rv);
- }
- }
-
- return NS_OK;
-}
-
-nsresult nsNavHistoryFolderResultNode::AppendRowAsChild(
- mozIStorageValueArray* aRow, int32_t& aCurrentIndex) {
- NS_ENSURE_ARG_POINTER(aRow);
-
- // The results will be in order of aCurrentIndex. Even if we don't add a node
- // because it was excluded, we need to count its index, so do that before
- // doing anything else.
- aCurrentIndex++;
-
- int32_t itemType;
- nsresult rv =
- aRow->GetInt32(nsNavBookmarks::kGetChildrenIndex_Type, &itemType);
- NS_ENSURE_SUCCESS(rv, rv);
- int64_t id;
- rv = aRow->GetInt64(nsNavHistory::kGetInfoIndex_ItemId, &id);
- NS_ENSURE_SUCCESS(rv, rv);
-
- RefPtr<nsNavHistoryResultNode> node;
-
- if (itemType == nsINavBookmarksService::TYPE_BOOKMARK) {
- nsNavHistory* history = nsNavHistory::GetHistoryService();
- NS_ENSURE_TRUE(history, NS_ERROR_OUT_OF_MEMORY);
- rv = history->RowToResult(aRow, mOptions, getter_AddRefs(node));
- NS_ENSURE_SUCCESS(rv, rv);
- uint32_t nodeType;
- node->GetType(&nodeType);
- if (nodeType == nsINavHistoryResultNode::RESULT_TYPE_QUERY &&
- mOptions->ExcludeQueries()) {
- return NS_OK;
- }
- } else if (itemType == nsINavBookmarksService::TYPE_FOLDER) {
- nsAutoCString title;
- bool isNull;
- rv = aRow->GetIsNull(nsNavHistory::kGetInfoIndex_Title, &isNull);
- NS_ENSURE_SUCCESS(rv, rv);
- if (!isNull) {
- rv = aRow->GetUTF8String(nsNavHistory::kGetInfoIndex_Title, title);
- NS_ENSURE_SUCCESS(rv, rv);
- }
-
- nsAutoCString guid;
- rv = aRow->GetUTF8String(nsNavBookmarks::kGetChildrenIndex_Guid, guid);
- NS_ENSURE_SUCCESS(rv, rv);
-
- // Don't use options from the parent to build the new folder node, it will
- // inherit those later when it's inserted in the result.
- node = new nsNavHistoryFolderResultNode(id, guid, id, guid, title,
- new nsNavHistoryQueryOptions());
-
- rv = aRow->GetInt64(nsNavHistory::kGetInfoIndex_ItemDateAdded,
- reinterpret_cast<int64_t*>(&node->mDateAdded));
- NS_ENSURE_SUCCESS(rv, rv);
- rv = aRow->GetInt64(nsNavHistory::kGetInfoIndex_ItemLastModified,
- reinterpret_cast<int64_t*>(&node->mLastModified));
- NS_ENSURE_SUCCESS(rv, rv);
- } else {
- // This is a separator.
- node = new nsNavHistorySeparatorResultNode();
-
- node->mItemId = id;
- rv = aRow->GetUTF8String(nsNavBookmarks::kGetChildrenIndex_Guid,
- node->mBookmarkGuid);
- NS_ENSURE_SUCCESS(rv, rv);
- rv = aRow->GetInt64(nsNavHistory::kGetInfoIndex_ItemDateAdded,
- reinterpret_cast<int64_t*>(&node->mDateAdded));
- NS_ENSURE_SUCCESS(rv, rv);
- rv = aRow->GetInt64(nsNavHistory::kGetInfoIndex_ItemLastModified,
- reinterpret_cast<int64_t*>(&node->mLastModified));
- NS_ENSURE_SUCCESS(rv, rv);
- }
-
- // Store the index of the node within this container. Note that this is not
- // moz_bookmarks.position.
- node->mBookmarkIndex = aCurrentIndex;
-
- NS_ENSURE_TRUE(mChildren.AppendObject(node), NS_ERROR_OUT_OF_MEMORY);
- return NS_OK;
-}
-
/**
* A mozIStorageStatementCallback method. Called during the async execution
* begun by FillChildrenAsync.
@@ -2943,10 +2798,17 @@ NS_IMETHODIMP
nsNavHistoryFolderResultNode::HandleResult(mozIStorageResultSet* aResultSet) {
NS_ENSURE_ARG_POINTER(aResultSet);
+ nsNavBookmarks* bmSvc = nsNavBookmarks::GetBookmarksService();
+ if (!bmSvc) {
+ CancelAsyncOpen(false);
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
// Consume all the currently available rows of the result set.
nsCOMPtr<mozIStorageRow> row;
while (NS_SUCCEEDED(aResultSet->GetNextRow(getter_AddRefs(row))) && row) {
- nsresult rv = AppendRowAsChild(row, mAsyncBookmarkIndex);
+ nsresult rv = bmSvc->ProcessFolderNodeRow(row, mOptions, &mChildren,
+ mAsyncBookmarkIndex);
if (NS_FAILED(rv)) {
CancelAsyncOpen(false);
return rv;
diff --git a/toolkit/components/places/nsNavHistoryResult.h b/toolkit/components/places/nsNavHistoryResult.h
@@ -797,29 +797,6 @@ class nsNavHistoryFolderResultNode final
nsresult OnChildrenFilled();
void EnsureRegisteredAsFolderObserver();
nsresult FillChildrenAsync();
- /*
- * Fill children of this folder by the current query.
- *
- * @param aPendingStmt
- * The Storage pending statement that will be used to control async
- * execution. If this is nullptr, this method processes as sync.
- */
- nsresult FillChildrenInternal(
- mozIStoragePendingStatement** aPendingStmt = nullptr);
-
- /**
- * Turns aRow into a node and appends it as a child of this node if it is
- * appropriate to do so.
- *
- * @param aRow
- * A Storage statement (in the case of synchronous execution) or row of
- * a result set (in the case of asynchronous execution).
- * @param aCurrentIndex
- * The index of aRow within the results. When called on the first row,
- * this should be set to -1.
- */
- nsresult AppendRowAsChild(mozIStorageValueArray* aRow,
- int32_t& aCurrentIndex);
bool mIsRegisteredFolderObserver;
int32_t mAsyncBookmarkIndex;