toolkit/components/places/nsNavBookmarks.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/toolkit/components/places/nsNavBookmarks.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,461 @@
     1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +#ifndef nsNavBookmarks_h_
    1.10 +#define nsNavBookmarks_h_
    1.11 +
    1.12 +#include "nsINavBookmarksService.h"
    1.13 +#include "nsIAnnotationService.h"
    1.14 +#include "nsITransaction.h"
    1.15 +#include "nsNavHistory.h"
    1.16 +#include "nsToolkitCompsCID.h"
    1.17 +#include "nsCategoryCache.h"
    1.18 +#include "nsTHashtable.h"
    1.19 +#include "nsWeakReference.h"
    1.20 +#include "mozilla/Attributes.h"
    1.21 +#include "prtime.h"
    1.22 +
    1.23 +class nsNavBookmarks;
    1.24 +class nsIOutputStream;
    1.25 +
    1.26 +namespace mozilla {
    1.27 +namespace places {
    1.28 +
    1.29 +  enum BookmarkStatementId {
    1.30 +    DB_FIND_REDIRECTED_BOOKMARK = 0
    1.31 +  , DB_GET_BOOKMARKS_FOR_URI
    1.32 +  };
    1.33 +
    1.34 +  struct BookmarkData {
    1.35 +    int64_t id;
    1.36 +    nsCString url;
    1.37 +    nsCString title;
    1.38 +    int32_t position;
    1.39 +    int64_t placeId;
    1.40 +    int64_t parentId;
    1.41 +    int64_t grandParentId;
    1.42 +    int32_t type;
    1.43 +    nsCString serviceCID;
    1.44 +    PRTime dateAdded;
    1.45 +    PRTime lastModified;
    1.46 +    nsCString guid;
    1.47 +    nsCString parentGuid;
    1.48 +  };
    1.49 +
    1.50 +  struct ItemVisitData {
    1.51 +    BookmarkData bookmark;
    1.52 +    int64_t visitId;
    1.53 +    uint32_t transitionType;
    1.54 +    PRTime time;
    1.55 +  };
    1.56 +
    1.57 +  struct ItemChangeData {
    1.58 +    BookmarkData bookmark;
    1.59 +    nsCString property;
    1.60 +    bool isAnnotation;
    1.61 +    nsCString newValue;
    1.62 +  };
    1.63 +
    1.64 +  typedef void (nsNavBookmarks::*ItemVisitMethod)(const ItemVisitData&);
    1.65 +  typedef void (nsNavBookmarks::*ItemChangeMethod)(const ItemChangeData&);
    1.66 +
    1.67 +  class BookmarkKeyClass : public nsTrimInt64HashKey
    1.68 +  {
    1.69 +    public:
    1.70 +    BookmarkKeyClass(const int64_t* aItemId)
    1.71 +    : nsTrimInt64HashKey(aItemId)
    1.72 +    , creationTime(PR_Now())
    1.73 +    {
    1.74 +    }
    1.75 +    BookmarkKeyClass(const BookmarkKeyClass& aOther)
    1.76 +    : nsTrimInt64HashKey(aOther)
    1.77 +    , creationTime(PR_Now())
    1.78 +    {
    1.79 +      NS_NOTREACHED("Do not call me!");
    1.80 +    }
    1.81 +    BookmarkData bookmark;
    1.82 +    PRTime creationTime;
    1.83 +  };
    1.84 +
    1.85 +  enum BookmarkDate {
    1.86 +    DATE_ADDED = 0
    1.87 +  , LAST_MODIFIED
    1.88 +  };
    1.89 +
    1.90 +} // namespace places
    1.91 +} // namespace mozilla
    1.92 +
    1.93 +class nsNavBookmarks MOZ_FINAL : public nsINavBookmarksService
    1.94 +                               , public nsINavHistoryObserver
    1.95 +                               , public nsIAnnotationObserver
    1.96 +                               , public nsIObserver
    1.97 +                               , public nsSupportsWeakReference
    1.98 +{
    1.99 +public:
   1.100 +  NS_DECL_ISUPPORTS
   1.101 +  NS_DECL_NSINAVBOOKMARKSSERVICE
   1.102 +  NS_DECL_NSINAVHISTORYOBSERVER
   1.103 +  NS_DECL_NSIANNOTATIONOBSERVER
   1.104 +  NS_DECL_NSIOBSERVER
   1.105 +
   1.106 +  nsNavBookmarks();
   1.107 +
   1.108 +  /**
   1.109 +   * Obtains the service's object.
   1.110 +   */
   1.111 +  static already_AddRefed<nsNavBookmarks> GetSingleton();
   1.112 +
   1.113 +  /**
   1.114 +   * Initializes the service's object.  This should only be called once.
   1.115 +   */
   1.116 +  nsresult Init();
   1.117 +
   1.118 +  static nsNavBookmarks* GetBookmarksService() {
   1.119 +    if (!gBookmarksService) {
   1.120 +      nsCOMPtr<nsINavBookmarksService> serv =
   1.121 +        do_GetService(NS_NAVBOOKMARKSSERVICE_CONTRACTID);
   1.122 +      NS_ENSURE_TRUE(serv, nullptr);
   1.123 +      NS_ASSERTION(gBookmarksService,
   1.124 +                   "Should have static instance pointer now");
   1.125 +    }
   1.126 +    return gBookmarksService;
   1.127 +  }
   1.128 +
   1.129 +  typedef mozilla::places::BookmarkData BookmarkData;
   1.130 +  typedef mozilla::places::BookmarkKeyClass BookmarkKeyClass;
   1.131 +  typedef mozilla::places::ItemVisitData ItemVisitData;
   1.132 +  typedef mozilla::places::ItemChangeData ItemChangeData;
   1.133 +  typedef mozilla::places::BookmarkStatementId BookmarkStatementId;
   1.134 +
   1.135 +  nsresult ResultNodeForContainer(int64_t aID,
   1.136 +                                  nsNavHistoryQueryOptions* aOptions,
   1.137 +                                  nsNavHistoryResultNode** aNode);
   1.138 +
   1.139 +  // Find all the children of a folder, using the given query and options.
   1.140 +  // For each child, a ResultNode is created and added to |children|.
   1.141 +  // The results are ordered by folder position.
   1.142 +  nsresult QueryFolderChildren(int64_t aFolderId,
   1.143 +                               nsNavHistoryQueryOptions* aOptions,
   1.144 +                               nsCOMArray<nsNavHistoryResultNode>* children);
   1.145 +
   1.146 +  /**
   1.147 +   * Turns aRow into a node and appends it to aChildren if it is appropriate to
   1.148 +   * do so.
   1.149 +   *
   1.150 +   * @param aRow
   1.151 +   *        A Storage statement (in the case of synchronous execution) or row of
   1.152 +   *        a result set (in the case of asynchronous execution).
   1.153 +   * @param aOptions
   1.154 +   *        The options of the parent folder node.
   1.155 +   * @param aChildren
   1.156 +   *        The children of the parent folder node.
   1.157 +   * @param aCurrentIndex
   1.158 +   *        The index of aRow within the results.  When called on the first row,
   1.159 +   *        this should be set to -1.
   1.160 +   */
   1.161 +  nsresult ProcessFolderNodeRow(mozIStorageValueArray* aRow,
   1.162 +                                nsNavHistoryQueryOptions* aOptions,
   1.163 +                                nsCOMArray<nsNavHistoryResultNode>* aChildren,
   1.164 +                                int32_t& aCurrentIndex);
   1.165 +
   1.166 +  /**
   1.167 +   * The async version of QueryFolderChildren.
   1.168 +   *
   1.169 +   * @param aNode
   1.170 +   *        The folder node that will receive the children.
   1.171 +   * @param _pendingStmt
   1.172 +   *        The Storage pending statement that will be used to control async
   1.173 +   *        execution.
   1.174 +   */
   1.175 +  nsresult QueryFolderChildrenAsync(nsNavHistoryFolderResultNode* aNode,
   1.176 +                                    int64_t aFolderId,
   1.177 +                                    mozIStoragePendingStatement** _pendingStmt);
   1.178 +
   1.179 +  /**
   1.180 +   * @return index of the new folder in aIndex, whether it was passed in or
   1.181 +   *         generated by autoincrement.
   1.182 +   *
   1.183 +   * @note If aFolder is -1, uses the autoincrement id for folder index.
   1.184 +   * @note aTitle will be truncated to TITLE_LENGTH_MAX
   1.185 +   */
   1.186 +  nsresult CreateContainerWithID(int64_t aId, int64_t aParent,
   1.187 +                                 const nsACString& aTitle,
   1.188 +                                 bool aIsBookmarkFolder,
   1.189 +                                 int32_t* aIndex,
   1.190 +                                 const nsACString& aGUID,
   1.191 +                                 int64_t* aNewFolder);
   1.192 +
   1.193 +  /**
   1.194 +   * Fetches information about the specified id from the database.
   1.195 +   *
   1.196 +   * @param aItemId
   1.197 +   *        Id of the item to fetch information for.
   1.198 +   * @param aBookmark
   1.199 +   *        BookmarkData to store the information.
   1.200 +   */
   1.201 +  nsresult FetchItemInfo(int64_t aItemId,
   1.202 +                         BookmarkData& _bookmark);
   1.203 +
   1.204 +  /**
   1.205 +   * Notifies that a bookmark has been visited.
   1.206 +   *
   1.207 +   * @param aItemId
   1.208 +   *        The visited item id.
   1.209 +   * @param aData
   1.210 +   *        Details about the new visit.
   1.211 +   */
   1.212 +  void NotifyItemVisited(const ItemVisitData& aData);
   1.213 +
   1.214 +  /**
   1.215 +   * Notifies that a bookmark has changed.
   1.216 +   *
   1.217 +   * @param aItemId
   1.218 +   *        The changed item id.
   1.219 +   * @param aData
   1.220 +   *        Details about the change.
   1.221 +   */
   1.222 +  void NotifyItemChanged(const ItemChangeData& aData);
   1.223 +
   1.224 +  /**
   1.225 +   * Recursively builds an array of descendant folders inside a given folder.
   1.226 +   *
   1.227 +   * @param aFolderId
   1.228 +   *        The folder to fetch descendants from.
   1.229 +   * @param aDescendantFoldersArray
   1.230 +   *        Output array to put descendant folders id.
   1.231 +   */
   1.232 +  nsresult GetDescendantFolders(int64_t aFolderId,
   1.233 +                                nsTArray<int64_t>& aDescendantFoldersArray);
   1.234 +
   1.235 +private:
   1.236 +  static nsNavBookmarks* gBookmarksService;
   1.237 +
   1.238 +  ~nsNavBookmarks();
   1.239 +
   1.240 +  /**
   1.241 +   * Locates the root items in the bookmarks folder hierarchy assigning folder
   1.242 +   * ids to the root properties that are exposed through the service interface.
   1.243 +   */
   1.244 +  nsresult ReadRoots();
   1.245 +
   1.246 +  nsresult AdjustIndices(int64_t aFolder,
   1.247 +                         int32_t aStartIndex,
   1.248 +                         int32_t aEndIndex,
   1.249 +                         int32_t aDelta);
   1.250 +
   1.251 +  /**
   1.252 +   * Fetches properties of a folder.
   1.253 +   *
   1.254 +   * @param aFolderId
   1.255 +   *        Folder to count children for.
   1.256 +   * @param _folderCount
   1.257 +   *        Number of children in the folder.
   1.258 +   * @param _guid
   1.259 +   *        Unique id of the folder.
   1.260 +   * @param _parentId
   1.261 +   *        Id of the parent of the folder.
   1.262 +   *
   1.263 +   * @throws If folder does not exist.
   1.264 +   */
   1.265 +  nsresult FetchFolderInfo(int64_t aFolderId,
   1.266 +                           int32_t* _folderCount,
   1.267 +                           nsACString& _guid,
   1.268 +                           int64_t* _parentId);
   1.269 +
   1.270 +  nsresult GetLastChildId(int64_t aFolder, int64_t* aItemId);
   1.271 +
   1.272 +  /**
   1.273 +   * This is an handle to the Places database.
   1.274 +   */
   1.275 +  nsRefPtr<mozilla::places::Database> mDB;
   1.276 +
   1.277 +  int32_t mItemCount;
   1.278 +
   1.279 +  nsMaybeWeakPtrArray<nsINavBookmarkObserver> mObservers;
   1.280 +
   1.281 +  int64_t mRoot;
   1.282 +  int64_t mMenuRoot;
   1.283 +  int64_t mTagsRoot;
   1.284 +  int64_t mUnfiledRoot;
   1.285 +  int64_t mToolbarRoot;
   1.286 +
   1.287 +  inline bool IsRoot(int64_t aFolderId) {
   1.288 +    return aFolderId == mRoot || aFolderId == mMenuRoot ||
   1.289 +           aFolderId == mTagsRoot || aFolderId == mUnfiledRoot ||
   1.290 +           aFolderId == mToolbarRoot;
   1.291 +  }
   1.292 +
   1.293 +  nsresult IsBookmarkedInDatabase(int64_t aBookmarkID, bool* aIsBookmarked);
   1.294 +
   1.295 +  nsresult SetItemDateInternal(enum mozilla::places::BookmarkDate aDateType,
   1.296 +                               int64_t aItemId,
   1.297 +                               PRTime aValue);
   1.298 +
   1.299 +  // Recursive method to build an array of folder's children
   1.300 +  nsresult GetDescendantChildren(int64_t aFolderId,
   1.301 +                                 const nsACString& aFolderGuid,
   1.302 +                                 int64_t aGrandParentId,
   1.303 +                                 nsTArray<BookmarkData>& aFolderChildrenArray);
   1.304 +
   1.305 +  enum ItemType {
   1.306 +    BOOKMARK = TYPE_BOOKMARK,
   1.307 +    FOLDER = TYPE_FOLDER,
   1.308 +    SEPARATOR = TYPE_SEPARATOR,
   1.309 +  };
   1.310 +
   1.311 +  /**
   1.312 +   * Helper to insert a bookmark in the database.
   1.313 +   *
   1.314 +   *  @param aItemId
   1.315 +   *         The itemId to insert, pass -1 to generate a new one.
   1.316 +   *  @param aPlaceId
   1.317 +   *         The placeId to which this bookmark refers to, pass nullptr for
   1.318 +   *         items that don't refer to an URI (eg. folders, separators, ...).
   1.319 +   *  @param aItemType
   1.320 +   *         The type of the new bookmark, see TYPE_* constants.
   1.321 +   *  @param aParentId
   1.322 +   *         The itemId of the parent folder.
   1.323 +   *  @param aIndex
   1.324 +   *         The position inside the parent folder.
   1.325 +   *  @param aTitle
   1.326 +   *         The title for the new bookmark.
   1.327 +   *         Pass a void string to set a NULL title.
   1.328 +   *  @param aDateAdded
   1.329 +   *         The date for the insertion.
   1.330 +   *  @param [optional] aLastModified
   1.331 +   *         The last modified date for the insertion.
   1.332 +   *         It defaults to aDateAdded.
   1.333 +   *
   1.334 +   *  @return The new item id that has been inserted.
   1.335 +   *
   1.336 +   *  @note This will also update last modified date of the parent folder.
   1.337 +   */
   1.338 +  nsresult InsertBookmarkInDB(int64_t aPlaceId,
   1.339 +                              enum ItemType aItemType,
   1.340 +                              int64_t aParentId,
   1.341 +                              int32_t aIndex,
   1.342 +                              const nsACString& aTitle,
   1.343 +                              PRTime aDateAdded,
   1.344 +                              PRTime aLastModified,
   1.345 +                              const nsACString& aParentGuid,
   1.346 +                              int64_t aGrandParentId,
   1.347 +                              nsIURI* aURI,
   1.348 +                              int64_t* _itemId,
   1.349 +                              nsACString& _guid);
   1.350 +
   1.351 +  /**
   1.352 +   * TArray version of getBookmarksIdForURI for ease of use in C++ code.
   1.353 +   * Pass in a reference to a TArray; it will get filled with the
   1.354 +   * resulting list of bookmark IDs.
   1.355 +   *
   1.356 +   * @param aURI
   1.357 +   *        URI to get bookmarks for.
   1.358 +   * @param aResult
   1.359 +   *        Array of bookmark ids.
   1.360 +   * @param aSkipTags
   1.361 +   *        If true ids of tags-as-bookmarks entries will be excluded.
   1.362 +   */
   1.363 +  nsresult GetBookmarkIdsForURITArray(nsIURI* aURI,
   1.364 +                                      nsTArray<int64_t>& aResult,
   1.365 +                                      bool aSkipTags);
   1.366 +
   1.367 +  nsresult GetBookmarksForURI(nsIURI* aURI,
   1.368 +                              nsTArray<BookmarkData>& _bookmarks);
   1.369 +
   1.370 +  int64_t RecursiveFindRedirectedBookmark(int64_t aPlaceId);
   1.371 +
   1.372 +  static const int32_t kGetChildrenIndex_Position;
   1.373 +  static const int32_t kGetChildrenIndex_Type;
   1.374 +  static const int32_t kGetChildrenIndex_PlaceID;
   1.375 +  static const int32_t kGetChildrenIndex_Guid;
   1.376 +
   1.377 +  class RemoveFolderTransaction MOZ_FINAL : public nsITransaction {
   1.378 +  public:
   1.379 +    RemoveFolderTransaction(int64_t aID) : mID(aID) {}
   1.380 +
   1.381 +    NS_DECL_ISUPPORTS
   1.382 +
   1.383 +    NS_IMETHOD DoTransaction() {
   1.384 +      nsNavBookmarks* bookmarks = nsNavBookmarks::GetBookmarksService();
   1.385 +      NS_ENSURE_TRUE(bookmarks, NS_ERROR_OUT_OF_MEMORY);
   1.386 +      BookmarkData folder;
   1.387 +      nsresult rv = bookmarks->FetchItemInfo(mID, folder);
   1.388 +      // TODO (Bug 656935): store the BookmarkData struct instead.
   1.389 +      mParent = folder.parentId;
   1.390 +      mIndex = folder.position;
   1.391 +
   1.392 +      rv = bookmarks->GetItemTitle(mID, mTitle);
   1.393 +      NS_ENSURE_SUCCESS(rv, rv);
   1.394 +
   1.395 +      return bookmarks->RemoveItem(mID);
   1.396 +    }
   1.397 +
   1.398 +    NS_IMETHOD UndoTransaction() {
   1.399 +      nsNavBookmarks* bookmarks = nsNavBookmarks::GetBookmarksService();
   1.400 +      NS_ENSURE_TRUE(bookmarks, NS_ERROR_OUT_OF_MEMORY);
   1.401 +      int64_t newFolder;
   1.402 +      return bookmarks->CreateContainerWithID(mID, mParent, mTitle, true,
   1.403 +                                              &mIndex, EmptyCString(), &newFolder);
   1.404 +    }
   1.405 +
   1.406 +    NS_IMETHOD RedoTransaction() {
   1.407 +      return DoTransaction();
   1.408 +    }
   1.409 +
   1.410 +    NS_IMETHOD GetIsTransient(bool* aResult) {
   1.411 +      *aResult = false;
   1.412 +      return NS_OK;
   1.413 +    }
   1.414 +
   1.415 +    NS_IMETHOD Merge(nsITransaction* aTransaction, bool* aResult) {
   1.416 +      *aResult = false;
   1.417 +      return NS_OK;
   1.418 +    }
   1.419 +
   1.420 +  private:
   1.421 +    int64_t mID;
   1.422 +    int64_t mParent;
   1.423 +    nsCString mTitle;
   1.424 +    int32_t mIndex;
   1.425 +  };
   1.426 +
   1.427 +  // Used to enable and disable the observer notifications.
   1.428 +  bool mCanNotify;
   1.429 +  nsCategoryCache<nsINavBookmarkObserver> mCacheObservers;
   1.430 +
   1.431 +  // Tracks whether we are in batch mode.
   1.432 +  // Note: this is only tracking bookmarks batches, not history ones.
   1.433 +  bool mBatching;
   1.434 +
   1.435 +  /**
   1.436 +   * Always call EnsureKeywordsHash() and check it for errors before actually
   1.437 +   * using the hash.  Internal keyword methods are already doing that.
   1.438 +   */
   1.439 +  nsresult EnsureKeywordsHash();
   1.440 +  nsDataHashtable<nsTrimInt64HashKey, nsString> mBookmarkToKeywordHash;
   1.441 +  bool mBookmarkToKeywordHashInitialized;
   1.442 +
   1.443 +  /**
   1.444 +   * This function must be called every time a bookmark is removed.
   1.445 +   *
   1.446 +   * @param aURI
   1.447 +   *        Uri to test.
   1.448 +   */
   1.449 +  nsresult UpdateKeywordsHashForRemovedBookmark(int64_t aItemId);
   1.450 +
   1.451 +  /**
   1.452 +   * Cache for the last fetched BookmarkData entries.
   1.453 +   * This is used to speed up repeated requests to the same item id.
   1.454 +   */
   1.455 +  nsTHashtable<BookmarkKeyClass> mRecentBookmarksCache;
   1.456 +
   1.457 +  /**
   1.458 +   * Tracks bookmarks in the cache critical path.  Items should not be
   1.459 +   * added to the cache till they are removed from this hash.
   1.460 +   */
   1.461 +  nsTHashtable<nsTrimInt64HashKey> mUncachableBookmarks;
   1.462 +};
   1.463 +
   1.464 +#endif // nsNavBookmarks_h_

mercurial