Bug 606460 - Queries enhancements after temp tables removal.
authorMarco Bonardo <mbonardo@mozilla.com>
Wed, 27 Oct 2010 14:53:22 +0200
changeset 59316 b836e83fe06134853c6120c9380bde0fd696ba15
parent 59315 45655fe19c7fe27e3332ce904527bc5f5ee7bcc3
child 59317 165b1dfdd63911d1e34946ccd75d86427b846aaf
push id1
push usershaver@mozilla.com
push dateTue, 04 Jan 2011 17:58:04 +0000
bugs606460
milestone2.0b8pre
Bug 606460 - Queries enhancements after temp tables removal. r=sdwilsh a=blocking
toolkit/components/places/src/nsNavBookmarks.cpp
toolkit/components/places/src/nsNavHistory.cpp
toolkit/components/places/src/nsPlacesAutoComplete.js
toolkit/components/places/tests/unit/test_empty_tags.js
--- a/toolkit/components/places/src/nsNavBookmarks.cpp
+++ b/toolkit/components/places/src/nsNavBookmarks.cpp
@@ -250,22 +250,20 @@ nsNavBookmarks::GetStatement(const nsCOM
 
   // Double ordering covers possible lastModified ties, that could happen when
   // importing, syncing or due to extensions.
   // Note: not using a JOIN is cheaper in this case.
   RETURN_IF_STMT(mDBFindURIBookmarks, NS_LITERAL_CSTRING(
     "SELECT b.id "
     "FROM moz_bookmarks b "
     "WHERE b.fk = (SELECT id FROM moz_places WHERE url = :page_url) "
-      "AND b.fk NOTNULL "
     "ORDER BY b.lastModified DESC, b.id DESC "));
 
   // Select all children of a given folder, sorted by position.
-  // This is a LEFT OUTER JOIN with moz_places since folders does not have
-  // a reference into that table.
+  // 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.
   RETURN_IF_STMT(mDBGetChildren, NS_LITERAL_CSTRING(
     "SELECT h.id, h.url, IFNULL(b.title, h.title), h.rev_host, h.visit_count, "
            "h.last_visit_date, f.url, null, b.id, b.dateAdded, b.lastModified, "
            "b.parent, null, b.position, b.type, b.fk, b.folder_type "
     "FROM moz_bookmarks b "
@@ -280,22 +278,22 @@ nsNavBookmarks::GetStatement(const nsCOM
     "(SELECT id FROM moz_bookmarks WHERE id = :parent) "
     "FROM moz_bookmarks WHERE parent = :parent"));
 
   RETURN_IF_STMT(mDBGetChildAt, NS_LITERAL_CSTRING(
     "SELECT id, fk, type FROM moz_bookmarks "
     "WHERE parent = :parent AND position = :item_index"));
 
   // Get bookmark/folder/separator properties.
+  // This is a LEFT JOIN because not all bookmarks types have a place.
   RETURN_IF_STMT(mDBGetItemProperties, NS_LITERAL_CSTRING(
-    "SELECT b.id, "
-           "(SELECT url FROM moz_places WHERE id = b.fk), "
-           "b.title, b.position, b.fk, b.parent, b.type, b.folder_type, "
-           "b.dateAdded, b.lastModified "
+    "SELECT b.id, h.url, b.title, b.position, b.fk, b.parent, b.type, "
+           "b.folder_type, b.dateAdded, b.lastModified "
     "FROM moz_bookmarks b "
+    "LEFT JOIN moz_places h ON h.id = b.fk "
     "WHERE b.id = :item_id"));
 
   RETURN_IF_STMT(mDBGetItemIdForGUID, NS_LITERAL_CSTRING(
     "SELECT item_id FROM moz_items_annos "
     "WHERE content = :guid "
     "LIMIT 1"));
 
   RETURN_IF_STMT(mDBInsertBookmark, NS_LITERAL_CSTRING(
@@ -321,18 +319,17 @@ nsNavBookmarks::GetStatement(const nsCOM
     "FROM moz_bookmarks "
     "WHERE fk = :page_id "
       "AND type = :item_type "
       "AND parent NOT IN ("
         "SELECT a.item_id "
         "FROM moz_items_annos a "
         "JOIN moz_anno_attributes n ON a.anno_attribute_id = n.id "
         "WHERE n.name = :anno_name"
-      ") "
-    "LIMIT 1"));
+      ") "));
 
   RETURN_IF_STMT(mDBGetLastBookmarkID, NS_LITERAL_CSTRING(
     "SELECT id "
     "FROM moz_bookmarks "
     "ORDER BY ROWID DESC "
     "LIMIT 1"));
 
   // lastModified is set to the same value as dateAdded.  We do this for
@@ -353,17 +350,17 @@ nsNavBookmarks::GetStatement(const nsCOM
     "FROM moz_places h "
     "JOIN moz_bookmarks b ON b.fk = h.id "
     "JOIN moz_keywords k ON k.id = b.keyword_id "
     "WHERE h.url = :page_url "));
 
   RETURN_IF_STMT(mDBAdjustPosition, NS_LITERAL_CSTRING(
     "UPDATE moz_bookmarks SET position = position + :delta "
     "WHERE parent = :parent "
-      "AND position >= :from_index AND position <= :to_index"));
+      "AND position BETWEEN :from_index AND :to_index"));
 
   RETURN_IF_STMT(mDBRemoveItem, NS_LITERAL_CSTRING(
     "DELETE FROM moz_bookmarks WHERE id = :item_id"));
 
   RETURN_IF_STMT(mDBGetLastChildId, NS_LITERAL_CSTRING(
     "SELECT id FROM moz_bookmarks WHERE parent = :parent "
     "ORDER BY position DESC LIMIT 1"));
 
