diff --git a/browser/installer/unix/packages-static b/browser/installer/unix/packages-static index 12cb8a5f6051..d605dc975beb 100644 --- a/browser/installer/unix/packages-static +++ b/browser/installer/unix/packages-static @@ -236,7 +236,6 @@ bin/components/libbrowsercomps.so bin/components/txEXSLTRegExFunctions.js bin/components/nsLivemarkService.js bin/components/nsTaggingService.js -bin/components/nsPlacesDBFlush.js bin/components/nsDefaultCLH.js bin/components/nsContentPrefService.js bin/components/nsContentDispatchChooser.js diff --git a/browser/installer/windows/packages-static b/browser/installer/windows/packages-static index 56002272e2cc..c8e210e6dd16 100644 --- a/browser/installer/windows/packages-static +++ b/browser/installer/windows/packages-static @@ -243,7 +243,6 @@ bin\components\brwsrcmp.dll bin\components\txEXSLTRegExFunctions.js bin\components\nsLivemarkService.js bin\components\nsTaggingService.js -bin\components\nsPlacesDBFlush.js bin\components\nsDefaultCLH.js bin\components\nsContentPrefService.js bin\components\nsContentDispatchChooser.js diff --git a/toolkit/components/places/src/Makefile.in b/toolkit/components/places/src/Makefile.in index 6e6b16b3e07a..89d3805d8ef2 100644 --- a/toolkit/components/places/src/Makefile.in +++ b/toolkit/components/places/src/Makefile.in @@ -105,7 +105,6 @@ LOCAL_INCLUDES += -I$(srcdir)/../../build EXTRA_PP_COMPONENTS = nsLivemarkService.js \ nsTaggingService.js \ - nsPlacesDBFlush.js \ $(NULL) EXTRA_JS_MODULES = \ diff --git a/toolkit/components/places/src/PlacesBackground.jsm b/toolkit/components/places/src/PlacesBackground.jsm index 3e402727c90a..815f356b8794 100644 --- a/toolkit/components/places/src/PlacesBackground.jsm +++ b/toolkit/components/places/src/PlacesBackground.jsm @@ -49,7 +49,6 @@ const Ci = Components.interfaces; const Cr = Components.results; const kQuitApplication = "quit-application"; -const kPlacesBackgroundShutdown = "places-background-shutdown"; //////////////////////////////////////////////////////////////////////////////// //// nsPlacesBackgound class @@ -85,12 +84,6 @@ nsPlacesBackground.prototype = { observe: function PlacesBackground_observe(aSubject, aTopic, aData) { if (aTopic == kQuitApplication) { - // Notify consumers that we are shutting down. - let os = Cc["@mozilla.org/observer-service;1"]. - getService(Ci.nsIObserverService); - os.notifyObservers(null, kPlacesBackgroundShutdown, null); - - // Now shut the thread down. this._thread.shutdown(); this._thread = null; } diff --git a/toolkit/components/places/src/nsAnnotationService.cpp b/toolkit/components/places/src/nsAnnotationService.cpp index 7ab28fc58c94..0773e2d02101 100644 --- a/toolkit/components/places/src/nsAnnotationService.cpp +++ b/toolkit/components/places/src/nsAnnotationService.cpp @@ -109,8 +109,7 @@ nsAnnotationService::Init() // mDBSetAnnotation rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( "UPDATE moz_annos " - "SET mime_type = ?4, content = ?5, flags = ?6, expiration = ?7, " - "type = ?8, lastModified = ?10 " + "SET mime_type = ?4, content = ?5, flags = ?6, expiration = ?7, type = ?8, lastModified = ?10 " "WHERE id = ?1"), getter_AddRefs(mDBSetAnnotation)); NS_ENSURE_SUCCESS(rv, rv); @@ -118,8 +117,7 @@ nsAnnotationService::Init() // mDBSetItemAnnotation rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( "UPDATE moz_items_annos " - "SET mime_type = ?4, content = ?5, flags = ?6, expiration = ?7, " - "type = ?8, lastModified = ?10 " + "SET mime_type = ?4, content = ?5, flags = ?6, expiration = ?7, type = ?8, lastModified = ?10 " "WHERE id = ?1"), getter_AddRefs(mDBSetItemAnnotation)); NS_ENSURE_SUCCESS(rv, rv); @@ -129,7 +127,7 @@ nsAnnotationService::Init() "SELECT * " "FROM moz_annos " "WHERE place_id = ?1 AND anno_attribute_id = " - "(SELECT id FROM moz_anno_attributes WHERE name = ?2)"), + "(SELECT id FROM moz_anno_attributes WHERE name = ?2)"), getter_AddRefs(mDBGetAnnotation)); NS_ENSURE_SUCCESS(rv, rv); @@ -138,15 +136,14 @@ nsAnnotationService::Init() "SELECT * " "FROM moz_items_annos " "WHERE item_id = ?1 AND anno_attribute_id = " - "(SELECT id FROM moz_anno_attributes WHERE name = ?2)"), + "(SELECT id FROM moz_anno_attributes WHERE name = ?2)"), getter_AddRefs(mDBGetItemAnnotation)); NS_ENSURE_SUCCESS(rv, rv); // mDBGetAnnotationNames rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( "SELECT n.name " - "FROM moz_annos a " - "JOIN moz_anno_attributes n ON a.anno_attribute_id = n.id " + "FROM moz_annos a LEFT JOIN moz_anno_attributes n ON a.anno_attribute_id = n.id " "WHERE a.place_id = ?1"), getter_AddRefs(mDBGetAnnotationNames)); NS_ENSURE_SUCCESS(rv, rv); @@ -154,29 +151,18 @@ nsAnnotationService::Init() // mDBGetItemAnnotationNames rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( "SELECT n.name " - "FROM moz_items_annos a " - "JOIN moz_anno_attributes n ON a.anno_attribute_id = n.id " + "FROM moz_items_annos a LEFT JOIN moz_anno_attributes n ON a.anno_attribute_id = n.id " "WHERE a.item_id = ?1"), getter_AddRefs(mDBGetItemAnnotationNames)); NS_ENSURE_SUCCESS(rv, rv); // mDBGetAnnotationFromURI - // We are not checking for duplicated ids into the unified table - // for perf reasons, LIMIT 1 will discard duplicates faster since we - // can only have one anno with a certain name for every place_id. rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( "SELECT a.id, a.place_id, ?2, a.mime_type, a.content, a.flags, " "a.expiration, a.type " - "FROM ( " - "SELECT id FROM moz_places_temp " - "WHERE url = ?1 " - "UNION ALL " - "SELECT id FROM moz_places " - "WHERE url = ?1 " - ") AS h JOIN moz_annos a ON h.id = a.place_id " - "WHERE a.anno_attribute_id = " - "(SELECT id FROM moz_anno_attributes WHERE name = ?2) " - "LIMIT 1"), + "FROM moz_places h JOIN moz_annos a ON h.id = a.place_id " + "WHERE h.url = ?1 AND a.anno_attribute_id = " + "(SELECT id FROM moz_anno_attributes WHERE name = ?2)"), getter_AddRefs(mDBGetAnnotationFromURI)); NS_ENSURE_SUCCESS(rv, rv); @@ -186,7 +172,7 @@ nsAnnotationService::Init() "a.expiration, a.type " "FROM moz_items_annos a " "WHERE a.item_id = ?1 AND a.anno_attribute_id = " - "(SELECT id FROM moz_anno_attributes WHERE name = ?2)"), + "(SELECT id FROM moz_anno_attributes WHERE name = ?2)"), getter_AddRefs(mDBGetAnnotationFromItemId)); NS_ENSURE_SUCCESS(rv, rv); @@ -206,8 +192,7 @@ nsAnnotationService::Init() // Note: kAnnoIndex_Name here is a name ID and not a string like the getters rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( "INSERT INTO moz_annos " - "(place_id, anno_attribute_id, mime_type, content, flags, expiration, " - "type, dateAdded) " + "(place_id, anno_attribute_id, mime_type, content, flags, expiration, type, dateAdded) " "VALUES (?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9)"), getter_AddRefs(mDBAddAnnotation)); NS_ENSURE_SUCCESS(rv, rv); @@ -216,8 +201,7 @@ nsAnnotationService::Init() // Note: kAnnoIndex_Name here is a name ID and not a string like the getters rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( "INSERT INTO moz_items_annos " - "(item_id, anno_attribute_id, mime_type, content, flags, expiration, " - "type, dateAdded) " + "(item_id, anno_attribute_id, mime_type, content, flags, expiration, type, dateAdded) " "VALUES (?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9)"), getter_AddRefs(mDBAddItemAnnotation)); NS_ENSURE_SUCCESS(rv, rv); @@ -225,21 +209,21 @@ nsAnnotationService::Init() // mDBRemoveAnnotation rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( "DELETE FROM moz_annos WHERE place_id = ?1 AND anno_attribute_id = " - "(SELECT id FROM moz_anno_attributes WHERE name = ?2)"), + "(SELECT id FROM moz_anno_attributes WHERE name = ?2)"), getter_AddRefs(mDBRemoveAnnotation)); NS_ENSURE_SUCCESS(rv, rv); // mDBRemoveItemAnnotation rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( "DELETE FROM moz_items_annos WHERE item_id = ?1 AND anno_attribute_id = " - "(SELECT id FROM moz_anno_attributes WHERE name = ?2)"), + "(SELECT id FROM moz_anno_attributes WHERE name = ?2)"), getter_AddRefs(mDBRemoveItemAnnotation)); NS_ENSURE_SUCCESS(rv, rv); // mDBGetItemsWithAnnotation rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( "SELECT a.item_id FROM moz_anno_attributes n " - "JOIN moz_items_annos a ON n.id = a.anno_attribute_id " + "INNER JOIN moz_items_annos a ON n.id = a.anno_attribute_id " "WHERE n.name = ?1"), getter_AddRefs(mDBGetItemsWithAnnotation)); NS_ENSURE_SUCCESS(rv, rv); @@ -269,8 +253,7 @@ nsAnnotationService::InitTables(mozIStorageConnection* aDBConn) NS_ENSURE_SUCCESS(rv, rv); rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "CREATE UNIQUE INDEX moz_annos_placeattributeindex " - "ON moz_annos (place_id, anno_attribute_id)")); + "CREATE UNIQUE INDEX moz_annos_placeattributeindex ON moz_annos (place_id, anno_attribute_id)")); NS_ENSURE_SUCCESS(rv, rv); } @@ -287,8 +270,7 @@ nsAnnotationService::InitTables(mozIStorageConnection* aDBConn) rv = aDBConn->ExecuteSimpleSQL(CREATE_MOZ_ITEMS_ANNOS); NS_ENSURE_SUCCESS(rv, rv); rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "CREATE UNIQUE INDEX moz_items_annos_itemattributeindex " - "ON moz_items_annos (item_id, anno_attribute_id)")); + "CREATE UNIQUE INDEX moz_items_annos_itemattributeindex ON moz_items_annos (item_id, anno_attribute_id)")); NS_ENSURE_SUCCESS(rv, rv); } @@ -1228,18 +1210,10 @@ nsAnnotationService::GetPagesWithAnnotationCOMArray( // statement. Perhaps this should change. nsCOMPtr statement; nsresult rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "SELECT h.url " - "FROM moz_places_temp h " - "JOIN moz_annos a ON h.id = a.place_id " - "JOIN moz_anno_attributes n ON n.id = a.anno_attribute_id " - "WHERE n.name = ?1 " - "UNION ALL " - "SELECT h.url " - "FROM moz_places h " - "JOIN moz_annos a ON h.id = a.place_id " - "JOIN moz_anno_attributes n ON n.id = a.anno_attribute_id " - "WHERE n.name = ?1 " - "AND h.id NOT IN (SELECT id FROM moz_places_temp)"), + "SELECT h.url FROM moz_anno_attributes n " + "INNER JOIN moz_annos a ON n.id = a.anno_attribute_id " + "INNER JOIN moz_places h ON a.place_id = h.id " + "WHERE n.name = ?1"), getter_AddRefs(statement)); NS_ENSURE_SUCCESS(rv, rv); @@ -1654,12 +1628,10 @@ nsAnnotationService::CopyPageAnnotations(nsIURI* aSourceURI, // source with the same values of the annotation on dest. nsCOMPtr statement; rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "INSERT INTO moz_annos " - "(place_id, anno_attribute_id, mime_type, content, flags, expiration) " + "INSERT INTO moz_annos (place_id, anno_attribute_id, mime_type, content, flags, expiration) " "SELECT ?1, anno_attribute_id, mime_type, content, flags, expiration " - "FROM moz_annos " - "WHERE place_id = ?2 AND anno_attribute_id = " - "(SELECT id FROM moz_anno_attributes WHERE name = ?3)"), + "FROM moz_annos WHERE place_id = ?2 AND anno_attribute_id = " + "(SELECT id FROM moz_anno_attributes WHERE name = ?3)"), getter_AddRefs(statement)); NS_ENSURE_SUCCESS(rv, rv); diff --git a/toolkit/components/places/src/nsFaviconService.cpp b/toolkit/components/places/src/nsFaviconService.cpp index 2112c4c10106..26fb0b1c1905 100644 --- a/toolkit/components/places/src/nsFaviconService.cpp +++ b/toolkit/components/places/src/nsFaviconService.cpp @@ -154,19 +154,10 @@ nsFaviconService::Init() getter_AddRefs(mDBGetIconInfo)); NS_ENSURE_SUCCESS(rv, rv); - // We can avoid checking for duplicates in the unified table since an uri - // can only have one favicon associated. LIMIT 1 will ensure that we get - // only one result. rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( "SELECT f.id, f.url, length(f.data), f.expiration " - "FROM ( " - "SELECT * FROM moz_places_temp " - "WHERE url = ?1 " - "UNION ALL " - "SELECT * FROM moz_places " - "WHERE url = ?1 " - ") AS h JOIN moz_favicons f ON h.favicon_id = f.id " - "LIMIT 1"), + "FROM moz_places h JOIN moz_favicons f ON h.favicon_id = f.id " + "WHERE h.url = ?1"), getter_AddRefs(mDBGetURL)); NS_ENSURE_SUCCESS(rv, rv); @@ -188,7 +179,7 @@ nsFaviconService::Init() NS_ENSURE_SUCCESS(rv, rv); rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "UPDATE moz_places_view SET favicon_id = ?2 WHERE id = ?1"), + "UPDATE moz_places SET favicon_id = ?2 WHERE id = ?1"), getter_AddRefs(mDBSetPageFavicon)); NS_ENSURE_SUCCESS(rv, rv); @@ -1108,7 +1099,6 @@ FaviconLoadListener::OnStopRequest(nsIRequest *aRequest, nsISupports *aContext, PRTime expiration = PR_Now() + (PRInt64)(24 * 60 * 60) * (PRInt64)PR_USEC_PER_SEC; - mozStorageTransaction transaction(mFaviconService->mDBConn, PR_FALSE); // save the favicon data // This could fail if the favicon is bigger than defined limit, in such a // case data will not be saved to the db but we will still continue. @@ -1122,12 +1112,8 @@ FaviconLoadListener::OnStopRequest(nsIRequest *aRequest, nsISupports *aContext, &hasData, &expiration); NS_ENSURE_SUCCESS(rv, rv); - mFaviconService->UpdateBookmarkRedirectFavicon(mPageURI, mFaviconURI); - - rv = transaction.Commit(); - NS_ENSURE_SUCCESS(rv, rv); - mFaviconService->SendFaviconNotifications(mPageURI, mFaviconURI); + mFaviconService->UpdateBookmarkRedirectFavicon(mPageURI, mFaviconURI); return NS_OK; } diff --git a/toolkit/components/places/src/nsNavBookmarks.cpp b/toolkit/components/places/src/nsNavBookmarks.cpp index 56180677bd3f..5aae1f310db2 100644 --- a/toolkit/components/places/src/nsNavBookmarks.cpp +++ b/toolkit/components/places/src/nsNavBookmarks.cpp @@ -106,31 +106,217 @@ nsresult nsNavBookmarks::Init() { nsNavHistory *history = History(); - NS_ENSURE_TRUE(history, NS_ERROR_OUT_OF_MEMORY); - mDBConn = history->GetStorageConnection(); - mozStorageTransaction transaction(mDBConn, PR_FALSE); + NS_ENSURE_TRUE(history, NS_ERROR_UNEXPECTED); + mozIStorageConnection *dbConn = DBConn(); + mozStorageTransaction transaction(dbConn, PR_FALSE); + nsresult rv; - nsresult rv = InitStatements(); + { + nsCOMPtr statement; + rv = dbConn->CreateStatement(NS_LITERAL_CSTRING("SELECT id FROM moz_bookmarks WHERE type = ?1 AND parent IS NULL"), + getter_AddRefs(statement)); + NS_ENSURE_SUCCESS(rv, rv); + rv = statement->BindInt32Parameter(0, TYPE_FOLDER); + NS_ENSURE_SUCCESS(rv, rv); + + PRBool results; + rv = statement->ExecuteStep(&results); + NS_ENSURE_SUCCESS(rv, rv); + if (results) { + mRoot = statement->AsInt64(0); + } + } + + nsCAutoString buffer; + + nsCOMPtr bundleService = + do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + rv = bundleService->CreateBundle( + "chrome://places/locale/places.properties", + getter_AddRefs(mBundle)); NS_ENSURE_SUCCESS(rv, rv); - rv = FillBookmarksHash(); + // mDBFindURIBookmarks + // NOTE: Do not modify the ORDER BY segment of the query, as certain + // features depend on it. See bug 398914 for an example. + rv = dbConn->CreateStatement(NS_LITERAL_CSTRING( + "SELECT a.id " + "FROM moz_bookmarks a, moz_places h " + "WHERE h.url = ?1 AND a.fk = h.id and a.type = ?2 " + "ORDER BY MAX(COALESCE(a.lastModified, 0), a.dateAdded) DESC, a.id DESC"), + getter_AddRefs(mDBFindURIBookmarks)); NS_ENSURE_SUCCESS(rv, rv); + // 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. + // Results are kGetInfoIndex_* + + // mDBGetChildren: 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. + rv = dbConn->CreateStatement(NS_LITERAL_CSTRING( + "SELECT h.id, h.url, COALESCE(b.title, h.title), " + "h.rev_host, h.visit_count, " + SQL_STR_FRAGMENT_MAX_VISIT_DATE( "h.id" ) + ", f.url, null, b.id, " + "b.dateAdded, b.lastModified, " + "b.position, b.type, b.fk " + "FROM moz_bookmarks b " + "LEFT OUTER JOIN moz_places h ON b.fk = h.id " + "LEFT OUTER JOIN moz_favicons f ON h.favicon_id = f.id " + "WHERE b.parent = ?1 " + "ORDER BY b.position"), + getter_AddRefs(mDBGetChildren)); + NS_ENSURE_SUCCESS(rv, rv); + + // mDBFolderCount: count all of the children of a given folder + rv = dbConn->CreateStatement(NS_LITERAL_CSTRING("SELECT COUNT(*) FROM moz_bookmarks WHERE parent = ?1"), + getter_AddRefs(mDBFolderCount)); + NS_ENSURE_SUCCESS(rv, rv); + + rv = dbConn->CreateStatement(NS_LITERAL_CSTRING("SELECT position FROM moz_bookmarks WHERE id = ?1"), + getter_AddRefs(mDBGetItemIndex)); + NS_ENSURE_SUCCESS(rv, rv); + + rv = dbConn->CreateStatement(NS_LITERAL_CSTRING("SELECT id, fk, type FROM moz_bookmarks WHERE parent = ?1 AND position = ?2"), + getter_AddRefs(mDBGetChildAt)); + NS_ENSURE_SUCCESS(rv, rv); + + // get bookmark/folder/separator properties + rv = dbConn->CreateStatement(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 " + "FROM moz_bookmarks b " + "WHERE b.id = ?1"), + getter_AddRefs(mDBGetItemProperties)); + NS_ENSURE_SUCCESS(rv, rv); + + rv = dbConn->CreateStatement(NS_LITERAL_CSTRING( + "SELECT item_id FROM moz_items_annos " + "WHERE content = ?1 " + "LIMIT 1"), + getter_AddRefs(mDBGetItemIdForGUID)); + NS_ENSURE_SUCCESS(rv, rv); + + // mDBGetRedirectDestinations + // input = page ID, time threshold; output = unique ID input has redirected to + rv = dbConn->CreateStatement(NS_LITERAL_CSTRING( + "SELECT dest_v.place_id " + "FROM moz_historyvisits source_v " + "LEFT JOIN moz_historyvisits dest_v ON dest_v.from_visit = source_v.id " + "WHERE source_v.place_id = ?1 " + "AND source_v.visit_date >= ?2 " + "AND (dest_v.visit_type = 5 OR dest_v.visit_type = 6) " + "GROUP BY dest_v.place_id"), + getter_AddRefs(mDBGetRedirectDestinations)); + NS_ENSURE_SUCCESS(rv, rv); + + // mDBInsertBookmark + rv = dbConn->CreateStatement(NS_LITERAL_CSTRING("INSERT INTO moz_bookmarks " + "(fk, type, parent, position, title, dateAdded) " + "VALUES (?1, ?2, ?3, ?4, ?5, ?6)"), + getter_AddRefs(mDBInsertBookmark)); + NS_ENSURE_SUCCESS(rv, rv); + + // mDBIsBookmarkedInDatabase + // Just select position since it's just an int32 and may be faster. + // We don't actually care about the data, just whether there is any. + rv = DBConn()->CreateStatement(NS_LITERAL_CSTRING( + "SELECT position FROM moz_bookmarks WHERE fk = ?1 AND type = ?2"), + getter_AddRefs(mDBIsBookmarkedInDatabase)); + NS_ENSURE_SUCCESS(rv, rv); + + // mDBGetLastBookmarkID + rv = DBConn()->CreateStatement(NS_LITERAL_CSTRING( + "SELECT id " + "FROM moz_bookmarks " + "ORDER BY ROWID DESC " + "LIMIT 1"), + getter_AddRefs(mDBGetLastBookmarkID)); + + // mDBSetItemDateAdded + rv = dbConn->CreateStatement(NS_LITERAL_CSTRING("UPDATE moz_bookmarks SET dateAdded = ?1 WHERE id = ?2"), + getter_AddRefs(mDBSetItemDateAdded)); + NS_ENSURE_SUCCESS(rv, rv); + + // mDBSetItemLastModified + rv = dbConn->CreateStatement(NS_LITERAL_CSTRING("UPDATE moz_bookmarks SET lastModified = ?1 WHERE id = ?2"), + getter_AddRefs(mDBSetItemLastModified)); + NS_ENSURE_SUCCESS(rv, rv); + + // mDBSetItemIndex + rv = DBConn()->CreateStatement(NS_LITERAL_CSTRING("UPDATE moz_bookmarks SET position = ?2 WHERE id = ?1"), + getter_AddRefs(mDBSetItemIndex)); + NS_ENSURE_SUCCESS(rv, rv); + + FillBookmarksHash(); + + // must be last: This may cause bookmarks to be imported, which will exercise + // most of the bookmark system + + // get keyword text for bookmark id + rv = dbConn->CreateStatement(NS_LITERAL_CSTRING( + "SELECT k.keyword FROM moz_bookmarks b " + "JOIN moz_keywords k ON k.id = b.keyword_id " + "WHERE b.id = ?1"), + getter_AddRefs(mDBGetKeywordForBookmark)); + NS_ENSURE_SUCCESS(rv, rv); + // get keyword text for URI (must be a bookmarked URI) + rv = dbConn->CreateStatement(NS_LITERAL_CSTRING( + "SELECT k.keyword " + "FROM moz_places p " + "JOIN moz_bookmarks b ON b.fk = p.id " + "JOIN moz_keywords k ON k.id = b.keyword_id " + "WHERE p.url = ?1"), + getter_AddRefs(mDBGetKeywordForURI)); + NS_ENSURE_SUCCESS(rv, rv); + // get URI for keyword + rv = dbConn->CreateStatement(NS_LITERAL_CSTRING( + "SELECT p.url FROM moz_keywords k " + "JOIN moz_bookmarks b ON b.keyword_id = k.id " + "JOIN moz_places p ON b.fk = p.id " + "WHERE k.keyword = ?1"), + getter_AddRefs(mDBGetURIForKeyword)); + NS_ENSURE_SUCCESS(rv, rv); + + // generate a new GUID base for this session + nsCOMPtr uuidgen = do_GetService("@mozilla.org/uuid-generator;1", &rv); + NS_ENSURE_SUCCESS(rv, rv); + nsID GUID; + rv = uuidgen->GenerateUUIDInPlace(&GUID); + NS_ENSURE_SUCCESS(rv, rv); + char GUIDChars[NSID_LENGTH]; + GUID.ToProvidedString(GUIDChars); + CopyASCIItoUTF16(GUIDChars, mGUIDBase); + rv = InitRoots(); NS_ENSURE_SUCCESS(rv, rv); rv = transaction.Commit(); NS_ENSURE_SUCCESS(rv, rv); - // Add observers + // Temporary migration code for bug 396300 + nsCOMPtr moveUnfiledBookmarks; + rv = dbConn->CreateStatement(NS_LITERAL_CSTRING("UPDATE moz_bookmarks SET parent = ?1 WHERE type = ?2 AND parent=?3"), + getter_AddRefs(moveUnfiledBookmarks)); + rv = moveUnfiledBookmarks->BindInt64Parameter(0, mUnfiledRoot); + NS_ENSURE_SUCCESS(rv, rv); + rv = moveUnfiledBookmarks->BindInt32Parameter(1, TYPE_BOOKMARK); + NS_ENSURE_SUCCESS(rv, rv); + rv = moveUnfiledBookmarks->BindInt64Parameter(2, mRoot); + NS_ENSURE_SUCCESS(rv, rv); + rv = moveUnfiledBookmarks->Execute(); + NS_ENSURE_SUCCESS(rv, rv); + nsAnnotationService* annosvc = nsAnnotationService::GetAnnotationService(); NS_ENSURE_TRUE(annosvc, NS_ERROR_OUT_OF_MEMORY); - annosvc->AddObserver(this); // allows us to notify on title changes. MUST BE LAST so it is impossible // to fail after this call, or the history service will have a reference to // us and we won't go away. history->AddObserver(this, PR_FALSE); + annosvc->AddObserver(this); // DO NOT PUT STUFF HERE that can fail. See observer comment above. @@ -199,239 +385,6 @@ nsNavBookmarks::InitTables(mozIStorageConnection* aDBConn) } -// nsNavBookmarks::InitStatements -// -// Create common statements to query the database -nsresult -nsNavBookmarks::InitStatements() -{ - // mDBFindURIBookmarks - // NOTE: Do not modify the ORDER BY segment of the query, as certain - // features depend on it. See bug 398914 for an example. - nsresult rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "SELECT b.id " - "FROM moz_bookmarks b " - "JOIN ( " - "SELECT id FROM moz_places_temp " - "WHERE url = ?1 " - "UNION ALL " - "SELECT id FROM moz_places " - "WHERE url = ?1 " - "AND +id NOT IN (SELECT id FROM moz_places_temp) " - ") AS h ON b.fk = h.id " - "WHERE b.type = ?2 " - "ORDER BY MAX(IFNULL(b.lastModified, 0), b.dateAdded) DESC, b.id DESC"), - getter_AddRefs(mDBFindURIBookmarks)); - NS_ENSURE_SUCCESS(rv, rv); - - // 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. - // Results are kGetInfoIndex_* - - // mDBGetChildren: 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. - rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "SELECT * FROM ( " - "SELECT h.id, h.url, COALESCE(b.title, h.title), " - "h.rev_host, h.visit_count, " - SQL_STR_FRAGMENT_MAX_VISIT_DATE( "h.id" ) - ", f.url, null, b.id, b.dateAdded, b.lastModified, " - "b.position, b.type, b.fk " - "FROM moz_bookmarks b " - "JOIN moz_places_temp h ON b.fk = h.id " - "LEFT JOIN moz_favicons f ON h.favicon_id = f.id " - "WHERE b.parent = ?1 " - "UNION ALL " - "SELECT h.id, h.url, COALESCE(b.title, h.title), " - "h.rev_host, h.visit_count, " - SQL_STR_FRAGMENT_MAX_VISIT_DATE( "h.id" ) - ", f.url, null, b.id, b.dateAdded, b.lastModified, " - "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 " - "WHERE b.parent = ?1 " - "AND (b.fk ISNULL OR b.fk NOT IN (select id FROM moz_places_temp)) " - ") " - "ORDER BY 12 ASC"), /* position */ - getter_AddRefs(mDBGetChildren)); - NS_ENSURE_SUCCESS(rv, rv); - - // mDBFolderCount: count all of the children of a given folder - rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "SELECT COUNT(*) FROM moz_bookmarks WHERE parent = ?1"), - getter_AddRefs(mDBFolderCount)); - NS_ENSURE_SUCCESS(rv, rv); - - rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "SELECT position FROM moz_bookmarks WHERE id = ?1"), - getter_AddRefs(mDBGetItemIndex)); - NS_ENSURE_SUCCESS(rv, rv); - - rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "SELECT id, fk, type FROM moz_bookmarks WHERE parent = ?1 AND position = ?2"), - getter_AddRefs(mDBGetChildAt)); - NS_ENSURE_SUCCESS(rv, rv); - - // get bookmark/folder/separator properties - rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "SELECT b.id, " - "IFNULL( " - "(SELECT url FROM moz_places_temp " - "WHERE id = (SELECT fk FROM moz_bookmarks WHERE id = ?1)) " - ", " - "(SELECT url FROM moz_places " - "WHERE id = (SELECT fk FROM moz_bookmarks WHERE id = ?1)) " - "), b.title, b.position, b.fk, b.parent, b.type, b.folder_type, " - "b.dateAdded, b.lastModified " - "FROM moz_bookmarks b " - "WHERE b.id = ?1"), - getter_AddRefs(mDBGetItemProperties)); - NS_ENSURE_SUCCESS(rv, rv); - - rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "SELECT item_id FROM moz_items_annos " - "WHERE content = ?1 " - "LIMIT 1"), - getter_AddRefs(mDBGetItemIdForGUID)); - NS_ENSURE_SUCCESS(rv, rv); - - // mDBGetRedirectDestinations - // input = page ID, time threshold; output = unique ID input has redirected to - rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "SELECT DISTINCT dest_v.place_id " - "FROM moz_historyvisits_temp source_v " - "JOIN moz_historyvisits_temp dest_v ON dest_v.from_visit = source_v.id " - "WHERE source_v.place_id = ?1 " - "AND source_v.visit_date >= ?2 " - "AND dest_v.visit_type IN (") + - nsPrintfCString("%d,%d", - nsINavHistoryService::TRANSITION_REDIRECT_PERMANENT, - nsINavHistoryService::TRANSITION_REDIRECT_TEMPORARY) + - NS_LITERAL_CSTRING(") " - "UNION " - "SELECT DISTINCT dest_v.place_id " - "FROM moz_historyvisits_temp source_v " - "JOIN moz_historyvisits dest_v ON dest_v.from_visit = source_v.id " - "WHERE source_v.place_id = ?1 " - "AND source_v.visit_date >= ?2 " - "AND dest_v.visit_type IN (") + - nsPrintfCString("%d,%d", - nsINavHistoryService::TRANSITION_REDIRECT_PERMANENT, - nsINavHistoryService::TRANSITION_REDIRECT_TEMPORARY) + - NS_LITERAL_CSTRING(") " - "UNION " - "SELECT DISTINCT dest_v.place_id " - "FROM moz_historyvisits source_v " - "JOIN moz_historyvisits_temp dest_v ON dest_v.from_visit = source_v.id " - "WHERE source_v.place_id = ?1 " - "AND source_v.visit_date >= ?2 " - "AND dest_v.visit_type IN (") + - nsPrintfCString("%d,%d", - nsINavHistoryService::TRANSITION_REDIRECT_PERMANENT, - nsINavHistoryService::TRANSITION_REDIRECT_TEMPORARY) + - NS_LITERAL_CSTRING(") " - "UNION " - "SELECT DISTINCT dest_v.place_id " - "FROM moz_historyvisits source_v " - "JOIN moz_historyvisits dest_v ON dest_v.from_visit = source_v.id " - "WHERE source_v.place_id = ?1 " - "AND source_v.visit_date >= ?2 " - "AND dest_v.visit_type IN (") + - nsPrintfCString("%d,%d", - nsINavHistoryService::TRANSITION_REDIRECT_PERMANENT, - nsINavHistoryService::TRANSITION_REDIRECT_TEMPORARY) + - NS_LITERAL_CSTRING(") "), - getter_AddRefs(mDBGetRedirectDestinations)); - NS_ENSURE_SUCCESS(rv, rv); - - // mDBInsertBookmark - rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "INSERT INTO moz_bookmarks " - "(fk, type, parent, position, title, dateAdded) " - "VALUES (?1, ?2, ?3, ?4, ?5, ?6)"), - getter_AddRefs(mDBInsertBookmark)); - NS_ENSURE_SUCCESS(rv, rv); - - // mDBIsBookmarkedInDatabase - // Just select position since it's just an int32 and may be faster. - // We don't actually care about the data, just whether there is any. - rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "SELECT position FROM moz_bookmarks WHERE fk = ?1 AND type = ?2"), - getter_AddRefs(mDBIsBookmarkedInDatabase)); - NS_ENSURE_SUCCESS(rv, rv); - - // mDBGetLastBookmarkID - rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "SELECT id " - "FROM moz_bookmarks " - "ORDER BY ROWID DESC " - "LIMIT 1"), - getter_AddRefs(mDBGetLastBookmarkID)); - NS_ENSURE_SUCCESS(rv, rv); - - // mDBSetItemDateAdded - rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "UPDATE moz_bookmarks SET dateAdded = ?1 WHERE id = ?2"), - getter_AddRefs(mDBSetItemDateAdded)); - NS_ENSURE_SUCCESS(rv, rv); - - // mDBSetItemLastModified - rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "UPDATE moz_bookmarks SET lastModified = ?1 WHERE id = ?2"), - getter_AddRefs(mDBSetItemLastModified)); - NS_ENSURE_SUCCESS(rv, rv); - - // mDBSetItemIndex - rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "UPDATE moz_bookmarks SET position = ?2 WHERE id = ?1"), - getter_AddRefs(mDBSetItemIndex)); - NS_ENSURE_SUCCESS(rv, rv); - - // get keyword text for bookmark id - rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "SELECT k.keyword FROM moz_bookmarks b " - "JOIN moz_keywords k ON k.id = b.keyword_id " - "WHERE b.id = ?1"), - getter_AddRefs(mDBGetKeywordForBookmark)); - NS_ENSURE_SUCCESS(rv, rv); - // get keyword text for URI (must be a bookmarked URI) - rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "SELECT k.keyword " - "FROM ( " - "SELECT id FROM moz_places_temp " - "WHERE url = ?1 " - "UNION ALL " - "SELECT id FROM moz_places " - "WHERE +id NOT IN (SELECT id FROM moz_places_temp) " - "AND url = ?1 " - ") AS h " - "JOIN moz_bookmarks b ON b.fk = h.id " - "JOIN moz_keywords k ON k.id = b.keyword_id"), - getter_AddRefs(mDBGetKeywordForURI)); - NS_ENSURE_SUCCESS(rv, rv); - - // get URI for keyword - rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "SELECT url FROM moz_keywords k " - "JOIN moz_bookmarks b ON b.keyword_id = k.id " - "JOIN moz_places_temp h ON b.fk = h.id " - "WHERE k.keyword = ?1 " - "UNION ALL " - "SELECT url FROM moz_keywords k " - "JOIN moz_bookmarks b ON b.keyword_id = k.id " - "JOIN moz_places h ON b.fk = h.id " - "WHERE k.keyword = ?1 " - "AND h.id NOT IN (SELECT id FROM moz_places_temp)"), - getter_AddRefs(mDBGetURIForKeyword)); - NS_ENSURE_SUCCESS(rv, rv); - - return NS_OK; -} - - // nsNavBookmarks::InitRoots // // This locates and creates if necessary the root items in the bookmarks @@ -457,9 +410,8 @@ nsresult nsNavBookmarks::InitRoots() { nsCOMPtr getRootStatement; - nsresult rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "SELECT folder_id FROM moz_bookmarks_roots WHERE root_name = ?1"), - getter_AddRefs(getRootStatement)); + nsresult rv = DBConn()->CreateStatement(NS_LITERAL_CSTRING("SELECT folder_id FROM moz_bookmarks_roots WHERE root_name = ?1"), + getter_AddRefs(getRootStatement)); NS_ENSURE_SUCCESS(rv, rv); PRBool createdPlacesRoot = PR_FALSE; @@ -486,9 +438,8 @@ nsNavBookmarks::InitRoots() &folders); if (folders.Length() > 0) { nsCOMPtr moveItems; - rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "UPDATE moz_bookmarks SET parent = ?1 WHERE parent=?2"), - getter_AddRefs(moveItems)); + rv = DBConn()->CreateStatement(NS_LITERAL_CSTRING("UPDATE moz_bookmarks SET parent = ?1 WHERE parent=?2"), + getter_AddRefs(moveItems)); rv = moveItems->BindInt64Parameter(0, mToolbarFolder); NS_ENSURE_SUCCESS(rv, rv); rv = moveItems->BindInt64Parameter(1, folders[0]); @@ -538,37 +489,34 @@ nsNavBookmarks::InitRoots() nsresult nsNavBookmarks::InitDefaults() { - nsIStringBundle *bundle = History()->GetBundle(); - NS_ENSURE_TRUE(bundle, NS_ERROR_OUT_OF_MEMORY); - // Bookmarks Menu nsXPIDLString bookmarksTitle; - nsresult rv = bundle->GetStringFromName(NS_LITERAL_STRING("BookmarksMenuFolderTitle").get(), - getter_Copies(bookmarksTitle)); + nsresult rv = mBundle->GetStringFromName(NS_LITERAL_STRING("BookmarksMenuFolderTitle").get(), + getter_Copies(bookmarksTitle)); NS_ENSURE_SUCCESS(rv, rv); rv = SetItemTitle(mBookmarksRoot, NS_ConvertUTF16toUTF8(bookmarksTitle)); NS_ENSURE_SUCCESS(rv, rv); // Bookmarks Toolbar nsXPIDLString toolbarTitle; - rv = bundle->GetStringFromName(NS_LITERAL_STRING("BookmarksToolbarFolderTitle").get(), - getter_Copies(toolbarTitle)); + rv = mBundle->GetStringFromName(NS_LITERAL_STRING("BookmarksToolbarFolderTitle").get(), + getter_Copies(toolbarTitle)); NS_ENSURE_SUCCESS(rv, rv); rv = SetItemTitle(mToolbarFolder, NS_ConvertUTF16toUTF8(toolbarTitle)); NS_ENSURE_SUCCESS(rv, rv); // Unsorted Bookmarks nsXPIDLString unfiledTitle; - rv = bundle->GetStringFromName(NS_LITERAL_STRING("UnsortedBookmarksFolderTitle").get(), - getter_Copies(unfiledTitle)); + rv = mBundle->GetStringFromName(NS_LITERAL_STRING("UnsortedBookmarksFolderTitle").get(), + getter_Copies(unfiledTitle)); NS_ENSURE_SUCCESS(rv, rv); rv = SetItemTitle(mUnfiledRoot, NS_ConvertUTF16toUTF8(unfiledTitle)); NS_ENSURE_SUCCESS(rv, rv); // Tags nsXPIDLString tagsTitle; - rv = bundle->GetStringFromName(NS_LITERAL_STRING("TagsFolderTitle").get(), - getter_Copies(tagsTitle)); + rv = mBundle->GetStringFromName(NS_LITERAL_STRING("TagsFolderTitle").get(), + getter_Copies(tagsTitle)); NS_ENSURE_SUCCESS(rv, rv); rv = SetItemTitle(mTagRoot, NS_ConvertUTF16toUTF8(tagsTitle)); NS_ENSURE_SUCCESS(rv, rv); @@ -612,9 +560,8 @@ nsNavBookmarks::CreateRoot(mozIStorageStatement* aGetRootStatement, NS_ENSURE_SUCCESS(rv, rv); // save root ID - rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "INSERT INTO moz_bookmarks_roots (root_name, folder_id) VALUES (?1, ?2)"), - getter_AddRefs(insertStatement)); + rv = DBConn()->CreateStatement(NS_LITERAL_CSTRING("INSERT INTO moz_bookmarks_roots (root_name, folder_id) VALUES (?1, ?2)"), + getter_AddRefs(insertStatement)); NS_ENSURE_SUCCESS(rv, rv); rv = insertStatement->BindUTF8StringParameter(0, name); NS_ENSURE_SUCCESS(rv, rv); @@ -646,7 +593,7 @@ nsNavBookmarks::FillBookmarksHash() // first populate the table with all bookmarks nsCOMPtr statement; - nsresult rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( + nsresult rv = DBConn()->CreateStatement(NS_LITERAL_CSTRING( "SELECT h.id " "FROM moz_bookmarks b " "LEFT JOIN moz_places h ON b.fk = h.id where b.type = ?1"), @@ -667,50 +614,14 @@ nsNavBookmarks::FillBookmarksHash() // visit (v1) -> destination visit (v2) // This should catch most redirects, which are only one level. More levels of // redirection will be handled separately. - rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( + rv = DBConn()->CreateStatement(NS_LITERAL_CSTRING( "SELECT v1.place_id, v2.place_id " - "FROM moz_bookmarks b " - "LEFT JOIN moz_historyvisits_temp v1 on b.fk = v1.place_id " - "LEFT JOIN moz_historyvisits v2 on v2.from_visit = v1.id " - "WHERE b.fk IS NOT NULL AND b.type = ?1 " - "AND v2.visit_type IN (") + - nsPrintfCString("%d,%d", - nsINavHistoryService::TRANSITION_REDIRECT_PERMANENT, - nsINavHistoryService::TRANSITION_REDIRECT_TEMPORARY) + - NS_LITERAL_CSTRING(") GROUP BY v2.place_id " - "UNION " - "SELECT v1.place_id, v2.place_id " - "FROM moz_bookmarks b " - "LEFT JOIN moz_historyvisits v1 on b.fk = v1.place_id " - "LEFT JOIN moz_historyvisits_temp v2 on v2.from_visit = v1.id " - "WHERE b.fk IS NOT NULL AND b.type = ?1 " - "AND v2.visit_type IN (") + - nsPrintfCString("%d,%d", - nsINavHistoryService::TRANSITION_REDIRECT_PERMANENT, - nsINavHistoryService::TRANSITION_REDIRECT_TEMPORARY) + - NS_LITERAL_CSTRING(") GROUP BY v2.place_id " - "UNION " - "SELECT v1.place_id, v2.place_id " - "FROM moz_bookmarks b " - "LEFT JOIN moz_historyvisits v1 on b.fk = v1.place_id " - "LEFT JOIN moz_historyvisits v2 on v2.from_visit = v1.id " - "WHERE b.fk IS NOT NULL AND b.type = ?1 " - "AND v2.visit_type IN (") + - nsPrintfCString("%d,%d", - nsINavHistoryService::TRANSITION_REDIRECT_PERMANENT, - nsINavHistoryService::TRANSITION_REDIRECT_TEMPORARY) + - NS_LITERAL_CSTRING(") GROUP BY v2.place_id " - "UNION " - "SELECT v1.place_id, v2.place_id " - "FROM moz_bookmarks b " - "LEFT JOIN moz_historyvisits_temp v1 on b.fk = v1.place_id " - "LEFT JOIN moz_historyvisits_temp v2 on v2.from_visit = v1.id " - "WHERE b.fk IS NOT NULL AND b.type = ?1 " - "AND v2.visit_type IN (") + - nsPrintfCString("%d,%d", - nsINavHistoryService::TRANSITION_REDIRECT_PERMANENT, - nsINavHistoryService::TRANSITION_REDIRECT_TEMPORARY) + - NS_LITERAL_CSTRING(") GROUP BY v2.place_id "), + "FROM moz_bookmarks b " + "LEFT JOIN moz_historyvisits v1 on b.fk = v1.place_id " + "LEFT JOIN moz_historyvisits v2 on v2.from_visit = v1.id " + "WHERE b.fk IS NOT NULL AND b.type = ?1 " + "AND v2.visit_type = 5 OR v2.visit_type = 6 " // perm. or temp. RDRs + "GROUP BY v2.place_id"), getter_AddRefs(statement)); NS_ENSURE_SUCCESS(rv, rv); rv = statement->BindInt64Parameter(0, TYPE_BOOKMARK); @@ -900,7 +811,7 @@ nsNavBookmarks::AdjustIndices(PRInt64 aFolder, buffer.AppendInt(aEndIndex); } - nsresult rv = mDBConn->ExecuteSimpleSQL(buffer); + nsresult rv = DBConn()->ExecuteSimpleSQL(buffer); NS_ENSURE_SUCCESS(rv, rv); return NS_OK; @@ -951,7 +862,8 @@ nsNavBookmarks::InsertBookmark(PRInt64 aFolder, nsIURI *aItem, PRInt32 aIndex, return NS_ERROR_INVALID_ARG; NS_ENSURE_ARG_POINTER(aNewBookmarkId); - mozStorageTransaction transaction(mDBConn, PR_FALSE); + mozIStorageConnection *dbConn = DBConn(); + mozStorageTransaction transaction(dbConn, PR_FALSE); // This is really a place ID PRInt64 childID; @@ -1112,7 +1024,8 @@ nsNavBookmarks::RemoveItem(PRInt64 aItemId) return NS_OK; } - mozStorageTransaction transaction(mDBConn, PR_FALSE); + mozIStorageConnection *dbConn = DBConn(); + mozStorageTransaction transaction(dbConn, PR_FALSE); // First, remove item annotations nsAnnotationService* annosvc = nsAnnotationService::GetAnnotationService(); @@ -1123,7 +1036,7 @@ nsNavBookmarks::RemoveItem(PRInt64 aItemId) buffer.AssignLiteral("DELETE FROM moz_bookmarks WHERE id = "); buffer.AppendInt(aItemId); - rv = mDBConn->ExecuteSimpleSQL(buffer); + rv = dbConn->ExecuteSimpleSQL(buffer); NS_ENSURE_SUCCESS(rv, rv); if (childIndex != -1) { @@ -1248,7 +1161,8 @@ nsNavBookmarks::CreateContainerWithID(PRInt64 aItemId, PRInt64 aParent, if (*aIndex < -1) return NS_ERROR_INVALID_ARG; - mozStorageTransaction transaction(mDBConn, PR_FALSE); + mozIStorageConnection *dbConn = DBConn(); + mozStorageTransaction transaction(dbConn, PR_FALSE); PRInt32 index; nsresult rv; @@ -1262,19 +1176,13 @@ nsNavBookmarks::CreateContainerWithID(PRInt64 aItemId, PRInt64 aParent, nsCOMPtr statement; if (aItemId == -1) { - rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "INSERT INTO moz_bookmarks " - "(title, type, parent, position, folder_type, dateAdded) " - "VALUES (?1, ?2, ?3, ?4, ?5, ?6)"), - getter_AddRefs(statement)); + rv = dbConn->CreateStatement(NS_LITERAL_CSTRING("INSERT INTO moz_bookmarks (title, type, parent, position, folder_type, dateAdded) VALUES (?1, ?2, ?3, ?4, ?5, ?6)"), + getter_AddRefs(statement)); NS_ENSURE_SUCCESS(rv, rv); } else { - rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "INSERT INTO moz_bookmarks " - "(id, title, type, parent, position, folder_type, dateAdded) " - "VALUES (?7, ?1, ?2, ?3, ?4, ?5, ?6)"), - getter_AddRefs(statement)); + rv = dbConn->CreateStatement(NS_LITERAL_CSTRING("INSERT INTO moz_bookmarks (id, title, type, parent, position, folder_type, dateAdded) VALUES (?7, ?1, ?2, ?3, ?4, ?5, ?6)"), + getter_AddRefs(statement)); NS_ENSURE_SUCCESS(rv, rv); rv = statement->BindInt64Parameter(6, aItemId); @@ -1338,7 +1246,8 @@ nsNavBookmarks::InsertSeparator(PRInt64 aParent, PRInt32 aIndex, if (aIndex < -1) return NS_ERROR_INVALID_ARG; - mozStorageTransaction transaction(mDBConn, PR_FALSE); + mozIStorageConnection *dbConn = DBConn(); + mozStorageTransaction transaction(dbConn, PR_FALSE); PRInt32 index; nsresult rv; @@ -1351,10 +1260,9 @@ nsNavBookmarks::InsertSeparator(PRInt64 aParent, PRInt32 aIndex, } nsCOMPtr statement; - rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "INSERT INTO moz_bookmarks " - "(type, parent, position, dateAdded) VALUES (?1, ?2, ?3, ?4)"), - getter_AddRefs(statement)); + rv = dbConn->CreateStatement(NS_LITERAL_CSTRING("INSERT INTO moz_bookmarks " + "(type, parent, position, dateAdded) VALUES (?1, ?2, ?3, ?4)"), + getter_AddRefs(statement)); NS_ENSURE_SUCCESS(rv, rv); rv = statement->BindInt64Parameter(0, TYPE_SEPARATOR); @@ -1395,8 +1303,10 @@ nsNavBookmarks::InsertSeparator(PRInt64 aParent, PRInt32 aIndex, nsresult nsNavBookmarks::GetLastChildId(PRInt64 aFolder, PRInt64* aItemId) { + mozIStorageConnection *dbConn = DBConn(); + nsCOMPtr statement; - nsresult rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( + nsresult rv = dbConn->CreateStatement(NS_LITERAL_CSTRING( "SELECT id FROM moz_bookmarks WHERE parent = ?1 " "ORDER BY position DESC LIMIT 1"), getter_AddRefs(statement)); NS_ENSURE_SUCCESS(rv, rv); @@ -1450,7 +1360,8 @@ nsNavBookmarks::GetIdForItemAt(PRInt64 aFolder, PRInt32 aIndex, PRInt64* aItemId NS_IMETHODIMP nsNavBookmarks::RemoveChildAt(PRInt64 aParent, PRInt32 aIndex) { - mozStorageTransaction transaction(mDBConn, PR_FALSE); + mozIStorageConnection *dbConn = DBConn(); + mozStorageTransaction transaction(dbConn, PR_FALSE); nsresult rv; PRInt64 id; PRInt32 type; @@ -1500,7 +1411,7 @@ nsNavBookmarks::GetParentAndIndexOfFolder(PRInt64 aFolder, PRInt64* aParent, buffer.AppendInt(aFolder); nsCOMPtr statement; - nsresult rv = mDBConn->CreateStatement(buffer, getter_AddRefs(statement)); + nsresult rv = DBConn()->CreateStatement(buffer, getter_AddRefs(statement)); NS_ENSURE_SUCCESS(rv, rv); PRBool results; @@ -1519,7 +1430,8 @@ nsNavBookmarks::GetParentAndIndexOfFolder(PRInt64 aFolder, PRInt64* aParent, NS_IMETHODIMP nsNavBookmarks::RemoveFolder(PRInt64 aFolderId) { - mozStorageTransaction transaction(mDBConn, PR_FALSE); + mozIStorageConnection *dbConn = DBConn(); + mozStorageTransaction transaction(dbConn, PR_FALSE); nsresult rv; @@ -1574,7 +1486,7 @@ nsNavBookmarks::RemoveFolder(PRInt64 aFolderId) nsCAutoString buffer; buffer.AssignLiteral("DELETE FROM moz_bookmarks WHERE id = "); buffer.AppendInt(aFolderId); - rv = mDBConn->ExecuteSimpleSQL(buffer); + rv = dbConn->ExecuteSimpleSQL(buffer); NS_ENSURE_SUCCESS(rv, rv); rv = AdjustIndices(parent, index + 1, PR_INT32_MAX, -1); @@ -1616,7 +1528,7 @@ nsNavBookmarks::GetRemoveFolderTransaction(PRInt64 aFolder, nsITransaction** aRe NS_IMETHODIMP nsNavBookmarks::RemoveFolderChildren(PRInt64 aFolder) { - mozStorageTransaction transaction(mDBConn, PR_FALSE); + mozStorageTransaction transaction(DBConn(), PR_FALSE); nsTArray folderChildren; nsTArray itemChildren; // bookmarks / separators @@ -1669,7 +1581,8 @@ nsNavBookmarks::MoveItem(PRInt64 aItemId, PRInt64 aNewParent, PRInt32 aIndex) if (aItemId == aNewParent) return NS_ERROR_INVALID_ARG; - mozStorageTransaction transaction(mDBConn, PR_FALSE); + mozIStorageConnection *dbConn = DBConn(); + mozStorageTransaction transaction(dbConn, PR_FALSE); // get item properties nsresult rv; @@ -1787,7 +1700,7 @@ nsNavBookmarks::MoveItem(PRInt64 aItemId, PRInt64 aNewParent, PRInt32 aIndex) } buffer.AppendLiteral(" WHERE id = "); buffer.AppendInt(aItemId); - rv = mDBConn->ExecuteSimpleSQL(buffer); + rv = dbConn->ExecuteSimpleSQL(buffer); NS_ENSURE_SUCCESS(rv, rv); PRTime now = PR_Now(); @@ -1833,7 +1746,7 @@ nsNavBookmarks::GetChildFolder(PRInt64 aFolder, const nsAString& aSubFolder, nsPrintfCString("%d", TYPE_FOLDER) + NS_LITERAL_CSTRING(" AND title = ?2"); nsCOMPtr statement; - rv = mDBConn->CreateStatement(getChildFolderQuery, getter_AddRefs(statement)); + rv = DBConn()->CreateStatement(getChildFolderQuery, getter_AddRefs(statement)); NS_ENSURE_SUCCESS(rv, rv); statement->BindInt64Parameter(0, aFolder); statement->BindStringParameter(1, aSubFolder); @@ -1931,28 +1844,6 @@ nsNavBookmarks::GetItemLastModified(PRInt64 aItemId, PRTime *aLastModified) return mDBGetItemProperties->GetInt64(kGetItemPropertiesIndex_LastModified, aLastModified); } -nsresult -nsNavBookmarks::GetGUIDBase(nsAString &aGUIDBase) -{ - if (!mGUIDBase.IsEmpty()) { - aGUIDBase = mGUIDBase; - return NS_OK; - } - - // generate a new GUID base for this session - nsCOMPtr uuidgen = - do_GetService("@mozilla.org/uuid-generator;1"); - NS_ENSURE_TRUE(uuidgen, NS_ERROR_OUT_OF_MEMORY); - nsID GUID; - nsresult rv = uuidgen->GenerateUUIDInPlace(&GUID); - NS_ENSURE_SUCCESS(rv, rv); - char GUIDChars[NSID_LENGTH]; - GUID.ToProvidedString(GUIDChars); - CopyASCIItoUTF16(GUIDChars, mGUIDBase); - aGUIDBase = mGUIDBase; - return NS_OK; -} - NS_IMETHODIMP nsNavBookmarks::GetItemGUID(PRInt64 aItemId, nsAString &aGUID) { @@ -1966,10 +1857,7 @@ nsNavBookmarks::GetItemGUID(PRInt64 aItemId, nsAString &aGUID) nsAutoString tmp; tmp.AppendInt(mItemCount++); aGUID.SetCapacity(NSID_LENGTH - 1 + tmp.Length()); - nsString GUIDBase; - rv = GetGUIDBase(GUIDBase); - NS_ENSURE_SUCCESS(rv, rv); - aGUID.Assign(GUIDBase); + aGUID.Assign(mGUIDBase); aGUID.Append(tmp); return SetItemGUID(aItemId, aGUID); @@ -2010,8 +1898,10 @@ nsNavBookmarks::GetItemIdForGUID(const nsAString &aGUID, PRInt64 *aItemId) NS_IMETHODIMP nsNavBookmarks::SetItemTitle(PRInt64 aItemId, const nsACString &aTitle) { + mozIStorageConnection *dbConn = DBConn(); + nsCOMPtr statement; - nsresult rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( + nsresult rv = dbConn->CreateStatement(NS_LITERAL_CSTRING( "UPDATE moz_bookmarks SET title = ?1, lastModified = ?2 WHERE id = ?3"), getter_AddRefs(statement)); NS_ENSURE_SUCCESS(rv, rv); @@ -2341,7 +2231,8 @@ nsNavBookmarks::ChangeBookmarkURI(PRInt64 aBookmarkId, nsIURI *aNewURI) { NS_ENSURE_ARG(aNewURI); - mozStorageTransaction transaction(mDBConn, PR_FALSE); + mozIStorageConnection *dbConn = DBConn(); + mozStorageTransaction transaction(dbConn, PR_FALSE); PRInt64 placeId; nsresult rv = History()->GetUrlIdFor(aNewURI, &placeId, PR_TRUE); @@ -2350,9 +2241,8 @@ nsNavBookmarks::ChangeBookmarkURI(PRInt64 aBookmarkId, nsIURI *aNewURI) return NS_ERROR_INVALID_ARG; nsCOMPtr statement; - rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "UPDATE moz_bookmarks SET fk = ?1 WHERE id = ?2"), - getter_AddRefs(statement)); + rv = dbConn->CreateStatement(NS_LITERAL_CSTRING("UPDATE moz_bookmarks SET fk = ?1 WHERE id = ?2"), + getter_AddRefs(statement)); statement->BindInt64Parameter(0, placeId); statement->BindInt64Parameter(1, aBookmarkId); @@ -2526,7 +2416,7 @@ nsNavBookmarks::SetKeywordForBookmark(PRInt64 aBookmarkId, const nsAString& aKey nsAutoString kwd(aKeyword); ToLowerCase(kwd); - mozStorageTransaction transaction(mDBConn, PR_FALSE); + mozStorageTransaction transaction(DBConn(), PR_FALSE); nsresult rv; PRBool results; PRInt64 keywordId = 0; @@ -2534,8 +2424,8 @@ nsNavBookmarks::SetKeywordForBookmark(PRInt64 aBookmarkId, const nsAString& aKey if (!kwd.IsEmpty()) { // Attempt to find pre-existing keyword record nsCOMPtr getKeywordStmnt; - rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "SELECT id from moz_keywords WHERE keyword = ?1"), + rv = DBConn()->CreateStatement(NS_LITERAL_CSTRING( + "SELECT id from moz_keywords WHERE keyword = ?1"), getter_AddRefs(getKeywordStmnt)); NS_ENSURE_SUCCESS(rv, rv); rv = getKeywordStmnt->BindStringParameter(0, kwd); @@ -2551,7 +2441,7 @@ nsNavBookmarks::SetKeywordForBookmark(PRInt64 aBookmarkId, const nsAString& aKey else { // If not already in the db, create new keyword record nsCOMPtr addKeywordStmnt; - rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( + rv = DBConn()->CreateStatement(NS_LITERAL_CSTRING( "INSERT INTO moz_keywords (keyword) VALUES (?1)"), getter_AddRefs(addKeywordStmnt)); NS_ENSURE_SUCCESS(rv, rv); @@ -2561,7 +2451,7 @@ nsNavBookmarks::SetKeywordForBookmark(PRInt64 aBookmarkId, const nsAString& aKey NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr idStmt; - rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( + rv = DBConn()->CreateStatement(NS_LITERAL_CSTRING( "SELECT id " "FROM moz_keywords " "ORDER BY ROWID DESC " @@ -2579,7 +2469,7 @@ nsNavBookmarks::SetKeywordForBookmark(PRInt64 aBookmarkId, const nsAString& aKey // Update bookmark record w/ the keyword's id, or null nsCOMPtr updateKeywordStmnt; - rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( + rv = DBConn()->CreateStatement(NS_LITERAL_CSTRING( "UPDATE moz_bookmarks SET keyword_id = ?1 WHERE id = ?2"), getter_AddRefs(updateKeywordStmnt)); NS_ENSURE_SUCCESS(rv, rv); @@ -2675,7 +2565,7 @@ nsresult nsNavBookmarks::BeginUpdateBatch() { if (mBatchLevel++ == 0) { - mozIStorageConnection* conn = mDBConn; + mozIStorageConnection* conn = DBConn(); PRBool transactionInProgress = PR_TRUE; // default to no transaction on err conn->GetTransactionInProgress(&transactionInProgress); mBatchHasTransaction = ! transactionInProgress; @@ -2693,7 +2583,7 @@ nsNavBookmarks::EndUpdateBatch() { if (--mBatchLevel == 0) { if (mBatchHasTransaction) - mDBConn->CommitTransaction(); + DBConn()->CommitTransaction(); mBatchHasTransaction = PR_FALSE; ENUMERATE_WEAKARRAY(mObservers, nsINavBookmarkObserver, OnEndUpdateBatch()) diff --git a/toolkit/components/places/src/nsNavBookmarks.h b/toolkit/components/places/src/nsNavBookmarks.h index f968832d5f71..e165ec8176d2 100644 --- a/toolkit/components/places/src/nsNavBookmarks.h +++ b/toolkit/components/places/src/nsNavBookmarks.h @@ -41,6 +41,7 @@ #include "nsINavBookmarksService.h" #include "nsIAnnotationService.h" +#include "nsIStringBundle.h" #include "nsITransaction.h" #include "nsNavHistory.h" #include "nsNavHistoryResult.h" // need for Int64 hashtable @@ -111,7 +112,6 @@ private: nsresult InitRoots(); nsresult InitDefaults(); - nsresult InitStatements(); nsresult CreateRoot(mozIStorageStatement* aGetRootStatement, const nsCString& name, PRInt64* aID, PRInt64 aParentID, PRBool* aWasCreated); @@ -127,11 +127,12 @@ private: // remove me when there is better query initialization nsNavHistory* History() { return nsNavHistory::GetHistoryService(); } - nsCOMPtr mDBConn; + mozIStorageStatement* DBGetURLPageInfo() + { return History()->DBGetURLPageInfo(); } + + mozIStorageConnection* DBConn() { return History()->GetStorageConnection(); } nsString mGUIDBase; - nsresult GetGUIDBase(nsAString& aGUIDBase); - PRInt32 mItemCount; nsMaybeWeakPtrArray mObservers; @@ -212,6 +213,8 @@ private: nsCOMPtr mDBGetKeywordForBookmark; nsCOMPtr mDBGetURIForKeyword; + nsCOMPtr mBundle; + class RemoveFolderTransaction : public nsITransaction { public: RemoveFolderTransaction(PRInt64 aID) : mID(aID) {} diff --git a/toolkit/components/places/src/nsNavHistory.cpp b/toolkit/components/places/src/nsNavHistory.cpp index 11d8440ba32f..29815d92930a 100644 --- a/toolkit/components/places/src/nsNavHistory.cpp +++ b/toolkit/components/places/src/nsNavHistory.cpp @@ -433,8 +433,6 @@ nsNavHistory::Init() // session of the last visited page because we do have indices over dates. // We still do MAX(session) in case there are duplicate sessions for the same // date, but there will generally be very few (1) of these. - // This is long before we use our temporary tables, so we do not have to join - // on moz_historyvisits_temp to get the right result here. { nsCOMPtr selectSession; rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( @@ -450,6 +448,32 @@ nsNavHistory::Init() mLastSessionID = 1; } + // string bundle for localization + nsCOMPtr bundleService = + do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + rv = bundleService->CreateBundle( + "chrome://places/locale/places.properties", + getter_AddRefs(mBundle)); + NS_ENSURE_SUCCESS(rv, rv); + + // locale + nsCOMPtr ls = do_GetService(NS_LOCALESERVICE_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + rv = ls->GetApplicationLocale(getter_AddRefs(mLocale)); + NS_ENSURE_SUCCESS(rv, rv); + + // collation + nsCOMPtr cfact = do_CreateInstance( + NS_COLLATIONFACTORY_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + rv = cfact->CreateCollation(mLocale, getter_AddRefs(mCollation)); + NS_ENSURE_SUCCESS(rv, rv); + + // date formatter + mDateFormatter = do_CreateInstance(NS_DATETIMEFORMAT_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + // initialize idle timer InitializeIdleTimer(); @@ -620,7 +644,7 @@ nsNavHistory::InitDBFile(PRBool aForceInit) // -#define PLACES_SCHEMA_VERSION 8 +#define PLACES_SCHEMA_VERSION 7 nsresult nsNavHistory::InitDB(PRInt16 *aMadeChanges) @@ -712,13 +736,7 @@ nsNavHistory::InitDB(PRInt16 *aMadeChanges) NS_ENSURE_SUCCESS(rv, rv); } - // Migrate historyvisits up to V8 - if (DBSchemaVersion < 8) { - rv = MigrateV8Up(mDBConn); - NS_ENSURE_SUCCESS(rv, rv); - } - - // XXX Upgrades >V8 must add migration code here. + // XXX Upgrades >V7 must add migration code here. } else { // Downgrading @@ -836,6 +854,12 @@ nsNavHistory::InitDB(PRInt16 *aMadeChanges) rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( "CREATE INDEX moz_historyvisits_dateindex ON moz_historyvisits (visit_date)")); NS_ENSURE_SUCCESS(rv, rv); + + // Create our triggers for this table + rv = mDBConn->ExecuteSimpleSQL(CREATE_VISIT_COUNT_INSERT_TRIGGER); + NS_ENSURE_SUCCESS(rv, rv); + rv = mDBConn->ExecuteSimpleSQL(CREATE_VISIT_COUNT_DELETE_TRIGGER); + NS_ENSURE_SUCCESS(rv, rv); } // moz_inputhistory @@ -859,10 +883,6 @@ nsNavHistory::InitDB(PRInt16 *aMadeChanges) // DO NOT PUT ANY SCHEMA-MODIFYING THINGS HERE - rv = InitTempTables(); - NS_ENSURE_SUCCESS(rv, rv); - rv = InitViews(); - NS_ENSURE_SUCCESS(rv, rv); rv = InitFunctions(); NS_ENSURE_SUCCESS(rv, rv); rv = InitStatements(); @@ -941,94 +961,6 @@ NS_IMETHODIMP mozStorageFunctionGetUnreversedHost::OnFunctionCall( return NS_OK; } -nsresult -nsNavHistory::InitTempTables() -{ - nsresult rv; - - // moz_places_temp - rv = mDBConn->ExecuteSimpleSQL(CREATE_MOZ_PLACES_TEMP); - NS_ENSURE_SUCCESS(rv, rv); - - rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "CREATE UNIQUE INDEX moz_places_temp_url_uniqueindex ON moz_places_temp (url)")); - NS_ENSURE_SUCCESS(rv, rv); - - rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "CREATE INDEX moz_places_temp_faviconindex ON moz_places_temp (favicon_id)")); - NS_ENSURE_SUCCESS(rv, rv); - - rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "CREATE INDEX moz_places_temp_hostindex ON moz_places_temp (rev_host)")); - NS_ENSURE_SUCCESS(rv, rv); - - rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "CREATE INDEX moz_places_temp_visitcount ON moz_places_temp (visit_count)")); - NS_ENSURE_SUCCESS(rv, rv); - - rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "CREATE INDEX moz_places_temp_frecencyindex ON moz_places_temp (frecency)")); - NS_ENSURE_SUCCESS(rv, rv); - - rv = mDBConn->ExecuteSimpleSQL(CREATE_MOZ_PLACES_SYNC_TRIGGER); - NS_ENSURE_SUCCESS(rv, rv); - - - // moz_historyvisits_temp - rv = mDBConn->ExecuteSimpleSQL(CREATE_MOZ_HISTORYVISITS_TEMP); - NS_ENSURE_SUCCESS(rv, rv); - - rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "CREATE INDEX moz_historyvisits_temp_placedateindex " - "ON moz_historyvisits_temp (place_id, visit_date)")); - NS_ENSURE_SUCCESS(rv, rv); - - rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "CREATE INDEX moz_historyvisits_temp_fromindex " - "ON moz_historyvisits_temp (from_visit)")); - NS_ENSURE_SUCCESS(rv, rv); - - rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "CREATE INDEX moz_historyvisits_temp_dateindex " - "ON moz_historyvisits_temp (visit_date)")); - NS_ENSURE_SUCCESS(rv, rv); - - rv = mDBConn->ExecuteSimpleSQL(CREATE_MOZ_HISTORYVISITS_SYNC_TRIGGER); - NS_ENSURE_SUCCESS(rv, rv); - - return NS_OK; -} - -nsresult -nsNavHistory::InitViews() -{ - nsresult rv; - - // moz_places_view - rv = mDBConn->ExecuteSimpleSQL(CREATE_MOZ_PLACES_VIEW); - NS_ENSURE_SUCCESS(rv, rv); - - rv = mDBConn->ExecuteSimpleSQL(CREATE_PLACES_VIEW_INSERT_TRIGGER); - NS_ENSURE_SUCCESS(rv, rv); - rv = mDBConn->ExecuteSimpleSQL(CREATE_PLACES_VIEW_DELETE_TRIGGER); - NS_ENSURE_SUCCESS(rv, rv); - rv = mDBConn->ExecuteSimpleSQL(CREATE_PLACES_VIEW_UPDATE_TRIGGER); - NS_ENSURE_SUCCESS(rv, rv); - - // moz_historyvisits_view - rv = mDBConn->ExecuteSimpleSQL(CREATE_MOZ_HISTORYVISITS_VIEW); - NS_ENSURE_SUCCESS(rv, rv); - - rv = mDBConn->ExecuteSimpleSQL(CREATE_HISTORYVISITS_VIEW_INSERT_TRIGGER); - NS_ENSURE_SUCCESS(rv, rv); - rv = mDBConn->ExecuteSimpleSQL(CREATE_HISTORYVISITS_VIEW_DELETE_TRIGGER); - NS_ENSURE_SUCCESS(rv, rv); - rv = mDBConn->ExecuteSimpleSQL(CREATE_HISTORYVISITS_VIEW_UPDATE_TRIGGER); - NS_ENSURE_SUCCESS(rv, rv); - - return NS_OK; -} - nsresult nsNavHistory::InitFunctions() { @@ -1052,124 +984,62 @@ nsNavHistory::InitStatements() nsresult rv; // mDBGetURLPageInfo - // We are not checking for duplicated ids into the unified table - // for perf reasons, LIMIT 1 will discard duplicates faster since we - // have unique urls. rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "SELECT id, url, title, rev_host, visit_count " - "FROM moz_places_temp " - "WHERE url = ?1 " - "UNION ALL " - "SELECT id, url, title, rev_host, visit_count " - "FROM moz_places " - "WHERE url = ?1 " - "LIMIT 1"), + "SELECT h.id, h.url, h.title, h.rev_host, h.visit_count " + "FROM moz_places h " + "WHERE h.url = ?1"), getter_AddRefs(mDBGetURLPageInfo)); NS_ENSURE_SUCCESS(rv, rv); // mDBGetIdPageInfo - // 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. rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "SELECT id, url, title, rev_host, visit_count " - "FROM moz_places_temp " - "WHERE id = ?1 " - "UNION ALL " - "SELECT id, url, title, rev_host, visit_count " - "FROM moz_places " - "WHERE id = ?1 " - "LIMIT 1"), + "SELECT h.id, h.url, h.title, h.rev_host, h.visit_count " + "FROM moz_places h WHERE h.id = ?1"), getter_AddRefs(mDBGetIdPageInfo)); NS_ENSURE_SUCCESS(rv, rv); // mDBRecentVisitOfURL - // We are not checking for duplicated ids into the unified table - // for perf reasons, LIMIT 1 will discard duplicates faster since we - // expect visits in temp table being the most recent. rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "SELECT * FROM ( " - "SELECT v.id, v.session " - "FROM moz_historyvisits_temp v " - "WHERE v.place_id = IFNULL((SELECT id FROM moz_places_temp WHERE url = ?1), " - "(SELECT id FROM moz_places WHERE url = ?1)) " - "ORDER BY v.visit_date DESC LIMIT 1 " - ") " - "UNION ALL " - "SELECT * FROM ( " - "SELECT v.id, v.session " - "FROM moz_historyvisits v " - "WHERE v.place_id = IFNULL((SELECT id FROM moz_places_temp WHERE url = ?1), " - "(SELECT id FROM moz_places WHERE url = ?1)) " - "ORDER BY v.visit_date DESC LIMIT 1 " - ") " + "SELECT v.id, v.session " + "FROM moz_places h JOIN moz_historyvisits v ON h.id = v.place_id " + "WHERE h.url = ?1 " + "ORDER BY v.visit_date DESC " "LIMIT 1"), getter_AddRefs(mDBRecentVisitOfURL)); NS_ENSURE_SUCCESS(rv, rv); // mDBRecentVisitOfPlace - // We are not checking for duplicated ids into the unified table - // for perf reasons, LIMIT 1 will discard duplicates faster since we - // expect visits in temp table being the most recent. rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "SELECT id FROM moz_historyvisits_temp " + "SELECT id " + "FROM moz_historyvisits " "WHERE place_id = ?1 " - "AND visit_date = ?2 " - "AND session = ?3 " - "UNION ALL " - "SELECT id FROM moz_historyvisits " - "WHERE place_id = ?1 " - "AND visit_date = ?2 " - "AND session = ?3 " + "AND visit_date = ?2 " + "AND session = ?3 " "LIMIT 1"), getter_AddRefs(mDBRecentVisitOfPlace)); NS_ENSURE_SUCCESS(rv, rv); // mDBInsertVisit rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "INSERT INTO moz_historyvisits_view " - "(from_visit, place_id, visit_date, visit_type, session) " + "INSERT INTO moz_historyvisits " + "(from_visit, place_id, visit_date, visit_type, session) " "VALUES (?1, ?2, ?3, ?4, ?5)"), getter_AddRefs(mDBInsertVisit)); NS_ENSURE_SUCCESS(rv, rv); // mDBGetPageVisitStats (see InternalAdd) - // 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. rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "SELECT id, visit_count, typed, hidden " - "FROM moz_places_temp " - "WHERE url = ?1 " - "UNION ALL " "SELECT id, visit_count, typed, hidden " "FROM moz_places " - "WHERE url = ?1 " - "LIMIT 1"), + "WHERE url = ?1"), getter_AddRefs(mDBGetPageVisitStats)); NS_ENSURE_SUCCESS(rv, rv); // mDBIsPageVisited - // We are not checking for duplicated ids into the unified table - // for perf reasons, LIMIT 1 will discard duplicates faster since we - // only need to know if a visit exists. rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "SELECT h.id " - "FROM moz_places_temp h " - "WHERE url = ?1 " - "AND ( " - "EXISTS(SELECT id FROM moz_historyvisits_temp WHERE place_id = h.id LIMIT 1) " - "OR EXISTS(SELECT id FROM moz_historyvisits WHERE place_id = h.id LIMIT 1) " - ") " - "UNION ALL " - "SELECT h.id " - "FROM moz_places h " - "WHERE url = ?1 " - "AND ( " - "EXISTS(SELECT id FROM moz_historyvisits_temp WHERE place_id = h.id LIMIT 1) " - "OR EXISTS(SELECT id FROM moz_historyvisits WHERE place_id = h.id LIMIT 1) " - ") " - "LIMIT 1"), + "SELECT h.id FROM moz_places h WHERE h.url = ?1 " + "AND EXISTS " + "(SELECT id FROM moz_historyvisits WHERE place_id = h.id LIMIT 1)"), getter_AddRefs(mDBIsPageVisited)); NS_ENSURE_SUCCESS(rv, rv); @@ -1177,7 +1047,7 @@ nsNavHistory::InitStatements() // we don't need to update visit_count since it's maintained // in sync by triggers, and we must NEVER touch it rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "UPDATE moz_places_view " + "UPDATE moz_places " "SET hidden = ?2, typed = ?3 " "WHERE id = ?1"), getter_AddRefs(mDBUpdatePageVisitStats)); @@ -1185,43 +1055,79 @@ nsNavHistory::InitStatements() // mDBAddNewPage (see InternalAddNewPage) rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "INSERT OR REPLACE INTO moz_places_view " - "(url, title, rev_host, hidden, typed, frecency) " + "INSERT OR REPLACE INTO moz_places " + "(url, title, rev_host, hidden, typed, frecency) " "VALUES (?1, ?2, ?3, ?4, ?5, ?6)"), getter_AddRefs(mDBAddNewPage)); NS_ENSURE_SUCCESS(rv, rv); + // mDBVisitToURLResult, should match kGetInfoIndex_* (see GetQueryResults) + rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( + "SELECT h.id, h.url, h.title, h.rev_host, h.visit_count, " + SQL_STR_FRAGMENT_MAX_VISIT_DATE( "h.id" ) + ", f.url, null, null " + "FROM moz_places h " + "JOIN moz_historyvisits v ON h.id = v.place_id " + "LEFT OUTER JOIN moz_favicons f ON h.favicon_id = f.id " + "WHERE v.id = ?1"), + getter_AddRefs(mDBVisitToURLResult)); + NS_ENSURE_SUCCESS(rv, rv); + + // mDBVisitToVisitResult, should match kGetInfoIndex_* (see GetQueryResults) + rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( + "SELECT h.id, h.url, h.title, h.rev_host, h.visit_count, " + "v.visit_date, f.url, v.session, null " + "FROM moz_places h " + "JOIN moz_historyvisits v ON h.id = v.place_id " + "LEFT OUTER JOIN moz_favicons f ON h.favicon_id = f.id " + "WHERE v.id = ?1"), + getter_AddRefs(mDBVisitToVisitResult)); + NS_ENSURE_SUCCESS(rv, rv); + + // mDBUrlToURLResult, should match kGetInfoIndex_* + rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( + "SELECT h.id, h.url, h.title, h.rev_host, h.visit_count, " + SQL_STR_FRAGMENT_MAX_VISIT_DATE( "h.id" ) + ", f.url, null, null " + "FROM moz_places h " + "LEFT OUTER JOIN moz_favicons f ON h.favicon_id = f.id " + "WHERE h.url = ?1"), + getter_AddRefs(mDBUrlToUrlResult)); + NS_ENSURE_SUCCESS(rv, rv); + + // mDBBookmarkToUrlResult, should match kGetInfoIndex_* + rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( + "SELECT b.fk, h.url, COALESCE(b.title, h.title), " + "h.rev_host, h.visit_count, " + SQL_STR_FRAGMENT_MAX_VISIT_DATE( "b.fk" ) + ", f.url, null, b.id, b.dateAdded, b.lastModified " + "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 " + "WHERE b.id = ?1"), + getter_AddRefs(mDBBookmarkToUrlResult)); + NS_ENSURE_SUCCESS(rv, rv); + // mDBGetTags rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( "SELECT GROUP_CONCAT(t.title, ' ') " - "FROM moz_bookmarks b " - "JOIN moz_bookmarks t ON t.id = b.parent " - "WHERE b.fk = IFNULL((SELECT id FROM moz_places_temp WHERE url = ?2), " - "(SELECT id FROM moz_places WHERE url = ?2)) " - "AND b.type = ") + - nsPrintfCString("%d", nsINavBookmarksService::TYPE_BOOKMARK) + - NS_LITERAL_CSTRING(" AND t.parent = ?1 "), + "FROM moz_places h " + "JOIN moz_bookmarks b ON b.type = ") + + nsPrintfCString("%d", nsINavBookmarksService::TYPE_BOOKMARK) + + NS_LITERAL_CSTRING(" AND b.fk = h.id " + "JOIN moz_bookmarks t ON t.parent = ?1 AND t.id = b.parent " + "WHERE h.url = ?2"), getter_AddRefs(mDBGetTags)); NS_ENSURE_SUCCESS(rv, rv); // mFoldersWithAnnotationQuery rv = mDBConn->CreateStatement(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 = ?1"), + "SELECT annos.item_id, annos.content FROM moz_anno_attributes attrs " + "JOIN moz_items_annos annos ON attrs.id = annos.anno_attribute_id " + "WHERE attrs.name = ?1"), getter_AddRefs(mFoldersWithAnnotationQuery)); NS_ENSURE_SUCCESS(rv, rv); - // mDBSetPlaceTitle - rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "UPDATE moz_places_view " - "SET title = ?1 " - "WHERE url = ?2"), - getter_AddRefs(mDBSetPlaceTitle)); - NS_ENSURE_SUCCESS(rv, rv); - - // mDBVisitsForFrecency // NOTE: we are not limiting to visits with "visit_type NOT IN (0,4,7)" // because if we do that, mDBVisitsForFrecency would return no visits @@ -1231,64 +1137,82 @@ nsNavHistory::InitStatements() // for a place with only embedded visits, instead of a frecency of 0. If we // have a temporary or permanent redirect, calculate the frecency as if it // was the original page visited. - rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "SELECT COALESCE(r_t.visit_date, r.visit_date, v.visit_date) date, " - "COALESCE(r_t.visit_type, r.visit_type, v.visit_type) " - "FROM ( " - "SELECT visit_date, visit_type, from_visit FROM moz_historyvisits_temp " - "WHERE place_id = ?1 " - "UNION ALL " - "SELECT visit_date, visit_type, from_visit FROM moz_historyvisits " - "WHERE id NOT IN (SELECT id FROM moz_historyvisits_temp) " - "AND place_id = ?1 " - ") AS v " - "LEFT JOIN moz_historyvisits r ON r.id = v.from_visit " - "AND v.visit_type IN ") + - nsPrintfCString("(%d,%d) ", TRANSITION_REDIRECT_PERMANENT, - TRANSITION_REDIRECT_TEMPORARY) + NS_LITERAL_CSTRING( - "LEFT JOIN moz_historyvisits_temp r_t ON r_t.id = v.from_visit " - "AND v.visit_type IN ") + - nsPrintfCString("(%d,%d) ", TRANSITION_REDIRECT_PERMANENT, - TRANSITION_REDIRECT_TEMPORARY) + NS_LITERAL_CSTRING( - "ORDER BY date DESC LIMIT ") + - nsPrintfCString("%d", mNumVisitsForFrecency), + "SELECT IFNULL(r.visit_date, v.visit_date) date, IFNULL(r.visit_type, v.visit_type) " + "FROM moz_historyvisits v " + "LEFT OUTER JOIN moz_historyvisits r " + "ON r.id = v.from_visit AND v.visit_type IN ") + + nsPrintfCString("(%d,%d) ", TRANSITION_REDIRECT_PERMANENT, + TRANSITION_REDIRECT_TEMPORARY) + NS_LITERAL_CSTRING( + "WHERE v.place_id = ?1 ORDER BY date DESC LIMIT ") + + nsPrintfCString("%d", mNumVisitsForFrecency), getter_AddRefs(mDBVisitsForFrecency)); NS_ENSURE_SUCCESS(rv, rv); + // find places with invalid frecencies (frecency < 0) + // invalid frecencies can happen in these scenarios: + // 1) we've done "clear private data" + // 2) we've expired or deleted visits + // 3) we've migrated from an older version, before global frecency + // + // from older versions, unmigrated bookmarks might be hidden, + // so we can't exclude hidden places (by doing "WHERE hidden <> 1") + // from our query, as we want to calculate the frecency for those + // places and unhide them (if they are not livemark items and not + // place: queries.) + // + // Note, we are not limiting ourselves to places with visits + // because we may not have any if the place is a bookmark and + // we expired or deleted all the visits. + // We get two sets of places that are 1) most visited and 2) random so that + // we don't get stuck recalculating frecencies that end up being -1 every + // time + // Notice that frecency is invalidated as frecency = -visit_count + rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( + "SELECT * FROM " + "(SELECT id, visit_count, hidden, typed, frecency, url " + "FROM moz_places WHERE frecency < 0 " + "ORDER BY frecency ASC LIMIT ROUND(?1 / 2)) " + "UNION " + "SELECT * FROM " + "(SELECT id, visit_count, hidden, typed, frecency, url " + "FROM moz_places WHERE frecency < 0 " + "ORDER BY RANDOM() LIMIT ROUND(?1 / 2))"), + getter_AddRefs(mDBInvalidFrecencies)); + NS_ENSURE_SUCCESS(rv, rv); + + // This query finds random old places to update frecency because frequently + // visited places will have their frecencies updated when visited + rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( + "SELECT id, visit_count, hidden, typed, frecency, url " + "FROM moz_places " + "ORDER BY RANDOM() LIMIT ?1"), + getter_AddRefs(mDBOldFrecencies)); + NS_ENSURE_SUCCESS(rv, rv); + // mDBUpdateFrecencyAndHidden rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "UPDATE moz_places_view SET frecency = ?2, hidden = ?3 WHERE id = ?1"), + "UPDATE moz_places SET frecency = ?2, hidden = ?3 WHERE id = ?1"), getter_AddRefs(mDBUpdateFrecencyAndHidden)); NS_ENSURE_SUCCESS(rv, rv); // mDBGetPlaceVisitStats - // 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. rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "SELECT typed, hidden, frecency " - "FROM moz_places_temp WHERE id = ?1 " - "UNION ALL " - "SELECT typed, hidden, frecency " - "FROM moz_places WHERE id = ?1 " - "LIMIT 1"), + "SELECT typed, hidden, frecency FROM moz_places WHERE id = ?1"), getter_AddRefs(mDBGetPlaceVisitStats)); NS_ENSURE_SUCCESS(rv, rv); rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "SELECT b.parent FROM moz_bookmarks b " - "WHERE b.type = 1 AND b.fk = ?1"), + "SELECT b.parent FROM moz_places h JOIN moz_bookmarks b " + " on b.fk = h.id WHERE b.type = 1 and h.id = ?1"), getter_AddRefs(mDBGetBookmarkParentsForPlace)); NS_ENSURE_SUCCESS(rv, rv); // when calculating frecency, we want the visit count to be // all the visits. - rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "SELECT " - "(SELECT COUNT(*) FROM moz_historyvisits WHERE place_id = ?1) + " - "(SELECT COUNT(*) FROM moz_historyvisits_temp WHERE place_id = ?1 " - "AND id NOT IN (SELECT id FROM moz_historyvisits))"), + rv = mDBConn->CreateStatement( + NS_LITERAL_CSTRING("SELECT COUNT(*) FROM moz_historyvisits " + "WHERE place_id = ?1"), getter_AddRefs(mDBFullVisitCount)); NS_ENSURE_SUCCESS(rv, rv); @@ -1307,17 +1231,13 @@ nsresult nsNavHistory::ForceMigrateBookmarksDB(mozIStorageConnection* aDBConn) { // drop bookmarks tables - nsresult rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "DROP TABLE IF EXISTS moz_bookmarks")); + nsresult rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING("DROP TABLE IF EXISTS moz_bookmarks")); NS_ENSURE_SUCCESS(rv, rv); - rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "DROP TABLE IF EXISTS moz_bookmarks_folders")); + rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING("DROP TABLE IF EXISTS moz_bookmarks_folders")); NS_ENSURE_SUCCESS(rv, rv); - rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "DROP TABLE IF EXISTS moz_bookmarks_roots")); + rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING("DROP TABLE IF EXISTS moz_bookmarks_roots")); NS_ENSURE_SUCCESS(rv, rv); - rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "DROP TABLE IF EXISTS moz_keywords")); + rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING("DROP TABLE IF EXISTS moz_keywords")); NS_ENSURE_SUCCESS(rv, rv); // initialize bookmarks tables @@ -1339,19 +1259,17 @@ nsNavHistory::MigrateV3Up(mozIStorageConnection* aDBConn) // if type col is already there, then a partial update occurred. // return, making no changes, and allowing db version to be updated. nsCOMPtr statement; - nsresult rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "SELECT type from moz_annos"), - getter_AddRefs(statement)); + nsresult rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING("SELECT type from moz_annos"), + getter_AddRefs(statement)); if (NS_SUCCEEDED(rv)) return NS_OK; // add type column to moz_annos rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "ALTER TABLE moz_annos ADD type INTEGER DEFAULT 0")); + "ALTER TABLE moz_annos ADD type INTEGER DEFAULT 0")); if (NS_FAILED(rv)) { // if the alteration failed, force-migrate - rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "DROP TABLE IF EXISTS moz_annos")); + rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING("DROP TABLE IF EXISTS moz_annos")); NS_ENSURE_SUCCESS(rv, rv); rv = nsAnnotationService::InitTables(mDBConn); NS_ENSURE_SUCCESS(rv, rv); @@ -1370,30 +1288,30 @@ nsNavHistory::MigrateV6Up(mozIStorageConnection* aDBConn) // and so we should not attempt to add these cols. nsCOMPtr statement; nsresult rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "SELECT a.dateAdded, a.lastModified FROM moz_annos a"), + "SELECT a.dateAdded, a.lastModified FROM moz_annos a"), getter_AddRefs(statement)); if (NS_FAILED(rv)) { // add dateAdded and lastModified columns to moz_annos rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "ALTER TABLE moz_annos ADD dateAdded INTEGER DEFAULT 0")); + "ALTER TABLE moz_annos ADD dateAdded INTEGER DEFAULT 0")); NS_ENSURE_SUCCESS(rv, rv); rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "ALTER TABLE moz_annos ADD lastModified INTEGER DEFAULT 0")); + "ALTER TABLE moz_annos ADD lastModified INTEGER DEFAULT 0")); NS_ENSURE_SUCCESS(rv, rv); } // if dateAdded & lastModified cols are already there, then a partial update occurred, // and so we should not attempt to add these cols. see bug #408443 for details. rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "SELECT b.dateAdded, b.lastModified FROM moz_items_annos b"), + "SELECT b.dateAdded, b.lastModified FROM moz_items_annos b"), getter_AddRefs(statement)); if (NS_FAILED(rv)) { // add dateAdded and lastModified columns to moz_items_annos rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "ALTER TABLE moz_items_annos ADD dateAdded INTEGER DEFAULT 0")); + "ALTER TABLE moz_items_annos ADD dateAdded INTEGER DEFAULT 0")); NS_ENSURE_SUCCESS(rv, rv); rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "ALTER TABLE moz_items_annos ADD lastModified INTEGER DEFAULT 0")); + "ALTER TABLE moz_items_annos ADD lastModified INTEGER DEFAULT 0")); NS_ENSURE_SUCCESS(rv, rv); } @@ -1401,11 +1319,11 @@ nsNavHistory::MigrateV6Up(mozIStorageConnection* aDBConn) // moz_anno_attributes.name, but those indexes are not needed // because those columns are UNIQUE, so remove them. // see bug #386303 for more details - rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "DROP INDEX IF EXISTS moz_favicons_url")); + rv = aDBConn->ExecuteSimpleSQL( + NS_LITERAL_CSTRING("DROP INDEX IF EXISTS moz_favicons_url")); NS_ENSURE_SUCCESS(rv, rv); - rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "DROP INDEX IF EXISTS moz_anno_attributes_nameindex")); + rv = aDBConn->ExecuteSimpleSQL( + NS_LITERAL_CSTRING("DROP INDEX IF EXISTS moz_anno_attributes_nameindex")); NS_ENSURE_SUCCESS(rv, rv); return transaction.Commit(); @@ -1417,34 +1335,14 @@ nsNavHistory::MigrateV7Up(mozIStorageConnection* aDBConn) { mozStorageTransaction transaction(aDBConn, PR_FALSE); - // Temporary migration code for bug 396300 - nsNavBookmarks* bookmarks = nsNavBookmarks::GetBookmarksService(); - NS_ENSURE_TRUE(bookmarks, NS_ERROR_OUT_OF_MEMORY); - PRInt64 unfiledFolder, rootFolder; - bookmarks->GetUnfiledBookmarksFolder(&unfiledFolder); - bookmarks->GetPlacesRoot(&rootFolder); - - nsCOMPtr moveUnfiledBookmarks; - nsresult rv = aDBConn->CreateStatement(NS_LITERAL_CSTRING( - "UPDATE moz_bookmarks SET parent = ?1 WHERE type = ?2 AND parent=?3"), - getter_AddRefs(moveUnfiledBookmarks)); - rv = moveUnfiledBookmarks->BindInt64Parameter(0, unfiledFolder); - NS_ENSURE_SUCCESS(rv, rv); - rv = moveUnfiledBookmarks->BindInt32Parameter(1, nsINavBookmarksService::TYPE_BOOKMARK); - NS_ENSURE_SUCCESS(rv, rv); - rv = moveUnfiledBookmarks->BindInt64Parameter(2, rootFolder); - NS_ENSURE_SUCCESS(rv, rv); - rv = moveUnfiledBookmarks->Execute(); - NS_ENSURE_SUCCESS(rv, rv); - // Create a statement to test for trigger creation nsCOMPtr triggerDetection; - rv = aDBConn->CreateStatement(NS_LITERAL_CSTRING( - "SELECT name " - "FROM sqlite_master " - "WHERE type = 'trigger' " - "AND name = ?"), - getter_AddRefs(triggerDetection)); + nsresult rv = aDBConn->CreateStatement(NS_LITERAL_CSTRING( + "SELECT name " + "FROM sqlite_master " + "WHERE type = 'trigger' " + "AND name = ?" + ), getter_AddRefs(triggerDetection)); NS_ENSURE_SUCCESS(rv, rv); // Check for existence @@ -1465,19 +1363,18 @@ nsNavHistory::MigrateV7Up(mozIStorageConnection* aDBConn) if (!triggerExists) { // First, we do a one-time reset of all the moz_places.visit_count values. rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "UPDATE moz_places SET visit_count = " - "(SELECT count(*) FROM moz_historyvisits " - "WHERE place_id = moz_places.id " - "AND visit_type NOT IN ") + - nsPrintfCString("(0,%d,%d) ", - nsINavHistoryService::TRANSITION_EMBED, - nsINavHistoryService::TRANSITION_DOWNLOAD) + - NS_LITERAL_CSTRING(")")); + "UPDATE moz_places SET visit_count = " + "(SELECT count(*) FROM moz_historyvisits " + "WHERE place_id = moz_places.id " + "AND visit_type NOT IN (0, 4, 7))") /* invalid, EMBED, DOWNLOAD */ + ); NS_ENSURE_SUCCESS(rv, rv); - // We used to create two triggers here, but we no longer need that with - // schema version eight and greater. We've removed their creation here as - // a result. + // Now we create our two triggers + rv = aDBConn->ExecuteSimpleSQL(CREATE_VISIT_COUNT_INSERT_TRIGGER); + NS_ENSURE_SUCCESS(rv, rv); + rv = aDBConn->ExecuteSimpleSQL(CREATE_VISIT_COUNT_DELETE_TRIGGER); + NS_ENSURE_SUCCESS(rv, rv); } // Check for existence @@ -1495,14 +1392,15 @@ nsNavHistory::MigrateV7Up(mozIStorageConnection* aDBConn) if (!triggerExists) { // First, remove any existing dangling keywords rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "DELETE FROM moz_keywords " - "WHERE id IN (" - "SELECT k.id " - "FROM moz_keywords k " - "LEFT OUTER JOIN moz_bookmarks b " - "ON b.keyword_id = k.id " - "WHERE b.id IS NULL" - ")")); + "DELETE FROM moz_keywords " + "WHERE id IN (" + "SELECT k.id " + "FROM moz_keywords k " + "LEFT OUTER JOIN moz_bookmarks b " + "ON b.keyword_id = k.id " + "WHERE b.id IS NULL" + ")") + ); NS_ENSURE_SUCCESS(rv, rv); // Now we create our trigger @@ -1513,22 +1411,6 @@ nsNavHistory::MigrateV7Up(mozIStorageConnection* aDBConn) return transaction.Commit(); } -nsresult -nsNavHistory::MigrateV8Up(mozIStorageConnection *aDBConn) -{ - mozStorageTransaction transaction(aDBConn, PR_FALSE); - - nsresult rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "DROP TRIGGER moz_historyvisits_afterinsert_v1_trigger")); - NS_ENSURE_SUCCESS(rv, rv); - - rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "DROP TRIGGER moz_historyvisits_afterdelete_v1_trigger")); - NS_ENSURE_SUCCESS(rv, rv); - - return transaction.Commit(); -} - nsresult nsNavHistory::EnsureCurrentSchema(mozIStorageConnection* aDBConn, PRBool* aDidMigrate) { @@ -1578,8 +1460,7 @@ nsNavHistory::EnsureCurrentSchema(mozIStorageConnection* aDBConn, PRBool* aDidMi // for existing profiles, we may not have a frecency column nsCOMPtr statement; rv = aDBConn->CreateStatement(NS_LITERAL_CSTRING( - "SELECT frecency FROM moz_places"), - getter_AddRefs(statement)); + "SELECT frecency FROM moz_places"), getter_AddRefs(statement)); if (NS_FAILED(rv)) { *aDidMigrate = PR_TRUE; @@ -1590,14 +1471,14 @@ nsNavHistory::EnsureCurrentSchema(mozIStorageConnection* aDBConn, PRBool* aDidMi // so that all the frecencies are invalid and we'll // recalculate them on idle. rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "ALTER TABLE moz_places ADD frecency INTEGER DEFAULT -1 NOT NULL")); + "ALTER TABLE moz_places ADD frecency INTEGER DEFAULT -1 NOT NULL")); NS_ENSURE_SUCCESS(rv, rv); // create index for the frecency column // XXX multi column index with typed, and visit_count? rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "CREATE INDEX IF NOT EXISTS moz_places_frecencyindex " - "ON moz_places (frecency)")); + "CREATE INDEX IF NOT EXISTS " + "moz_places_frecencyindex ON moz_places (frecency)")); NS_ENSURE_SUCCESS(rv, rv); // XXX todo @@ -1623,30 +1504,29 @@ nsNavHistory::CleanUpOnQuit() // test for moz_places.user_title nsCOMPtr statement2; nsresult rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "SELECT user_title FROM moz_places"), - getter_AddRefs(statement2)); + "SELECT user_title FROM moz_places"), getter_AddRefs(statement2)); if (NS_SUCCEEDED(rv)) { mozStorageTransaction transaction(mDBConn, PR_FALSE); // 1. Indexes are moved along with the renamed table. Since we're dropping // that table, we're also dropping its indexes, and later re-creating them // for the new table. - rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "DROP INDEX IF EXISTS moz_places_urlindex")); + rv = mDBConn->ExecuteSimpleSQL( + NS_LITERAL_CSTRING("DROP INDEX IF EXISTS moz_places_urlindex")); NS_ENSURE_SUCCESS(rv, rv); - rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "DROP INDEX IF EXISTS moz_places_titleindex")); + rv = mDBConn->ExecuteSimpleSQL( + NS_LITERAL_CSTRING("DROP INDEX IF EXISTS moz_places_titleindex")); NS_ENSURE_SUCCESS(rv, rv); - rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "DROP INDEX IF EXISTS moz_places_faviconindex")); + rv = mDBConn->ExecuteSimpleSQL( + NS_LITERAL_CSTRING("DROP INDEX IF EXISTS moz_places_faviconindex")); NS_ENSURE_SUCCESS(rv, rv); - rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "DROP INDEX IF EXISTS moz_places_hostindex")); + rv = mDBConn->ExecuteSimpleSQL( + NS_LITERAL_CSTRING("DROP INDEX IF EXISTS moz_places_hostindex")); NS_ENSURE_SUCCESS(rv, rv); - rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "DROP INDEX IF EXISTS moz_places_visitcount")); + rv = mDBConn->ExecuteSimpleSQL( + NS_LITERAL_CSTRING("DROP INDEX IF EXISTS moz_places_visitcount")); NS_ENSURE_SUCCESS(rv, rv); - rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "DROP INDEX IF EXISTS moz_places_frecencyindex")); + rv = mDBConn->ExecuteSimpleSQL( + NS_LITERAL_CSTRING("DROP INDEX IF EXISTS moz_places_frecencyindex")); NS_ENSURE_SUCCESS(rv, rv); // 2. remove any duplicate URIs @@ -1654,95 +1534,90 @@ nsNavHistory::CleanUpOnQuit() NS_ENSURE_SUCCESS(rv, rv); // 3. rename moz_places to moz_places_backup - rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "ALTER TABLE moz_places RENAME TO moz_places_backup")); + rv = mDBConn->ExecuteSimpleSQL( + NS_LITERAL_CSTRING("ALTER TABLE moz_places RENAME TO moz_places_backup")); NS_ENSURE_SUCCESS(rv, rv); // 4. create moz_places w/o user_title - rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "CREATE TABLE moz_places (" - "id INTEGER PRIMARY KEY, " - "url LONGVARCHAR, " - "title LONGVARCHAR, " - "rev_host LONGVARCHAR, " - "visit_count INTEGER DEFAULT 0, " - "hidden INTEGER DEFAULT 0 NOT NULL, " - "typed INTEGER DEFAULT 0 NOT NULL, " - "favicon_id INTEGER, " - "frecency INTEGER DEFAULT -1 NOT NULL)")); + rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING("CREATE TABLE moz_places (" + "id INTEGER PRIMARY KEY, " + "url LONGVARCHAR, " + "title LONGVARCHAR, " + "rev_host LONGVARCHAR, " + "visit_count INTEGER DEFAULT 0, " + "hidden INTEGER DEFAULT 0 NOT NULL, " + "typed INTEGER DEFAULT 0 NOT NULL, " + "favicon_id INTEGER, " + "frecency INTEGER DEFAULT -1 NOT NULL)")); NS_ENSURE_SUCCESS(rv, rv); // 5. recreate the indexes // NOTE: tests showed that it's faster to create the indexes prior to filling // the table than it is to add them afterwards. - rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "CREATE UNIQUE INDEX moz_places_url_uniqueindex ON moz_places (url)")); + rv = mDBConn->ExecuteSimpleSQL( + NS_LITERAL_CSTRING("CREATE UNIQUE INDEX moz_places_url_uniqueindex ON moz_places (url)")); NS_ENSURE_SUCCESS(rv, rv); - rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "CREATE INDEX moz_places_faviconindex ON moz_places (favicon_id)")); + rv = mDBConn->ExecuteSimpleSQL( + NS_LITERAL_CSTRING("CREATE INDEX moz_places_faviconindex ON moz_places (favicon_id)")); NS_ENSURE_SUCCESS(rv, rv); - rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "CREATE INDEX moz_places_hostindex ON moz_places (rev_host)")); + rv = mDBConn->ExecuteSimpleSQL( + NS_LITERAL_CSTRING("CREATE INDEX moz_places_hostindex ON moz_places (rev_host)")); NS_ENSURE_SUCCESS(rv, rv); - rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "CREATE INDEX moz_places_visitcount ON moz_places (visit_count)")); + rv = mDBConn->ExecuteSimpleSQL( + NS_LITERAL_CSTRING("CREATE INDEX moz_places_visitcount ON moz_places (visit_count)")); NS_ENSURE_SUCCESS(rv, rv); - rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "CREATE INDEX moz_places_frecencyindex ON moz_places (frecency)")); + rv = mDBConn->ExecuteSimpleSQL( + NS_LITERAL_CSTRING("CREATE INDEX moz_places_frecencyindex ON moz_places (frecency)")); NS_ENSURE_SUCCESS(rv, rv); // 6. copy all data into moz_places rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "INSERT INTO moz_places " - "SELECT id, url, title, rev_host, visit_count, hidden, typed, " - "favicon_id, frecency " - "FROM moz_places_backup")); + "INSERT INTO moz_places " + "SELECT id, url, title, rev_host, visit_count, hidden, typed, favicon_id, frecency " + "FROM moz_places_backup")); NS_ENSURE_SUCCESS(rv, rv); // 7. drop moz_places_backup rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "DROP TABLE moz_places_backup")); + "DROP TABLE moz_places_backup")); NS_ENSURE_SUCCESS(rv, rv); transaction.Commit(); } // bug #381795 - remove unused indexes mozStorageTransaction idxTransaction(mDBConn, PR_FALSE); - rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "DROP INDEX IF EXISTS moz_places_titleindex")); - rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "DROP INDEX IF EXISTS moz_annos_item_idindex")); + rv = mDBConn->ExecuteSimpleSQL( + NS_LITERAL_CSTRING("DROP INDEX IF EXISTS moz_places_titleindex")); + rv = mDBConn->ExecuteSimpleSQL( + NS_LITERAL_CSTRING("DROP INDEX IF EXISTS moz_annos_item_idindex")); idxTransaction.Commit(); // Do a one-time re-creation of the moz_annos indexes (bug 415201) PRBool oldIndexExists = PR_FALSE; - rv = mDBConn->IndexExists(NS_LITERAL_CSTRING("moz_annos_attributesindex"), - &oldIndexExists); + rv = mDBConn->IndexExists(NS_LITERAL_CSTRING("moz_annos_attributesindex"), &oldIndexExists); NS_ENSURE_SUCCESS(rv, rv); if (oldIndexExists) { // wrap in a transaction for safety and performance mozStorageTransaction annoIndexTransaction(mDBConn, PR_FALSE); // drop old uri annos index - rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "DROP INDEX moz_annos_attributesindex")); + rv = mDBConn->ExecuteSimpleSQL( + NS_LITERAL_CSTRING("DROP INDEX moz_annos_attributesindex")); NS_ENSURE_SUCCESS(rv, rv); // create new uri annos index - rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "CREATE UNIQUE INDEX moz_annos_placeattributeindex " - "ON moz_annos (place_id, anno_attribute_id)")); + rv = mDBConn->ExecuteSimpleSQL( + NS_LITERAL_CSTRING("CREATE UNIQUE INDEX moz_annos_placeattributeindex ON moz_annos (place_id, anno_attribute_id)")); NS_ENSURE_SUCCESS(rv, rv); // drop old item annos index - rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "DROP INDEX IF EXISTS moz_items_annos_attributesindex")); + rv = mDBConn->ExecuteSimpleSQL( + NS_LITERAL_CSTRING("DROP INDEX IF EXISTS moz_items_annos_attributesindex")); NS_ENSURE_SUCCESS(rv, rv); // create new item annos index - rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "CREATE UNIQUE INDEX moz_items_annos_itemattributeindex " - "ON moz_items_annos (item_id, anno_attribute_id)")); + rv = mDBConn->ExecuteSimpleSQL( + NS_LITERAL_CSTRING("CREATE UNIQUE INDEX moz_items_annos_itemattributeindex ON moz_items_annos (item_id, anno_attribute_id)")); NS_ENSURE_SUCCESS(rv, rv); rv = annoIndexTransaction.Commit(); @@ -1928,7 +1803,6 @@ nsNavHistory::InternalAddVisit(PRInt64 aPageID, PRInt64 aReferringVisit, *visitID = mDBRecentVisitOfPlace->AsInt64(0); } - return NS_OK; } @@ -2460,11 +2334,9 @@ nsNavHistory::GetHasHistoryEntries(PRBool* aHasEntries) NS_ASSERTION(NS_IsMainThread(), "This can only be called on the main thread"); nsCOMPtr dbSelectStatement; - nsresult rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "SELECT 1 " - "WHERE EXISTS (SELECT id FROM moz_historyvisits_temp LIMIT 1) " - "OR EXISTS (SELECT id FROM moz_historyvisits LIMIT 1)"), - getter_AddRefs(dbSelectStatement)); + nsresult rv = mDBConn->CreateStatement( + NS_LITERAL_CSTRING("SELECT id FROM moz_historyvisits LIMIT 1"), + getter_AddRefs(dbSelectStatement)); NS_ENSURE_SUCCESS(rv, rv); return dbSelectStatement->ExecuteStep(aHasEntries); } @@ -2477,25 +2349,18 @@ nsNavHistory::FixInvalidFrecenciesForExcludedPlaces() // set frecency to 0 so that it is excluded from url bar autocomplete. nsCOMPtr dbUpdateStatement; nsresult rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "UPDATE moz_places_view " - "SET frecency = 0 WHERE id IN (" - "SELECT h.id FROM moz_places h " - "WHERE h.url >= 'place:' AND h.url < 'place;' " - "UNION " - "SELECT h.id FROM moz_places_temp h " - "WHERE h.url >= 'place:' AND h.url < 'place;' " - "UNION " - // Unvisited child of a livemark - "SELECT b.fk FROM moz_bookmarks b " - "JOIN moz_items_annos a ON a.item_id = b.id " - "JOIN moz_anno_attributes n ON n.id = a.anno_attribute_id " - "WHERE n.name = ?1 " - "AND fk IN( " - "SELECT id FROM moz_places WHERE visit_count = 0 AND frecency < 0 " - "UNION ALL " - "SELECT id FROM moz_places_temp WHERE visit_count = 0 AND frecency < 0 " - ") " - ")"), + "UPDATE moz_places " + "SET frecency = 0 WHERE id IN (" + "SELECT h.id FROM moz_places h " + "LEFT OUTER JOIN moz_bookmarks b ON h.id = b.fk " + "WHERE frecency < 0 AND " + // place is an unvisited child of a livemark feed + "(b.parent IN (" + "SELECT annos.item_id FROM moz_anno_attributes attrs " + "JOIN moz_items_annos annos ON attrs.id = annos.anno_attribute_id " + "WHERE attrs.name = ?1) " + "AND visit_count = 0) " + "OR SUBSTR(h.url,0,6) = 'place:')"), getter_AddRefs(dbUpdateStatement)); NS_ENSURE_SUCCESS(rv, rv); @@ -3107,160 +2972,19 @@ PlacesSQLQueryBuilder::SelectAsURI() switch (mQueryType) { case nsINavHistoryQueryOptions::QUERY_TYPE_HISTORY: - if (!mIncludeHidden) { - mQueryString = NS_LITERAL_CSTRING( - "SELECT id, url, title, rev_host, visit_count, MAX(visit_date), " - "favicon_url, session, empty " - "FROM ( " - "SELECT id, url, title, rev_host, visit_count, visit_date, " - "favicon_url, session, empty " - "FROM (" - "SELECT h.id AS id, h.url AS url, h.title AS title, " - "h.rev_host AS rev_host, h.visit_count AS visit_count, " - "MAX(v.visit_date) AS visit_date, f.url AS favicon_url, " - "v.session AS session, null AS empty " - "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 h.hidden <> 1 AND v.visit_type NOT IN ") + - nsPrintfCString("(0,%d,%d) ", - nsINavHistoryService::TRANSITION_EMBED, - nsINavHistoryService::TRANSITION_DOWNLOAD) + - NS_LITERAL_CSTRING("AND h.visit_count > 0 " - "{ADDITIONAL_CONDITIONS} " - "GROUP BY h.id " - ") " - "UNION ALL " - "SELECT id, url, title, rev_host, visit_count, visit_date, " - "favicon_url, session, empty " - "FROM ( " - "SELECT h.id AS id, h.url AS url, h.title AS title, " - "h.rev_host AS rev_host, h.visit_count AS visit_count, " - "MAX(v.visit_date) AS visit_date, f.url AS favicon_url, " - "v.session AS session, null AS empty " - "FROM moz_places_temp h " - "JOIN moz_historyvisits v ON h.id = v.place_id " - "LEFT JOIN moz_favicons f ON h.favicon_id = f.id " - "WHERE h.hidden <> 1 AND v.visit_type NOT IN ") + - nsPrintfCString("(0,%d,%d) ", - nsINavHistoryService::TRANSITION_EMBED, - nsINavHistoryService::TRANSITION_DOWNLOAD) + - NS_LITERAL_CSTRING("AND h.visit_count > 0 " - "AND h.id NOT IN (SELECT id FROM moz_places_temp) " - "{ADDITIONAL_CONDITIONS} " - "GROUP BY h.id " - ") " - "UNION ALL " - "SELECT id, url, title, rev_host, visit_count, visit_date, " - "favicon_url, session, empty " - "FROM ( " - "SELECT h.id AS id, h.url AS url, h.title AS title, " - "h.rev_host AS rev_host, h.visit_count AS visit_count, " - "MAX(v.visit_date) AS visit_date, f.url AS favicon_url, " - "v.session AS session, null AS empty " - "FROM moz_places h " - "JOIN moz_historyvisits_temp v ON h.id = v.place_id " - "LEFT JOIN moz_favicons f ON h.favicon_id = f.id " - "WHERE h.hidden <> 1 AND v.visit_type NOT IN ") + - nsPrintfCString("(0,%d,%d) ", - nsINavHistoryService::TRANSITION_EMBED, - nsINavHistoryService::TRANSITION_DOWNLOAD) + - NS_LITERAL_CSTRING("AND h.visit_count > 0 " - "AND h.id NOT IN (SELECT id FROM moz_places_temp) " - "{ADDITIONAL_CONDITIONS} " - "GROUP BY h.id " - ") " - "UNION ALL " - "SELECT id, url, title, rev_host, visit_count, visit_date, " - "favicon_url, session, empty " - "FROM ( " - "SELECT h.id AS id, h.url AS url, h.title AS title, " - "h.rev_host AS rev_host, h.visit_count AS visit_count, " - "MAX(v.visit_date) AS visit_date, f.url AS favicon_url, " - "v.session AS session, null AS empty " - "FROM moz_places_temp h " - "JOIN moz_historyvisits_temp v ON h.id = v.place_id " - "LEFT JOIN moz_favicons f ON h.favicon_id = f.id " - "WHERE h.hidden <> 1 AND v.visit_type NOT IN ") + - nsPrintfCString("(0,%d,%d) ", - nsINavHistoryService::TRANSITION_EMBED, - nsINavHistoryService::TRANSITION_DOWNLOAD) + - NS_LITERAL_CSTRING("AND h.visit_count > 0 " - "{ADDITIONAL_CONDITIONS} " - "GROUP BY h.id " - ") " - ") " - "GROUP BY id "); - } - else { - mQueryString = NS_LITERAL_CSTRING( - "SELECT id, url, title, rev_host, visit_count, MAX(visit_date), " - "favicon_url, session, empty " - "FROM ( " - "SELECT id, url, title, rev_host, visit_count, visit_date, " - "favicon_url, session, empty " - "FROM (" - "SELECT h.id AS id, h.url AS url, h.title AS title, " - "h.rev_host AS rev_host, h.visit_count AS visit_count, " - "MAX(v.visit_date) AS visit_date, f.url AS favicon_url, " - "v.session AS session, null AS empty " - "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 " - // no-op since {ADDITIONAL_CONDITIONS} will start with AND - "WHERE 1=1 " - "{ADDITIONAL_CONDITIONS} " - "GROUP BY h.id " - ") " - "UNION ALL " - "SELECT id, url, title, rev_host, visit_count, visit_date, " - "favicon_url, session, empty " - "FROM ( " - "SELECT h.id AS id, h.url AS url, h.title AS title, " - "h.rev_host AS rev_host, h.visit_count AS visit_count, " - "MAX(v.visit_date) AS visit_date, f.url AS favicon_url, " - "v.session AS session, null AS empty " - "FROM moz_places_temp h " - "JOIN moz_historyvisits v ON h.id = v.place_id " - "LEFT JOIN moz_favicons f ON h.favicon_id = f.id " - "WHERE h.id NOT IN (SELECT id FROM moz_places_temp) " - "{ADDITIONAL_CONDITIONS} " - "GROUP BY h.id " - ") " - "UNION ALL " - "SELECT id, url, title, rev_host, visit_count, visit_date, " - "favicon_url, session, empty " - "FROM ( " - "SELECT h.id AS id, h.url AS url, h.title AS title, " - "h.rev_host AS rev_host, h.visit_count AS visit_count, " - "MAX(v.visit_date) AS visit_date, f.url AS favicon_url, " - "v.session AS session, null AS empty " - "FROM moz_places h " - "JOIN moz_historyvisits_temp v ON h.id = v.place_id " - "LEFT JOIN moz_favicons f ON h.favicon_id = f.id " - "WHERE h.id NOT IN (SELECT id FROM moz_places_temp) " - "{ADDITIONAL_CONDITIONS} " - "GROUP BY h.id " - ") " - "UNION ALL " - "SELECT id, url, title, rev_host, visit_count, visit_date, " - "favicon_url, session, empty " - "FROM ( " - "SELECT h.id AS id, h.url AS url, h.title AS title, " - "h.rev_host AS rev_host, h.visit_count AS visit_count, " - "MAX(v.visit_date) AS visit_date, f.url AS favicon_url, " - "v.session AS session, null AS empty " - "FROM moz_places_temp h " - "JOIN moz_historyvisits_temp v ON h.id = v.place_id " - "LEFT JOIN moz_favicons f ON h.favicon_id = f.id " - // no-op since {ADDITIONAL_CONDITIONS} will start with AND - "WHERE 1=1 " - "{ADDITIONAL_CONDITIONS} " - "GROUP BY h.id " - ") " - ") " - "GROUP BY id "); - } + mQueryString = NS_LITERAL_CSTRING( + "SELECT h.id, h.url, h.title, h.rev_host, h.visit_count, " + "MAX(visit_date), f.url, null, null " + "FROM moz_places h " + "LEFT OUTER JOIN moz_historyvisits v ON h.id = v.place_id " + "LEFT OUTER JOIN moz_favicons f ON h.favicon_id = f.id "); + + if (!mIncludeHidden) + mQueryString += NS_LITERAL_CSTRING( + " WHERE h.hidden <> 1 AND v.visit_type NOT IN (0,4)" + " {ADDITIONAL_CONDITIONS} "); + + mGroupBy = NS_LITERAL_CSTRING(" GROUP BY h.id"); break; case nsINavHistoryQueryOptions::QUERY_TYPE_BOOKMARKS: @@ -3284,53 +3008,19 @@ PlacesSQLQueryBuilder::SelectAsURI() SQL_STR_FRAGMENT_MAX_VISIT_DATE( "b2.fk" ) ", f.url, null, b2.id, b2.dateAdded, b2.lastModified " "FROM moz_bookmarks b2 " - "JOIN moz_places_temp h ON b2.fk = h.id AND b2.type = 1 " - "LEFT OUTER JOIN moz_favicons f ON h.favicon_id = f.id " - "WHERE b2.id IN ( " - "SELECT b1.id FROM moz_bookmarks b1 " - "WHERE b1.fk IN " - "(SELECT b.fk FROM moz_bookmarks b WHERE b.type = 1 {ADDITIONAL_CONDITIONS}) " - "AND NOT EXISTS ( " - "SELECT id FROM moz_bookmarks WHERE id = b1.parent AND parent = ") + + "JOIN moz_places h ON b2.fk = h.id AND b2.type = 1 " + "LEFT OUTER JOIN moz_favicons f ON h.favicon_id = f.id " + "WHERE b2.id IN (" + "SELECT b1.id FROM moz_bookmarks b1 " + "WHERE b1.fk IN " + "(SELECT b.fk FROM moz_bookmarks b WHERE b.type = 1 {ADDITIONAL_CONDITIONS}) " + "AND NOT EXISTS " + "(SELECT id FROM moz_bookmarks WHERE id = b1.parent AND parent = ") + nsPrintfCString("%lld", history->GetTagsFolder()) + - NS_LITERAL_CSTRING(") " - ") " - "UNION ALL " - "SELECT b2.fk, h.url, COALESCE(b2.title, h.title), h.rev_host, " - "h.visit_count, " - SQL_STR_FRAGMENT_MAX_VISIT_DATE( "b2.fk" ) - ", f.url, null, b2.id, b2.dateAdded, b2.lastModified " - "FROM moz_bookmarks b2 " - "JOIN moz_places h ON b2.fk = h.id AND b2.type = 1 " - "LEFT OUTER JOIN moz_favicons f ON h.favicon_id = f.id " - "WHERE b2.id IN ( " - "SELECT b1.id FROM moz_bookmarks b1 " - "WHERE h.id NOT IN (SELECT id FROM moz_places_temp) " - "AND b1.fk IN " - "(SELECT b.fk FROM moz_bookmarks b WHERE b.type = 1 {ADDITIONAL_CONDITIONS}) " - "AND NOT EXISTS ( " - "SELECT id FROM moz_bookmarks WHERE id = b1.parent AND parent = ") + - nsPrintfCString("%lld", history->GetTagsFolder()) + - NS_LITERAL_CSTRING(") " - ") " - "ORDER BY b2.fk DESC, b2.lastModified DESC"); + NS_LITERAL_CSTRING(")) ORDER BY b2.fk DESC, b2.lastModified DESC"); } else { mQueryString = NS_LITERAL_CSTRING( - "SELECT b.fk, h.url, COALESCE(b.title, h.title), h.rev_host, " - "h.visit_count," - SQL_STR_FRAGMENT_MAX_VISIT_DATE( "b.fk" ) - ", f.url, null, b.id, b.dateAdded, b.lastModified " - "FROM moz_bookmarks b " - "JOIN moz_places_temp h ON b.fk = h.id AND b.type = 1 " - "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}" - "UNION ALL " "SELECT b.fk, h.url, COALESCE(b.title, h.title), h.rev_host, " "h.visit_count," SQL_STR_FRAGMENT_MAX_VISIT_DATE( "b.fk" ) @@ -3338,13 +3028,10 @@ PlacesSQLQueryBuilder::SelectAsURI() "FROM moz_bookmarks b " "JOIN moz_places h ON b.fk = h.id AND b.type = 1 " "LEFT OUTER JOIN moz_favicons f ON h.favicon_id = f.id " - "WHERE h.id NOT IN (SELECT id FROM moz_places_temp) " - "AND NOT EXISTS " - "(SELECT id FROM moz_bookmarks " - "WHERE id = b.parent AND parent = ") + - nsPrintfCString("%lld", history->GetTagsFolder()) + - NS_LITERAL_CSTRING(") " - "{ADDITIONAL_CONDITIONS}"); + "WHERE NOT EXISTS " + "(SELECT id FROM moz_bookmarks WHERE id = b.parent AND parent = ") + + nsPrintfCString("%lld", history->GetTagsFolder()) + + NS_LITERAL_CSTRING(") {ADDITIONAL_CONDITIONS}"); } break; @@ -3357,94 +3044,17 @@ PlacesSQLQueryBuilder::SelectAsURI() nsresult PlacesSQLQueryBuilder::SelectAsVisit() { - if (!mIncludeHidden) { - mQueryString = NS_LITERAL_CSTRING( - "SELECT h.id, h.url, h.title, h.rev_host, h.visit_count, " - "v.visit_date, f.url, v.session, 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 h.visit_count > 0 " - "AND h.hidden <> 1 AND v.visit_type NOT IN ") + - nsPrintfCString("(0,%d,%d) ", - nsINavHistoryService::TRANSITION_EMBED, - nsINavHistoryService::TRANSITION_DOWNLOAD) + - NS_LITERAL_CSTRING("AND h.id NOT IN (SELECT id FROM moz_places_temp) " - "{ADDITIONAL_CONDITIONS} " - "UNION ALL " - "SELECT h.id, h.url, h.title, h.rev_host, h.visit_count, " - "v.visit_date, f.url, v.session, null " - "FROM moz_places_temp h " - "JOIN moz_historyvisits v ON h.id = v.place_id " - "LEFT JOIN moz_favicons f ON h.favicon_id = f.id " - "WHERE h.visit_count > 0 " - "AND h.hidden <> 1 AND v.visit_type NOT IN ") + - nsPrintfCString("(0,%d,%d) ", - nsINavHistoryService::TRANSITION_EMBED, - nsINavHistoryService::TRANSITION_DOWNLOAD) + - NS_LITERAL_CSTRING("{ADDITIONAL_CONDITIONS} " - "UNION ALL " - "SELECT h.id, h.url, h.title, h.rev_host, h.visit_count, " - "v.visit_date, f.url, v.session, null " - "FROM moz_places h " - "JOIN moz_historyvisits_temp v ON h.id = v.place_id " - "LEFT JOIN moz_favicons f ON h.favicon_id = f.id " - "WHERE h.visit_count > 0 " - "AND h.id NOT IN (SELECT id FROM moz_places_temp) " - "AND h.hidden <> 1 AND v.visit_type NOT IN ") + - nsPrintfCString("(0,%d,%d) ", - nsINavHistoryService::TRANSITION_EMBED, - nsINavHistoryService::TRANSITION_DOWNLOAD) + - NS_LITERAL_CSTRING("{ADDITIONAL_CONDITIONS} " - "UNION ALL " - "SELECT h.id, h.url, h.title, h.rev_host, h.visit_count, " - "v.visit_date, f.url, v.session, null " - "FROM moz_places_temp h " - "JOIN moz_historyvisits_temp v ON h.id = v.place_id " - "LEFT JOIN moz_favicons f ON h.favicon_id = f.id " - "WHERE h.visit_count > 0 " - "AND h.hidden <> 1 AND v.visit_type NOT IN ") + - nsPrintfCString("(0,%d,%d) ", - nsINavHistoryService::TRANSITION_EMBED, - nsINavHistoryService::TRANSITION_DOWNLOAD) + - NS_LITERAL_CSTRING("{ADDITIONAL_CONDITIONS} "); - } - else { - mQueryString = NS_LITERAL_CSTRING( - "SELECT h.id, h.url, h.title, h.rev_host, h.visit_count, " - "v.visit_date, f.url, v.session, 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 h.id NOT IN (SELECT id FROM moz_places_temp) " - "{ADDITIONAL_CONDITIONS} " - "UNION ALL " - "SELECT h.id, h.url, h.title, h.rev_host, h.visit_count, " - "v.visit_date, f.url, v.session, null " - "FROM moz_places_temp h " - "JOIN moz_historyvisits v ON h.id = v.place_id " - "LEFT JOIN moz_favicons f ON h.favicon_id = f.id " - // no-op since {ADDITIONAL_CONDITIONS} will start with AND - "WHERE 1=1 " - "{ADDITIONAL_CONDITIONS} " - "UNION ALL " - "SELECT h.id, h.url, h.title, h.rev_host, h.visit_count, " - "v.visit_date, f.url, v.session, null " - "FROM moz_places h " - "JOIN moz_historyvisits_temp v ON h.id = v.place_id " - "LEFT JOIN moz_favicons f ON h.favicon_id = f.id " - "WHERE h.id NOT IN (SELECT id FROM moz_places_temp) " - "{ADDITIONAL_CONDITIONS} " - "UNION ALL " - "SELECT h.id, h.url, h.title, h.rev_host, h.visit_count, " - "v.visit_date, f.url, v.session, null " - "FROM moz_places_temp h " - "JOIN moz_historyvisits_temp v ON h.id = v.place_id " - "LEFT JOIN moz_favicons f ON h.favicon_id = f.id " - // no-op since {ADDITIONAL_CONDITIONS} will start with AND - "WHERE 1=1 " - "{ADDITIONAL_CONDITIONS} "); - } + mQueryString = NS_LITERAL_CSTRING( + "SELECT h.id, h.url, h.title, h.rev_host, h.visit_count, " + "v.visit_date, f.url, v.session, null " + "FROM moz_places h " + "LEFT OUTER JOIN moz_historyvisits v ON h.id = v.place_id " + "LEFT OUTER JOIN moz_favicons f ON h.favicon_id = f.id "); + + if (!mIncludeHidden) + mQueryString += NS_LITERAL_CSTRING( + " WHERE h.hidden <> 1 AND v.visit_type NOT IN (0,4)" + " {ADDITIONAL_CONDITIONS} "); return NS_OK; } @@ -3511,34 +3121,20 @@ PlacesSQLQueryBuilder::SelectAsDay() nsPrintfCString dayRange(1024, "SELECT * " - "FROM ( " - "SELECT %d dayOrder, " - "'%d' dayRange, " - "%s dayTitle, " // This will be bound - "%llu beginTime, " - "%llu endTime " - "WHERE EXISTS ( " - "SELECT id FROM moz_historyvisits_temp " - "WHERE visit_date >= %llu " - "AND visit_date < %llu " - "AND visit_type NOT IN (0, 4) " - "LIMIT 1 " - ") " - "OR EXISTS ( " - "SELECT * FROM moz_historyvisits " - "WHERE visit_date >= %llu " - "AND visit_date < %llu " - "AND visit_type NOT IN (0, 4) " - "LIMIT 1 " - ") " + "FROM (SELECT %d dayOrder, " + "'%d' dayRange, " + "%s dayTitle, " // This will be bound + "%llu beginTime, " + "%llu endTime " + "FROM moz_historyvisits " + "WHERE visit_date >= %llu AND visit_date < %llu " + " AND visit_type NOT IN (0,4) " "LIMIT 1) TUNION%d UNION ", i, i, dateParam.get(), midnight.Get(fromDayAgo), midnight.Get(toDayAgo), midnight.Get(fromDayAgo), midnight.Get(toDayAgo), - midnight.Get(fromDayAgo), - midnight.Get(toDayAgo), i); mQueryString.Append( dayRange ); @@ -3552,32 +3148,21 @@ PlacesSQLQueryBuilder::SelectAsDay() mQueryString.Append(nsPrintfCString(1024, "SELECT * " - "FROM (" - "SELECT %d dayOrder, " - "'%d+' dayRange, " - "%s dayTitle, " // This will be bound - "1 beginTime, " - "%llu endTime " - "WHERE EXISTS ( " - "SELECT id FROM moz_historyvisits_temp " - "WHERE visit_date < %llu " - "AND visit_type NOT IN (0, 4) " - "LIMIT 1 " - ") " - "OR EXISTS ( " - "SELECT id FROM moz_historyvisits " - "WHERE visit_date < %llu " - "AND visit_type NOT IN (0, 4) " - "LIMIT 1 " - ") " - "LIMIT 1) TUNIONLAST " + "FROM (SELECT %d dayOrder, " + "'%d+' dayRange, " + "%s dayTitle, " // This will be bound + "1 beginTime, " + "%llu endTime " + "FROM moz_historyvisits " + "WHERE visit_date < %llu " + " AND visit_type NOT IN (0,4) " + "LIMIT 1) TUNIONLAST " ") TOUTER " // TOUTER END "ORDER BY dayOrder ASC", MAX_HISTORY_DAYS+1, MAX_HISTORY_DAYS+1, dateParam.get(), midnight.Get(-MAX_HISTORY_DAYS), - midnight.Get(-MAX_HISTORY_DAYS), midnight.Get(-MAX_HISTORY_DAYS) )); @@ -3597,43 +3182,26 @@ PlacesSQLQueryBuilder::SelectAsSite() // 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 " - "WHERE EXISTS ( " - "SELECT id FROM moz_places_temp " - "WHERE hidden <> 1 " - "AND rev_host = '.' " - "AND visit_count > 0 " - "AND url BETWEEN 'file://' AND 'file:/~' " - "UNION ALL " - "SELECT id FROM moz_places " - "WHERE id NOT IN (SELECT id FROM moz_places_temp) " - "AND hidden <> 1 " - "AND rev_host = '.' " - "AND visit_count > 0 " - "AND url BETWEEN 'file://' AND 'file:/~' " - ") " + "WHERE EXISTS(SELECT '*' " + "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 " - "FROM ( " - "SELECT get_unreversed_host(rev_host) host " - "FROM ( " - "SELECT DISTINCT rev_host FROM moz_places_temp " - "WHERE hidden <> 1 " - "AND rev_host <> '.' " - "AND visit_count > 0 " - "UNION ALL " - "SELECT DISTINCT rev_host FROM moz_places " - "WHERE id NOT IN (SELECT id FROM moz_places_temp) " - "AND hidden <> 1 " - "AND rev_host <> '.' " - "AND visit_count > 0 " - ") " - "ORDER BY 1 ASC)", + "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 ) inner0 " + "ORDER BY 1 ASC) inner1", nsINavHistoryQueryOptions::RESULTS_AS_URI, nsINavHistoryQueryOptions::SORT_BY_TITLE_ASCENDING, nsINavHistoryQueryOptions::RESULTS_AS_URI, @@ -3646,74 +3214,27 @@ PlacesSQLQueryBuilder::SelectAsSite() "'place:type=%ld&sort=%ld&domain=&domainIsHost=true" "&beginTime='||:begin_time||'&endTime='||:end_time, " ":localhost, :localhost, 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:/~' " - "{ADDITIONAL_CONDITIONS} " - "UNION " - "SELECT h.id " - "FROM moz_places_temp 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:/~' " - "{ADDITIONAL_CONDITIONS} " - "UNION " - "SELECT h.id " - "FROM moz_places h " - "JOIN moz_historyvisits_temp 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:/~' " - "{ADDITIONAL_CONDITIONS} " - "UNION " - "SELECT h.id " - "FROM moz_places_temp h " - "JOIN moz_historyvisits_temp 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:/~' " - "{ADDITIONAL_CONDITIONS} " - ") " + "WHERE EXISTS(SELECT '*' " + "FROM moz_places h " + "JOIN moz_historyvisits v ON h.id = v.place_id " + "WHERE h.hidden <> 1 AND h.rev_host = '.' " + "AND h.visit_count > 0 " + "AND h.url BETWEEN 'file://' AND 'file:/~' " + "AND v.visit_type NOT IN (0,4) {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 " - "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.hidden <> 1 AND h.rev_host <> '.' " - "AND h.visit_count > 0 " - "{ADDITIONAL_CONDITIONS} " - "UNION " - "SELECT DISTINCT get_unreversed_host(rev_host) AS host " - "FROM moz_places_temp h " - "JOIN moz_historyvisits v ON v.place_id = h.id " - "WHERE h.hidden <> 1 AND h.rev_host <> '.' " - "AND h.visit_count > 0 " - "{ADDITIONAL_CONDITIONS} " - "UNION " - "SELECT DISTINCT get_unreversed_host(rev_host) AS host " - "FROM moz_places h " - "JOIN moz_historyvisits_temp v ON v.place_id = h.id " - "WHERE h.hidden <> 1 AND h.rev_host <> '.' " - "AND h.visit_count > 0 " - "{ADDITIONAL_CONDITIONS} " - "UNION " - "SELECT DISTINCT get_unreversed_host(rev_host) AS host " - "FROM moz_places_temp h " - "JOIN moz_historyvisits_temp v ON v.place_id = h.id " - "WHERE h.hidden <> 1 AND h.rev_host <> '.' " - "AND h.visit_count > 0 " - "{ADDITIONAL_CONDITIONS} " - "ORDER BY 1 ASC " - ")", + "FROM (SELECT get_unreversed_host(rev_host) host " + "FROM (SELECT DISTINCT rev_host " + "FROM moz_places h " + "JOIN moz_historyvisits v ON h.id = v.place_id " + "WHERE h.hidden <> 1 AND h.rev_host <> '.' " + "AND h.visit_count > 0 " + "AND v.visit_type NOT IN (0,4) " + "{ADDITIONAL_CONDITIONS} ) inner0 " + "ORDER BY 1 ASC) inner1", nsINavHistoryQueryOptions::RESULTS_AS_URI, nsINavHistoryQueryOptions::SORT_BY_TITLE_ASCENDING, nsINavHistoryQueryOptions::RESULTS_AS_URI, @@ -3900,44 +3421,21 @@ nsNavHistory::ConstructQueryString( if (IsHistoryMenuQuery(aQueries, aOptions, nsINavHistoryQueryOptions::SORT_BY_DATE_DESCENDING)) { - nsCString sqlFragment = NS_LITERAL_CSTRING( - "SELECT * FROM ( " - "SELECT DISTINCT place_id " - "FROM moz_historyvisits " - "WHERE visit_type NOT IN (0,4) " - "AND NOT EXISTS (SELECT id FROM moz_places h WHERE h.id = place_id AND hidden = 1) " - "AND NOT EXISTS (SELECT id FROM moz_places_temp h WHERE h.id = place_id AND hidden = 1) " - "ORDER by visit_date DESC LIMIT ") + - nsPrintfCString("%d ", aOptions->MaxResults()) + - NS_LITERAL_CSTRING(") " - "UNION ALL " - "SELECT * FROM ( " - "SELECT DISTINCT place_id " - "FROM moz_historyvisits_temp " - "WHERE visit_type NOT IN (0,4) " - "AND NOT EXISTS (SELECT id FROM moz_places h WHERE h.id = place_id AND hidden = 1) " - "AND NOT EXISTS (SELECT id FROM moz_places_temp h WHERE h.id = place_id AND hidden = 1) " - "ORDER by visit_date DESC LIMIT ") + - nsPrintfCString("%d ", aOptions->MaxResults()) + - NS_LITERAL_CSTRING(")"); - queryString = NS_LITERAL_CSTRING( "SELECT h.id, h.url, h.title, h.rev_host, h.visit_count, " - SQL_STR_FRAGMENT_MAX_VISIT_DATE( "h.id" ) - ", f.url, null, null " - "FROM moz_places_temp h " - "LEFT OUTER JOIN moz_favicons f ON h.favicon_id = f.id " - "WHERE h.id IN ( ") + sqlFragment + NS_LITERAL_CSTRING(") " - "UNION " - "SELECT h.id, h.url, h.title, h.rev_host, h.visit_count, " - SQL_STR_FRAGMENT_MAX_VISIT_DATE( "h.id" ) - ", f.url, null, null " - "FROM moz_places h " - "LEFT OUTER JOIN moz_favicons f ON h.favicon_id = f.id " - "WHERE h.id IN ( ") + sqlFragment + NS_LITERAL_CSTRING(") " - "ORDER BY 6 DESC " // last visit date + SQL_STR_FRAGMENT_MAX_VISIT_DATE( "h.id" ) + ", f.url, null, null " + "FROM moz_places h " + "LEFT OUTER JOIN moz_favicons f ON h.favicon_id = f.id " + "WHERE h.id IN ( " + "SELECT DISTINCT p.id " + "FROM moz_places p " + "JOIN moz_historyvisits v ON v.place_id = p.id " + "WHERE p.hidden <> 1 AND v.visit_type NOT IN (0,4) " + "ORDER BY v.visit_date DESC " "LIMIT "); queryString.AppendInt(aOptions->MaxResults()); + queryString += NS_LITERAL_CSTRING(") ORDER BY 6 DESC"); // v.visit_date return NS_OK; } @@ -3946,30 +3444,17 @@ nsNavHistory::ConstructQueryString( if (IsHistoryMenuQuery(aQueries, aOptions, nsINavHistoryQueryOptions::SORT_BY_VISITCOUNT_DESCENDING)) { queryString = NS_LITERAL_CSTRING( - "SELECT * FROM ( " - "SELECT h.id, h.url, h.title, h.rev_host, h.visit_count, " - SQL_STR_FRAGMENT_MAX_VISIT_DATE( "h.id" ) - ", f.url, null, null " - "FROM moz_places_temp h " - "LEFT OUTER JOIN moz_favicons f ON h.favicon_id = f.id " - "WHERE h.hidden <> 1 AND visit_count > 0 " - "ORDER BY h.visit_count DESC LIMIT ") + - nsPrintfCString("%d ", aOptions->MaxResults()) + - NS_LITERAL_CSTRING(") " - "UNION " - "SELECT * FROM ( " - "SELECT h.id, h.url, h.title, h.rev_host, h.visit_count, " - SQL_STR_FRAGMENT_MAX_VISIT_DATE( "h.id" ) - ", f.url, null, null " - "FROM moz_places h " - "LEFT OUTER JOIN moz_favicons f ON h.favicon_id = f.id " - "WHERE h.hidden <> 1 AND visit_count > 0 " - "ORDER BY h.visit_count DESC LIMIT ") + - nsPrintfCString("%d ", aOptions->MaxResults()) + - NS_LITERAL_CSTRING(") " - "ORDER BY 5 DESC LIMIT "); // visit_count + "SELECT h.id, h.url, h.title, h.rev_host, h.visit_count, " + SQL_STR_FRAGMENT_MAX_VISIT_DATE( "h.id" ) + ", f.url, null, null " + "FROM moz_places h " + "LEFT OUTER JOIN moz_favicons f ON h.favicon_id = f.id " + "WHERE h.id IN (" + "SELECT p.id FROM moz_places p " + "WHERE p.hidden <> 1 AND visit_count > 0 " + "ORDER BY p.visit_count DESC LIMIT "); queryString.AppendInt(aOptions->MaxResults()); - + queryString += NS_LITERAL_CSTRING(") ORDER BY h.visit_count DESC"); return NS_OK; } @@ -4054,7 +3539,7 @@ nsNavHistory::GetQueryResults(nsNavHistoryQueryResultNode *aResultNode, paramsPresent, addParams); NS_ENSURE_SUCCESS(rv,rv); -#ifdef DEBUG_FRECENCY +#ifdef DEBUG_thunder printf("Constructed the query: %s\n", PromiseFlatCString(queryString).get()); #endif @@ -4206,38 +3691,13 @@ nsNavHistory::GetLastPageVisited(nsACString & aLastPageVisited) NS_ASSERTION(NS_IsMainThread(), "This can only be called on the main thread"); nsCOMPtr statement; - // We are not checking for duplicated ids into the unified table - // for perf reasons, LIMIT 1 will discard duplicates faster since we - // expect newest visits being in temp table. nsresult rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "SELECT * FROM ( " - "SELECT url, visit_date FROM moz_historyvisits_temp v " - "JOIN moz_places_temp h ON v.place_id = h.id " - "WHERE h.hidden <> 1 " - "ORDER BY visit_date DESC LIMIT 1 " - ") " - "UNION ALL " - "SELECT * FROM ( " - "SELECT url, visit_date FROM moz_historyvisits_temp v " - "JOIN moz_places h ON v.place_id = h.id " - "WHERE h.hidden <> 1 " - "ORDER BY visit_date DESC LIMIT 1 " - ") " - "UNION ALL " - "SELECT * FROM ( " - "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 LIMIT 1 " - ") " - "UNION ALL " - "SELECT * FROM ( " - "SELECT url, visit_date FROM moz_historyvisits v " - "JOIN moz_places_temp h ON v.place_id = h.id " - "WHERE h.hidden <> 1 " - "ORDER BY visit_date DESC LIMIT 1 " - ") " - "ORDER BY 2 DESC LIMIT 1"), /* visit date */ + "SELECT h.url " + "FROM moz_places h LEFT OUTER JOIN moz_historyvisits v ON h.id = v.place_id " + "WHERE v.visit_date IN " + "(SELECT MAX(visit_date) " + "FROM moz_historyvisits v2 LEFT JOIN moz_places h2 ON v2.place_id = h2.id " + "WHERE h2.hidden != 1)"), getter_AddRefs(statement)); NS_ENSURE_SUCCESS(rv, rv); @@ -4295,31 +3755,19 @@ nsNavHistory::RemovePagesInternal(const nsCString& aPlaceIdsQueryString) // to figure out which places to recalculate frecency first. // Pay attention to not set frecency = 0 if visit_count = 0 nsresult rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "UPDATE moz_places_view " + "UPDATE moz_places " "SET frecency = -MAX(visit_count, 1) " - "WHERE id IN ( " - "SELECT h.id " - "FROM moz_places_temp h " - "WHERE h.id IN ( ") + aPlaceIdsQueryString + NS_LITERAL_CSTRING(") " - "AND ( " - "EXISTS (SELECT b.id FROM moz_bookmarks b WHERE b.fk =h.id) " - "OR EXISTS (SELECT a.id FROM moz_annos a WHERE a.place_id = h.id) " - ") " - "UNION ALL " - "SELECT h.id " - "FROM moz_places h " - "WHERE h.id IN ( ") + aPlaceIdsQueryString + NS_LITERAL_CSTRING(") " - "AND h.id NOT IN (SELECT id FROM moz_places_temp) " - "AND ( " - "EXISTS (SELECT b.id FROM moz_bookmarks b WHERE b.fk =h.id) " - "OR EXISTS (SELECT a.id FROM moz_annos a WHERE a.place_id = h.id) " - ") " - ")")); + "WHERE id IN(") + + aPlaceIdsQueryString + + NS_LITERAL_CSTRING(") AND (" + "EXISTS (SELECT b.id FROM moz_bookmarks b WHERE b.fk = moz_places.id) " + "OR EXISTS " + "(SELECT a.id FROM moz_annos a WHERE a.place_id = moz_places.id))")); NS_ENSURE_SUCCESS(rv, rv); // delete all visits rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "DELETE FROM moz_historyvisits_view WHERE place_id IN (") + + "DELETE FROM moz_historyvisits WHERE place_id IN (") + aPlaceIdsQueryString + NS_LITERAL_CSTRING(")")); NS_ENSURE_SUCCESS(rv, rv); @@ -4333,20 +3781,12 @@ nsNavHistory::RemovePagesInternal(const nsCString& aPlaceIdsQueryString) // Note that we do NOT delete favicons. Any unreferenced favicons will be // deleted next time the browser is shut down. rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "DELETE FROM moz_places_view WHERE id IN (" - "SELECT h.id FROM moz_places_temp h " - "WHERE h.id IN ( ") + aPlaceIdsQueryString + NS_LITERAL_CSTRING(") " - "AND SUBSTR(h.url, 0, 6) <> 'place:' " - "AND NOT EXISTS " - "(SELECT b.id FROM moz_bookmarks b WHERE b.fk = h.id LIMIT 1) " - "UNION ALL " - "SELECT h.id FROM moz_places h " - "WHERE h.id NOT IN (SELECT id FROM moz_places_temp) " - "AND h.id IN ( ") + aPlaceIdsQueryString + NS_LITERAL_CSTRING(") " - "AND SUBSTR(h.url, 0, 6) <> 'place:' " - "AND NOT EXISTS " - "(SELECT b.id FROM moz_bookmarks b WHERE b.fk = h.id LIMIT 1) " - ")")); + "DELETE FROM moz_places WHERE id IN (" + "SELECT h.id FROM moz_places h WHERE h.id IN (") + + aPlaceIdsQueryString + + NS_LITERAL_CSTRING(") AND " + "NOT EXISTS (SELECT b.id FROM moz_bookmarks b WHERE b.fk = h.id LIMIT 1) " + "AND SUBSTR(h.url,0,6) <> 'place:')")); NS_ENSURE_SUCCESS(rv, rv); // placeId could have a livemark item, so setting the frecency to -1 @@ -4470,21 +3910,16 @@ nsNavHistory::RemovePagesFromHost(const nsACString& aHost, PRBool aEntireDomain) // build condition string based on host selection type nsCAutoString conditionString; if (aEntireDomain) - conditionString.AssignLiteral("rev_host >= ?1 AND rev_host < ?2 "); + conditionString.AssignLiteral("h.rev_host >= ?1 AND h.rev_host < ?2 "); else - conditionString.AssignLiteral("rev_host = ?1 "); + conditionString.AssignLiteral("h.rev_host = ?1 "); nsCOMPtr statement; // create statement depending on delete type rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "SELECT id FROM moz_places_temp " - "WHERE ") + conditionString + NS_LITERAL_CSTRING( - "UNION ALL " - "SELECT id FROM moz_places " - "WHERE id NOT IN (SELECT id FROM moz_places_temp) " - "AND ") + conditionString, - getter_AddRefs(statement)); + "SELECT h.id FROM moz_places h WHERE ") + + conditionString, getter_AddRefs(statement)); NS_ENSURE_SUCCESS(rv, rv); rv = statement->BindStringParameter(0, revHostDot); NS_ENSURE_SUCCESS(rv, rv); @@ -4535,21 +3970,9 @@ nsNavHistory::RemovePagesByTimeframe(PRTime aBeginTime, PRTime aEndTime) // this query is faster than actually selecting in moz_historyvisits nsCOMPtr selectByTime; rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "SELECT h.id FROM moz_places_temp h WHERE " - "EXISTS " - "(SELECT id FROM moz_historyvisits v WHERE v.place_id = h.id " - "AND v.visit_date >= ?1 AND v.visit_date <= ?2 LIMIT 1)" - "OR EXISTS " - "(SELECT id FROM moz_historyvisits_temp v WHERE v.place_id = h.id " - "AND v.visit_date >= ?1 AND v.visit_date <= ?2 LIMIT 1) " - "UNION " "SELECT h.id FROM moz_places h WHERE " - "EXISTS " - "(SELECT id FROM moz_historyvisits v WHERE v.place_id = h.id " - "AND v.visit_date >= ?1 AND v.visit_date <= ?2 LIMIT 1)" - "OR EXISTS " - "(SELECT id FROM moz_historyvisits_temp v WHERE v.place_id = h.id " - "AND v.visit_date >= ?1 AND v.visit_date <= ?2 LIMIT 1)"), + "EXISTS (SELECT id FROM moz_historyvisits v WHERE v.place_id = h.id " + " AND v.visit_date >= ?1 AND v.visit_date <= ?2 LIMIT 1)"), getter_AddRefs(selectByTime)); NS_ENSURE_SUCCESS(rv, rv); rv = selectByTime->BindInt64Parameter(0, aBeginTime); @@ -5580,8 +5003,8 @@ nsNavHistory::QueryToSelectClause(nsNavHistoryQuery* aQuery, // const "EXISTS " "(SELECT h.id " "FROM moz_annos anno " - "JOIN moz_anno_attributes annoname " - "ON anno.anno_attribute_id = annoname.id " + "JOIN moz_anno_attributes annoname " + "ON anno.anno_attribute_id = annoname.id " "WHERE anno.place_id = h.id " "AND annoname.name = ").Param(":anno").Str(")"); // annotation-based queries don't get the common conditions, so you get @@ -6326,12 +5749,12 @@ nsNavHistory::VisitIdToResultNode(PRInt64 visitId, case nsNavHistoryQueryOptions::RESULTS_AS_VISIT: case nsNavHistoryQueryOptions::RESULTS_AS_FULL_VISIT: // visit query - want exact visit time - statement = GetDBVisitToVisitResult(); + statement = mDBVisitToVisitResult; break; case nsNavHistoryQueryOptions::RESULTS_AS_URI: // URL results - want last visit time - statement = GetDBVisitToURLResult(); + statement = mDBVisitToURLResult; break; default: @@ -6339,7 +5762,6 @@ nsNavHistory::VisitIdToResultNode(PRInt64 visitId, // by registering their own observers when they are expanded. return NS_OK; } - NS_ENSURE_TRUE(statement, NS_ERROR_UNEXPECTED); mozStorageStatementScoper scoper(statement); nsresult rv = statement->BindInt64Parameter(0, visitId); @@ -6360,21 +5782,19 @@ nsresult nsNavHistory::BookmarkIdToResultNode(PRInt64 aBookmarkId, nsNavHistoryQueryOptions* aOptions, nsNavHistoryResultNode** aResult) { - mozIStorageStatement *stmt = GetDBBookmarkToUrlResult(); - NS_ENSURE_TRUE(stmt, NS_ERROR_UNEXPECTED); - mozStorageStatementScoper scoper(stmt); - nsresult rv = stmt->BindInt64Parameter(0, aBookmarkId); + mozStorageStatementScoper scoper(mDBBookmarkToUrlResult); + nsresult rv = mDBBookmarkToUrlResult->BindInt64Parameter(0, aBookmarkId); NS_ENSURE_SUCCESS(rv, rv); PRBool hasMore = PR_FALSE; - rv = stmt->ExecuteStep(&hasMore); + rv = mDBBookmarkToUrlResult->ExecuteStep(&hasMore); NS_ENSURE_SUCCESS(rv, rv); if (!hasMore) { NS_NOTREACHED("Trying to get a result node for an invalid bookmark identifier"); return NS_ERROR_INVALID_ARG; } - return RowToResult(stmt, aOptions, aResult); + return RowToResult(mDBBookmarkToUrlResult, aOptions, aResult); } // nsNavHistory::TitleForDomain @@ -6398,16 +5818,12 @@ nsNavHistory::TitleForDomain(const nsCString& domain, nsACString& aTitle) void nsNavHistory::GetAgeInDaysString(PRInt32 aInt, const PRUnichar *aName, nsACString& aResult) { - nsIStringBundle *bundle = GetBundle(); - if (!bundle) - aResult.Truncate(0); - nsAutoString intString; intString.AppendInt(aInt); const PRUnichar* strings[1] = { intString.get() }; nsXPIDLString value; - nsresult rv = bundle->FormatStringFromName(aName, strings, - 1, getter_Copies(value)); + nsresult rv = mBundle->FormatStringFromName(aName, strings, + 1, getter_Copies(value)); if (NS_SUCCEEDED(rv)) CopyUTF16toUTF8(value, aResult); else @@ -6417,12 +5833,8 @@ nsNavHistory::GetAgeInDaysString(PRInt32 aInt, const PRUnichar *aName, nsACStrin void nsNavHistory::GetStringFromName(const PRUnichar *aName, nsACString& aResult) { - nsIStringBundle *bundle = GetBundle(); - if (!bundle) - aResult.Truncate(0); - nsXPIDLString value; - nsresult rv = bundle->GetStringFromName(aName, getter_Copies(value)); + nsresult rv = mBundle->GetStringFromName(aName, getter_Copies(value)); if (NS_SUCCEEDED(rv)) CopyUTF16toUTF8(value, aResult); else @@ -6443,6 +5855,8 @@ nsNavHistory::SetPageTitleInternal(nsIURI* aURI, const nsAString& aTitle) { nsresult rv; + mozStorageTransaction transaction(mDBConn, PR_TRUE); + // first, make sure the page exists, and fetch the old title (we need the one // that isn't changing to send notifications) nsAutoString title; @@ -6470,24 +5884,32 @@ nsNavHistory::SetPageTitleInternal(nsIURI* aURI, const nsAString& aTitle) if ((aTitle.IsVoid() && title.IsVoid()) || aTitle == title) return NS_OK; - mozStorageStatementScoper scoper(mDBSetPlaceTitle); + nsCOMPtr dbModStatement; + title = aTitle; + rv = mDBConn->CreateStatement( + NS_LITERAL_CSTRING("UPDATE moz_places SET title = ?1 WHERE url = ?2"), + getter_AddRefs(dbModStatement)); + NS_ENSURE_SUCCESS(rv, rv); + // title if (aTitle.IsVoid()) - rv = mDBSetPlaceTitle->BindNullParameter(0); + dbModStatement->BindNullParameter(0); else - rv = mDBSetPlaceTitle->BindStringParameter(0, StringHead(aTitle, HISTORY_TITLE_LENGTH_MAX)); + dbModStatement->BindStringParameter(0, StringHead(aTitle, HISTORY_TITLE_LENGTH_MAX)); NS_ENSURE_SUCCESS(rv, rv); // url - rv = BindStatementURI(mDBSetPlaceTitle, 1, aURI); + rv = BindStatementURI(dbModStatement, 1, aURI); NS_ENSURE_SUCCESS(rv, rv); - rv = mDBSetPlaceTitle->Execute(); + rv = dbModStatement->Execute(); + NS_ENSURE_SUCCESS(rv, rv); + rv = transaction.Commit(); NS_ENSURE_SUCCESS(rv, rv); // observers (have to check first if it's bookmarked) ENUMERATE_WEAKARRAY(mObservers, nsINavHistoryObserver, - OnTitleChanged(aURI, aTitle)) + OnTitleChanged(aURI, title)) return NS_OK; @@ -6534,58 +5956,57 @@ nsNavHistory::RemoveDuplicateURIs() // this id will be retained while duplicates will be discarded // total_visit_count is the sum of all duplicate uris visit_count nsCOMPtr selectStatement; - nsresult rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "SELECT " - "(SELECT h.id FROM moz_places_view h WHERE h.url = url " - "ORDER BY h.visit_count DESC LIMIT 1), " + nsresult rv = mDBConn->CreateStatement( + NS_LITERAL_CSTRING("SELECT " + "(SELECT h.id FROM moz_places h WHERE h.url=url ORDER BY h.visit_count DESC LIMIT 1), " "url, SUM(visit_count) " - "FROM moz_places_view " - "GROUP BY url HAVING( COUNT(url) > 1)"), - getter_AddRefs(selectStatement)); + "FROM moz_places " + "GROUP BY url HAVING( COUNT(url) > 1)"), + getter_AddRefs(selectStatement)); NS_ENSURE_SUCCESS(rv, rv); // this query remaps history visits to the retained place_id nsCOMPtr updateStatement; - rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "UPDATE moz_historyvisits_view " - "SET place_id = ?1 " - "WHERE place_id IN " - "(SELECT id FROM moz_places_view WHERE id <> ?1 AND url = ?2)"), - getter_AddRefs(updateStatement)); + rv = mDBConn->CreateStatement( + NS_LITERAL_CSTRING( + "UPDATE moz_historyvisits " + "SET place_id = ?1 " + "WHERE place_id IN (SELECT id FROM moz_places WHERE id <> ?1 AND url = ?2)"), + getter_AddRefs(updateStatement)); NS_ENSURE_SUCCESS(rv, rv); // this query remaps bookmarks to the retained place_id nsCOMPtr bookmarkStatement; - rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "UPDATE moz_bookmarks " - "SET fk = ?1 " - "WHERE fk IN " - "(SELECT id FROM moz_places_view WHERE id <> ?1 AND url = ?2)"), - getter_AddRefs(bookmarkStatement)); + rv = mDBConn->CreateStatement( + NS_LITERAL_CSTRING( + "UPDATE moz_bookmarks " + "SET fk = ?1 " + "WHERE fk IN (SELECT id FROM moz_places WHERE id <> ?1 AND url = ?2)"), + getter_AddRefs(bookmarkStatement)); NS_ENSURE_SUCCESS(rv, rv); // this query remaps annotations to the retained place_id nsCOMPtr annoStatement; - rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "UPDATE moz_annos " - "SET place_id = ?1 " - "WHERE place_id IN " - "(SELECT id FROM moz_places_view WHERE id <> ?1 AND url = ?2)"), - getter_AddRefs(annoStatement)); + rv = mDBConn->CreateStatement( + NS_LITERAL_CSTRING( + "UPDATE moz_annos " + "SET place_id = ?1 " + "WHERE place_id IN (SELECT id FROM moz_places WHERE id <> ?1 AND url = ?2)"), + getter_AddRefs(annoStatement)); NS_ENSURE_SUCCESS(rv, rv); // this query deletes all duplicate uris except the choosen id nsCOMPtr deleteStatement; - rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "DELETE FROM moz_places_view WHERE url = ?1 AND id <> ?2"), - getter_AddRefs(deleteStatement)); + rv = mDBConn->CreateStatement( + NS_LITERAL_CSTRING("DELETE FROM moz_places WHERE url = ?1 AND id <> ?2"), + getter_AddRefs(deleteStatement)); NS_ENSURE_SUCCESS(rv, rv); // this query updates visit_count to the sum of all visits nsCOMPtr countStatement; - rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "UPDATE moz_places_view SET visit_count = ?1 WHERE id = ?2"), - getter_AddRefs(countStatement)); + rv = mDBConn->CreateStatement( + NS_LITERAL_CSTRING("UPDATE moz_places SET visit_count = ?1 WHERE id = ?2"), + getter_AddRefs(countStatement)); NS_ENSURE_SUCCESS(rv, rv); // for each duplicate uri we update historyvisit and visit_count @@ -7125,11 +6546,11 @@ nsNavHistory::RecalculateFrecencies(PRInt32 aCount, PRBool aRecalcOld) { mozStorageTransaction transaction(mDBConn, PR_TRUE); - nsresult rv = RecalculateFrecenciesInternal(GetDBInvalidFrecencies(), aCount); + nsresult rv = RecalculateFrecenciesInternal(mDBInvalidFrecencies, aCount); NS_ENSURE_SUCCESS(rv, rv); if (aRecalcOld) { - rv = RecalculateFrecenciesInternal(GetDBOldFrecencies(), aCount); + rv = RecalculateFrecenciesInternal(mDBOldFrecencies, aCount); NS_ENSURE_SUCCESS(rv, rv); } return NS_OK; @@ -7192,228 +6613,6 @@ nsNavHistory::RecalculateFrecenciesInternal(mozIStorageStatement *aStatement, PR return NS_OK; } - -nsICollation * -nsNavHistory::GetCollation() -{ - if (mCollation) - return mCollation; - - // locale - nsCOMPtr locale; - nsCOMPtr ls(do_GetService(NS_LOCALESERVICE_CONTRACTID)); - NS_ENSURE_TRUE(ls, nsnull); - nsresult rv = ls->GetApplicationLocale(getter_AddRefs(locale)); - NS_ENSURE_SUCCESS(rv, nsnull); - - // collation - nsCOMPtr cfact = - do_CreateInstance(NS_COLLATIONFACTORY_CONTRACTID); - NS_ENSURE_TRUE(cfact, nsnull); - rv = cfact->CreateCollation(locale, getter_AddRefs(mCollation)); - NS_ENSURE_SUCCESS(rv, nsnull); - - return mCollation; -} - -nsIStringBundle * -nsNavHistory::GetBundle() -{ - if (mBundle) - return mBundle; - - nsCOMPtr bundleService = - do_GetService(NS_STRINGBUNDLE_CONTRACTID); - NS_ENSURE_TRUE(bundleService, nsnull); - nsresult rv = bundleService->CreateBundle( - "chrome://places/locale/places.properties", - getter_AddRefs(mBundle)); - NS_ENSURE_SUCCESS(rv, nsnull); - - return mBundle; -} - -mozIStorageStatement * -nsNavHistory::GetDBVisitToVisitResult() -{ - if (mDBVisitToVisitResult) - return mDBVisitToVisitResult; - - // mDBVisitToVisitResult, should match kGetInfoIndex_* (see GetQueryResults) - // We are not checking for duplicated ids into the unified table - // for perf reasons, LIMIT 1 will discard duplicates faster since we - // have unique visit ids. - nsresult rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "SELECT h.id, h.url, h.title, h.rev_host, h.visit_count, " - "v.visit_date, f.url, v.session, null " - "FROM moz_places_temp h " - "LEFT JOIN moz_historyvisits_temp v_t ON h.id = v_t.place_id " - "LEFT JOIN moz_historyvisits v ON h.id = v.place_id " - "LEFT JOIN moz_favicons f ON h.favicon_id = f.id " - "WHERE v.id = ?1 OR v_t.id = ?1 " - "UNION ALL " - "SELECT h.id, h.url, h.title, h.rev_host, h.visit_count, " - "v.visit_date, f.url, v.session, null " - "FROM moz_places h " - "LEFT JOIN moz_historyvisits_temp v_t ON h.id = v_t.place_id " - "LEFT JOIN moz_historyvisits v ON h.id = v.place_id " - "LEFT JOIN moz_favicons f ON h.favicon_id = f.id " - "WHERE v.id = ?1 OR v_t.id = ?1 " - "LIMIT 1"), - getter_AddRefs(mDBVisitToVisitResult)); - NS_ENSURE_SUCCESS(rv, nsnull); - - return mDBVisitToVisitResult; -} - -mozIStorageStatement * -nsNavHistory::GetDBVisitToURLResult() -{ - if (mDBVisitToURLResult) - return mDBVisitToURLResult; - - // mDBVisitToURLResult, should match kGetInfoIndex_* (see GetQueryResults) - // We are not checking for duplicated ids into the unified table - // for perf reasons, LIMIT 1 will discard duplicates faster since we - // have unique visit ids. - nsresult rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "SELECT h.id, h.url, h.title, h.rev_host, h.visit_count, " - SQL_STR_FRAGMENT_MAX_VISIT_DATE( "h.id" ) - ", f.url, null, null " - "FROM moz_places_temp h " - "LEFT JOIN moz_historyvisits_temp v_t ON h.id = v_t.place_id " - "LEFT JOIN moz_historyvisits v ON h.id = v.place_id " - "LEFT JOIN moz_favicons f ON h.favicon_id = f.id " - "WHERE v.id = ?1 OR v_t.id = ?1 " - "UNION ALL " - "SELECT h.id, h.url, h.title, h.rev_host, h.visit_count, " - SQL_STR_FRAGMENT_MAX_VISIT_DATE( "h.id" ) - ", f.url, null, null " - "FROM moz_places h " - "LEFT JOIN moz_historyvisits_temp v_t ON h.id = v_t.place_id " - "LEFT JOIN moz_historyvisits v ON h.id = v.place_id " - "LEFT JOIN moz_favicons f ON h.favicon_id = f.id " - "WHERE v.id = ?1 OR v_t.id = ?1 " - "LIMIT 1"), - getter_AddRefs(mDBVisitToURLResult)); - NS_ENSURE_SUCCESS(rv, nsnull); - - return mDBVisitToURLResult; -} - -mozIStorageStatement * -nsNavHistory::GetDBBookmarkToUrlResult() -{ - if (mDBBookmarkToUrlResult) - return mDBBookmarkToUrlResult; - - // 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. - nsresult rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "SELECT b.fk, h.url, COALESCE(b.title, h.title), " - "h.rev_host, h.visit_count, " - SQL_STR_FRAGMENT_MAX_VISIT_DATE( "b.fk" ) - ", f.url, null, b.id, b.dateAdded, b.lastModified " - "FROM moz_bookmarks b " - "JOIN moz_places_temp h ON b.fk = h.id " - "LEFT OUTER JOIN moz_favicons f ON h.favicon_id = f.id " - "WHERE b.id = ?1 " - "UNION ALL " - "SELECT b.fk, h.url, COALESCE(b.title, h.title), " - "h.rev_host, h.visit_count, " - SQL_STR_FRAGMENT_MAX_VISIT_DATE( "b.fk" ) - ", f.url, null, b.id, b.dateAdded, b.lastModified " - "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 " - "WHERE b.id = ?1 " - "LIMIT 1"), - getter_AddRefs(mDBBookmarkToUrlResult)); - NS_ENSURE_SUCCESS(rv, nsnull); - - return mDBBookmarkToUrlResult; -} - -mozIStorageStatement * -nsNavHistory::GetDBInvalidFrecencies() -{ - if (mDBInvalidFrecencies) - return mDBInvalidFrecencies; - - // find places with invalid frecencies (frecency < 0) - // invalid frecencies can happen in these scenarios: - // 1) we've done "clear private data" - // 2) we've expired or deleted visits - // 3) we've migrated from an older version, before global frecency - // - // from older versions, unmigrated bookmarks might be hidden, - // so we can't exclude hidden places (by doing "WHERE hidden <> 1") - // from our query, as we want to calculate the frecency for those - // places and unhide them (if they are not livemark items and not - // place: queries.) - // - // Note, we are not limiting ourselves to places with visits - // because we may not have any if the place is a bookmark and - // we expired or deleted all the visits. - // We get two sets of places that are 1) most visited and 2) random so that - // we don't get stuck recalculating frecencies that end up being -1 every - // time - // Since we don't need real random results and ORDER BY RANDOM() is slow - // we will jump at a random rowid in the table and we will get random results - // only from moz_places since temp will be synched there sometimes. - // Notice that frecency is invalidated as frecency = -visit_count - nsresult rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "SELECT * FROM ( " - "SELECT id, visit_count, hidden, typed, frecency, url " - "FROM ( " - "SELECT * FROM moz_places_temp " - "WHERE frecency < 0 " - "UNION ALL " - "SELECT * FROM ( " - "SELECT * FROM moz_places " - "WHERE +id NOT IN (SELECT id FROM moz_places_temp) " - "AND frecency < 0 " - "ORDER BY frecency ASC LIMIT ROUND(?1 / 2) " - ") " - ") ORDER BY frecency ASC LIMIT ROUND(?1 / 2)) " - "UNION " - "SELECT * FROM ( " - "SELECT id, visit_count, hidden, typed, frecency, url " - "FROM moz_places " - "WHERE frecency < 0 " - "AND ROWID >= ABS(RANDOM() % (SELECT MAX(ROWID) FROM moz_places)) " - "LIMIT ROUND(?1 / 2))"), - getter_AddRefs(mDBInvalidFrecencies)); - NS_ENSURE_SUCCESS(rv, nsnull); - - return mDBInvalidFrecencies; -} - -mozIStorageStatement * -nsNavHistory::GetDBOldFrecencies() -{ - if (mDBOldFrecencies) - return mDBOldFrecencies; - - // This query finds random old places to update frecency because frequently - // visited places will have their frecencies updated when visited. - // We can limit the selection to moz_places since results in temp tables - // have been most likely visited recently. - // Since we don't need real random results and ORDER BY RANDOM() is slow - // we will jump at a random rowid in the table. - nsresult rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - "SELECT id, visit_count, hidden, typed, frecency, url " - "FROM moz_places " - "WHERE ROWID >= ABS(RANDOM() % (SELECT MAX(ROWID) FROM moz_places)) " - "LIMIT ?1"), - getter_AddRefs(mDBOldFrecencies)); - NS_ENSURE_SUCCESS(rv, nsnull); - - return mDBOldFrecencies; -} - // nsICharsetResolver ********************************************************** NS_IMETHODIMP diff --git a/toolkit/components/places/src/nsNavHistory.h b/toolkit/components/places/src/nsNavHistory.h index 17e7c67f8604..c1aa15edd660 100644 --- a/toolkit/components/places/src/nsNavHistory.h +++ b/toolkit/components/places/src/nsNavHistory.h @@ -104,15 +104,10 @@ // this is a work-around for a problem with the optimizer of sqlite // A sub-select on MAX(visit_date) is slower than this query with our indexes // see Bug #392399 for more details -#define SQL_STR_FRAGMENT_MAX_VISIT_DATE_BASE( __place_relation, __table_name ) \ - "(SELECT visit_date FROM " __table_name \ - " WHERE place_id = " __place_relation \ +#define SQL_STR_FRAGMENT_MAX_VISIT_DATE( place_relation ) \ + "(SELECT visit_date FROM moz_historyvisits WHERE place_id = " place_relation \ " AND visit_type NOT IN (0,4,7) ORDER BY visit_date DESC LIMIT 1)" -#define SQL_STR_FRAGMENT_MAX_VISIT_DATE( __place_relation ) \ - "IFNULL( " SQL_STR_FRAGMENT_MAX_VISIT_DATE_BASE( __place_relation, "moz_historyvisits_temp") \ - ", " SQL_STR_FRAGMENT_MAX_VISIT_DATE_BASE( __place_relation, "moz_historyvisits") ")" - struct AutoCompleteIntermediateResult; class AutoCompleteResultComparator; class mozIAnnotationService; @@ -237,13 +232,17 @@ public: /** * These functions return non-owning references to the locale-specific - * objects for places components. + * objects for places components. Guaranteed to return non-NULL. */ - nsIStringBundle* GetBundle(); - nsICollation* GetCollation(); + nsIStringBundle* GetBundle() + { return mBundle; } + nsILocale* GetLocale() + { return mLocale; } + nsICollation* GetCollation() + { return mCollation; } + nsIDateTimeFormat* GetDateFormatter() + { return mDateFormatter; } void GetStringFromName(const PRUnichar* aName, nsACString& aResult); - void GetAgeInDaysString(PRInt32 aInt, const PRUnichar *aName, - nsACString& aResult); // returns true if history has been disabled PRBool IsHistoryDisabled() { return mExpireDaysMax == 0; } @@ -405,15 +404,11 @@ protected: nsCOMPtr mDBAddNewPage; // used by InternalAddNewPage nsCOMPtr mDBGetTags; // used by FilterResultSet nsCOMPtr mFoldersWithAnnotationQuery; // used by StartSearch and FilterResultSet - nsCOMPtr mDBSetPlaceTitle; // used by SetPageTitleInternal // these are used by VisitIdToResultNode for making new result nodes from IDs - // Consumers need to use the getters since these statements are lazily created - mozIStorageStatement *GetDBVisitToURLResult(); nsCOMPtr mDBVisitToURLResult; // kGetInfoIndex_* results - mozIStorageStatement *GetDBVisitToVisitResult(); nsCOMPtr mDBVisitToVisitResult; // kGetInfoIndex_* results - mozIStorageStatement *GetDBBookmarkToUrlResult(); + nsCOMPtr mDBUrlToUrlResult; // kGetInfoIndex_* results nsCOMPtr mDBBookmarkToUrlResult; // kGetInfoIndex_* results // nsICharsetResolver @@ -434,14 +429,12 @@ protected: nsresult CalculateFrecency(PRInt64 aPageID, PRInt32 aTyped, PRInt32 aVisitCount, nsCAutoString &aURL, PRInt32 *aFrecency); nsresult CalculateFrecencyInternal(PRInt64 aPageID, PRInt32 aTyped, PRInt32 aVisitCount, PRBool aIsBookmarked, PRInt32 *aFrecency); nsCOMPtr mDBVisitsForFrecency; + nsCOMPtr mDBInvalidFrecencies; + nsCOMPtr mDBOldFrecencies; nsCOMPtr mDBUpdateFrecencyAndHidden; nsCOMPtr mDBGetPlaceVisitStats; nsCOMPtr mDBGetBookmarkParentsForPlace; nsCOMPtr mDBFullVisitCount; - mozIStorageStatement *GetDBInvalidFrecencies(); - nsCOMPtr mDBInvalidFrecencies; - mozIStorageStatement *GetDBOldFrecencies(); - nsCOMPtr mDBOldFrecencies; /** * Initializes the database file. If the database does not exist, was @@ -470,15 +463,12 @@ protected: * The database was migrated to a new version. */ nsresult InitDB(PRInt16 *aMadeChanges); - nsresult InitTempTables(); - nsresult InitViews(); nsresult InitFunctions(); nsresult InitStatements(); nsresult ForceMigrateBookmarksDB(mozIStorageConnection *aDBConn); nsresult MigrateV3Up(mozIStorageConnection *aDBConn); nsresult MigrateV6Up(mozIStorageConnection *aDBConn); nsresult MigrateV7Up(mozIStorageConnection *aDBConn); - nsresult MigrateV8Up(mozIStorageConnection *aDBConn); nsresult EnsureCurrentSchema(mozIStorageConnection* aDBConn, PRBool *aMadeChanges); nsresult CleanUpOnQuit(); @@ -592,6 +582,9 @@ protected: nsNavHistoryQueryOptions* aOptions, nsCOMArray* aResults); + void GetAgeInDaysString(PRInt32 aInt, const PRUnichar *aName, + nsACString& aResult); + void TitleForDomain(const nsCString& domain, nsACString& aTitle); nsresult SetPageTitleInternal(nsIURI* aURI, const nsAString& aTitle); @@ -611,7 +604,9 @@ protected: // localization nsCOMPtr mBundle; + nsCOMPtr mLocale; nsCOMPtr mCollation; + nsCOMPtr mDateFormatter; // annotation service : MAY BE NULL! //nsCOMPtr mAnnotationService; @@ -654,16 +649,12 @@ protected: static const PRInt32 kAutoCompleteIndex_VisitCount; nsCOMPtr mDBCurrentQuery; // kAutoCompleteIndex_* results nsCOMPtr mDBAutoCompleteQuery; // kAutoCompleteIndex_* results - mozIStorageStatement* GetDBAutoCompleteHistoryQuery(); nsCOMPtr mDBAutoCompleteHistoryQuery; // kAutoCompleteIndex_* results - mozIStorageStatement* GetDBAutoCompleteStarQuery(); nsCOMPtr mDBAutoCompleteStarQuery; // kAutoCompleteIndex_* results - mozIStorageStatement* GetDBAutoCompleteTagsQuery(); nsCOMPtr mDBAutoCompleteTagsQuery; // kAutoCompleteIndex_* results nsCOMPtr mDBPreviousQuery; // kAutoCompleteIndex_* results nsCOMPtr mDBAdaptiveQuery; // kAutoCompleteIndex_* results nsCOMPtr mDBKeywordQuery; // kAutoCompleteIndex_* results - mozIStorageStatement* GetDBFeedbackIncrease(); nsCOMPtr mDBFeedbackIncrease; /** diff --git a/toolkit/components/places/src/nsNavHistoryAutoComplete.cpp b/toolkit/components/places/src/nsNavHistoryAutoComplete.cpp index ed7d7498f5b5..2afa757392e3 100644 --- a/toolkit/components/places/src/nsNavHistoryAutoComplete.cpp +++ b/toolkit/components/places/src/nsNavHistoryAutoComplete.cpp @@ -26,7 +26,6 @@ * Seth Spitzer * Dietrich Ayala * Edward Lee - * Marco Bonardo * * 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 @@ -93,7 +92,7 @@ NS_LITERAL_CSTRING(" AND b.fk = h.id") + \ (getMostRecent ? NS_LITERAL_CSTRING(" " \ "ORDER BY b.lastModified DESC LIMIT 1") : EmptyCString()) + \ - NS_LITERAL_CSTRING(") AS " name) + NS_LITERAL_CSTRING(") " name) // Get three named columns from the bookmarks and tags table #define BOOK_TAG_SQL (\ @@ -108,49 +107,6 @@ const PRUnichar kTitleTagsSeparatorChars[] = { ' ', 0x2013, ' ', 0 }; #define TITLE_TAGS_SEPARATOR nsAutoString(kTitleTagsSeparatorChars) -// This fragment is used to get best favicon for a rev_host -#define BEST_FAVICON_FOR_REVHOST( __table_name ) \ - "(SELECT f.url FROM " __table_name " " \ - "JOIN moz_favicons f ON f.id = favicon_id " \ - "WHERE rev_host = IFNULL( " \ - "(SELECT rev_host FROM moz_places_temp WHERE id = b.fk), " \ - "(SELECT rev_host FROM moz_places WHERE id = b.fk)) " \ - "ORDER BY frecency DESC LIMIT 1) " - -void GetAutoCompleteBaseQuery(nsACString& aQuery) { -// Define common pieces of various queries -// XXX bug 412736 -// in the case of a frecency tie, break it with h.typed and h.visit_count -// which is better than nothing. but this is slow, so not doing it yet. - -// Try to reduce size of compound table since with partitioning this became -// slower. Limiting moz_places with OFFSET+LIMIT will mostly help speed -// of first chunks, that are usually most wanted. -// Can do this only if there aren't additional conditions on final resultset. - -// Note: h.frecency is selected because we need it for ordering, but will -// not be read later and we don't have an associated kAutoCompleteIndex_ - aQuery = NS_LITERAL_CSTRING( - "SELECT h.url, h.title, f.url") + BOOK_TAG_SQL + NS_LITERAL_CSTRING(", " - "h.visit_count, h.frecency " - "FROM moz_places_temp h " - "LEFT OUTER JOIN moz_favicons f ON f.id = h.favicon_id " - "WHERE h.frecency <> 0 " - "{ADDITIONAL_CONDITIONS} " - "UNION ALL " - "SELECT * FROM ( " - "SELECT h.url, h.title, f.url") + BOOK_TAG_SQL + NS_LITERAL_CSTRING(", " - "h.visit_count, h.frecency " - "FROM moz_places h " - "LEFT OUTER JOIN moz_favicons f ON f.id = h.favicon_id " - "WHERE h.id NOT IN (SELECT id FROM moz_places_temp) " - "AND h.frecency <> 0 " - "{ADDITIONAL_CONDITIONS} " - "ORDER BY h.frecency DESC LIMIT (?2 + ?3) " - ") " - "ORDER BY 8 DESC LIMIT ?2 OFFSET ?3"); -} - //////////////////////////////////////////////////////////////////////////////// //// nsNavHistoryAutoComplete Helper Functions @@ -297,159 +253,94 @@ nsNavHistory::InitAutoComplete() return NS_OK; } -// nsNavHistory::GetDBAutoCompleteHistoryQuery() -// -// Returns the auto complete statement used when autocomplete results are -// restricted to history entries. -mozIStorageStatement* -nsNavHistory::GetDBAutoCompleteHistoryQuery() -{ - if (mDBAutoCompleteHistoryQuery) - return mDBAutoCompleteHistoryQuery; - - nsCString AutoCompleteHistoryQuery; - GetAutoCompleteBaseQuery(AutoCompleteHistoryQuery); - AutoCompleteHistoryQuery.ReplaceSubstring("{ADDITIONAL_CONDITIONS}", - "AND h.visit_count > 0"); - nsresult rv = mDBConn->CreateStatement(AutoCompleteHistoryQuery, - getter_AddRefs(mDBAutoCompleteHistoryQuery)); - NS_ENSURE_SUCCESS(rv, nsnull); - - return mDBAutoCompleteHistoryQuery; -} - -// nsNavHistory::GetDBAutoCompleteStarQuery() -// -// Returns the auto complete statement used when autocomplete results are -// restricted to bookmarked entries. -mozIStorageStatement* -nsNavHistory::GetDBAutoCompleteStarQuery() -{ - if (mDBAutoCompleteStarQuery) - return mDBAutoCompleteStarQuery; - - nsCString AutoCompleteStarQuery; - GetAutoCompleteBaseQuery(AutoCompleteStarQuery); - AutoCompleteStarQuery.ReplaceSubstring("{ADDITIONAL_CONDITIONS}", - "AND bookmark IS NOT NULL"); - nsresult rv = mDBConn->CreateStatement(AutoCompleteStarQuery, - getter_AddRefs(mDBAutoCompleteStarQuery)); - NS_ENSURE_SUCCESS(rv, nsnull); - - return mDBAutoCompleteStarQuery; -} - -// nsNavHistory::GetDBAutoCompleteTagsQuery() -// -// Returns the auto complete statement used when autocomplete results are -// restricted to tagged entries. -mozIStorageStatement* -nsNavHistory::GetDBAutoCompleteTagsQuery() -{ - if (mDBAutoCompleteTagsQuery) - return mDBAutoCompleteTagsQuery; - - nsCString AutoCompleteTagsQuery; - GetAutoCompleteBaseQuery(AutoCompleteTagsQuery); - AutoCompleteTagsQuery.ReplaceSubstring("{ADDITIONAL_CONDITIONS}", - "AND tags IS NOT NULL"); - nsresult rv = mDBConn->CreateStatement(AutoCompleteTagsQuery, - getter_AddRefs(mDBAutoCompleteTagsQuery)); - NS_ENSURE_SUCCESS(rv, nsnull); - - return mDBAutoCompleteTagsQuery; -} - -// nsNavHistory::GetDBFeedbackIncrease() -// -// Returns the statement to update the input history that keeps track of -// selections in the locationbar. Input history is used for adaptive query. -mozIStorageStatement* -nsNavHistory::GetDBFeedbackIncrease() -{ - if (mDBFeedbackIncrease) - return mDBFeedbackIncrease; - - nsresult rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( - // Leverage the PRIMARY KEY (place_id, input) to insert/update entries - "INSERT OR REPLACE INTO moz_inputhistory " - // use_count will asymptotically approach the max of 10 - "SELECT h.id, IFNULL(i.input, ?1), IFNULL(i.use_count, 0) * .9 + 1 " - "FROM moz_places_temp h " - "LEFT JOIN moz_inputhistory i ON i.place_id = h.id AND i.input = ?1 " - "WHERE url = ?2 " - "UNION ALL " - "SELECT h.id, IFNULL(i.input, ?1), IFNULL(i.use_count, 0) * .9 + 1 " - "FROM moz_places h " - "LEFT JOIN moz_inputhistory i ON i.place_id = h.id AND i.input = ?1 " - "WHERE url = ?2 " - "AND h.id NOT IN (SELECT id FROM moz_places_temp)"), - getter_AddRefs(mDBFeedbackIncrease)); - NS_ENSURE_SUCCESS(rv, nsnull); - - return mDBFeedbackIncrease; -} // nsNavHistory::CreateAutoCompleteQueries // // The auto complete queries we use depend on options, so we have them in // a separate function so it can be re-created when the option changes. -// We are not lazy creating these queries because they will be most likely -// used on first search, and we don't want to lag on first autocomplete use. + nsresult nsNavHistory::CreateAutoCompleteQueries() { - nsCString AutoCompleteQuery; - GetAutoCompleteBaseQuery(AutoCompleteQuery); - AutoCompleteQuery.ReplaceSubstring("{ADDITIONAL_CONDITIONS}", - (mAutoCompleteOnlyTyped ? - "AND h.typed = 1" : "")); - nsresult rv = mDBConn->CreateStatement(AutoCompleteQuery, - getter_AddRefs(mDBAutoCompleteQuery)); + // Define common pieces of various queries + nsCString sqlHead = NS_LITERAL_CSTRING( + "SELECT h.url, h.title, f.url") + BOOK_TAG_SQL + NS_LITERAL_CSTRING(", " + "h.visit_count " + "FROM moz_places h " + "LEFT OUTER JOIN moz_favicons f ON f.id = h.favicon_id " + "WHERE h.frecency <> 0 "); + // NOTE: + // after migration or clear all private data, we might end up with + // a lot of places with frecency < 0 (until idle) + // + // XXX bug 412736 + // in the case of a frecency tie, break it with h.typed and h.visit_count + // which is better than nothing. but this is slow, so not doing it yet. + nsCString sqlTail = NS_LITERAL_CSTRING( + "ORDER BY h.frecency DESC LIMIT ?2 OFFSET ?3"); + + nsresult rv = mDBConn->CreateStatement(sqlHead + (mAutoCompleteOnlyTyped ? + NS_LITERAL_CSTRING("AND h.typed = 1 ") : EmptyCString()) + sqlTail, + getter_AddRefs(mDBAutoCompleteQuery)); + NS_ENSURE_SUCCESS(rv, rv); + + rv = mDBConn->CreateStatement(sqlHead + + NS_LITERAL_CSTRING("AND h.visit_count > 0 ") + sqlTail, + getter_AddRefs(mDBAutoCompleteHistoryQuery)); + NS_ENSURE_SUCCESS(rv, rv); + + rv = mDBConn->CreateStatement(sqlHead + + NS_LITERAL_CSTRING("AND bookmark IS NOT NULL ") + sqlTail, + getter_AddRefs(mDBAutoCompleteStarQuery)); + NS_ENSURE_SUCCESS(rv, rv); + + rv = mDBConn->CreateStatement(sqlHead + + NS_LITERAL_CSTRING("AND tags IS NOT NULL ") + sqlTail, + getter_AddRefs(mDBAutoCompleteTagsQuery)); NS_ENSURE_SUCCESS(rv, rv); - // In this query we are taking BOOK_TAG_SQL only for h.id because it - // uses data from moz_bookmarks table and we sync tables on bookmark insert. - // So, most likely, h.id will always be populated when we have any bookmark. - // We still need to join on moz_places_temp for other data (eg. title). nsCString sql = NS_LITERAL_CSTRING( - "SELECT IFNULL(h_t.url, h.url), IFNULL(h_t.title, h.title), f.url ") + - BOOK_TAG_SQL + NS_LITERAL_CSTRING(", " - "IFNULL(h_t.visit_count, h.visit_count), rank " - "FROM ( " - "SELECT ROUND(MAX(((i.input = ?2) + (SUBSTR(i.input, 1, LENGTH(?2)) = ?2)) * " - "i.use_count), 1) AS rank, place_id " - "FROM moz_inputhistory i " - "GROUP BY i.place_id HAVING rank > 0 " - ") AS i " - "LEFT JOIN moz_places h ON h.id = i.place_id " - "LEFT JOIN moz_places_temp h_t ON h_t.id = i.place_id " - "LEFT JOIN moz_favicons f ON f.id = IFNULL(h_t.favicon_id, h.favicon_id) " - "WHERE IFNULL(h_t.url, h.url) NOTNULL " - "ORDER BY rank DESC, IFNULL(h_t.frecency, h.frecency) DESC"); + "SELECT h.url, h.title, f.url") + BOOK_TAG_SQL + NS_LITERAL_CSTRING(", " + "h.visit_count, " + "ROUND(MAX(((i.input = ?2) + (SUBSTR(i.input, 1, LENGTH(?2)) = ?2)) * " + "i.use_count), 1) rank " + "FROM moz_inputhistory i " + "JOIN moz_places h ON h.id = i.place_id " + "LEFT OUTER JOIN moz_favicons f ON f.id = h.favicon_id " + "GROUP BY i.place_id HAVING rank > 0 " + "ORDER BY rank DESC, h.frecency DESC"); rv = mDBConn->CreateStatement(sql, getter_AddRefs(mDBAdaptiveQuery)); NS_ENSURE_SUCCESS(rv, rv); sql = NS_LITERAL_CSTRING( - "SELECT IFNULL( " - "(SELECT REPLACE(url, '%s', ?2) FROM moz_places_temp WHERE id = b.fk), " - "(SELECT REPLACE(url, '%s', ?2) FROM moz_places WHERE id = b.fk) " - ") AS search_url, IFNULL(h_t.title, h.title), " - "COALESCE(f.url, " - BEST_FAVICON_FOR_REVHOST("moz_places_temp") ", " - BEST_FAVICON_FOR_REVHOST("moz_places") - "), " - "b.parent, b.title, NULL, IFNULL(h_t.visit_count, h.visit_count) " + "SELECT REPLACE(s.url, '%s', ?2) search_url, h.title, IFNULL(f.url, " + "(SELECT f.url " + "FROM moz_places r " + "JOIN moz_favicons f ON f.id = r.favicon_id " + "WHERE r.rev_host = s.rev_host " + "ORDER BY r.frecency DESC LIMIT 1)), " + "b.parent, b.title, NULL, h.visit_count " "FROM moz_keywords k " "JOIN moz_bookmarks b ON b.keyword_id = k.id " - "LEFT JOIN moz_places AS h ON h.url = search_url " - "LEFT JOIN moz_places_temp AS h_t ON h_t.url = search_url " - "LEFT JOIN moz_favicons f ON f.id = IFNULL(h_t.favicon_id, h.favicon_id) " + "JOIN moz_places s ON s.id = b.fk " + "LEFT OUTER JOIN moz_places h ON h.url = search_url " + "LEFT OUTER JOIN moz_favicons f ON f.id = h.favicon_id " "WHERE LOWER(k.keyword) = LOWER(?1) " - "ORDER BY IFNULL(h_t.frecency, h.frecency) DESC"); + "ORDER BY h.frecency DESC"); rv = mDBConn->CreateStatement(sql, getter_AddRefs(mDBKeywordQuery)); NS_ENSURE_SUCCESS(rv, rv); + sql = NS_LITERAL_CSTRING( + // Leverage the PRIMARY KEY (place_id, input) to insert/update entries + "INSERT OR REPLACE INTO moz_inputhistory " + // use_count will asymptotically approach the max of 10 + "SELECT h.id, IFNULL(i.input, ?1), IFNULL(i.use_count, 0) * .9 + 1 " + "FROM moz_places h " + "LEFT OUTER JOIN moz_inputhistory i ON i.place_id = h.id AND i.input = ?1 " + "WHERE h.url = ?2"); + rv = mDBConn->CreateStatement(sql, getter_AddRefs(mDBFeedbackIncrease)); + NS_ENSURE_SUCCESS(rv, rv); + return NS_OK; } @@ -646,30 +537,23 @@ nsNavHistory::StartSearch(const nsAString & aSearchString, // has more than 0 results. We can continue from where the previous // search left off, but first we want to create an optimized query that // only searches through the urls that were previously found - - // We have to do the bindings for both tables, so we build a temporary - // string - nsCString bindings; - for (PRUint32 i = 0; i < prevMatchCount; i++) { - if (i) - bindings += NS_LITERAL_CSTRING(","); - - // +2 to skip over the ?1 for the tag root parameter - bindings += nsPrintfCString("?%d", i + 2); - } - nsCString sql = NS_LITERAL_CSTRING( "SELECT h.url, h.title, f.url") + BOOK_TAG_SQL + NS_LITERAL_CSTRING(", " "h.visit_count " - "FROM ( " - "SELECT * FROM moz_places_temp " - "WHERE url IN (") + bindings + NS_LITERAL_CSTRING(") " - "UNION ALL " - "SELECT * FROM moz_places " - "WHERE id NOT IN (SELECT id FROM moz_places_temp) " - "AND url IN (") + bindings + NS_LITERAL_CSTRING(") " - ") AS h " + "FROM moz_places h " "LEFT OUTER JOIN moz_favicons f ON f.id = h.favicon_id " + "WHERE h.url IN ("); + + // Put in bind spots for the urls + for (PRUint32 i = 0; i < prevMatchCount; i++) { + if (i) + sql += NS_LITERAL_CSTRING(","); + + // +2 to skip over the ?1 for the tag root parameter + sql += nsPrintfCString("?%d", i + 2); + } + + sql += NS_LITERAL_CSTRING(") " "ORDER BY h.frecency DESC"); rv = mDBConn->CreateStatement(sql, getter_AddRefs(mDBPreviousQuery)); @@ -819,10 +703,10 @@ nsNavHistory::ProcessTokensForSpecialSearch() // We can use optimized queries for restricts, so check for the most // restrictive query first - mDBCurrentQuery = mRestrictTag ? GetDBAutoCompleteTagsQuery() : - mRestrictBookmark ? GetDBAutoCompleteStarQuery() : - mRestrictHistory ? GetDBAutoCompleteHistoryQuery() : - static_cast(mDBAutoCompleteQuery); + mDBCurrentQuery = mRestrictTag ? mDBAutoCompleteTagsQuery : + mRestrictBookmark ? mDBAutoCompleteStarQuery : + mRestrictHistory ? mDBAutoCompleteHistoryQuery : + mDBAutoCompleteQuery; } nsresult @@ -1125,22 +1009,21 @@ nsresult nsNavHistory::AutoCompleteFeedback(PRInt32 aIndex, nsIAutoCompleteController *aController) { - mozIStorageStatement* statement = GetDBFeedbackIncrease(); - mozStorageStatementScoper scope(statement); + mozStorageStatementScoper scope(mDBFeedbackIncrease); nsAutoString input; nsresult rv = aController->GetSearchString(input); NS_ENSURE_SUCCESS(rv, rv); - rv = statement->BindStringParameter(0, input); + rv = mDBFeedbackIncrease->BindStringParameter(0, input); NS_ENSURE_SUCCESS(rv, rv); nsAutoString url; rv = aController->GetValueAt(aIndex, url); NS_ENSURE_SUCCESS(rv, rv); - rv = statement->BindStringParameter(1, url); + rv = mDBFeedbackIncrease->BindStringParameter(1, url); NS_ENSURE_SUCCESS(rv, rv); - rv = statement->Execute(); + rv = mDBFeedbackIncrease->Execute(); NS_ENSURE_SUCCESS(rv, rv); return NS_OK; diff --git a/toolkit/components/places/src/nsNavHistoryExpire.cpp b/toolkit/components/places/src/nsNavHistoryExpire.cpp index 4b24556fc9ac..2a6d96c994ac 100644 --- a/toolkit/components/places/src/nsNavHistoryExpire.cpp +++ b/toolkit/components/places/src/nsNavHistoryExpire.cpp @@ -252,29 +252,20 @@ nsNavHistoryExpire::ClearHistory() // idle query to figure out which places to recalcuate frecency first. // We must do this before deleting visits nsresult rv = connection->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "UPDATE moz_places_view SET frecency = -MAX(visit_count, 1) " + "UPDATE moz_places SET frecency = -MAX(visit_count, 1) " "WHERE id IN(" - "SELECT h.id FROM moz_places_temp h " - "WHERE " + "SELECT h.id FROM moz_places h WHERE " "EXISTS (SELECT id FROM moz_bookmarks WHERE fk = h.id) " "OR EXISTS " - "(SELECT id FROM moz_annos WHERE place_id = h.id AND expiration = ") + - nsPrintfCString("%d", nsIAnnotationService::EXPIRE_NEVER) + - NS_LITERAL_CSTRING(") " - "UNION ALL " - "SELECT h.id FROM moz_places h " - "WHERE " - "EXISTS (SELECT id FROM moz_bookmarks WHERE fk = h.id) " - "OR EXISTS " - "(SELECT id FROM moz_annos WHERE place_id = h.id AND expiration = ") + - nsPrintfCString("%d", nsIAnnotationService::EXPIRE_NEVER) + - NS_LITERAL_CSTRING(") " - ")")); - NS_ENSURE_SUCCESS(rv, rv); + "(SELECT id FROM moz_annos WHERE place_id = h.id AND expiration = ") + + nsPrintfCString("%d", nsIAnnotationService::EXPIRE_NEVER) + + NS_LITERAL_CSTRING(")")); + if (NS_FAILED(rv)) + NS_WARNING("failed to recent frecency"); // expire visits, then let the paranoid functions do the cleanup for us rv = connection->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "DELETE FROM moz_historyvisits_view")); + "DELETE FROM moz_historyvisits")); NS_ENSURE_SUCCESS(rv, rv); rv = ExpireHistoryParanoid(connection, -1); @@ -480,38 +471,11 @@ nsNavHistoryExpire::FindVisits(PRTime aExpireThreshold, PRUint32 aNumToExpire, // Select a limited number of visits older than a time nsCOMPtr selectStatement; nsresult rv = aConnection->CreateStatement(NS_LITERAL_CSTRING( - "SELECT * FROM ( " - "SELECT v.id, v.place_id, v.visit_date, h.url, h.favicon_id, h.hidden, " - "(SELECT fk FROM moz_bookmarks WHERE fk = h.id) " - "FROM moz_places h " - "JOIN moz_historyvisits AS v ON h.id = v.place_id " - "WHERE visit_date < ?1 " - "ORDER BY v.visit_date ASC LIMIT ?2 " - ") UNION ALL " - "SELECT * FROM ( " - "SELECT v.id, v.place_id, v.visit_date, h.url, h.favicon_id, h.hidden, " - "(SELECT fk FROM moz_bookmarks WHERE fk = h.id)" - "FROM moz_places_temp h " - "JOIN moz_historyvisits AS v ON h.id = v.place_id " - "WHERE visit_date < ?1 " - "ORDER BY v.visit_date ASC LIMIT ?2 " - ") UNION ALL " - "SELECT * FROM ( " - "SELECT v.id, v.place_id, v.visit_date, h.url, h.favicon_id, h.hidden, " - "(SELECT fk FROM moz_bookmarks WHERE fk = h.id) " - "FROM moz_places h " - "JOIN moz_historyvisits_temp AS v ON h.id = v.place_id " - "WHERE visit_date < ?1 " - "ORDER BY v.visit_date ASC LIMIT ?2 " - ") UNION ALL " - "SELECT * FROM ( " - "SELECT v.id, v.place_id, v.visit_date, h.url, h.favicon_id, h.hidden, " - "(SELECT fk FROM moz_bookmarks WHERE fk = h.id) " - "FROM moz_places_temp h " - "JOIN moz_historyvisits_temp AS v ON h.id = v.place_id " - "WHERE visit_date < ?1 " - "ORDER BY v.visit_date ASC LIMIT ?2 " - ") GROUP BY 1 ORDER BY 3 ASC LIMIT ?2"), + "SELECT v.id, v.place_id, v.visit_date, h.url, h.favicon_id, h.hidden, " + "(SELECT fk FROM moz_bookmarks WHERE fk = h.id) " + "FROM moz_places h JOIN moz_historyvisits v ON h.id = v.place_id " + "WHERE v.visit_date < ?1 " + "ORDER BY v.visit_date ASC LIMIT ?2"), getter_AddRefs(selectStatement)); NS_ENSURE_SUCCESS(rv, rv); @@ -537,11 +501,7 @@ nsNavHistoryExpire::FindVisits(PRTime aExpireThreshold, PRUint32 aNumToExpire, // check the number of visited unique urls in the db. nsCOMPtr countStatement; rv = aConnection->CreateStatement(NS_LITERAL_CSTRING( - "SELECT " - "(SELECT count(*) FROM moz_places_temp WHERE visit_count > 0) + " - "(SELECT count(*) FROM moz_places WHERE visit_count > 0) - " - "(SELECT count(*) FROM moz_places WHERE id IN " - "(SELECT id FROM moz_places_temp))"), + "SELECT count(*) FROM moz_places WHERE visit_count > 0"), getter_AddRefs(countStatement)); NS_ENSURE_SUCCESS(rv, rv); @@ -616,44 +576,23 @@ nsNavHistoryExpire::EraseVisits(mozIStorageConnection* aConnection, // keep the old frecencies when possible as an estimate for the new frecency // unless we know it has to be invalidated. // We must do this before deleting visits - nsresult rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "UPDATE moz_places_view " - "SET frecency = -MAX(visit_count, 1) " - "WHERE id IN ( " - "SELECT h.id FROM moz_places_temp h " - "WHERE " - "NOT EXISTS (SELECT id FROM moz_bookmarks WHERE fk = h.id) AND " - "NOT EXISTS ( " - "SELECT v.id FROM moz_historyvisits_temp v " - "WHERE v.place_id = h.id " - "AND v.id NOT IN (") + deletedVisitIds + NS_LITERAL_CSTRING(") " - ") AND " - "NOT EXISTS ( " - "SELECT v.id FROM moz_historyvisits v " - "WHERE v.place_id = h.id " - "AND v.id NOT IN (") + deletedVisitIds + NS_LITERAL_CSTRING(") " - ") AND " - "h.id IN (") + placeIds + NS_LITERAL_CSTRING(") " - "UNION ALL " - "SELECT h.id FROM moz_places h " - "WHERE " - "NOT EXISTS (SELECT id FROM moz_bookmarks WHERE fk = h.id) AND " - "NOT EXISTS ( " - "SELECT v.id FROM moz_historyvisits_temp v " - "WHERE v.place_id = h.id " - "AND v.id NOT IN (") + deletedVisitIds + NS_LITERAL_CSTRING(") " - ") AND " - "NOT EXISTS ( " - "SELECT v.id FROM moz_historyvisits v " - "WHERE v.place_id = h.id " - "AND v.id NOT IN (") + deletedVisitIds + NS_LITERAL_CSTRING(") " - ") AND " - "h.id IN (") + placeIds + NS_LITERAL_CSTRING(") " - ")")); + nsresult rv = aConnection->ExecuteSimpleSQL( + NS_LITERAL_CSTRING( + "UPDATE moz_places " + "SET frecency = -MAX(visit_count, 1) " + "WHERE id IN (" + "SELECT h.id FROM moz_places h " + "WHERE NOT EXISTS (SELECT b.id FROM moz_bookmarks b WHERE b.fk = h.id) " + "AND NOT EXISTS " + "(SELECT v.id FROM moz_historyvisits v WHERE v.place_id = h.id AND " + "v.id NOT IN (") + deletedVisitIds + + NS_LITERAL_CSTRING(")) AND " + "h.id IN (") + placeIds + + NS_LITERAL_CSTRING("))")); NS_ENSURE_SUCCESS(rv, rv); rv = aConnection->ExecuteSimpleSQL( - NS_LITERAL_CSTRING("DELETE FROM moz_historyvisits_view WHERE id IN (") + + NS_LITERAL_CSTRING("DELETE FROM moz_historyvisits WHERE id IN (") + deletedVisitIds + NS_LITERAL_CSTRING(")")); NS_ENSURE_SUCCESS(rv, rv); @@ -697,33 +636,17 @@ nsNavHistoryExpire::EraseHistory(mozIStorageConnection* aConnection, if (deletedPlaceIds.IsEmpty()) return NS_OK; - nsresult rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "DELETE FROM moz_places_view WHERE id IN( " - "SELECT h.id " - "FROM moz_places h " - "WHERE h.id IN(") + deletedPlaceIds + NS_LITERAL_CSTRING(") " + return aConnection->ExecuteSimpleSQL( + NS_LITERAL_CSTRING("DELETE FROM moz_places WHERE id IN( " + "SELECT h.id " + "FROM moz_places h " + "WHERE h.id IN(") + + deletedPlaceIds + + NS_LITERAL_CSTRING(") AND NOT EXISTS " + "(SELECT id FROM moz_historyvisits WHERE place_id = h.id LIMIT 1) " "AND NOT EXISTS " - "(SELECT id FROM moz_historyvisits WHERE place_id = h.id LIMIT 1) " - "AND NOT EXISTS " - "(SELECT id FROM moz_historyvisits_temp WHERE place_id = h.id LIMIT 1) " - "AND NOT EXISTS " - "(SELECT id FROM moz_bookmarks WHERE fk = h.id LIMIT 1) " - "AND SUBSTR(h.url,0,6) <> 'place:' " - "UNION ALL " - "SELECT h.id " - "FROM moz_places_temp h " - "WHERE h.id IN(") + deletedPlaceIds + NS_LITERAL_CSTRING(") " - "AND NOT EXISTS " - "(SELECT id FROM moz_historyvisits WHERE place_id = h.id LIMIT 1) " - "AND NOT EXISTS " - "(SELECT id FROM moz_historyvisits_temp WHERE place_id = h.id LIMIT 1) " - "AND NOT EXISTS " - "(SELECT id FROM moz_bookmarks WHERE fk = h.id LIMIT 1) " - "AND SUBSTR(h.url,0,6) <> 'place:' " - ")")); - NS_ENSURE_SUCCESS(rv, rv); - - return NS_OK; + "(SELECT id FROM moz_bookmarks WHERE fk = h.id LIMIT 1) " + "AND SUBSTR(h.url,0,6) <> 'place:')")); } @@ -753,19 +676,13 @@ nsNavHistoryExpire::EraseFavicons(mozIStorageConnection* aConnection, if (deletedFaviconIds.IsEmpty()) return NS_OK; - // delete only if favicon id is not referenced - nsresult rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "DELETE FROM moz_favicons WHERE id IN ( " - "SELECT f.id FROM moz_favicons f " - "LEFT JOIN moz_places h ON f.id = h.favicon_id " - "LEFT JOIN moz_places_temp h_t ON f.id = h_t.favicon_id " - "WHERE f.id IN (") + deletedFaviconIds + NS_LITERAL_CSTRING(") " - "AND h.favicon_id IS NULL " - "AND h_t.favicon_id IS NULL " - ")")); - NS_ENSURE_SUCCESS(rv, rv); - - return NS_OK; + // delete only if id is not referenced in moz_places + return aConnection->ExecuteSimpleSQL( + NS_LITERAL_CSTRING("DELETE FROM moz_favicons WHERE id IN ( " + "SELECT f.id FROM moz_favicons f " + "LEFT OUTER JOIN moz_places h ON f.id = h.favicon_id " + "WHERE f.id IN (") + deletedFaviconIds + + NS_LITERAL_CSTRING(") AND h.favicon_id IS NULL)")); } @@ -818,16 +735,12 @@ nsNavHistoryExpire::ExpireAnnotations(mozIStorageConnection* aConnection) PRTime now = PR_Now(); nsCOMPtr expirePagesStatement; nsresult rv = aConnection->CreateStatement(NS_LITERAL_CSTRING( - "DELETE FROM moz_annos " - "WHERE expiration = ?1 AND " - "(?2 > MAX(COALESCE(lastModified, 0), dateAdded))"), + "DELETE FROM moz_annos WHERE expiration = ?1 AND (?2 > MAX(COALESCE(lastModified, 0), dateAdded))"), getter_AddRefs(expirePagesStatement)); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr expireItemsStatement; rv = aConnection->CreateStatement(NS_LITERAL_CSTRING( - "DELETE FROM moz_items_annos " - "WHERE expiration = ?1 AND " - "(?2 > MAX(COALESCE(lastModified, 0), dateAdded))"), + "DELETE FROM moz_items_annos WHERE expiration = ?1 AND (?2 > MAX(COALESCE(lastModified, 0), dateAdded))"), getter_AddRefs(expireItemsStatement)); NS_ENSURE_SUCCESS(rv, rv); @@ -884,9 +797,6 @@ nsNavHistoryExpire::ExpireAnnotations(mozIStorageConnection* aConnection) "DELETE FROM moz_annos WHERE expiration = ") + nsPrintfCString("%d", nsIAnnotationService::EXPIRE_WITH_HISTORY) + NS_LITERAL_CSTRING(" AND NOT EXISTS " - "(SELECT id FROM moz_historyvisits_temp " - "WHERE place_id = moz_annos.place_id LIMIT 1) " - "AND NOT EXISTS " "(SELECT id FROM moz_historyvisits " "WHERE place_id = moz_annos.place_id LIMIT 1)")); NS_ENSURE_SUCCESS(rv, rv); @@ -907,31 +817,16 @@ nsNavHistoryExpire::ExpireEmbeddedLinks(mozIStorageConnection* aConnection) nsCOMPtr expireEmbeddedLinksStatement; // Note: This query also removes visit_type = 0 entries, for bug #375777. nsresult rv = aConnection->CreateStatement(NS_LITERAL_CSTRING( - "DELETE FROM moz_historyvisits_view WHERE id IN (" - "SELECT * FROM ( " - "SELECT id FROM moz_historyvisits_temp " - "WHERE visit_date < ?1 " - "AND visit_type IN (") + - nsPrintfCString("%d", nsINavHistoryService::TRANSITION_EMBED) + - NS_LITERAL_CSTRING(", 0) " - "LIMIT ?2 " - ") " - "UNION ALL " - "SELECT * FROM ( " - "SELECT id FROM moz_historyvisits " - "WHERE visit_date < ?1 " - "AND visit_type IN (") + - nsPrintfCString("%d", nsINavHistoryService::TRANSITION_EMBED) + - NS_LITERAL_CSTRING(", 0) " - "LIMIT ?2 " - ") " - "LIMIT ?2 " - ")"), + "DELETE FROM moz_historyvisits WHERE id IN (" + "SELECT id FROM moz_historyvisits WHERE visit_date < ?1 " + "AND (visit_type = ?2 OR visit_type = 0) LIMIT ?3)"), getter_AddRefs(expireEmbeddedLinksStatement)); NS_ENSURE_SUCCESS(rv, rv); rv = expireEmbeddedLinksStatement->BindInt64Parameter(0, maxEmbeddedAge); NS_ENSURE_SUCCESS(rv, rv); - rv = expireEmbeddedLinksStatement->BindInt32Parameter(1, EXPIRATION_CAP_EMBEDDED); + rv = expireEmbeddedLinksStatement->BindInt32Parameter(1, nsINavHistoryService::TRANSITION_EMBED); + NS_ENSURE_SUCCESS(rv, rv); + rv = expireEmbeddedLinksStatement->BindInt32Parameter(2, EXPIRATION_CAP_EMBEDDED); NS_ENSURE_SUCCESS(rv, rv); rv = expireEmbeddedLinksStatement->Execute(); NS_ENSURE_SUCCESS(rv, rv); @@ -952,24 +847,11 @@ nsNavHistoryExpire::ExpireHistoryParanoid(mozIStorageConnection* aConnection, PRInt32 aMaxRecords) { nsCAutoString query( - "DELETE FROM moz_places_view WHERE id IN (" + "DELETE FROM moz_places WHERE id IN (" "SELECT h.id FROM moz_places h " - "LEFT JOIN moz_historyvisits v ON h.id = v.place_id " - "LEFT JOIN moz_historyvisits_temp v_t ON h.id = v_t.place_id " - "LEFT JOIN moz_bookmarks b ON h.id = b.fk " - "WHERE v.id IS NULL " - "AND v_t.id IS NULL " - "AND b.id IS NULL " - "AND SUBSTR(h.url,0,6) <> 'place:' " - "UNION ALL " - "SELECT h.id FROM moz_places_temp h " - "LEFT JOIN moz_historyvisits v ON h.id = v.place_id " - "LEFT JOIN moz_historyvisits_temp v_t ON h.id = v_t.place_id " - "LEFT JOIN moz_bookmarks b ON h.id = b.fk " - "WHERE v.id IS NULL " - "AND v_t.id IS NULL " - "AND b.id IS NULL " - "AND SUBSTR(h.url,0,6) <> 'place:'"); + "LEFT OUTER JOIN moz_historyvisits v ON h.id = v.place_id " + "LEFT OUTER JOIN moz_bookmarks b ON h.id = b.fk " + "WHERE v.id IS NULL AND b.id IS NULL AND SUBSTR(h.url,0,6) <> 'place:'"); if (aMaxRecords != -1) { query.AppendLiteral(" LIMIT "); query.AppendInt(aMaxRecords); @@ -989,13 +871,10 @@ nsresult nsNavHistoryExpire::ExpireFaviconsParanoid(mozIStorageConnection* aConnection) { nsresult rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "DELETE FROM moz_favicons WHERE id IN (" - "SELECT f.id FROM moz_favicons f " - "LEFT JOIN moz_places h ON f.id = h.favicon_id " - "LEFT JOIN moz_places_temp h_t ON f.id = h_t.favicon_id " - "WHERE h.favicon_id IS NULL " - "AND h_t.favicon_id IS NULL " - ")")); + "DELETE FROM moz_favicons WHERE id IN " + "(SELECT f.id FROM moz_favicons f " + "LEFT OUTER JOIN moz_places h ON f.id = h.favicon_id " + "WHERE h.favicon_id IS NULL)")); NS_ENSURE_SUCCESS(rv, rv); return rv; } @@ -1019,17 +898,14 @@ nsNavHistoryExpire::ExpireAnnotationsParanoid(mozIStorageConnection* aConnection // delete all uri annos w/o a corresponding place id // or without any visits *and* not EXPIRE_NEVER. rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "DELETE FROM moz_annos WHERE id IN (" - "SELECT a.id FROM moz_annos a " - "LEFT JOIN moz_places h ON a.place_id = h.id " - "LEFT JOIN moz_places_temp h_t ON a.place_id = h_t.id " - "LEFT JOIN moz_historyvisits v ON a.place_id = v.place_id " - "LEFT JOIN moz_historyvisits_temp v_t ON a.place_id = v_t.place_id " - "WHERE (h.id IS NULL AND h_t.id IS NULL) " - "OR (v.id IS NULL AND v_t.id IS NULL AND a.expiration != ") + - nsPrintfCString("%d", nsIAnnotationService::EXPIRE_NEVER) + - NS_LITERAL_CSTRING(")" - ")")); + "DELETE FROM moz_annos WHERE id IN " + "(SELECT a.id FROM moz_annos a " + "LEFT OUTER JOIN moz_places p ON a.place_id = p.id " + "LEFT OUTER JOIN moz_historyvisits v ON a.place_id = v.place_id " + "WHERE p.id IS NULL " + "OR (v.id IS NULL AND a.expiration != ") + + nsPrintfCString("%d", nsIAnnotationService::EXPIRE_NEVER) + + NS_LITERAL_CSTRING("))")); NS_ENSURE_SUCCESS(rv, rv); // delete item annos w/o a corresponding item id @@ -1040,15 +916,16 @@ nsNavHistoryExpire::ExpireAnnotationsParanoid(mozIStorageConnection* aConnection "WHERE b.id IS NULL)")); NS_ENSURE_SUCCESS(rv, rv); - // delete all anno names w/o a corresponding anno + // delete all anno names w/o a corresponding uri or item entry rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "DELETE FROM moz_anno_attributes WHERE id IN (" - "SELECT n.id FROM moz_anno_attributes n " - "LEFT JOIN moz_annos a ON n.id = a.anno_attribute_id " - "LEFT JOIN moz_items_annos t ON n.id = t.anno_attribute_id " - "WHERE a.anno_attribute_id IS NULL " - "AND t.anno_attribute_id IS NULL " - ")")); + "DELETE FROM moz_anno_attributes WHERE " + "id NOT IN (SELECT DISTINCT a.id FROM moz_anno_attributes a " + "JOIN moz_annos b ON b.anno_attribute_id = a.id " + "JOIN moz_places p ON b.place_id = p.id) " + "AND " + "id NOT IN (SELECT DISTINCT a.id FROM moz_anno_attributes a " + "JOIN moz_items_annos c ON c.anno_attribute_id = a.id " + "JOIN moz_bookmarks p ON c.item_id = p.id)")); NS_ENSURE_SUCCESS(rv, rv); return NS_OK; } @@ -1063,20 +940,17 @@ nsNavHistoryExpire::ExpireInputHistoryParanoid(mozIStorageConnection* aConnectio { // Delete dangling input history that have no associated pages nsresult rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "DELETE FROM moz_inputhistory WHERE place_id IN ( " - "SELECT place_id FROM moz_inputhistory " - "LEFT JOIN moz_places h ON h.id = place_id " - "LEFT JOIN moz_places_temp h_t ON h_t.id = place_id " - "WHERE h.id IS NULL " - "AND h_t.id IS NULL " - ")")); + "DELETE FROM moz_inputhistory WHERE place_id IN " + "(SELECT i.place_id FROM moz_inputhistory i " + "LEFT OUTER JOIN moz_places h ON i.place_id = h.id " + "WHERE h.id IS NULL)")); NS_ENSURE_SUCCESS(rv, rv); // Decay potentially unused entries (e.g. those that are at 1) to allow // better chances for new entries that will start at 1 rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING( - "UPDATE moz_inputhistory " - "SET use_count = use_count * .9")); + "UPDATE moz_inputhistory " + "SET use_count = use_count * .9")); NS_ENSURE_SUCCESS(rv, rv); return NS_OK; diff --git a/toolkit/components/places/src/nsPlacesDBFlush.js b/toolkit/components/places/src/nsPlacesDBFlush.js deleted file mode 100644 index 44d58f896016..000000000000 --- a/toolkit/components/places/src/nsPlacesDBFlush.js +++ /dev/null @@ -1,262 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: sw=2 ts=2 sts=2 expandtab - * ***** 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 mozilla.org code. - * - * The Initial Developer of the Original Code is - * Mozilla Corporation. - * Portions created by the Initial Developer are Copyright (C) 2008 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Shawn Wilsher (Original Author) - * Marco Bonardo - * - * 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 ***** */ - -Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); - -//////////////////////////////////////////////////////////////////////////////// -//// Constants - -const Cc = Components.classes; -const Ci = Components.interfaces; -const Cr = Components.results; - -const kQuitApplication = "quit-application"; -const kSyncFinished = "places-sync-finished"; - -const kSyncPrefName = "syncDBTableIntervalInSecs"; -const kDefaultSyncInterval = 120; - -//////////////////////////////////////////////////////////////////////////////// -//// nsPlacesDBFlush class - -function nsPlacesDBFlush() -{ - this._prefs = Cc["@mozilla.org/preferences-service;1"]. - getService(Ci.nsIPrefService). - getBranch("places."); - - // Get our sync interval - try { - // We want to silently fail if the preference does not exist, and use a - // default to fallback to. - this._syncInterval = this._prefs.getIntPref(kSyncPrefName); - if (this._syncInterval <= 0) - this._syncInterval = kDefaultSyncInterval; - } - catch (e) { - // The preference did not exist, so default to two minutes. - this._syncInterval = kDefaultSyncInterval; - } - - // Register observers - this._bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"]. - getService(Ci.nsINavBookmarksService); - this._bs.addObserver(this, false); - - this._os = Cc["@mozilla.org/observer-service;1"]. - getService(Ci.nsIObserverService); - this._os.addObserver(this, kQuitApplication, false); - - this._prefs.QueryInterface(Ci.nsIPrefBranch2) - .addObserver("", this, false); - - // Create our timer to update everything - this._timer = this._newTimer(); -} - -nsPlacesDBFlush.prototype = { - ////////////////////////////////////////////////////////////////////////////// - //// nsIObserver - - observe: function DBFlush_observe(aSubject, aTopic, aData) - { - if (aTopic == kQuitApplication) { - this._bs.removeObserver(this); - this._os.removeObserver(this, kQuitApplication); - this._prefs.QueryInterface(Ci.nsIPrefBranch2).removeObserver("", this); - this._timer.cancel(); - this._timer = null; - this._syncTables(["places", "historyvisits"]); - } - else if (aTopic == "nsPref:changed" && aData == kSyncPrefName) { - // Get the new pref value, and then update our timer - this._syncInterval = aSubject.getIntPref(kSyncPrefName); - if (this._syncInterval <= 0) - this._syncInterval = kDefaultSyncInterval; - - // We may have canceled the timer already for batch updates, so we want to - // exit early. - if (!this._timer) - return; - - this._timer.cancel(); - this._timer = this._newTimer(); - } - }, - - ////////////////////////////////////////////////////////////////////////////// - //// nsINavBookmarkObserver - - onBeginUpdateBatch: function DBFlush_onBeginUpdateBatch() - { - this._inBatchMode = true; - - // We do not want to sync while we are doing batch work. - this._timer.cancel(); - this._timer = null; - }, - - onEndUpdateBatch: function DBFlush_onEndUpdateBatch() - { - this._inBatchMode = false; - - // We need to sync and restore our timer now. - this._syncTables(["places", "historyvisits"]); - this._timer = this._newTimer(); - }, - - onItemAdded: function() this._syncTables(["places"]), - - onItemChanged: function DBFlush_onItemChanged(aItemId, aProperty, - aIsAnnotationProperty, - aValue) - { - if (aProperty == "uri") - this._syncTables(["places"]); - }, - - onItemRemoved: function() { }, - onItemVisited: function() { }, - onItemMoved: function() { }, - - ////////////////////////////////////////////////////////////////////////////// - //// nsITimerCallback - - notify: function() this._syncTables(["places", "historyvisits"]), - - ////////////////////////////////////////////////////////////////////////////// - //// mozIStorageStatementCallback - - handleCompletion: function DBFlush_handleCompletion(aReason) - { - if (aReason == Ci.mozIStorageStatementCallback.REASON_FINISHED) { - // Dispatch a notification that sync has finished. - this._os.notifyObservers(null, kSyncFinished, null); - } - }, - - ////////////////////////////////////////////////////////////////////////////// - //// nsPlacesDBFlush - _syncInterval: kDefaultSyncInterval, - - /** - * Execute async statements to sync temporary places table. - * @param aTableNames - * array of table names that should be synced, as moz_{TableName}_temp. - */ - _syncTables: function DBFlush_syncTables(aTableNames) - { - // No need to do extra work if we are in batch mode - if (this._inBatchMode) - return; - - let statements = []; - for (let i = 0; i < aTableNames.length; i++) - statements.push(this._getSyncTableStatement(aTableNames[i])); - - // Execute sync statements async in a transaction - this._db.executeAsync(statements, statements.length, this); - }, - - /** - * Generate the statement to synchronizes the moz_{aTableName} and - * moz_{aTableName}_temp by copying all the data from the temporary table - * into the permanent one. - * Most of the work is done through triggers defined in nsPlacesTriggers.h, - * they sync back to disk, then delete the data in the temporary table. - * @param aTableName - * name of the table to build statement for, as moz_{TableName}_temp. - */ - _getSyncTableStatement: function DBFlush_getSyncTableStatement(aTableName) - { - // Delete all the data in the temp table. - // We have triggers setup that ensure that the data is transferred over - // upon deletion. - return this._db.createStatement("DELETE FROM moz_" + aTableName + "_temp"); - }, - - /** - * Creates a new timer based on this._syncInterval. - * - * @returns a REPEATING_SLACK nsITimer that runs every this._syncInterval. - */ - _newTimer: function DBFlush_newTimer() - { - let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - timer.initWithCallback(this, this._syncInterval * 1000, - Ci.nsITimer.TYPE_REPEATING_SLACK); - return timer; - }, - - ////////////////////////////////////////////////////////////////////////////// - //// nsISupports - - classDescription: "Used to synchronize the temporary and permanent tables of Places", - classID: Components.ID("c1751cfc-e8f1-4ade-b0bb-f74edfb8ef6a"), - contractID: "@mozilla.org/places/sync;1", - _xpcom_categories: [{ - category: "profile-after-change", - }], - - QueryInterface: XPCOMUtils.generateQI([ - Ci.nsIObserver, - Ci.nsINavBookmarkObserver, - Ci.nsITimerCallback, - ]) -}; - -////////////////////////////////////////////////////////////////////////////// -//// Smart Getters - -nsPlacesDBFlush.prototype.__defineGetter__("_db", function() { - delete nsPlacesDBFlush._db; - return nsPlacesDBFlush._db = Cc["@mozilla.org/browser/nav-history-service;1"]. - getService(Ci.nsPIPlacesDatabase). - DBConnection; -}); - -//////////////////////////////////////////////////////////////////////////////// -//// Module Registration - -let components = [nsPlacesDBFlush]; -function NSGetModule(compMgr, fileSpec) -{ - return XPCOMUtils.generateModule(components); -} diff --git a/toolkit/components/places/src/nsPlacesTables.h b/toolkit/components/places/src/nsPlacesTables.h index f2598fc41340..a7892d94ef28 100644 --- a/toolkit/components/places/src/nsPlacesTables.h +++ b/toolkit/components/places/src/nsPlacesTables.h @@ -39,8 +39,8 @@ #ifndef __nsPlacesTables_h__ #define __nsPlacesTables_h__ -#define CREATE_MOZ_PLACES_BASE(__name, __temporary) NS_LITERAL_CSTRING( \ - "CREATE " __temporary " TABLE " __name " ( " \ +#define CREATE_MOZ_PLACES NS_LITERAL_CSTRING( \ + "CREATE TABLE moz_places ( " \ " id INTEGER PRIMARY KEY" \ ", url LONGVARCHAR" \ ", title LONGVARCHAR" \ @@ -52,18 +52,9 @@ ", frecency INTEGER DEFAULT -1 NOT NULL" \ ")" \ ) -#define CREATE_MOZ_PLACES CREATE_MOZ_PLACES_BASE("moz_places", "") -#define CREATE_MOZ_PLACES_TEMP CREATE_MOZ_PLACES_BASE("moz_places_temp", "TEMP") -#define CREATE_MOZ_PLACES_VIEW NS_LITERAL_CSTRING( \ - "CREATE TEMPORARY VIEW moz_places_view AS " \ - "SELECT * FROM moz_places_temp " \ - "UNION ALL " \ - "SELECT * FROM moz_places " \ - "WHERE id NOT IN (SELECT id FROM moz_places_temp) " \ -) -#define CREATE_MOZ_HISTORYVISITS_BASE(__name, __temporary) NS_LITERAL_CSTRING( \ - "CREATE " __temporary " TABLE " __name " (" \ +#define CREATE_MOZ_HISTORYVISITS NS_LITERAL_CSTRING( \ + "CREATE TABLE moz_historyvisits (" \ " id INTEGER PRIMARY KEY" \ ", from_visit INTEGER" \ ", place_id INTEGER" \ @@ -72,17 +63,6 @@ ", session INTEGER" \ ")" \ ) -#define CREATE_MOZ_HISTORYVISITS \ - CREATE_MOZ_HISTORYVISITS_BASE("moz_historyvisits", "") -#define CREATE_MOZ_HISTORYVISITS_TEMP \ - CREATE_MOZ_HISTORYVISITS_BASE("moz_historyvisits_temp", "TEMP") -#define CREATE_MOZ_HISTORYVISITS_VIEW NS_LITERAL_CSTRING( \ - "CREATE TEMPORARY VIEW moz_historyvisits_view AS " \ - "SELECT * FROM moz_historyvisits_temp " \ - "UNION ALL " \ - "SELECT * FROM moz_historyvisits " \ - "WHERE id NOT IN (SELECT id FROM moz_historyvisits_temp) " \ -) #define CREATE_MOZ_INPUTHISTORY NS_LITERAL_CSTRING( \ "CREATE TABLE moz_inputhistory (" \ diff --git a/toolkit/components/places/src/nsPlacesTriggers.h b/toolkit/components/places/src/nsPlacesTriggers.h index edf5fd0911d4..76fe1a81a47b 100644 --- a/toolkit/components/places/src/nsPlacesTriggers.h +++ b/toolkit/components/places/src/nsPlacesTriggers.h @@ -39,6 +39,38 @@ #ifndef __nsPlacesTriggers_h__ #define __nsPlacesTriggers_h__ +/** + * Trigger increments the visit count by one for each inserted visit that isn't + * an invalid transition, embedded transition, or a download transition. + */ +#define CREATE_VISIT_COUNT_INSERT_TRIGGER NS_LITERAL_CSTRING( \ + "CREATE TRIGGER moz_historyvisits_afterinsert_v1_trigger " \ + "AFTER INSERT ON moz_historyvisits FOR EACH ROW " \ + "WHEN NEW.visit_type NOT IN (0, 4, 7) " /* invalid, EMBED, DOWNLOAD */ \ + "BEGIN " \ + "UPDATE moz_places " \ + "SET visit_count = visit_count + 1 " \ + "WHERE moz_places.id = NEW.place_id; " \ + "END" \ +) + +/** + * Trigger decrements the visit count by one for each removed visit that isn't + * an invalid transition, embeded transition, or a download transition. To be + * safe, we ensure that the visit count will not fall below zero. + */ +#define CREATE_VISIT_COUNT_DELETE_TRIGGER NS_LITERAL_CSTRING( \ + "CREATE TRIGGER moz_historyvisits_afterdelete_v1_trigger " \ + "AFTER DELETE ON moz_historyvisits FOR EACH ROW " \ + "WHEN OLD.visit_type NOT IN (0, 4, 7) " /* invalid, EMBED, DOWNLOAD */ \ + "BEGIN " \ + "UPDATE moz_places " \ + "SET visit_count = visit_count - 1 " \ + "WHERE moz_places.id = OLD.place_id " \ + "AND visit_count > 0; " \ + "END" \ +) + /** * Trigger checks to ensure that at least one bookmark is still using a keyword * when any bookmark is deleted. If there are no more bookmarks using it, the @@ -61,183 +93,4 @@ "END" \ ) -/** - * This trigger allows for an insertion into moz_places_view. It enters the new - * data into the temporary table, ensuring that the new id is one greater than - * the largest id value found. - */ -#define CREATE_PLACES_VIEW_INSERT_TRIGGER NS_LITERAL_CSTRING( \ - "CREATE TEMPORARY TRIGGER moz_places_view_insert_trigger " \ - "INSTEAD OF INSERT " \ - "ON moz_places_view " \ - "BEGIN " \ - "INSERT INTO moz_places_temp ( " \ - "id, url, title, rev_host, visit_count, hidden, typed, favicon_id, " \ - "frecency " \ - ") " \ - "VALUES (MAX((SELECT IFNULL(MAX(id), 0) FROM moz_places_temp), " \ - "(SELECT IFNULL(MAX(id), 0) FROM moz_places)) + 1, " \ - "NEW.url, NEW.title, NEW.rev_host, " \ - "IFNULL(NEW.visit_count, 0), " /* enforce having a value */ \ - "NEW.hidden, NEW.typed, NEW.favicon_id, NEW.frecency);" \ - "END" \ -) - -/** - * This trigger allows for the deletion of a record in moz_places_view. It - * removes any entry in the temporary table, and any entry in the permanent - * table as well. - */ -#define CREATE_PLACES_VIEW_DELETE_TRIGGER NS_LITERAL_CSTRING( \ - "CREATE TEMPORARY TRIGGER moz_places_view_delete_trigger " \ - "INSTEAD OF DELETE " \ - "ON moz_places_view " \ - "BEGIN " \ - "DELETE FROM moz_places_temp " \ - "WHERE id = OLD.id; " \ - "DELETE FROM moz_places " \ - "WHERE id = OLD.id; " \ - "END" \ -) - -/** - * This trigger allows for updates to a record in moz_places_view. It first - * copies the row from the permanent table over to the temp table if it does not - * exist in the temporary table. Then, it will update the temporary table with - * the new data. - * We use INSERT OR IGNORE to avoid looking if the place already exists in the - * temp table. - */ -#define CREATE_PLACES_VIEW_UPDATE_TRIGGER NS_LITERAL_CSTRING( \ - "CREATE TEMPORARY TRIGGER moz_places_view_update_trigger " \ - "INSTEAD OF UPDATE " \ - "ON moz_places_view " \ - "BEGIN " \ - "INSERT OR IGNORE INTO moz_places_temp " \ - "SELECT * " \ - "FROM moz_places " \ - "WHERE id = OLD.id; " \ - "UPDATE moz_places_temp " \ - "SET url = IFNULL(NEW.url, OLD.url), " \ - "title = IFNULL(NEW.title, OLD.title), " \ - "rev_host = IFNULL(NEW.rev_host, OLD.rev_host), " \ - "visit_count = IFNULL(NEW.visit_count, OLD.visit_count), " \ - "hidden = IFNULL(NEW.hidden, OLD.hidden), " \ - "typed = IFNULL(NEW.typed, OLD.typed), " \ - "favicon_id = IFNULL(NEW.favicon_id, OLD.favicon_id), " \ - "frecency = IFNULL(NEW.frecency, OLD.frecency) " \ - "WHERE id = OLD.id; " \ - "END" \ -) - -/** - * This trigger allows for an insertion into moz_historyvisits_view. It enters - * the new data into the temporary table, ensuring that the new id is one - * greater than the largest id value found. It then updates moz_places_view - * with the new visit count. - * We use INSERT OR IGNORE to avoid looking if the place already exists in the - * temp table. - */ -#define CREATE_HISTORYVISITS_VIEW_INSERT_TRIGGER NS_LITERAL_CSTRING( \ - "CREATE TEMPORARY TRIGGER moz_historyvisits_view_insert_trigger " \ - "INSTEAD OF INSERT " \ - "ON moz_historyvisits_view " \ - "BEGIN " \ - "INSERT INTO moz_historyvisits_temp ( " \ - "id, from_visit, place_id, visit_date, visit_type, session " \ - ") " \ - "VALUES (MAX((SELECT IFNULL(MAX(id), 0) FROM moz_historyvisits_temp), " \ - "(SELECT IFNULL(MAX(id), 0) FROM moz_historyvisits)) + 1, " \ - "NEW.from_visit, NEW.place_id, NEW.visit_date, NEW.visit_type, " \ - "NEW.session); " \ - "INSERT OR IGNORE INTO moz_places_temp " \ - "SELECT * " \ - "FROM moz_places " \ - "WHERE id = NEW.place_id " \ - "AND NEW.visit_type NOT IN (0, 4, 7); " \ - "UPDATE moz_places_temp " \ - "SET visit_count = visit_count + 1 " \ - "WHERE id = NEW.place_id " \ - "AND NEW.visit_type NOT IN (0, 4, 7); " /* invalid, EMBED, DOWNLOAD */ \ - "END" \ -) - -/** - * This trigger allows for the deletion of a record in moz_historyvisits_view. - * It removes any entry in the temporary table, and removes any entry in the - * permanent table as well. It then updates moz_places_view with the new visit - * count. - * We use INSERT OR IGNORE to avoid looking if the place already exists in the - * temp table. - */ -#define CREATE_HISTORYVISITS_VIEW_DELETE_TRIGGER NS_LITERAL_CSTRING( \ - "CREATE TEMPORARY TRIGGER moz_historyvisits_view_delete_trigger " \ - "INSTEAD OF DELETE " \ - "ON moz_historyvisits_view " \ - "BEGIN " \ - "DELETE FROM moz_historyvisits_temp " \ - "WHERE id = OLD.id; " \ - "DELETE FROM moz_historyvisits " \ - "WHERE id = OLD.id; " \ - "INSERT OR IGNORE INTO moz_places_temp " \ - "SELECT * " \ - "FROM moz_places " \ - "WHERE id = OLD.place_id " \ - "AND OLD.visit_type NOT IN (0, 4, 7); " \ - "UPDATE moz_places_temp " \ - "SET visit_count = visit_count - 1 " \ - "WHERE id = OLD.place_id " \ - "AND OLD.visit_type NOT IN (0, 4, 7); " /* invalid, EMBED, DOWNLOAD */ \ - "END" \ -) - -/** - * This trigger allows for updates to a record in moz_historyvisits_view. It - * first copies the row from the permanent table over to the temp table if it - * does not exist in the temporary table. Then it will update the temporary - * table with the new data. - * We use INSERT OR IGNORE to avoid looking if the visit already exists in the - * temp table. - */ -#define CREATE_HISTORYVISITS_VIEW_UPDATE_TRIGGER NS_LITERAL_CSTRING( \ - "CREATE TEMPORARY TRIGGER moz_historyvisits_view_update_trigger " \ - "INSTEAD OF UPDATE " \ - "ON moz_historyvisits_view " \ - "BEGIN " \ - "INSERT OR IGNORE INTO moz_historyvisits_temp " \ - "SELECT * " \ - "FROM moz_historyvisits " \ - "WHERE id = OLD.id; " \ - "UPDATE moz_historyvisits_temp " \ - "SET from_visit = IFNULL(NEW.from_visit, OLD.from_visit), " \ - "place_id = IFNULL(NEW.place_id, OLD.place_id), " \ - "visit_date = IFNULL(NEW.visit_date, OLD.visit_date), " \ - "visit_type = IFNULL(NEW.visit_type, OLD.visit_type), " \ - "session = IFNULL(NEW.session, OLD.session) " \ - "WHERE id = OLD.id; " \ - "END" \ -) - -/** - * This trigger moves the data out of a temporary table into the permanent one - * before deleting from the temporary table. - * - * Note - it's OK to use an INSERT OR REPLACE here because the only conflict - * that will happen is the primary key. As a result, the row will be deleted, - * and the replacement will be inserted with the same id. - */ -#define CREATE_TEMP_SYNC_TRIGGER_BASE(__table) NS_LITERAL_CSTRING( \ - "CREATE TEMPORARY TRIGGER " __table "_beforedelete_trigger " \ - "BEFORE DELETE ON " __table "_temp FOR EACH ROW " \ - "BEGIN " \ - "INSERT OR REPLACE INTO " __table " " \ - "SELECT * FROM " __table "_temp " \ - "WHERE id = OLD.id;" \ - "END" \ -) -#define CREATE_MOZ_PLACES_SYNC_TRIGGER \ - CREATE_TEMP_SYNC_TRIGGER_BASE("moz_places") -#define CREATE_MOZ_HISTORYVISITS_SYNC_TRIGGER \ - CREATE_TEMP_SYNC_TRIGGER_BASE("moz_historyvisits") - #endif // __nsPlacesTriggers_h__ diff --git a/toolkit/components/places/tests/Makefile.in b/toolkit/components/places/tests/Makefile.in index c9dc3c16b995..97a2dc108f23 100644 --- a/toolkit/components/places/tests/Makefile.in +++ b/toolkit/components/places/tests/Makefile.in @@ -49,7 +49,6 @@ MODULE = test_places XPCSHELL_TESTS = \ autocomplete \ background \ - sync \ bookmarks \ queries \ unit \ diff --git a/toolkit/components/places/tests/background/head_background.js b/toolkit/components/places/tests/background/head_background.js deleted file mode 100644 index 4b070422be84..000000000000 --- a/toolkit/components/places/tests/background/head_background.js +++ /dev/null @@ -1,102 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** 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. - * - * The Initial Developer of the Original Code is - * Google Inc. - * Portions created by the Initial Developer are Copyright (C) 2005 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Brian Ryner - * Dietrich Ayala - * - * 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 ***** */ - -const NS_APP_USER_PROFILE_50_DIR = "ProfD"; -const NS_APP_HISTORY_50_FILE = "UHist"; - -const Ci = Components.interfaces; -const Cc = Components.classes; -const Cr = Components.results; - -function LOG(aMsg) { - aMsg = ("*** PLACES TESTS: " + aMsg); - Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService). - logStringMessage(aMsg); - print(aMsg); -} - -// If there's no location registered for the profile direcotry, register one now. -var dirSvc = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties); -var profileDir = null; -try { - profileDir = dirSvc.get(NS_APP_USER_PROFILE_50_DIR, Ci.nsIFile); -} catch (e) {} -if (!profileDir) { - // Register our own provider for the profile directory. - // It will simply return the current directory. - var provider = { - getFile: function(prop, persistent) { - persistent.value = true; - if (prop == NS_APP_USER_PROFILE_50_DIR) { - return dirSvc.get("CurProcD", Ci.nsIFile); - } - if (prop == NS_APP_HISTORY_50_FILE) { - var histFile = dirSvc.get("CurProcD", Ci.nsIFile); - histFile.append("history.dat"); - return histFile; - } - throw Cr.NS_ERROR_FAILURE; - }, - QueryInterface: function(iid) { - if (iid.equals(Ci.nsIDirectoryServiceProvider) || - iid.equals(Ci.nsISupports)) { - return this; - } - throw Cr.NS_ERROR_NO_INTERFACE; - } - }; - dirSvc.QueryInterface(Ci.nsIDirectoryService).registerProvider(provider); -} - -var iosvc = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService); - -function uri(spec) { - return iosvc.newURI(spec, null, null); -} - -// Delete a previously created sqlite file -function clearDB() { - try { - var file = dirSvc.get('ProfD', Ci.nsIFile); - file.append("places.sqlite"); - if (file.exists()) - file.remove(false); - } catch(ex) { dump("Exception: " + ex); } -} -clearDB(); diff --git a/toolkit/components/places/tests/background/test_background.js b/toolkit/components/places/tests/background/test_background.js index 93790d32b0bf..35cbf1b323d0 100644 --- a/toolkit/components/places/tests/background/test_background.js +++ b/toolkit/components/places/tests/background/test_background.js @@ -39,6 +39,10 @@ Components.utils.import("resource://gre/modules/PlacesBackground.jsm"); +const Cc = Components.classes; +const Ci = Components.interfaces; +const Cr = Components.results; + function test_service_exists() { do_check_neq(PlacesBackground, null); @@ -83,32 +87,10 @@ function test_two_events_same_thread() do_check_eq(event.thread1, event.thread2); } -function test_places_background_shutdown_topic() -{ - // Ensures that the places shutdown topic is dispatched before the thread is - // shutdown. - let os = Cc["@mozilla.org/observer-service;1"]. - getService(Ci.nsIObserverService); - os.addObserver({ - observe: function(aSubject, aTopic, aData) - { - // We should still be able to dispatch an event without throwing now! - PlacesBackground.dispatch({ - run: function() - { - do_test_finished(); - } - }, Ci.nsIEventTarget.DISPATCH_NORMAL); - } - }, "places-background-shutdown", false); - do_test_pending(); -} - let tests = [ test_service_exists, test_isOnCurrentThread, test_two_events_same_thread, - test_places_background_shutdown_topic, ]; function run_test() diff --git a/toolkit/components/places/tests/mochitest/bug_411966/redirect.js b/toolkit/components/places/tests/mochitest/bug_411966/redirect.js index 63b2348222b4..8a8ff9c0d288 100644 --- a/toolkit/components/places/tests/mochitest/bug_411966/redirect.js +++ b/toolkit/components/places/tests/mochitest/bug_411966/redirect.js @@ -164,11 +164,11 @@ function checkDBOnTimeout() { netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect'); // Get all pages visited from the original typed one - var sql = "SELECT url FROM moz_historyvisits_view " + - "JOIN moz_places_view h ON h.id = place_id " + + var sql = "SELECT url FROM moz_historyvisits " + + "JOIN moz_places h ON h.id = place_id " + "WHERE from_visit IN " + - "(SELECT v.id FROM moz_historyvisits_view v " + - "JOIN moz_places_view p ON p.id = v.place_id " + + "(SELECT v.id FROM moz_historyvisits v " + + "JOIN moz_places p ON p.id = v.place_id " + "WHERE p.url = ?1)"; var stmt = mDBConn.createStatement(sql); stmt.bindUTF8StringParameter(0, typedURI.spec); diff --git a/toolkit/components/places/tests/sync/head_sync.js b/toolkit/components/places/tests/sync/head_sync.js deleted file mode 100644 index a2a02fa40ce5..000000000000 --- a/toolkit/components/places/tests/sync/head_sync.js +++ /dev/null @@ -1,258 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** 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. - * - * The Initial Developer of the Original Code is - * Google Inc. - * Portions created by the Initial Developer are Copyright (C) 2005 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Brian Ryner - * Dietrich Ayala - * Shawn Wilsher - * Marco Bonardo - * - * 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 ***** */ - -const NS_APP_USER_PROFILE_50_DIR = "ProfD"; -const NS_APP_HISTORY_50_FILE = "UHist"; - -const Ci = Components.interfaces; -const Cc = Components.classes; -const Cr = Components.results; - -function LOG(aMsg) { - aMsg = ("*** PLACES TESTS: " + aMsg); - Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService). - logStringMessage(aMsg); - print(aMsg); -} - -// If there's no location registered for the profile direcotry, register one now. -var dirSvc = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties); -var profileDir = null; -try { - profileDir = dirSvc.get(NS_APP_USER_PROFILE_50_DIR, Ci.nsIFile); -} catch (e) {} -if (!profileDir) { - // Register our own provider for the profile directory. - // It will simply return the current directory. - var provider = { - getFile: function(prop, persistent) { - persistent.value = true; - if (prop == NS_APP_USER_PROFILE_50_DIR) { - return dirSvc.get("CurProcD", Ci.nsIFile); - } - if (prop == NS_APP_HISTORY_50_FILE) { - var histFile = dirSvc.get("CurProcD", Ci.nsIFile); - histFile.append("history.dat"); - return histFile; - } - throw Cr.NS_ERROR_FAILURE; - }, - QueryInterface: function(iid) { - if (iid.equals(Ci.nsIDirectoryServiceProvider) || - iid.equals(Ci.nsISupports)) { - return this; - } - throw Cr.NS_ERROR_NO_INTERFACE; - } - }; - dirSvc.QueryInterface(Ci.nsIDirectoryService).registerProvider(provider); -} - -var iosvc = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService); - -function uri(spec) { - return iosvc.newURI(spec, null, null); -} - -// Delete a previously created sqlite file -function clearDB() { - try { - var file = dirSvc.get('ProfD', Ci.nsIFile); - file.append("places.sqlite"); - if (file.exists()) - file.remove(false); - } catch(ex) { dump("Exception: " + ex); } -} -clearDB(); - -/** - * Dumps the rows of a table out to the console. - * - * @param aName - * The name of the table or view to output. - */ -function dump_table(aName) -{ - let db = Cc["@mozilla.org/browser/nav-history-service;1"]. - getService(Ci.nsPIPlacesDatabase). - DBConnection; - let stmt = db.createStatement("SELECT * FROM " + aName); - - dump("\n*** Printing data from " + aName + ":\n"); - let count = 0; - while (stmt.executeStep()) { - let columns = stmt.numEntries; - - if (count == 0) { - // print the column names - for (let i = 0; i < columns; i++) - dump(stmt.getColumnName(i) + "\t"); - dump("\n"); - } - - // print the row - for (let i = 0; i < columns; i++) { - switch (stmt.getTypeOfIndex(i)) { - case Ci.mozIStorageValueArray.VALUE_TYPE_NULL: - dump("NULL\t"); - break; - case Ci.mozIStorageValueArray.VALUE_TYPE_INTEGER: - dump(stmt.getInt64(i) + "\t"); - break; - case Ci.mozIStorageValueArray.VALUE_TYPE_FLOAT: - dump(stmt.getDouble(i) + "\t"); - break; - case Ci.mozIStorageValueArray.VALUE_TYPE_TEXT: - dump(stmt.getString(i) + "\t"); - break; - } - } - dump("\n"); - - count++; - } - dump("*** There were a total of " + count + " rows of data.\n\n"); - - stmt.reset(); - stmt.finalize(); - stmt = null; -} - -/** - * This dispatches the observer topic "quit-application" to clean up the sync - * component. - */ -function finish_test() -{ - // xpcshell doesn't dispatch shutdown-application - let os = Cc["@mozilla.org/observer-service;1"]. - getService(Ci.nsIObserverService); - os.notifyObservers(null, "quit-application", null); - do_test_finished(); -} - -/** - * Function tests to see if the place associated with the bookmark with id - * aBookmarkId has the uri aExpectedURI. The event will call finish_test() if - * aFinish is true. - * - * @param aBookmarkId - * The bookmark to check against. - * @param aExpectedURI - * The URI we expect to be in moz_places. - * @param aExpected - * Indicates if we expect to get a result or not. - * @param [optional] aFinish - * Indicates if the test should be completed or not. - */ -function new_test_bookmark_uri_event(aBookmarkId, aExpectedURI, aExpected, aFinish) -{ - let db = Cc["@mozilla.org/browser/nav-history-service;1"]. - getService(Ci.nsPIPlacesDatabase). - DBConnection; - let stmt = db.createStatement( - "SELECT moz_places.url " + - "FROM moz_bookmarks INNER JOIN moz_places " + - "ON moz_bookmarks.fk = moz_places.id " + - "WHERE moz_bookmarks.id = ?1" - ); - stmt.bindInt64Parameter(0, aBookmarkId); - - if (aExpected) { - do_check_true(stmt.executeStep()); - do_check_eq(stmt.getUTF8String(0), aExpectedURI); - } - else { - do_check_false(stmt.executeStep()); - } - stmt.reset(); - stmt.finalize(); - stmt = null; - - if (aFinish) - finish_test(); -} - -/** - * Function tests to see if the place associated with the visit with id aVisitId - * has the uri aExpectedURI. The event will call finish_test() if aFinish is - * true. - * - * @param aVisitId - * The visit to check against. - * @param aExpectedURI - * The URI we expect to be in moz_places. - * @param aExpected - * Indicates if we expect to get a result or not. - * @param [optional] aFinish - * Indicates if the test should be completed or not. - */ -function new_test_visit_uri_event(aVisitId, aExpectedURI, aExpected, aFinish) -{ - let db = Cc["@mozilla.org/browser/nav-history-service;1"]. - getService(Ci.nsPIPlacesDatabase). - DBConnection; - let stmt = db.createStatement( - "SELECT moz_places.url " + - "FROM moz_historyvisits INNER JOIN moz_places " + - "ON moz_historyvisits.place_id = moz_places.id " + - "WHERE moz_historyvisits.id = ?1" - ); - stmt.bindInt64Parameter(0, aVisitId); - - if (aExpected) { - do_check_true(stmt.executeStep()); - do_check_eq(stmt.getUTF8String(0), aExpectedURI); - } - else { - do_check_false(stmt.executeStep()); - } - stmt.reset(); - stmt.finalize(); - stmt = null; - - if (aFinish) - finish_test(); -} - -// profile-after-change doesn't create components in xpcshell, so we have to do -// it ourselves -Cc["@mozilla.org/places/sync;1"].getService(Ci.nsISupports); diff --git a/toolkit/components/places/tests/sync/test_database_sync_after_addBookmark.js b/toolkit/components/places/tests/sync/test_database_sync_after_addBookmark.js deleted file mode 100644 index 85033c5f683d..000000000000 --- a/toolkit/components/places/tests/sync/test_database_sync_after_addBookmark.js +++ /dev/null @@ -1,89 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: sw=2 ts=2 sts=2 expandtab - * ***** 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 mozilla.org code. - * - * The Initial Developer of the Original Code is - * Mozilla Corporation. - * Portions created by the Initial Developer are Copyright (C) 2008 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Shawn Wilsher (Original Author) - * Marco Bonardo - * - * 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 ***** */ - -var bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"]. - getService(Ci.nsINavBookmarksService); -var os = Cc["@mozilla.org/observer-service;1"]. - getService(Ci.nsIObserverService); -var prefs = Cc["@mozilla.org/preferences-service;1"]. - getService(Ci.nsIPrefService). - getBranch("places."); - -const TEST_URI = "http://test.com/"; - -const SYNC_INTERVAL = 600; // ten minutes -const kSyncPrefName = "syncDBTableIntervalInSecs"; -const kSyncFinished = "places-sync-finished"; - -// Used to update observer itemId -var bookmarksObserver = { - onItemAdded: function(aItemId, aNewParent, aNewIndex) { - observer.itemId = aItemId; - } -} -bs.addObserver(bookmarksObserver, false); - -var observer = { - itemId: -1, - observe: function(aSubject, aTopic, aData) { - if (aTopic == kSyncFinished) { - do_check_neq(this.itemId, -1); - // remove the observer, we don't need to observe sync on quit - os.removeObserver(this, kSyncFinished); - bs.removeObserver(bookmarksObserver); - // Check that moz_places table has been correctly synced - new_test_bookmark_uri_event(this.itemId, TEST_URI, true, true); - } - } -} -os.addObserver(observer, kSyncFinished, false); - -function run_test() -{ - // First set the preference for the timer to a really large value so it won't - // run before the test finishes. - prefs.setIntPref(kSyncPrefName, SYNC_INTERVAL); - - // Insert a new bookmark - bs.insertBookmark(bs.unfiledBookmarksFolder, uri(TEST_URI), - bs.DEFAULT_INDEX, "test"); - - do_test_pending(); -} diff --git a/toolkit/components/places/tests/sync/test_database_sync_after_addBookmark_batched.js b/toolkit/components/places/tests/sync/test_database_sync_after_addBookmark_batched.js deleted file mode 100644 index f95227bd01b5..000000000000 --- a/toolkit/components/places/tests/sync/test_database_sync_after_addBookmark_batched.js +++ /dev/null @@ -1,110 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: sw=2 ts=2 sts=2 expandtab - * ***** 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 mozilla.org code. - * - * The Initial Developer of the Original Code is - * Mozilla Corporation. - * Portions created by the Initial Developer are Copyright (C) 2008 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Shawn Wilsher (Original Author) - * Marco Bonardo - * - * 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 ***** */ - -var bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"]. - getService(Ci.nsINavBookmarksService); -var os = Cc["@mozilla.org/observer-service;1"]. - getService(Ci.nsIObserverService); -var prefs = Cc["@mozilla.org/preferences-service;1"]. - getService(Ci.nsIPrefService). - getBranch("places."); - -const TEST_URI = "http://test.com/"; - -const SYNC_INTERVAL = 600; // ten minutes -const kSyncPrefName = "syncDBTableIntervalInSecs"; -const kSyncFinished = "places-sync-finished"; - -// Used to check if we are batching and to update observer itemId -var bookmarksObserver = { - _batching: false, - onBeginUpdateBatch: function() { - this._batching = true; - }, - onEndUpdateBatch: function() { - this._batching = false; - }, - onItemAdded: function(aItemId, aNewParent, aNewIndex) { - observer.itemId = aItemId; - } -} -bs.addObserver(bookmarksObserver, false); - -var observer = { - itemId: -1, - observe: function(aSubject, aTopic, aData) { - if (aTopic == kSyncFinished) { - dump(this.itemId); - // item id must be valid - do_check_neq(this.itemId, -1); - // Check that we are not in a batch - do_check_false(bookmarksObserver._batching); - // remove the observer, we don't need to observe sync on quit - os.removeObserver(this, kSyncFinished); - bs.removeObserver(bookmarksObserver); - // Check that tables have been correctly synced - new_test_bookmark_uri_event(this.itemId, TEST_URI, true, true); - } - } -} -os.addObserver(observer, kSyncFinished, false); - -function run_test() -{ - // Set the preference for the timer to a really large value, so it won't - // run before the test finishes. - prefs.setIntPref(kSyncPrefName, SYNC_INTERVAL); - - // Add a bookmark in batch mode - let id = -1; - bs.runInBatchMode({ - runBatched: function(aUserData) - { - id = bs.insertBookmark(bs.unfiledBookmarksFolder, uri(TEST_URI), - bs.DEFAULT_INDEX, "test"); - // We should not sync during a batch - new_test_bookmark_uri_event(id, TEST_URI, false); - } - }, null); - // Ensure the bookmark has been added - do_check_neq(id, -1); - - do_test_pending(); -} diff --git a/toolkit/components/places/tests/sync/test_database_sync_after_addVisit.js b/toolkit/components/places/tests/sync/test_database_sync_after_addVisit.js deleted file mode 100644 index 431324cf46a8..000000000000 --- a/toolkit/components/places/tests/sync/test_database_sync_after_addVisit.js +++ /dev/null @@ -1,73 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: sw=2 ts=2 sts=2 expandtab - * ***** 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 mozilla.org code. - * - * The Initial Developer of the Original Code is - * Mozilla Corporation. - * Portions created by the Initial Developer are Copyright (C) 2008 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Shawn Wilsher (Original Author) - * Marco Bonardo - * - * 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 ***** */ - -var hs = Cc["@mozilla.org/browser/nav-history-service;1"]. - getService(Ci.nsINavHistoryService); -var bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"]. - getService(Ci.nsINavBookmarksService); -var prefs = Cc["@mozilla.org/preferences-service;1"]. - getService(Ci.nsIPrefService). - getBranch("places."); - -const TEST_URI = "http://test.com/"; - -const kSyncPrefName = "syncDBTableIntervalInSecs"; -const SYNC_INTERVAL = 1; - -function run_test() -{ - // First set the preference for the timer to a small value - prefs.setIntPref(kSyncPrefName, SYNC_INTERVAL); - - // Now add the visit - let id = hs.addVisit(uri(TEST_URI), Date.now() * 1000, null, - hs.TRANSITION_TYPED, false, 0); - - // Check the visit, but after enough time has passed for the DB flush service - // to have fired it's timer. - let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - timer.initWithCallback({ - notify: function(aTimer) - { - new_test_visit_uri_event(id, TEST_URI, true, true); - } - }, (SYNC_INTERVAL * 1000) * 2, Ci.nsITimer.TYPE_ONE_SHOT); - do_test_pending(); -} diff --git a/toolkit/components/places/tests/sync/test_database_sync_after_addVisit_batched.js b/toolkit/components/places/tests/sync/test_database_sync_after_addVisit_batched.js deleted file mode 100644 index 6c9055594692..000000000000 --- a/toolkit/components/places/tests/sync/test_database_sync_after_addVisit_batched.js +++ /dev/null @@ -1,109 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: sw=2 ts=2 sts=2 expandtab - * ***** 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 mozilla.org code. - * - * The Initial Developer of the Original Code is - * Mozilla Corporation. - * Portions created by the Initial Developer are Copyright (C) 2008 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Shawn Wilsher (Original Author) - * Marco Bonardo - * - * 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 ***** */ - - var bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"]. - getService(Ci.nsINavBookmarksService); - var hs = Cc["@mozilla.org/browser/nav-history-service;1"]. - getService(Ci.nsINavHistoryService); - var os = Cc["@mozilla.org/observer-service;1"]. - getService(Ci.nsIObserverService); - -const TEST_URI = "http://test.com/"; - -const kSyncFinished = "places-sync-finished"; - -// Used to check if we are batching -var bookmarksObserver = { - _batching: false, - onBeginUpdateBatch: function() { - this._batching = true; - }, - onEndUpdateBatch: function() { - this._batching = false; - } -} -bs.addObserver(bookmarksObserver, false); - -// Used to update observer visitId -var historyObserver = { - onVisit: function(aURI, aVisitId, aTime, aSessionId, aReferringId, - aTransitionType, aAdded) { - observer.visitId = aVisitId; - } -} -hs.addObserver(historyObserver, false); - -var observer = { - visitId: -1, - observe: function(aSubject, aTopic, aData) { - if (aTopic == kSyncFinished) { - // visit id must be valid - do_check_neq(this.visitId, -1); - // Check that we are not in a batch - do_check_false(bookmarksObserver._batching); - // remove the observer, we don't need to observe sync on quit - os.removeObserver(this, kSyncFinished); - bs.removeObserver(bookmarksObserver); - hs.removeObserver(historyObserver); - // Check that tables have been correctly synced - new_test_visit_uri_event(this.visitId, TEST_URI, true, true); - } - } -} -os.addObserver(observer, kSyncFinished, false); - -function run_test() -{ - // Add a visit in batch mode - let id = -1; - bs.runInBatchMode({ - runBatched: function(aUserData) - { - id = hs.addVisit(uri(TEST_URI), Date.now() * 1000, null, - hs.TRANSITION_TYPED, false, 0); - // We should not sync during a batch - new_test_visit_uri_event(id, TEST_URI, false); - } - }, null); - // Ensure the visit has been added - do_check_neq(id, -1); - - do_test_pending(); -} diff --git a/toolkit/components/places/tests/sync/test_database_sync_after_modifyBookmark.js b/toolkit/components/places/tests/sync/test_database_sync_after_modifyBookmark.js deleted file mode 100644 index 4ec54d836a21..000000000000 --- a/toolkit/components/places/tests/sync/test_database_sync_after_modifyBookmark.js +++ /dev/null @@ -1,108 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: sw=2 ts=2 sts=2 expandtab - * ***** 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 mozilla.org code. - * - * The Initial Developer of the Original Code is - * Mozilla Corporation. - * Portions created by the Initial Developer are Copyright (C) 2008 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Shawn Wilsher (Original Author) - * Marco Bonardo - * - * 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 ***** */ - -var bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"]. - getService(Ci.nsINavBookmarksService); -var os = Cc["@mozilla.org/observer-service;1"]. - getService(Ci.nsIObserverService); -var prefs = Cc["@mozilla.org/preferences-service;1"]. - getService(Ci.nsIPrefService). - getBranch("places."); - -const TEST_URI = "http://test.com/"; -const MODIFIED_URI = "http://test.com/index.html"; - -const SYNC_INTERVAL = 600; // ten minutes -const kSyncPrefName = "syncDBTableIntervalInSecs"; -const kSyncFinished = "places-sync-finished"; - -// Used to update observer itemId -var bookmarksObserver = { - onItemAdded: function(aItemId, aNewParent, aNewIndex) { - observer.itemId = aItemId; - }, - onItemChanged: function(aItemId, aProperty, aValue) { - if (aProperty == "uri") - do_check_eq(observer.itemId, aItemId); - } -} -bs.addObserver(bookmarksObserver, false); - -var observer = { - itemId: -1, - _runCount: 0, - observe: function(aSubject, aTopic, aData) { - if (aTopic == kSyncFinished) { - // item id must be valid - do_check_neq(this.itemId, -1); - if (++this._runCount == 1) { - // First sync is fired by adding the bookmark - // Check that tables have been synced after insertBookmark - new_test_bookmark_uri_event(this.itemId, TEST_URI, true); - // Now modify the bookmark - bs.changeBookmarkURI(this.itemId, uri(MODIFIED_URI)); - } - else if (this._runCount == 2) { - // Second sync is fired by changing the bookmark's uri - // remove the observer, we don't need to observe sync on quit - os.removeObserver(this, kSyncFinished); - bs.removeObserver(bookmarksObserver); - // Check that tables have been synced after changeBookmarkURI - new_test_bookmark_uri_event(this.itemId, MODIFIED_URI, true, true); - } - else - do_throw("Too many places sync calls"); - } - } -} -os.addObserver(observer, kSyncFinished, false); - -function run_test() -{ - // Set the preference for the timer to a really large value, so it won't - // run before the test finishes. - prefs.setIntPref(kSyncPrefName, SYNC_INTERVAL); - - // Insert a new bookmark - bs.insertBookmark(bs.unfiledBookmarksFolder, uri(TEST_URI), - bs.DEFAULT_INDEX, "test"); - - do_test_pending(); -} diff --git a/toolkit/components/places/tests/sync/test_database_sync_after_quit_application.js b/toolkit/components/places/tests/sync/test_database_sync_after_quit_application.js deleted file mode 100644 index 9fa61bf0b9e6..000000000000 --- a/toolkit/components/places/tests/sync/test_database_sync_after_quit_application.js +++ /dev/null @@ -1,93 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: sw=2 ts=2 sts=2 expandtab - * ***** 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 mozilla.org code. - * - * The Initial Developer of the Original Code is - * Mozilla Corporation. - * Portions created by the Initial Developer are Copyright (C) 2008 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Shawn Wilsher (Original Author) - * Marco Bonardo - * - * 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 ***** */ - -var os = Cc["@mozilla.org/observer-service;1"]. - getService(Ci.nsIObserverService); -var prefs = Cc["@mozilla.org/preferences-service;1"]. - getService(Ci.nsIPrefService). - getBranch("places."); -var hs = Cc["@mozilla.org/browser/nav-history-service;1"]. - getService(Ci.nsINavHistoryService); - -const TEST_URI = "http://test.com/"; - -const kSyncPrefName = "syncDBTableIntervalInSecs"; -const SYNC_INTERVAL = 600; // ten minutes -const kSyncFinished = "places-sync-finished"; - -var historyObserver = { - onVisit: function(aURI, aVisitId, aTime, aSessionId, aReferringId, - aTransitionType, aAdded) { - observer.visitId = aVisitId; - } -} -hs.addObserver(historyObserver, false); - -var observer = { - visitId: -1, - observe: function(aSubject, aTopic, aData) { - if (aTopic == kSyncFinished) { - // visit id must be valid - do_check_neq(this.visitId, -1); - // remove the observer, we don't need to observe sync on quit - os.removeObserver(this, kSyncFinished); - hs.removeObserver(historyObserver); - // Check that tables have been correctly synced - new_test_visit_uri_event(this.visitId, TEST_URI, true, true); - } - } -} -os.addObserver(observer, kSyncFinished, false); - -function run_test() -{ - // Set the preference for the timer to a really large value, so it won't - // run before the test finishes. - prefs.setIntPref(kSyncPrefName, SYNC_INTERVAL); - - // Now add a visit - hs.addVisit(uri(TEST_URI), Date.now() * 1000, null, - hs.TRANSITION_TYPED, false, 0); - - // Notify that we are quitting the app - we should sync! - os.notifyObservers(null, "quit-application", null); - - do_test_pending(); -} diff --git a/toolkit/components/places/tests/sync/test_multiple_bookmarks_around_sync.js b/toolkit/components/places/tests/sync/test_multiple_bookmarks_around_sync.js deleted file mode 100644 index 222e08c0526b..000000000000 --- a/toolkit/components/places/tests/sync/test_multiple_bookmarks_around_sync.js +++ /dev/null @@ -1,150 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: sw=2 ts=2 sts=2 expandtab - * ***** 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 mozilla.org code. - * - * The Initial Developer of the Original Code is - * Mozilla Corporation. - * Portions created by the Initial Developer are Copyright (C) 2008 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Shawn Wilsher (Original Author) - * Marco Bonardo - * - * 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 ***** */ - -/** - * This test ensures that adding a bookmark (which has an implicit sync), then - * adding another one that has the same place, we end up with only one entry in - * moz_places. - */ - -var bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"]. - getService(Ci.nsINavBookmarksService); -var hs = Cc["@mozilla.org/browser/nav-history-service;1"]. - getService(Ci.nsINavHistoryService); -var db = Cc["@mozilla.org/browser/nav-history-service;1"]. - getService(Ci.nsPIPlacesDatabase). - DBConnection; -var os = Cc["@mozilla.org/observer-service;1"]. - getService(Ci.nsIObserverService); -var prefs = Cc["@mozilla.org/preferences-service;1"]. - getService(Ci.nsIPrefService). - getBranch("places."); - -const TEST_URI = "http://test.com/"; - -const SYNC_INTERVAL = 600; // ten minutes -const kSyncPrefName = "syncDBTableIntervalInSecs"; -const kSyncFinished = "places-sync-finished"; - -// Used to update observer itemId -var bookmarksObserver = { - onItemAdded: function(aItemId, aNewParent, aNewIndex) { - observer.itemIds.push(aItemId); - } -} -bs.addObserver(bookmarksObserver, false); - -var observer = { - itemIds: [], - _placeId: -1, - _runCount: 0, - observe: function(aSubject, aTopic, aData) { - if (aTopic == kSyncFinished) { - if (++this._runCount == 1) { - let itemId = this.itemIds[this._runCount - 1]; - // item id must be valid - do_check_neq(itemId, null); - // Ensure tables have been synced - new_test_bookmark_uri_event(itemId, TEST_URI, true); - - // Get the place_id - let stmt = db.createStatement( - "SELECT fk " + - "FROM moz_bookmarks " + - "WHERE id = ?" - ); - stmt.bindInt64Parameter(0, itemId); - do_check_true(stmt.executeStep()); - this._placeId = stmt.getInt64(0); - stmt.finalize(); - stmt = null; - // place id must be valid - do_check_true(this._placeId > 0); - } - else if (this._runCount == 2) { - let itemId = this.itemIds[this._runCount - 1]; - // item id must be valid - do_check_neq(itemId, null); - // Ensure it was added - new_test_bookmark_uri_event(itemId, TEST_URI, true); - - // Check to make sure we have the same place_id - stmt = db.createStatement( - "SELECT * " + - "FROM moz_bookmarks " + - "WHERE id = ?1 " + - "AND fk = ?2" - ); - stmt.bindInt64Parameter(0, itemId); - stmt.bindInt64Parameter(1, this._placeId); - do_check_true(stmt.executeStep()); - stmt.finalize(); - stmt = null; - - // remove the observer, we don't need to observe sync on quit - os.removeObserver(this, kSyncFinished); - bs.removeObserver(bookmarksObserver); - // test ends here - finish_test(); - } - else - do_throw("Too many places sync calls"); - } - } -} -os.addObserver(observer, kSyncFinished, false); - -function run_test() -{ - // Set the preference for the timer to a really large value, so it won't - // run before the test finishes. - prefs.setIntPref(kSyncPrefName, SYNC_INTERVAL); - - // Add the first bookmark - let id1 = bs.insertBookmark(bs.unfiledBookmarksFolder, uri(TEST_URI), - bs.DEFAULT_INDEX, "test"); - - // Now we add another bookmark to a different folder - let id2 = bs.insertBookmark(bs.toolbarFolder, uri(TEST_URI), - bs.DEFAULT_INDEX, "test"); - do_check_neq(id1, id2); - - do_test_pending(); -} diff --git a/toolkit/components/places/tests/sync/test_multiple_visits_around_sync.js b/toolkit/components/places/tests/sync/test_multiple_visits_around_sync.js deleted file mode 100644 index 3796c24cf8e5..000000000000 --- a/toolkit/components/places/tests/sync/test_multiple_visits_around_sync.js +++ /dev/null @@ -1,127 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: sw=2 ts=2 sts=2 expandtab - * ***** 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 mozilla.org code. - * - * The Initial Developer of the Original Code is - * Mozilla Corporation. - * Portions created by the Initial Developer are Copyright (C) 2008 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Shawn Wilsher (Original Author) - * Marco Bonardo - * - * 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 ***** */ - -/** - * This test ensures that when adding a visit, then syncing, and adding another - * visit to the same url creates two visits and that we only end up with one - * entry in moz_places. - */ - -var hs = Cc["@mozilla.org/browser/nav-history-service;1"]. - getService(Ci.nsINavHistoryService); -var db = Cc["@mozilla.org/browser/nav-history-service;1"]. - getService(Ci.nsPIPlacesDatabase). - DBConnection; -var prefs = Cc["@mozilla.org/preferences-service;1"]. - getService(Ci.nsIPrefService). - getBranch("places."); - -const TEST_URI = "http://test.com/"; - -const kSyncPrefName = "syncDBTableIntervalInSecs"; -const SYNC_INTERVAL = 1; - -function run_test() -{ - // First set the preference for the timer to a small value - prefs.setIntPref(kSyncPrefName, SYNC_INTERVAL); - - // Now add the first visit - let id = hs.addVisit(uri(TEST_URI), Date.now() * 1000, null, - hs.TRANSITION_TYPED, false, 0); - - // Check the visit, but after enough time has passed for the DB flush service - // to have fired it's timer. - let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - timer.initWithCallback({ - notify: function(aTimer) - { - new_test_visit_uri_event(id, TEST_URI, true); - - // Get the place_id and pass it on - let db = hs.QueryInterface(Ci.nsPIPlacesDatabase).DBConnection; - let stmt = db.createStatement( - "SELECT place_id " + - "FROM moz_historyvisits " + - "WHERE id = ?" - ); - stmt.bindInt64Parameter(0, id); - do_check_true(stmt.executeStep()); - continue_test(id, stmt.getInt64(0)); - stmt.finalize(); - stmt = null; - } - }, (SYNC_INTERVAL * 1000) * 2, Ci.nsITimer.TYPE_ONE_SHOT); - do_test_pending(); -} - -function continue_test(aLastVisitId, aPlaceId) -{ - // Now we add another visit - let id = hs.addVisit(uri(TEST_URI), Date.now() * 1000, null, - hs.TRANSITION_TYPED, false, 0); - do_check_neq(aLastVisitId, id); - - // Check the visit, but after enough time has passed for the DB flush service - // to have fired it's timer. - let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - timer.initWithCallback({ - notify: function(aTimer) - { - new_test_visit_uri_event(id, TEST_URI, true); - - // Check to make sure we have the same place_id - let db = hs.QueryInterface(Ci.nsPIPlacesDatabase).DBConnection; - let stmt = db.createStatement( - "SELECT * " + - "FROM moz_historyvisits " + - "WHERE id = ?1 " + - "AND place_id = ?2" - ); - stmt.bindInt64Parameter(0, id); - stmt.bindInt64Parameter(1, aPlaceId); - do_check_true(stmt.executeStep()); - stmt.finalize(); - stmt = null; - - finish_test(); - } - }, (SYNC_INTERVAL * 1000) * 2, Ci.nsITimer.TYPE_ONE_SHOT); -} diff --git a/toolkit/components/places/tests/unit/test_history.js b/toolkit/components/places/tests/unit/test_history.js index 30598e1da9c9..93fa1c2409c0 100644 --- a/toolkit/components/places/tests/unit/test_history.js +++ b/toolkit/components/places/tests/unit/test_history.js @@ -41,8 +41,6 @@ // Get history service try { var histsvc = Cc["@mozilla.org/browser/nav-history-service;1"].getService(Ci.nsINavHistoryService); - var gh = Cc["@mozilla.org/browser/global-history;2"]. - getService(Ci.nsIGlobalHistory2); } catch(ex) { do_throw("Could not get history service\n"); } @@ -63,9 +61,7 @@ function add_visit(aURI, aReferrer) { histsvc.TRANSITION_TYPED, // user typed in URL bar false, // not redirect 0); - dump("### Added visit with id of " + placeID + "\n"); do_check_true(placeID > 0); - do_check_true(gh.isVisited(aURI)); return placeID; }