Bug 1113175 - Implement async History.clear() r=mak
authorTim Taubert <ttaubert@mozilla.com>
Tue, 13 Jan 2015 11:23:16 +0100
changeset 237189 f2058d853176691c6995a15ea5cc838d9056eeb5
parent 237188 38fb85296699e42131141c4a97a995e8e7052d74
child 237190 2cc184d6dc0f826a395bbb046b05c7e579d6f9f4
push id431
push usernalexander@mozilla.com
push dateThu, 15 Jan 2015 22:02:12 +0000
reviewersmak
bugs1113175
milestone38.0a1
Bug 1113175 - Implement async History.clear() r=mak
toolkit/components/places/History.jsm
--- a/toolkit/components/places/History.jsm
+++ b/toolkit/components/places/History.jsm
@@ -143,17 +143,17 @@ function ensureModuleIsOpen() {
  *
  * @param observers
  *        array of nsINavBookmarkObserver objects.
  * @param notification
  *        the notification name.
  * @param args
  *        array of arguments to pass to the notification.
  */
-function notify(observers, notification, args) {
+function notify(observers, notification, args = []) {
   for (let observer of observers) {
     try {
       observer[notification](...args);
     } catch (ex) {}
   }
 }
 
 this.History = Object.freeze({
@@ -248,17 +248,17 @@ this.History = Object.freeze({
    *             or (string)
    *      Either the full URI of the page or the GUID of the page.
    *             or (Array<URL|nsIURI|string>)
    *      An array of the above, to batch requests.
    * @param onResult: (function(PageInfo))
    *      A callback invoked for each page found.
    *
    * @return (Promise)
-   *      A promise resoled once the operation is complete.
+   *      A promise resolved once the operation is complete.
    * @resolve (bool)
    *      `true` if at least one page was removed, `false` otherwise.
    * @throws (TypeError)
    *       If `pages` has an unexpected type or if a string provided
    *       is neither a valid GUID nor a valid URI or if `pages`
    *       is an empty array.
    */
   remove: function (pages, onResult = null) {
@@ -323,28 +323,50 @@ this.History = Object.freeze({
    * Determine if a page has been visited.
    *
    * @param pages: (URL or nsIURI)
    *      The full URI of the page.
    *            or (string)
    *      The full URI of the page or the GUID of the page.
    *
    * @return (Promise)
-   *      A promise resoled once the operation is complete.
+   *      A promise resolved once the operation is complete.
    * @resolve (bool)
    *      `true` if the page has been visited, `false` otherwise.
    * @throws (Error)
    *      If `pages` has an unexpected type or if a string provided
    *      is neither not a valid GUID nor a valid URI.
    */
   hasVisits: function(page, onResult) {
     throw new Error("Method not implemented");
   },
 
   /**
+   * Clear all history.
+   *
+   * @return (Promise)
+   *      A promise resolved once the operation is complete.
+   */
+  clear() {
+    ensureModuleIsOpen();
+
+    return Task.spawn(function* () {
+      let promise = clear();
+      operationsBarrier.client.addBlocker("History.clear", promise);
+
+      try {
+        return (yield promise);
+      } finally {
+        // Cleanup the barrier.
+        operationsBarrier.client.removeBlocker(promise);
+      }
+    });
+  },
+
+  /**
    * Possible values for the `transition` property of `VisitInfo`
    * objects.
    */
 
   /**
    * The user followed a link and got a new toplevel window.
    */
   TRANSITION_LINK: Ci.nsINavHistoryService.TRANSITION_LINK,
@@ -448,16 +470,44 @@ let invalidateFrecencies = Task.async(fu
   yield db.execute(
     `UPDATE moz_places
      SET hidden = 0
      WHERE id in (${ ids })
      AND frecency <> 0`
   );
 });
 
+// Inner implementation of History.clear().
+let clear = Task.async(function* () {
+  let db = yield DBConnPromised;
+
+  // Remove all history.
+  yield db.execute("DELETE FROM moz_historyvisits");
+
+  // Clear the registered embed visits.
+  PlacesUtils.history.clearEmbedVisits();
+
+  // Expiration will take care of orphans.
+  let observers = PlacesUtils.history.getObservers();
+  notify(observers, "onClearHistory");
+
+  // Invalidate frecencies for the remaining places. This must happen
+  // after the notification to ensure it runs enqueued to expiration.
+  yield db.execute(
+    `UPDATE moz_places SET frecency =
+     (CASE
+      WHEN url BETWEEN 'place:' AND 'place;'
+      THEN 0
+      ELSE -1
+      END)
+     WHERE frecency > 0`);
+
+  // Notify frecency change observers.
+  notify(observers, "onManyFrecenciesChanged");
+});
 
 // Inner implementation of History.remove.
 let remove = Task.async(function*({guids, urls}, onResult = null) {
   let db = yield DBConnPromised;
 
   // 1. Find out what needs to be removed
   let query =
     `SELECT id, url, guid, foreign_count, title, frecency FROM moz_places