--- a/toolkit/components/places/src/nsNavHistory.cpp
+++ b/toolkit/components/places/src/nsNavHistory.cpp
@@ -1156,21 +1156,19 @@ nsNavHistory::GetStatement(const nsCOMPt
   RETURN_IF_STMT(mDBGetTags, NS_LITERAL_CSTRING(
     "/* do not warn (bug 487594) */ "
     "SELECT GROUP_CONCAT(tag_title, ', ') "
     "FROM ( "
       "SELECT t.title AS tag_title "
       "FROM moz_bookmarks b "
       "JOIN moz_bookmarks t ON t.id = b.parent "
       "WHERE b.fk = (SELECT id FROM moz_places WHERE url = :page_url) "
-        "AND LENGTH(t.title) > 0 "
-        "AND b.type = ") +
-          nsPrintfCString("%d", nsINavBookmarksService::TYPE_BOOKMARK) +
-        NS_LITERAL_CSTRING(" AND t.parent = :tags_folder "
-      "ORDER BY t.title COLLATE NOCASE ASC) "
+        "AND t.parent = :tags_folder "
+      "ORDER BY t.title COLLATE NOCASE ASC "
+    ") "
   ));
 
   RETURN_IF_STMT(mDBGetItemsWithAnno, NS_LITERAL_CSTRING(
     "SELECT a.item_id, a.content "
     "FROM moz_anno_attributes n "
     "JOIN moz_items_annos a ON n.id = a.anno_attribute_id "
     "WHERE n.name = :anno_name "
   ));
@@ -1292,28 +1290,24 @@ nsNavHistory::GetStatement(const nsCOMPt
            "h.last_visit_date, f.url, null, null, null, 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 "
     "WHERE v.id = :visit_id "
   ));
 
   // mDBBookmarkToUrlResult, should match kGetInfoIndex_*
-  // We are not checking for duplicated ids into the unified table
-  // for perf reasons, LIMIT 1 will discard duplicates faster since we
-  // have unique place ids.
   RETURN_IF_STMT(mDBBookmarkToUrlResult, NS_LITERAL_CSTRING(
     "SELECT b.fk, h.url, COALESCE(b.title, h.title), "
            "h.rev_host, h.visit_count, h.last_visit_date, f.url, null, b.id, "
            "b.dateAdded, b.lastModified, b.parent, null "
     "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 "
+    "LEFT JOIN moz_favicons f ON h.favicon_id = f.id "
     "WHERE b.id = :item_id "
-    "LIMIT 1"
   ));
 
   return nsnull;
 }
 
 
 /**
  * This dumps all bookmarks-related tables, and recreates them,
@@ -3300,17 +3294,17 @@ PlacesSQLQueryBuilder::SelectAsURI()
                            mHasSearchTerms,
                            tagsSqlFragment);
         mQueryString = NS_LITERAL_CSTRING(
           "SELECT b.fk, h.url, COALESCE(b.title, h.title), h.rev_host, "
             "h.visit_count, h.last_visit_date, f.url, null, b.id, "
             "b.dateAdded, b.lastModified, b.parent, ") +
             tagsSqlFragment + NS_LITERAL_CSTRING(
           "FROM moz_bookmarks b "
-          "JOIN moz_places h ON b.fk = h.id AND b.type = 1 "
+          "JOIN moz_places h ON b.fk = h.id "
           "LEFT OUTER JOIN moz_favicons f ON h.favicon_id = f.id "
           "WHERE NOT EXISTS "
               "(SELECT id FROM moz_bookmarks "
                 "WHERE id = b.parent AND parent = ") +
                   nsPrintfCString("%lld", history->GetTagsFolder()) +
               NS_LITERAL_CSTRING(") "
             "{ADDITIONAL_CONDITIONS}");
       }
@@ -3507,35 +3501,36 @@ PlacesSQLQueryBuilder::SelectAsDay()
         sqlFragmentSearchBeginTime = sqlFragmentContainerBeginTime;
         sqlFragmentSearchEndTime = sqlFragmentContainerEndTime;
         break;
     }
 
     nsPrintfCString dateParam("dayTitle%d", i);
     mAddParams.Put(dateParam, dateName);
 
-     nsPrintfCString dayRange(1024,
-        "SELECT :%s AS dayTitle, "
-               "%s AS beginTime, "
-               "%s AS endTime "
-         "WHERE EXISTS ( "
-          "SELECT id FROM moz_historyvisits "
-          "WHERE visit_date >= %s "
-            "AND visit_date < %s "
-             "AND visit_type NOT IN (0,%d,%d) "
-             "{QUERY_OPTIONS_VISITS} "
-           "LIMIT 1 "
-        ") ",
+    nsPrintfCString dayRange(1024,
+      "SELECT :%s AS dayTitle, "
+             "%s AS beginTime, "
+             "%s AS endTime "
+       "WHERE EXISTS ( "
+        "SELECT id FROM moz_historyvisits "
+        "WHERE visit_date >= %s "
+          "AND visit_date < %s "
+           "AND visit_type NOT IN (0,%d,%d) "
+           "{QUERY_OPTIONS_VISITS} "
+         "LIMIT 1 "
+      ") ",
       dateParam.get(),
       sqlFragmentContainerBeginTime.get(),
       sqlFragmentContainerEndTime.get(),
       sqlFragmentSearchBeginTime.get(),
       sqlFragmentSearchEndTime.get(),
       nsINavHistoryService::TRANSITION_EMBED,
-      nsINavHistoryService::TRANSITION_FRAMED_LINK);
+      nsINavHistoryService::TRANSITION_FRAMED_LINK
+    );
 
     mQueryString.Append(dayRange);
 
     if (i < HISTORY_DATE_CONT_NUM(daysOfHistory))
       mQueryString.Append(NS_LITERAL_CSTRING(" UNION ALL "));
   }
 
   mQueryString.Append(NS_LITERAL_CSTRING(") ")); // TOUTER END
@@ -3549,107 +3544,86 @@ PlacesSQLQueryBuilder::SelectAsSite()
   nsCAutoString localFiles;
 
   nsNavHistory *history = nsNavHistory::GetHistoryService();
   NS_ENSURE_STATE(history);
 
   history->GetStringFromName(NS_LITERAL_STRING("localhost").get(), localFiles);
   mAddParams.Put(NS_LITERAL_CSTRING("localhost"), localFiles);
 
-  // We want just sites, but from whole database.
-  if (mConditions.IsEmpty()) {
-    mQueryString = nsPrintfCString(2048,
-      "SELECT DISTINCT null, "
-             "'place:type=%ld&sort=%ld&domain=&domainIsHost=true', "
-             ":localhost, :localhost, null, null, null, null, null, null, null "
-      "WHERE EXISTS ( "
-        "SELECT id FROM moz_places "
-        "WHERE hidden <> 1 "
-          "AND rev_host = '.' "
-          "AND visit_count > 0 "
-          "AND url BETWEEN 'file://' AND 'file:/~' "
-      ") "
-      "UNION ALL "
-      "SELECT DISTINCT null, "
-             "'place:type=%ld&sort=%ld&domain='||host||'&domainIsHost=true', "
-             "host, host, null, null, null, null, null, null, null "
-      "FROM ( "
-        "SELECT get_unreversed_host(rev_host) host "
-        "FROM ( "
-          "SELECT DISTINCT rev_host FROM moz_places "
-          "WHERE hidden <> 1 "
-            "AND rev_host <> '.' "
-            "AND visit_count > 0 "
-        ") "
-      "ORDER BY 1 ASC) ",
-      nsINavHistoryQueryOptions::RESULTS_AS_URI,
-      mSortingMode,
-      nsINavHistoryQueryOptions::RESULTS_AS_URI,
-      mSortingMode);
-  // Now we need to use the filters - we need them all
-  } else {
-
-    mQueryString = nsPrintfCString(4096,
-      "SELECT DISTINCT null, "
-             "'place:type=%ld&sort=%ld&domain=&domainIsHost=true"
-               "&beginTime='||:begin_time||'&endTime='||:end_time, "
-             ":localhost, :localhost, null, null, null, null, null, null, null "
-      "WHERE EXISTS( "
-        "SELECT h.id "
-        "FROM moz_places h "
-        "JOIN moz_historyvisits v ON v.place_id = h.id "
-        "WHERE h.hidden <> 1 AND h.rev_host = '.' "
-          "AND h.visit_count > 0 "
-          "AND h.url BETWEEN 'file://' AND 'file:/~' "
-          "{QUERY_OPTIONS_VISITS} {QUERY_OPTIONS_PLACES} "
-          "{ADDITIONAL_CONDITIONS} "
-      ") "
-      "UNION ALL "
-      "SELECT DISTINCT null, "
-             "'place:type=%ld&sort=%ld&domain='||host||'&domainIsHost=true"
-               "&beginTime='||:begin_time||'&endTime='||:end_time, "
-             "host, host, null, null, null, null, null, null, null "
-      "FROM ( "
-        "SELECT DISTINCT get_unreversed_host(rev_host) AS host "
-        "FROM moz_places h "
-        "JOIN moz_historyvisits v ON v.place_id = h.id "
-        "WHERE h.rev_host <> '.' "
-          "AND h.visit_count > 0 "
-          "{QUERY_OPTIONS_VISITS} {QUERY_OPTIONS_PLACES} "
-          "{ADDITIONAL_CONDITIONS} "
-        "ORDER BY 1 ASC "
-      ") ",
-      nsINavHistoryQueryOptions::RESULTS_AS_URI,
-      mSortingMode,
-      nsINavHistoryQueryOptions::RESULTS_AS_URI,
-      mSortingMode);
-  }
+  // If there are additional conditions the query has to join on visits too.
+  nsCAutoString visitsJoin;
+  nsCAutoString additionalConditions;
+  if (!mConditions.IsEmpty()) {
+    visitsJoin.AssignLiteral("JOIN moz_historyvisits v ON v.place_id = h.id ");
+    additionalConditions.AssignLiteral("{QUERY_OPTIONS_VISITS} "
+                                       "{QUERY_OPTIONS_PLACES} "
+                                       "{ADDITIONAL_CONDITIONS} ");
+  }
+
+  mQueryString = nsPrintfCString(2048,
+    "SELECT null, 'place:type=%ld&sort=%ld&domain=&domainIsHost=true', "
+           ":localhost, :localhost, null, null, null, null, null, null, null "
+    "WHERE EXISTS ( "
+      "SELECT h.id FROM moz_places h "
+      "%s "
+      "WHERE h.hidden <> 1 "
+        "AND h.visit_count > 0 "
+        "AND h.url BETWEEN 'file://' AND 'file:/~' "
+      "%s "
+      "LIMIT 1 "
+    ") "
+    "UNION ALL "
+    "SELECT null, "
+           "'place:type=%ld&sort=%ld&domain='||host||'&domainIsHost=true', "
+           "host, host, null, null, null, null, null, null, null "
+    "FROM ( "
+      "SELECT get_unreversed_host(h.rev_host) AS host "
+      "FROM moz_places h "
+      "%s "
+      "WHERE h.hidden <> 1 "
+        "AND h.rev_host <> '.' "
+        "AND h.visit_count > 0 "
+        "%s "
+      "GROUP BY h.rev_host "
+      "ORDER BY host ASC "
+    ") ",
+    nsINavHistoryQueryOptions::RESULTS_AS_URI,
+    mSortingMode,
+    PromiseFlatCString(visitsJoin).get(),
+    PromiseFlatCString(additionalConditions).get(),
+    nsINavHistoryQueryOptions::RESULTS_AS_URI,
+    mSortingMode,
+    PromiseFlatCString(visitsJoin).get(),
+    PromiseFlatCString(additionalConditions).get()
+  );
 
   return NS_OK;
 }
 
 nsresult
 PlacesSQLQueryBuilder::SelectAsTag()
 {
   nsNavHistory *history = nsNavHistory::GetHistoryService();
   NS_ENSURE_STATE(history);
 
   // This allows sorting by date fields what is not possible with
   // other history queries.
   mHasDateColumns = PR_TRUE; 
 
   mQueryString = nsPrintfCString(2048,
     "SELECT null, 'place:folder=' || id || '&queryType=%d&type=%ld', "
-      "title, null, null, null, null, null, null, dateAdded, lastModified, "
-      "null, null "
-    "FROM   moz_bookmarks "
-    "WHERE  parent = %lld",
+           "title, null, null, null, null, null, null, dateAdded, "
+           "lastModified, null, null "
+    "FROM moz_bookmarks "
+    "WHERE parent = %lld",
     nsINavHistoryQueryOptions::QUERY_TYPE_BOOKMARKS,
     nsINavHistoryQueryOptions::RESULTS_AS_TAG_CONTENTS,
-    history->GetTagsFolder());
+    history->GetTagsFolder()
+  );
 
   return NS_OK;
 }
 
 nsresult
 PlacesSQLQueryBuilder::Where()
 {
 
@@ -3685,20 +3659,17 @@ PlacesSQLQueryBuilder::Where()
 
   mQueryString.ReplaceSubstring("{QUERY_OPTIONS_VISITS}",
                                 additionalVisitsConditions.get());
   mQueryString.ReplaceSubstring("{QUERY_OPTIONS_PLACES}",
                                 additionalPlacesConditions.get());
 
   // If we used WHERE already, we inject the conditions 
   // in place of {ADDITIONAL_CONDITIONS}
-  PRInt32 useInnerCondition;
-  useInnerCondition = mQueryString.Find("{ADDITIONAL_CONDITIONS}", 0);
-  if (useInnerCondition != kNotFound) {
-
+  if (mQueryString.Find("{ADDITIONAL_CONDITIONS}", 0) != kNotFound) {
     nsCAutoString innerCondition;
     // If we have condition AND it
     if (!mConditions.IsEmpty()) {
       innerCondition = " AND (";
       innerCondition += mConditions;
       innerCondition += ")";
     }
     mQueryString.ReplaceSubstring("{ADDITIONAL_CONDITIONS}",
@@ -4145,33 +4116,33 @@ nsNavHistory::AddPageWithDetails(nsIURI 
   nsresult rv = AddVisit(aURI, aLastVisited, 0, TRANSITION_LINK, PR_FALSE,
                          0, &visitID);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return SetPageTitleInternal(aURI, nsString(aTitle));
 }
 
 
-// nsNavHistory::GetLastPageVisited
-//
-//    This was once used when the new window is set to "previous page." It
-//    doesn't seem to be used anymore, so we don't spend any time precompiling
-//    the statement.
-
+/**
+ * This was once used when the new window was set to "previous page".
+ * Currently it is still referenced by browser.startup.page == 2, but that value
+ * is not selectable from the UI.
+ * TODO: Should be deprecated? There is no fast alternative to get this info.
+ */
 NS_IMETHODIMP
 nsNavHistory::GetLastPageVisited(nsACString & aLastPageVisited)
 {
   NS_ASSERTION(NS_IsMainThread(), "This can only be called on the main thread");
 
   nsCOMPtr<mozIStorageStatement> statement;
   nsresult rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
-      "SELECT url, visit_date FROM moz_historyvisits v "
-      "JOIN moz_places h ON v.place_id = h.id "
-      "WHERE h.hidden <> 1 "
-      "ORDER BY visit_date DESC "),
+      "SELECT url FROM moz_places "
+      "WHERE hidden <> 1 "
+        "AND last_visit_date NOTNULL "
+      "ORDER BY last_visit_date DESC "),
     getter_AddRefs(statement));
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRBool hasMatch = PR_FALSE;
   if (NS_SUCCEEDED(statement->ExecuteStep(&hasMatch)) && hasMatch)
     return statement->GetUTF8String(0, aLastPageVisited);
 
   aLastPageVisited.Truncate(0);
--- a/toolkit/components/places/src/nsPlacesAutoComplete.js
+++ b/toolkit/components/places/src/nsPlacesAutoComplete.js
@@ -50,20 +50,18 @@ const Cr = Components.results;
 function book_tag_sql_fragment(aName, aColumn, aForTag)
 {
   return ["(",
     "SELECT ", aColumn, " ",
     "FROM moz_bookmarks b ",
     "JOIN moz_bookmarks t ",
       "ON t.id = b.parent ",
       "AND t.parent ", (aForTag ? "" : "!"), "= :parent ",
-    "WHERE b.type = ", Ci.nsINavBookmarksService.TYPE_BOOKMARK, " ",
-      "AND b.fk = h.id ",
-    (aForTag ? "AND LENGTH(t.title) > 0" :
-               "ORDER BY b.lastModified DESC LIMIT 1"),
+    "WHERE b.fk = h.id ",
+    (aForTag ? "" : "ORDER BY b.lastModified DESC LIMIT 1"),
   ") AS ", aName].join("");
 }
 
 // This SQL query fragment provides the following:
 //   - the parent folder for bookmarked entries (kQueryIndexParent)
 //   - the bookmark title, if it is a bookmark (kQueryIndexBookmarkTitle)
 //   - the tags associated with a bookmarked entry (kQueryIndexTags)
 const kBookTagSQLFragment =
deleted file mode 100644
--- a/toolkit/components/places/tests/unit/test_empty_tags.js
+++ /dev/null
@@ -1,112 +0,0 @@
-/***************************** BEGIN LICENSE BLOCK *****************************
-* Version: MPL 1.1/GPL 2.0/LGPL 2.1
-*
-* The contents of this file are subject to the Mozilla Public License Version
-* 1.1 (the "License"); you may not use this file except in compliance with the
-* License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
-*
-* Software distributed under the License is distributed on an "AS IS" basis,
-* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
-* the specific language governing rights and limitations under the License.
-*
-* The Original Code is Places Test Code.
-*
-* The Initial Developer of the Original Code is Mozilla Foundation.
-* Portions created by the Initial Developer are Copyright (C) 2009 the Initial
-* Developer. All Rights Reserved.
-*
-* Contributor(s):
-*  Edward Lee <edilee@mozilla.com> (original author)
-*
-* 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 decision by deleting the
-* provisions above and replace them with the notice and other provisions
-* required by the GPL or the LGPL. If you do not delete the provisions above, a
-* recipient may use your version of this file under the terms of any one of the
-* MPL, the GPL or the LGPL.
-*
-****************************** END LICENSE BLOCK ******************************/
-
-/**
- * Test bug 489443 to make sure bookmarks with empty tags don't have the empty
- * tags shown.
- */
-
-let ac = Cc["@mozilla.org/autocomplete/search;1?name=history"].
-  getService(Ci.nsIAutoCompleteSearch);
-let bm = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
-  getService(Ci.nsINavBookmarksService);
-let io = Cc["@mozilla.org/network/io-service;1"].
-  getService(Ci.nsIIOService);
-let ts = Cc["@mozilla.org/browser/tagging-service;1"].
-  getService(Ci.nsITaggingService);
-
-let _ = function(some, debug, message) print(Array.slice(arguments).join(" "));
-
-function run_test() {
-  // always search in history + bookmarks, no matter what the default is
-  var prefs = Cc["@mozilla.org/preferences-service;1"].
-              getService(Ci.nsIPrefBranch);
-  prefs.setIntPref("browser.urlbar.search.sources", 3);
-  prefs.setIntPref("browser.urlbar.default.behavior", 0);
-
-  let uri = io.newURI("http://uri/", null, null);
-  bm.insertBookmark(bm.toolbarFolder, uri, bm.DEFAULT_INDEX, "title");
-
-  _("Adding 3 tags to the bookmark");
-  let tagIds = [];
-  for (let i = 0; i < 3; i++) {
-    _("Tagging uri with tag:", i);
-    ts.tagURI(uri, ["" + i]);
-    let id = bm.getIdForItemAt(bm.tagsFolder, i);
-    _("Saving bookmark id of tag to rename it later:", id);
-    tagIds.push(id);
-  }
-
-  _("Search 4 times: make sure we get the right amount of tags then remove one");
-  (function doSearch(query) {
-    _("Searching for:", query);
-    ac.startSearch(query, "", null, {
-      onSearchResult: function(search, result) {
-        _("Got results with status:", result.searchResult);
-        if (result.searchResult != result.RESULT_SUCCESS)
-          return;
-
-        let comment = result.getCommentAt(0);
-        _("Got the title/tags:", comment);
-
-        _("Until we get bug 489443, we have title and tags separated by \u2013");
-        if (comment.indexOf("\u2013") == -1) {
-          let num = tagIds.length;
-          _("No tags in result, so making sure we have no tags:", num);
-          do_check_eq(num, 0);
-          do_test_finished();
-          return;
-        }
-
-        let num = tagIds.length;
-        _("Making sure we get the expected number of tags:", num);
-        do_check_eq(comment.split(",").length, num);
-
-        _("Removing a tag from the tag ids array:", tagIds);
-        let id = tagIds.shift();
-        _("Setting an empty title for tag:", id);
-        bm.setItemTitle(id, "");
-
-        _("Creating a timer to do a new search to let the current one finish");
-        let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
-        let next = query.slice(1);
-        _("Do a new, uncached search with a new query:", next);
-        timer.initWithCallback({ notify: function() doSearch(next) },
-          0, timer.TYPE_ONE_SHOT);
-      }
-    });
-  })("title");
-
-  do_test_pending();
-}