Bug 552023 - Kill Places partitioned temp tables.

r=sdwilsh
r=mak
a=blocking2.0
This commit is contained in:
Marco Bonardo ext:(%2C%20Shawn%20Wilsher%20%3Cme%40shawnwilsher.com%3E) 2010-08-09 17:59:59 +02:00
parent bf20473281
commit 50d31806a3
57 changed files with 495 additions and 3718 deletions

View File

@ -221,10 +221,9 @@ function ensure_opentabs_match_db() {
try {
var stmt = db.createStatement(
"SELECT t.url, open_count, IFNULL(p_t.id, p.id) " +
"SELECT t.url, open_count, p.id " +
"FROM moz_openpages_temp t " +
"LEFT JOIN moz_places p ON p.url = t.url " +
"LEFT JOIN moz_places_temp p_t ON p_t.url = t.url");
"LEFT JOIN moz_places p ON p.url = t.url ");
} catch (e) {
ok(false, "error creating db statement: " + e);
return;

View File

@ -417,10 +417,7 @@ BrowserGlue.prototype = {
}
// Load the "more info" page for a locked places.sqlite
// This property is set earlier in the startup process:
// nsPlacesDBFlush loads after profile-after-change and initializes
// the history service, which sends out places-database-locked
// which sets this property.
// This property is set earlier by places-database-locked topic.
if (this._isPlacesDatabaseLocked) {
this._showPlacesLockedNotificationBox();
}

View File

@ -53,9 +53,7 @@ let EXPECTED_NOTIFICATIONS = [
"places-shutdown"
, "places-will-close-connection"
, "places-connection-closing"
, "places-sync-finished"
, "places-expiration-finished"
, "places-sync-finished"
, "places-connection-closed"
];

View File

@ -345,7 +345,6 @@
@BINPATH@/components/toolkitplaces.manifest
@BINPATH@/components/nsLivemarkService.js
@BINPATH@/components/nsTaggingService.js
@BINPATH@/components/nsPlacesDBFlush.js
@BINPATH@/components/nsPlacesAutoComplete.manifest
@BINPATH@/components/nsPlacesAutoComplete.js
@BINPATH@/components/nsPlacesExpiration.js

View File

@ -1089,3 +1089,4 @@ extensions/inspector@mozilla.org/components/@DLL_PREFIX@inspector@DLL_SUFFIX@
extensions/inspector@mozilla.org/chrome/icons/default/winInspectorMain.ico
components/nsPlacesTransactionsService.js
components/browserplaces.xpt
components/nsPlacesDBFlush.js

View File

@ -71,6 +71,24 @@ public:
* Macros to use for lazy statements initialization in Places services that use
* GetStatement() method.
*/
#ifdef DEBUG
#define RETURN_IF_STMT(_stmt, _sql) \
PR_BEGIN_MACRO \
if (address_of(_stmt) == address_of(aStmt)) { \
if (!_stmt) { \
nsresult rv = mDBConn->CreateStatement(_sql, getter_AddRefs(_stmt)); \
if (NS_FAILED(rv)) { \
nsCAutoString err; \
(void)mDBConn->GetLastErrorString(err); \
(void)fprintf(stderr, "$$$ compiling statement failed with '%s'\n", \
err.get()); \
} \
NS_ENSURE_TRUE(NS_SUCCEEDED(rv) && _stmt, nsnull); \
} \
return _stmt.get(); \
} \
PR_END_MACRO
#else
#define RETURN_IF_STMT(_stmt, _sql) \
PR_BEGIN_MACRO \
if (address_of(_stmt) == address_of(aStmt)) { \
@ -81,6 +99,7 @@ public:
return _stmt.get(); \
} \
PR_END_MACRO
#endif
// Async statements don't need to be scoped, they are reset when done.
// So use this version for statements used async, scoped version for statements

View File

@ -89,7 +89,6 @@ EXTRA_COMPONENTS = \
toolkitplaces.manifest \
nsLivemarkService.js \
nsTaggingService.js \
nsPlacesDBFlush.js \
nsPlacesExpiration.js \
nsMicrosummaryService.js \
$(NULL)

View File

@ -212,8 +212,6 @@ nsPlacesDBUtils.prototype = {
"DELETE FROM moz_annos WHERE id IN ( " +
"SELECT id FROM moz_annos a " +
"WHERE NOT EXISTS " +
"(SELECT id FROM moz_places_temp WHERE id = a.place_id LIMIT 1) " +
"AND NOT EXISTS " +
"(SELECT id FROM moz_places WHERE id = a.place_id LIMIT 1) " +
")");
cleanupStatements.push(deleteOrphanAnnos);
@ -288,7 +286,6 @@ nsPlacesDBUtils.prototype = {
") AND id IN (" +
"SELECT b.id FROM moz_bookmarks b " +
"WHERE fk NOT NULL AND b.type = :bookmark_type " +
"AND NOT EXISTS (SELECT url FROM moz_places_temp WHERE id = b.fk LIMIT 1) " +
"AND NOT EXISTS (SELECT url FROM moz_places WHERE id = b.fk LIMIT 1) " +
")");
deleteNoPlaceItems.params["bookmark_type"] = this._bms.TYPE_BOOKMARK;
@ -447,7 +444,6 @@ nsPlacesDBUtils.prototype = {
// D.11 remove old livemarks status items
// Livemark status items are now static but some livemark has still old
// status items bookmarks inside it. We should remove them.
// Note: This does not need to query the temp table.
let removeLivemarkStaticItems = this._dbConn.createStatement(
"DELETE FROM moz_bookmarks WHERE type = :bookmark_type AND fk IN ( " +
"SELECT id FROM moz_places WHERE url = :lmloading OR url = :lmfailed " +
@ -463,8 +459,6 @@ nsPlacesDBUtils.prototype = {
"DELETE FROM moz_favicons WHERE id IN (" +
"SELECT id FROM moz_favicons f " +
"WHERE NOT EXISTS " +
"(SELECT id FROM moz_places_temp WHERE favicon_id = f.id LIMIT 1) " +
"AND NOT EXISTS" +
"(SELECT id FROM moz_places WHERE favicon_id = f.id LIMIT 1) " +
")");
cleanupStatements.push(deleteOrphanIcons);
@ -475,8 +469,6 @@ nsPlacesDBUtils.prototype = {
"DELETE FROM moz_historyvisits WHERE id IN (" +
"SELECT id FROM moz_historyvisits v " +
"WHERE NOT EXISTS " +
"(SELECT id FROM moz_places_temp WHERE id = v.place_id LIMIT 1) " +
"AND NOT EXISTS " +
"(SELECT id FROM moz_places WHERE id = v.place_id LIMIT 1) " +
")");
cleanupStatements.push(deleteOrphanVisits);
@ -487,8 +479,6 @@ nsPlacesDBUtils.prototype = {
"DELETE FROM moz_inputhistory WHERE place_id IN (" +
"SELECT place_id FROM moz_inputhistory i " +
"WHERE NOT EXISTS " +
"(SELECT id FROM moz_places_temp WHERE id = i.place_id LIMIT 1) " +
"AND NOT EXISTS " +
"(SELECT id FROM moz_places WHERE id = i.place_id LIMIT 1) " +
")");
cleanupStatements.push(deleteOrphanInputHistory);
@ -536,22 +526,17 @@ nsPlacesDBUtils.prototype = {
/* XXX needs test
// L.2 recalculate visit_count
// We're detecting errors only in disk table since temp tables could have
// different values based on the number of visits not yet synced to disk.
let detectWrongCountPlaces = this._dbConn.createStatement(
"SELECT id FROM moz_places h " +
"WHERE id NOT IN (SELECT id FROM moz_places_temp) " +
"AND h.visit_count <> " +
"WHERE h.visit_count <> " +
"(SELECT count(*) FROM moz_historyvisits " +
"WHERE place_id = h.id AND visit_type NOT IN (0,4,7,8))");
while (detectWrongCountPlaces.executeStep()) {
let placeId = detectWrongCountPlaces.getInt64(0);
let fixCountForPlace = this._dbConn.createStatement(
"UPDATE moz_places_view SET visit_count = ( " +
"UPDATE moz_places SET visit_count = ( " +
"(SELECT count(*) FROM moz_historyvisits " +
"WHERE place_id = :place_id AND visit_type NOT IN (0,4,7,8)) + " +
"(SELECT count(*) FROM moz_historyvisits_temp " +
"WHERE place_id = :place_id AND visit_type NOT IN (0,4,7,8)) + " +
"WHERE place_id = :place_id AND visit_type NOT IN (0,4,7,8)) + "
") WHERE id = :place_id");
fixCountForPlace.params["place_id"] = placeId;
cleanupStatements.push(fixCountForPlace);

View File

@ -150,7 +150,6 @@ var PlacesUtils = {
TOPIC_DATABASE_LOCKED: "places-database-locked",
TOPIC_EXPIRATION_FINISHED: "places-expiration-finished",
TOPIC_FEEDBACK_UPDATED: "places-autocomplete-feedback-updated",
TOPIC_SYNC_FINISHED: "places-sync-finished",
TOPIC_FAVICONS_EXPIRED: "places-favicons-expired",
TOPIC_VACUUM_STARTING: "places-vacuum-starting",

View File

@ -136,23 +136,17 @@ nsAnnotationService::GetStatement(const nsCOMPtr<mozIStorageStatement>& aStmt)
"SELECT n.name "
"FROM moz_anno_attributes n "
"JOIN moz_annos a ON a.anno_attribute_id = n.id "
"JOIN ( "
"SELECT id FROM moz_places_temp WHERE url = :page_url "
"UNION "
"SELECT id FROM moz_places WHERE url = :page_url "
") AS h ON h.id = a.place_id"));
"JOIN moz_places h ON h.id = a.place_id "
"WHERE h.url = :page_url"));
RETURN_IF_STMT(mDBGetPageAnnotationValue, NS_LITERAL_CSTRING(
"SELECT a.id, a.place_id, :anno_name, a.mime_type, a.content, a.flags, "
"a.expiration, a.type "
"FROM moz_anno_attributes n "
"JOIN moz_annos a ON n.id = a.anno_attribute_id "
"JOIN ( "
"SELECT id FROM moz_places_temp WHERE url = :page_url "
"UNION "
"SELECT id FROM moz_places WHERE url = :page_url "
") AS h ON h.id = a.place_id "
"WHERE n.name = :anno_name"));
"JOIN moz_places h ON h.id = a.place_id "
"WHERE h.url = :page_url "
"AND n.name = :anno_name"));
RETURN_IF_STMT(mDBGetItemAnnotationValue, NS_LITERAL_CSTRING(
"SELECT a.id, a.item_id, :anno_name, a.mime_type, a.content, a.flags, "
@ -181,26 +175,22 @@ nsAnnotationService::GetStatement(const nsCOMPtr<mozIStorageStatement>& aStmt)
RETURN_IF_STMT(mDBRemovePageAnnotation, NS_LITERAL_CSTRING(
"DELETE FROM moz_annos "
"WHERE place_id = ( "
"SELECT id FROM moz_places_temp WHERE url = :page_url "
"UNION "
"SELECT id FROM moz_places WHERE url = :page_url) "
"AND anno_attribute_id = "
"(SELECT id FROM moz_anno_attributes WHERE name = :anno_name)"));
"WHERE place_id = (SELECT id FROM moz_places WHERE url = :page_url) "
"AND anno_attribute_id = "
"(SELECT id FROM moz_anno_attributes WHERE name = :anno_name)"));
RETURN_IF_STMT(mDBRemoveItemAnnotation, NS_LITERAL_CSTRING(
"DELETE FROM moz_items_annos "
"WHERE item_id = :item_id "
"AND anno_attribute_id = "
"(SELECT id FROM moz_anno_attributes WHERE name = :anno_name)"));
"AND anno_attribute_id = "
"(SELECT id FROM moz_anno_attributes WHERE name = :anno_name)"));
RETURN_IF_STMT(mDBGetPagesWithAnnotation, NS_LITERAL_CSTRING(
"SELECT IFNULL(h_t.url, h.url) AS coalesced_url "
"SELECT h.url "
"FROM moz_anno_attributes n "
"JOIN moz_annos a ON n.id = a.anno_attribute_id "
"LEFT JOIN moz_places h ON h.id = a.place_id "
"LEFT JOIN moz_places_temp h_t ON h_t.id = a.place_id "
"WHERE n.name = :anno_name AND coalesced_url NOT NULL"));
"JOIN moz_places h ON h.id = a.place_id "
"WHERE n.name = :anno_name"));
RETURN_IF_STMT(mDBGetItemsWithAnnotation, NS_LITERAL_CSTRING(
"SELECT a.item_id "
@ -212,12 +202,10 @@ nsAnnotationService::GetStatement(const nsCOMPtr<mozIStorageStatement>& aStmt)
"SELECT h.id, "
"(SELECT id FROM moz_anno_attributes WHERE name = :anno_name) AS nameid, "
"a.id, a.dateAdded "
"FROM (SELECT id FROM moz_places_temp WHERE url = :page_url "
"UNION "
"SELECT id FROM moz_places WHERE url = :page_url "
") AS h "
"FROM moz_places h "
"LEFT JOIN moz_annos a ON a.place_id = h.id "
"AND a.anno_attribute_id = nameid"));
"AND a.anno_attribute_id = nameid "
"WHERE h.url = :page_url"));
RETURN_IF_STMT(mDBCheckItemAnnotation, NS_LITERAL_CSTRING(
"SELECT b.id, "
@ -1582,9 +1570,7 @@ nsAnnotationService::RemovePageAnnotations(nsIURI* aURI)
nsCOMPtr<mozIStorageStatement> statement;
nsresult rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
"DELETE FROM moz_annos WHERE place_id = "
"(SELECT id FROM moz_places_temp WHERE url = :page_url "
"UNION "
"SELECT id FROM moz_places WHERE url = :page_url)"),
"(SELECT id FROM moz_places WHERE url = :page_url)"),
getter_AddRefs(statement));
NS_ENSURE_SUCCESS(rv, rv);
rv = URIBinder::Bind(statement, NS_LITERAL_CSTRING("page_url"), aURI);
@ -1644,18 +1630,13 @@ nsAnnotationService::CopyPageAnnotations(nsIURI* aSourceURI,
nsCOMPtr<mozIStorageStatement> sourceStmt;
nsresult rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
"SELECT h.id, n.id, n.name, a2.id "
"FROM ( "
"SELECT id from moz_places_temp WHERE url = :source_url "
"UNION "
"SELECT id FROM moz_places WHERE url = :source_url "
") AS h "
"FROM moz_places h "
"JOIN moz_annos a ON a.place_id = h.id "
"JOIN moz_anno_attributes n ON n.id = a.anno_attribute_id "
"LEFT JOIN moz_annos a2 ON a2.place_id = ( "
"SELECT id FROM moz_places_temp WHERE url = :dest_url "
"UNION "
"SELECT id FROM moz_places WHERE url = :dest_url "
") AND a2.anno_attribute_id = n.id"),
"LEFT JOIN moz_annos a2 ON a2.place_id = "
"(SELECT id FROM moz_places WHERE url = :dest_url) "
"AND a2.anno_attribute_id = n.id "
"WHERE url = :source_url"),
getter_AddRefs(sourceStmt));
NS_ENSURE_SUCCESS(rv, rv);
@ -1669,12 +1650,9 @@ nsAnnotationService::CopyPageAnnotations(nsIURI* aSourceURI,
"INSERT INTO moz_annos "
"(place_id, anno_attribute_id, mime_type, content, flags, expiration, "
"type, dateAdded, lastModified) "
"SELECT ( "
"SELECT id FROM moz_places_temp WHERE url = :page_url "
"UNION "
"SELECT id FROM moz_places WHERE url = :page_url "
"), anno_attribute_id, mime_type, content, flags, expiration, type, "
":date, :date "
"SELECT (SELECT id FROM moz_places WHERE url = :page_url), "
"anno_attribute_id, mime_type, content, flags, expiration, type, "
":date, :date "
"FROM moz_annos "
"WHERE place_id = :page_id "
"AND anno_attribute_id = :name_id"),

View File

@ -171,30 +171,20 @@ nsFaviconService::GetStatement(const nsCOMPtr<mozIStorageStatement>& aStmt)
RETURN_IF_STMT(mDBGetIconInfoWithPage, NS_LITERAL_CSTRING(
"SELECT id, length(data), expiration, data, mime_type, "
"IFNULL(url = (SELECT f.url "
"FROM ( "
"SELECT favicon_id FROM moz_places_temp "
"WHERE url = :page_url "
"UNION ALL "
"SELECT favicon_id FROM moz_places "
"WHERE url = :page_url "
") AS h "
"FROM moz_places h "
"JOIN moz_favicons f ON h.favicon_id = f.id "
"WHERE h.url = :page_url "
"LIMIT 1), "
"0)"
"0) "
"FROM moz_favicons WHERE url = :icon_url"));
RETURN_IF_STMT(mDBGetURL, NS_LITERAL_CSTRING(
"SELECT f.id, f.url, length(f.data), f.expiration "
"FROM ( "
"SELECT " MOZ_PLACES_COLUMNS " FROM moz_places_temp "
"WHERE url = :page_url "
"UNION ALL "
"SELECT " MOZ_PLACES_COLUMNS " FROM moz_places "
"WHERE url = :page_url "
") AS h JOIN moz_favicons f ON h.favicon_id = f.id "
"FROM moz_places h "
"JOIN moz_favicons f ON h.favicon_id = f.id "
"WHERE h.url = :page_url "
"LIMIT 1"));
RETURN_IF_STMT(mDBGetData, NS_LITERAL_CSTRING(
"SELECT f.data, f.mime_type FROM moz_favicons f WHERE url = :icon_url"));
@ -208,10 +198,10 @@ nsFaviconService::GetStatement(const nsCOMPtr<mozIStorageStatement>& aStmt)
"WHERE id = :icon_id"));
RETURN_IF_STMT(mDBSetPageFavicon, NS_LITERAL_CSTRING(
"UPDATE moz_places_view SET favicon_id = :icon_id WHERE id = :page_id"));
"UPDATE moz_places SET favicon_id = :icon_id WHERE id = :page_id"));
RETURN_IF_STMT(mDBAssociateFaviconURIToPageURI, NS_LITERAL_CSTRING(
"UPDATE moz_places_view "
"UPDATE moz_places "
"SET favicon_id = (SELECT id FROM moz_favicons WHERE url = :icon_url) "
"WHERE url = :page_url"));
@ -220,15 +210,8 @@ nsFaviconService::GetStatement(const nsCOMPtr<mozIStorageStatement>& aStmt)
"SET favicon_id = NULL "
"WHERE favicon_id NOT NULL"));
RETURN_IF_STMT(mDBRemoveTempReferences, NS_LITERAL_CSTRING(
"UPDATE moz_places_temp "
"SET favicon_id = NULL "
"WHERE favicon_id NOT NULL"));
RETURN_IF_STMT(mDBRemoveAllFavicons, NS_LITERAL_CSTRING(
"DELETE FROM moz_favicons WHERE id NOT IN ("
"SELECT favicon_id FROM moz_places_temp WHERE favicon_id NOT NULL "
"UNION ALL "
"SELECT favicon_id FROM moz_places WHERE favicon_id NOT NULL "
")"));
@ -262,16 +245,11 @@ nsFaviconService::ExpireAllFavicons()
{
mFaviconsExpirationRunning = true;
// We do this in 2 steps, first we null-out all favicons in the disk table,
// then we do the same in the temp table. This is because the view UPDATE
// trigger does not allow setting a NULL value to prevent dataloss.
mozIStorageBaseStatement *stmts[] = {
GetStatement(mDBRemoveOnDiskReferences),
GetStatement(mDBRemoveTempReferences),
GetStatement(mDBRemoveAllFavicons),
};
NS_ENSURE_STATE(stmts[0] && stmts[1] && stmts[2]);
NS_ENSURE_STATE(stmts[0] && stmts[1]);
nsCOMPtr<mozIStoragePendingStatement> ps;
nsCOMPtr<ExpireFaviconsStatementCallbackNotifier> callback =
new ExpireFaviconsStatementCallbackNotifier(&mFaviconsExpirationRunning);
@ -1051,7 +1029,6 @@ nsFaviconService::FinalizeStatements() {
mDBUpdateIcon,
mDBSetPageFavicon,
mDBRemoveOnDiskReferences,
mDBRemoveTempReferences,
mDBRemoveAllFavicons,
mDBAssociateFaviconURIToPageURI,
};

View File

@ -190,7 +190,6 @@ private:
nsCOMPtr<mozIStorageStatement> mDBSetPageFavicon;
nsCOMPtr<mozIStorageStatement> mDBAssociateFaviconURIToPageURI;
nsCOMPtr<mozIStorageStatement> mDBRemoveOnDiskReferences;
nsCOMPtr<mozIStorageStatement> mDBRemoveTempReferences;
nsCOMPtr<mozIStorageStatement> mDBRemoveAllFavicons;
static nsFaviconService* gFaviconService;

View File

@ -251,17 +251,12 @@ nsNavBookmarks::GetStatement(const nsCOMPtr<mozIStorageStatement>& aStmt)
// Double ordering covers possible lastModified ties, that could happen when
// importing, syncing or due to extensions.
// Note: not using a JOIN is cheaper in this case.
RETURN_IF_STMT(mDBFindURIBookmarks, NS_LITERAL_CSTRING(
"SELECT b.id "
"FROM moz_bookmarks b "
"WHERE b.type = :item_type AND b.fk = ( "
"SELECT id FROM moz_places_temp "
"WHERE url = :page_url "
"UNION "
"SELECT id FROM moz_places "
"WHERE url = :page_url "
"LIMIT 1 "
") "
"WHERE b.fk = (SELECT id FROM moz_places WHERE url = :page_url) "
"AND b.fk NOTNULL "
"ORDER BY b.lastModified DESC, b.id DESC "));
// Select all children of a given folder, sorted by position.
@ -271,15 +266,10 @@ nsNavBookmarks::GetStatement(const nsCOMPtr<mozIStorageStatement>& aStmt)
// by mDBGetURLPageInfo, and additionally contains columns for position,
// item_child, and folder_child from moz_bookmarks.
RETURN_IF_STMT(mDBGetChildren, NS_LITERAL_CSTRING(
"SELECT IFNULL(h_t.id, h.id), IFNULL(h_t.url, h.url), "
"COALESCE(b.title, h_t.title, h.title), "
"IFNULL(h_t.rev_host, h.rev_host), "
"IFNULL(h_t.visit_count, h.visit_count), "
"IFNULL(h_t.last_visit_date, h.last_visit_date), "
"f.url, null, b.id, b.dateAdded, b.lastModified, b.parent, null, "
"b.position, b.type, b.fk, b.folder_type "
"SELECT h.id, h.url, IFNULL(b.title, h.title), h.rev_host, h.visit_count, "
"h.last_visit_date, f.url, null, b.id, b.dateAdded, b.lastModified, "
"b.parent, null, b.position, b.type, b.fk, b.folder_type "
"FROM moz_bookmarks b "
"LEFT JOIN moz_places_temp h_t ON b.fk = h_t.id "
"LEFT JOIN moz_places h ON b.fk = h.id "
"LEFT JOIN moz_favicons f ON h.favicon_id = f.id "
"WHERE b.parent = :parent "
@ -298,8 +288,7 @@ nsNavBookmarks::GetStatement(const nsCOMPtr<mozIStorageStatement>& aStmt)
// Get bookmark/folder/separator properties.
RETURN_IF_STMT(mDBGetItemProperties, NS_LITERAL_CSTRING(
"SELECT b.id, "
"IFNULL((SELECT url FROM moz_places_temp WHERE id = b.fk), "
"(SELECT url FROM moz_places WHERE id = b.fk)), "
"(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 "
@ -323,12 +312,9 @@ nsNavBookmarks::GetStatement(const nsCOMPtr<mozIStorageStatement>& aStmt)
"SELECT 1 FROM moz_bookmarks WHERE fk = :page_id"));
RETURN_IF_STMT(mDBIsURIBookmarkedInDatabase, NS_LITERAL_CSTRING(
"SELECT 1 FROM moz_bookmarks WHERE fk = ("
"SELECT id FROM moz_places_temp WHERE url = :page_url "
"UNION ALL "
"SELECT id FROM moz_places WHERE url = :page_url "
"LIMIT 1"
")"));
"SELECT 1 FROM moz_bookmarks b "
"JOIN moz_places h ON b.fk = h.id "
"WHERE h.url = :page_url"));
// Checks to make sure a place id is a bookmark, and isn't a livemark.
RETURN_IF_STMT(mDBIsRealBookmark, NS_LITERAL_CSTRING(
@ -363,19 +349,12 @@ nsNavBookmarks::GetStatement(const nsCOMPtr<mozIStorageStatement>& aStmt)
RETURN_IF_STMT(mDBSetItemIndex, NS_LITERAL_CSTRING(
"UPDATE moz_bookmarks SET position = :item_index WHERE id = :item_id"));
// Get keyword text for bookmarked URI.
RETURN_IF_STMT(mDBGetKeywordForURI, NS_LITERAL_CSTRING(
"SELECT k.keyword "
"FROM ( "
"SELECT id FROM moz_places_temp "
"WHERE url = :page_url "
"UNION ALL "
"SELECT id FROM moz_places "
"WHERE url = :page_url "
"LIMIT 1 "
") AS h "
"FROM moz_places h "
"JOIN moz_bookmarks b ON b.fk = h.id "
"JOIN moz_keywords k ON k.id = b.keyword_id"));
"JOIN moz_keywords k ON k.id = b.keyword_id "
"WHERE h.url = :page_url "));
RETURN_IF_STMT(mDBAdjustPosition, NS_LITERAL_CSTRING(
"UPDATE moz_bookmarks SET position = position + :delta "
@ -422,14 +401,6 @@ nsNavBookmarks::GetStatement(const nsCOMPtr<mozIStorageStatement>& aStmt)
// For most cases these levels of redirects should be fine though, it's hard
// to hit a page that is 4 or 5 levels of redirects below a bookmarked page.
//
// Moreover this query does not mix-up all possible cases of disk and temp
// tables. This is because we expect a redirects chain to be completely on
// disk or completely in memory. We never bring back visits from disk to
// memory, we sync visits on a timer (the chained visits have narrow times),
// or on bookmarks changes. The likely possiblity that we break a chain in
// the middle is so much smaller than the perf and readability hit we would
// get making complete crossing joins.
//
// As a bonus the query also checks first if place_id is already a bookmark,
// so you don't have to check that apart.
@ -442,31 +413,13 @@ nsNavBookmarks::GetStatement(const nsCOMPtr<mozIStorageStatement>& aStmt)
nsINavHistoryService::TRANSITION_REDIRECT_TEMPORARY);
RETURN_IF_STMT(mDBFindRedirectedBookmark, NS_LITERAL_CSTRING(
"SELECT IFNULL( "
"(SELECT url FROM moz_places_temp WHERE id = :page_id), "
"SELECT "
"(SELECT url FROM moz_places WHERE id = :page_id) "
") "
"FROM moz_bookmarks b "
"WHERE b.fk = :page_id "
"UNION ALL " // Not directly bookmarked.
"SELECT IFNULL( "
"(SELECT url FROM moz_places_temp WHERE id = " COALESCE_PLACEID "), "
"SELECT "
"(SELECT url FROM moz_places WHERE id = " COALESCE_PLACEID ") "
") "
"FROM moz_historyvisits_temp self "
"JOIN moz_bookmarks b ON b.fk = " COALESCE_PLACEID
"LEFT JOIN moz_historyvisits_temp parent ON parent.id = self.from_visit "
"LEFT JOIN moz_historyvisits_temp grandparent ON parent.from_visit = grandparent.id "
"AND parent.visit_type IN (") + redirectsFragment + NS_LITERAL_CSTRING(") "
"LEFT JOIN moz_historyvisits_temp greatgrandparent ON grandparent.from_visit = greatgrandparent.id "
"AND grandparent.visit_type IN (") + redirectsFragment + NS_LITERAL_CSTRING(") "
"WHERE self.visit_type IN (") + redirectsFragment + NS_LITERAL_CSTRING(") "
"AND self.place_id = :page_id "
"UNION ALL " // Not in the temp table.
"SELECT IFNULL( "
"(SELECT url FROM moz_places_temp WHERE id = " COALESCE_PLACEID "), "
"(SELECT url FROM moz_places WHERE id = " COALESCE_PLACEID ") "
") "
"FROM moz_historyvisits self "
"JOIN moz_bookmarks b ON b.fk = " COALESCE_PLACEID
"LEFT JOIN moz_historyvisits parent ON parent.id = self.from_visit "
@ -2631,8 +2584,6 @@ nsNavBookmarks::GetBookmarkIdsForURITArray(nsIURI* aURI,
DECLARE_AND_ASSIGN_SCOPED_LAZY_STMT(stmt, mDBFindURIBookmarks);
nsresult rv = URIBinder::Bind(stmt, NS_LITERAL_CSTRING("page_url"), aURI);
NS_ENSURE_SUCCESS(rv, rv);
rv = stmt->BindInt32ByName(NS_LITERAL_CSTRING("item_type"), TYPE_BOOKMARK);
NS_ENSURE_SUCCESS(rv, rv);
PRBool more;
while (NS_SUCCEEDED((rv = stmt->ExecuteStep(&more))) && more) {

File diff suppressed because it is too large Load Diff

View File

@ -579,7 +579,6 @@ protected:
*/
nsresult InitAdditionalDBItems();
nsresult InitTempTables();
nsresult InitViews();
nsresult InitFunctions();
nsresult InitStatements();
nsresult ForceMigrateBookmarksDB(mozIStorageConnection *aDBConn);
@ -589,6 +588,7 @@ protected:
nsresult MigrateV8Up(mozIStorageConnection *aDBConn);
nsresult MigrateV9Up(mozIStorageConnection *aDBConn);
nsresult MigrateV10Up(mozIStorageConnection *aDBConn);
nsresult MigrateV11Up(mozIStorageConnection *aDBConn);
nsresult RemovePagesInternal(const nsCString& aPlaceIdsQueryString);
nsresult PreparePlacesForVisitsDelete(const nsCString& aPlaceIdsQueryString);

View File

@ -108,33 +108,6 @@ const kTitleTagsSeparator = " \u2013 ";
const kBrowserUrlbarBranch = "browser.urlbar.";
////////////////////////////////////////////////////////////////////////////////
//// Global Functions
/**
* Generates the SQL subquery to get the best favicon for a given revhost. This
* is the favicon for the most recent visit.
*
* @param aTableName
* The table to join to the moz_favicons table with. This must have a
* column called favicon_id.
* @return the SQL subquery (in string form) to get the best favicon.
*/
function best_favicon_for_revhost(aTableName)
{
return "(" +
"SELECT f.url " +
"FROM " + aTableName + " " +
"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 " +
")";
}
////////////////////////////////////////////////////////////////////////////////
//// AutoCompleteStatementCallbackWrapper class
@ -211,32 +184,24 @@ function nsPlacesAutoComplete()
//////////////////////////////////////////////////////////////////////////////
//// Shared Constants for Smart Getters
// Define common pieces of various queries.
// TODO bug 412736 in case of a frecency tie, break it with h.typed and
// h.visit_count which is better than nothing. This is slow, so not doing it
// yet...
// Note: h.frecency is only selected because we need it for ordering.
function sql_base_fragment(aTableName) {
return "SELECT h.url, h.title, f.url, " + kBookTagSQLFragment + ", " +
"h.visit_count, h.typed, h.id, :query_type, t.open_count, " +
"h.frecency " +
"FROM " + aTableName + " h " +
"LEFT OUTER JOIN moz_favicons f ON f.id = h.favicon_id " +
"LEFT OUTER JOIN moz_openpages_temp t ON t.url = h.url " +
"WHERE h.frecency <> 0 " +
"AND AUTOCOMPLETE_MATCH(:searchString, h.url, " +
"IFNULL(bookmark, h.title), tags, " +
"h.visit_count, h.typed, parent, " +
"t.open_count, " +
":matchBehavior, :searchBehavior) " +
"{ADDITIONAL_CONDITIONS} ";
}
const SQL_BASE = sql_base_fragment("moz_places_temp") +
"UNION ALL " +
sql_base_fragment("moz_places") +
"AND +h.id NOT IN (SELECT id FROM moz_places_temp) " +
"ORDER BY h.frecency DESC, h.id DESC " +
"LIMIT :maxResults";
const SQL_BASE = "SELECT h.url, h.title, f.url, " + kBookTagSQLFragment + ", "
+ "h.visit_count, h.typed, h.id, :query_type, "
+ "t.open_count "
+ "FROM moz_places h "
+ "LEFT JOIN moz_favicons f ON f.id = h.favicon_id "
+ "LEFT JOIN moz_openpages_temp t ON t.url = h.url "
+ "WHERE h.frecency <> 0 "
+ "AND AUTOCOMPLETE_MATCH(:searchString, h.url, "
+ "IFNULL(bookmark, h.title), tags, "
+ "h.visit_count, h.typed, parent, "
+ "t.open_count, "
+ ":matchBehavior, :searchBehavior) "
+ "{ADDITIONAL_CONDITIONS} "
+ "ORDER BY h.frecency DESC, h.id DESC "
+ "LIMIT :maxResults";
//////////////////////////////////////////////////////////////////////////////
//// Smart Getters
@ -269,60 +234,56 @@ function nsPlacesAutoComplete()
XPCOMUtils.defineLazyGetter(this, "_defaultQuery", function() {
let replacementText = "";
return this._db.createStatement(
return this._db.createAsyncStatement(
SQL_BASE.replace("{ADDITIONAL_CONDITIONS}", replacementText, "g")
);
});
XPCOMUtils.defineLazyGetter(this, "_historyQuery", function() {
let replacementText = "AND h.visit_count > 0";
return this._db.createStatement(
return this._db.createAsyncStatement(
SQL_BASE.replace("{ADDITIONAL_CONDITIONS}", replacementText, "g")
);
});
XPCOMUtils.defineLazyGetter(this, "_bookmarkQuery", function() {
let replacementText = "AND bookmark IS NOT NULL";
return this._db.createStatement(
return this._db.createAsyncStatement(
SQL_BASE.replace("{ADDITIONAL_CONDITIONS}", replacementText, "g")
);
});
XPCOMUtils.defineLazyGetter(this, "_tagsQuery", function() {
let replacementText = "AND tags IS NOT NULL";
return this._db.createStatement(
return this._db.createAsyncStatement(
SQL_BASE.replace("{ADDITIONAL_CONDITIONS}", replacementText, "g")
);
});
XPCOMUtils.defineLazyGetter(this, "_openPagesQuery", function() {
return this._db.createStatement(
"/* do not warn (bug 487789) */ " +
"SELECT t.url, " +
"COALESCE(h_t.title, h.title, t.url) AS c_title, f.url, " +
kBookTagSQLFragment + ", " +
"IFNULL(h_t.visit_count, h.visit_count) AS c_visit_count, " +
"IFNULL(h_t.typed, h.typed) AS c_typed, " +
"IFNULL(h_t.id, h.id), :query_type, t.open_count, " +
"IFNULL(h_t.frecency, h.frecency) AS c_frecency " +
"FROM moz_openpages_temp t " +
"LEFT JOIN moz_places_temp h_t ON h_t.url = t.url " +
"LEFT JOIN moz_places h ON h.url = t.url " +
"LEFT JOIN moz_favicons f ON f.id = IFNULL(h_t.favicon_id, h.favicon_id) " +
"WHERE t.open_count > 0 " +
"AND AUTOCOMPLETE_MATCH(:searchString, t.url, " +
"COALESCE(bookmark, c_title, t.url), tags, " +
"c_visit_count, c_typed, parent, " +
"t.open_count, " +
":matchBehavior, :searchBehavior) " +
"ORDER BY c_frecency DESC, t.ROWID DESC " +
"LIMIT :maxResults"
return this._db.createAsyncStatement(
"SELECT t.url, "
+ "IFNULL(h.title, t.url) AS c_title, f.url, "
+ kBookTagSQLFragment + ", "
+ "h.visit_count, h.typed, "
+ "h.id, :query_type, t.open_count, h.frecency "
+ "FROM moz_openpages_temp t "
+ "LEFT JOIN moz_places h ON h.url = t.url "
+ "LEFT JOIN moz_favicons f ON f.id = h.favicon_id "
+ "WHERE t.open_count > 0 "
+ "AND AUTOCOMPLETE_MATCH(:searchString, t.url, "
+ "COALESCE(bookmark, c_title, t.url), tags, "
+ "h.visit_count, h.typed, parent, "
+ "t.open_count, "
+ ":matchBehavior, :searchBehavior) "
+ "ORDER BY h.frecency DESC, t.ROWID DESC "
+ "LIMIT :maxResults"
);
});
XPCOMUtils.defineLazyGetter(this, "_typedQuery", function() {
let replacementText = "AND h.typed = 1";
return this._db.createStatement(
return this._db.createAsyncStatement(
SQL_BASE.replace("{ADDITIONAL_CONDITIONS}", replacementText, "g")
);
});
@ -331,58 +292,55 @@ function nsPlacesAutoComplete()
// In this query, we are taking kBookTagSQLFragment only for h.id because it
// uses data from the 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).
return this._db.createStatement(
"/* do not warn (bug 487789) */ " +
"SELECT IFNULL(h_t.url, h.url) AS c_url, " +
"IFNULL(h_t.title, h.title) AS c_title, f.url, " +
kBookTagSQLFragment + ", " +
"IFNULL(h_t.visit_count, h.visit_count) AS c_visit_count, " +
"IFNULL(h_t.typed, h.typed) AS c_typed, " +
"IFNULL(h_t.id, h.id), :query_type, t.open_count, rank " +
"FROM ( " +
"SELECT ROUND(MAX(((i.input = :search_string) + " +
"(SUBSTR(i.input, 1, LENGTH(:search_string)) = :search_string)) * " +
"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) " +
"LEFT JOIN moz_openpages_temp t ON t.url = c_url " +
"WHERE c_url NOTNULL " +
"AND AUTOCOMPLETE_MATCH(:searchString, c_url, " +
"IFNULL(bookmark, c_title), tags, " +
"c_visit_count, c_typed, parent, " +
"t.open_count, " +
":matchBehavior, :searchBehavior) " +
"ORDER BY rank DESC, IFNULL(h_t.frecency, h.frecency) DESC"
// bookmark.
return this._db.createAsyncStatement(
"/* do not warn (bug 487789) */ "
+ "SELECT h.url, h.title, f.url, " + kBookTagSQLFragment + ", "
+ "h.visit_count, h.typed, h.id, :query_type, t.open_count, rank "
+ "FROM ( "
+ "SELECT ROUND( "
+ "MAX(((i.input = :search_string) + "
+ "(SUBSTR(i.input, 1, LENGTH(:search_string)) = :search_string) "
+ ") * i.use_count "
+ ") , 1 " // Round at first decimal.
+ ") AS rank, place_id "
+ "FROM moz_inputhistory i "
+ "GROUP BY i.place_id "
+ "HAVING rank > 0 "
+ ") AS i "
+ "JOIN moz_places h ON h.id = i.place_id "
+ "LEFT JOIN moz_favicons f ON f.id = h.favicon_id "
+ "LEFT JOIN moz_openpages_temp t ON t.url = h.url "
+ "WHERE AUTOCOMPLETE_MATCH(:searchString, h.url, "
+ "IFNULL(bookmark, h.title), tags, "
+ "h.visit_count, h.typed, parent, "
+ "t.open_count, "
+ ":matchBehavior, :searchBehavior) "
+ "ORDER BY rank DESC, h.frecency DESC "
);
});
XPCOMUtils.defineLazyGetter(this, "_keywordQuery", function() {
return this._db.createStatement(
"/* do not warn (bug 487787) */ " +
"SELECT IFNULL( " +
"(SELECT REPLACE(url, '%s', :query_string) FROM moz_places_temp WHERE id = b.fk), " +
"(SELECT REPLACE(url, '%s', :query_string) 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), " +
"IFNULL(h_t.typed, h.typed), COALESCE(h_t.id, h.id, b.fk), " +
":query_type, t.open_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) " +
"LEFT JOIN moz_openpages_temp t ON t.url = search_url " +
"WHERE LOWER(k.keyword) = LOWER(:keyword) " +
"ORDER BY IFNULL(h_t.frecency, h.frecency) DESC"
return this._db.createAsyncStatement(
"/* do not warn (bug 487787) */ "
+ "SELECT "
+ "(SELECT REPLACE(url, '%s', :query_string) FROM moz_places WHERE id = b.fk) "
+ "AS search_url, h.title, "
+ "IFNULL(f.url, (SELECT f.url "
+ "FROM moz_places "
+ "JOIN moz_favicons f ON f.id = favicon_id "
+ "WHERE rev_host = (SELECT rev_host FROM moz_places WHERE id = b.fk) "
+ "ORDER BY frecency DESC "
+ "LIMIT 1) "
+ "), b.parent, b.title, NULL, h.visit_count, h.typed, IFNULL(h.id, b.fk), "
+ ":query_type, t.open_count "
+ "FROM moz_keywords k "
+ "JOIN moz_bookmarks b ON b.keyword_id = k.id "
+ "LEFT JOIN moz_places h ON h.url = search_url "
+ "LEFT JOIN moz_favicons f ON f.id = h.favicon_id "
+ "LEFT JOIN moz_openpages_temp t ON t.url = search_url "
+ "WHERE LOWER(k.keyword) = LOWER(:keyword) "
+ "ORDER BY h.frecency DESC "
);
});

View File

@ -1,384 +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 <me@shawnwilsher.com> (Original Author)
* Marco Bonardo <mak77@bonardo.net>
*
* 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 ***** */
////////////////////////////////////////////////////////////////////////////////
//// Constants
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
const Cu = Components.utils;
// A database flush should be the last operation during the shutdown process.
const kTopicShutdown = "places-connection-closing";
const kSyncFinished = "places-sync-finished";
const kDebugStopSync = "places-debug-stop-sync";
const kDebugStartSync = "places-debug-start-sync";
const kSyncPrefName = "places.syncDBTableIntervalInSecs";
const kDefaultSyncInterval = 120;
// Query Constants. These describe the queries we use.
const kQuerySyncPlacesId = 0;
const kQuerySyncHistoryVisitsId = 1;
////////////////////////////////////////////////////////////////////////////////
//// Modules
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/PlacesUtils.jsm");
////////////////////////////////////////////////////////////////////////////////
//// nsPlacesDBFlush class
function nsPlacesDBFlush()
{
// Get our sync interval
try {
// We want to silently fail since getIntPref throws if it does not exist,
// and use a default to fallback to.
this._syncInterval = Services.prefs.getIntPref(kSyncPrefName);
if (this._syncInterval <= 0)
this._syncInterval = kDefaultSyncInterval;
}
catch (e) {
// The preference did not exist, so use the default.
this._syncInterval = kDefaultSyncInterval;
}
// Register observers
Services.obs.addObserver(this, kTopicShutdown, false);
Services.obs.addObserver(this, kDebugStopSync, false);
Services.obs.addObserver(this, kDebugStartSync, false);
let (pb2 = Services.prefs.QueryInterface(Ci.nsIPrefBranch2))
pb2.addObserver(kSyncPrefName, this, false);
// Create our timer to update everything
this._timer = this._newTimer();
//////////////////////////////////////////////////////////////////////////////
//// Smart Getters
XPCOMUtils.defineLazyGetter(this, "_db", function() {
return PlacesUtils.history.QueryInterface(Ci.nsPIPlacesDatabase)
.DBConnection;
});
}
nsPlacesDBFlush.prototype = {
//////////////////////////////////////////////////////////////////////////////
//// nsIObserver
observe: function DBFlush_observe(aSubject, aTopic, aData)
{
if (aTopic == kTopicShutdown) {
Services.obs.removeObserver(this, kTopicShutdown);
Services.obs.removeObserver(this, kDebugStopSync);
Services.obs.removeObserver(this, kDebugStartSync);
let (pb2 = Services.prefs.QueryInterface(Ci.nsIPrefBranch2))
pb2.removeObserver(kSyncPrefName, this);
if (this._timer) {
this._timer.cancel();
this._timer = null;
}
// Flush any remaining change to disk tables.
this._flushWithQueries([kQuerySyncPlacesId, kQuerySyncHistoryVisitsId]);
this._finalizeInternalStatements();
}
else if (aTopic == "nsPref:changed" && aData == kSyncPrefName) {
// Get the new pref value, and then update our timer
this._syncInterval = Services.prefs.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();
}
else if (aTopic == kDebugStopSync) {
this._syncStopped = true;
}
else if (aTopic == kDebugStartSync) {
if (_syncStopped in this)
delete this._syncStopped;
}
},
//////////////////////////////////////////////////////////////////////////////
//// 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;
// Restore our timer
this._timer = this._newTimer();
// We need to sync now
this._flushWithQueries([kQuerySyncPlacesId, kQuerySyncHistoryVisitsId]);
},
onItemAdded: function(aItemId, aParentId, aIndex, aItemType)
{
// Sync only if we added a TYPE_BOOKMARK item. Note, we want to run the
// least amount of queries as possible here for performance reasons.
if (!this._inBatchMode && aItemType == PlacesUtils.bookmarks.TYPE_BOOKMARK)
this._flushWithQueries([kQuerySyncPlacesId]);
},
onItemChanged: function DBFlush_onItemChanged(aItemId, aProperty,
aIsAnnotationProperty,
aNewValue, aLastModified,
aItemType)
{
if (!this._inBatchMode && aProperty == "uri")
this._flushWithQueries([kQuerySyncPlacesId]);
},
onBeforeItemRemoved: function() { },
onItemRemoved: function() { },
onItemVisited: function() { },
onItemMoved: function() { },
//////////////////////////////////////////////////////////////////////////////
//// nsINavHistoryObserver
// We currently only use the history observer to know when the history service
// is activated. At that point, we actually get initialized, and our timer
// to sync history is added.
// These methods share the name of the ones on nsINavBookmarkObserver, so
// the implementations can be found above.
//onBeginUpdateBatch: function() { },
//onEndUpdateBatch: function() { },
onVisit: function() { },
onTitleChanged: function() { },
onBeforeDeleteURI: function() { },
onDeleteURI: function() { },
onClearHistory: function() { },
onPageChanged: function() { },
onDeleteVisits: function() { },
//////////////////////////////////////////////////////////////////////////////
//// nsITimerCallback
notify: function DBFlush_timerCallback()
{
let queries = [
kQuerySyncPlacesId,
kQuerySyncHistoryVisitsId,
];
this._flushWithQueries(queries);
},
//////////////////////////////////////////////////////////////////////////////
//// mozIStorageStatementCallback
handleResult: function DBFlush_handleResult(aResultSet)
{
},
handleError: function DBFlush_handleError(aError)
{
Cu.reportError("Async statement execution returned with '" +
aError.result + "', '" + aError.message + "'");
},
handleCompletion: function DBFlush_handleCompletion(aReason)
{
if (aReason == Ci.mozIStorageStatementCallback.REASON_FINISHED) {
// Dispatch a notification that sync has finished.
Services.obs.notifyObservers(null, kSyncFinished, null);
}
},
//////////////////////////////////////////////////////////////////////////////
//// nsPlacesDBFlush
_syncInterval: kDefaultSyncInterval,
/**
* Execute async statements to flush tables with the specified queries.
*
* @param aQueryNames
* The names of the queries to use with this flush.
*/
_flushWithQueries: function DBFlush_flushWithQueries(aQueryNames)
{
// No need to do extra work if we are in batch mode
if (this._inBatchMode || this._syncStopped)
return;
let statements = [];
for (let i = 0; i < aQueryNames.length; i++)
statements.push(this._getQuery(aQueryNames[i]));
// Execute sync statements async in a transaction
this._db.executeAsync(statements, statements.length, this);
},
/**
* Finalizes all of our mozIStorageStatements so we can properly close the
* database.
*/
_finalizeInternalStatements: function DBFlush_finalizeInternalStatements()
{
this._cachedStatements.forEach(function(stmt) {
if (stmt instanceof Ci.mozIStorageAsyncStatement)
stmt.finalize();
});
},
/**
* 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 aQueryType
* Type of the query to build statement for.
*/
_cachedStatements: [],
_getQuery: function DBFlush_getQuery(aQueryType)
{
// Statement creating can be expensive, so always cache if we can.
if (aQueryType in this._cachedStatements) {
let stmt = this._cachedStatements[aQueryType];
// Bind the appropriate parameters.
let params = stmt.params;
switch (aQueryType) {
case kQuerySyncHistoryVisitsId:
case kQuerySyncPlacesId:
params.transition_type = Ci.nsINavHistoryService.TRANSITION_EMBED;
break;
}
return stmt;
}
switch(aQueryType) {
case kQuerySyncHistoryVisitsId:
// For history table we want to leave embed visits in memory, since
// those are expired with current session, so we are filtering them out.
// Notice that instead we _want_ to sync framed_link visits, since those
// come from user's actions.
this._cachedStatements[aQueryType] = this._db.createAsyncStatement(
"DELETE FROM moz_historyvisits_temp " +
"WHERE visit_type <> :transition_type"
);
break;
case kQuerySyncPlacesId:
// For places table we want to leave places associated with embed visits
// in memory, they usually have hidden = 1 and at least an embed visit
// in historyvisits_temp table.
this._cachedStatements[aQueryType] = this._db.createAsyncStatement(
"DELETE FROM moz_places_temp " +
"WHERE id IN ( " +
"SELECT id FROM moz_places_temp h " +
"WHERE h.hidden <> 1 OR NOT EXISTS ( " +
"SELECT id FROM moz_historyvisits_temp " +
"WHERE place_id = h.id AND visit_type = :transition_type " +
"LIMIT 1 " +
") " +
")"
);
break;
default:
throw "Unexpected statement!";
}
// We only bind our own parameters when we have a cached statement, so we
// call ourself since we now have a cached statement.
return this._getQuery(aQueryType);
},
/**
* 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
classID: Components.ID("c1751cfc-e8f1-4ade-b0bb-f74edfb8ef6a"),
QueryInterface: XPCOMUtils.generateQI([
Ci.nsIObserver,
Ci.nsINavBookmarkObserver,
Ci.nsINavHistoryObserver,
Ci.nsITimerCallback,
Ci.mozIStorageStatementCallback,
])
};
////////////////////////////////////////////////////////////////////////////////
//// Module Registration
let components = [nsPlacesDBFlush];
var NSGetFactory = XPCOMUtils.generateNSGetFactory(components);

View File

@ -211,23 +211,10 @@ const EXPIRATION_QUERIES = {
QUERY_FIND_VISITS_TO_EXPIRE: {
sql: "INSERT INTO expiration_notify "
+ "(v_id, url, visit_date, expected_results) "
+ "SELECT v.id, IFNULL(h_t.url, h.url) AS url, "
+ "v.visit_date AS visit_date, "
+ ":limit_visits AS expected_results "
+ "FROM moz_historyvisits_temp v "
+ "LEFT JOIN moz_places_temp AS h_t ON h_t.id = v.place_id "
+ "LEFT JOIN moz_places AS h ON h.id = v.place_id "
+ "WHERE ((SELECT COUNT(*) FROM moz_places_temp) + "
+ "(SELECT COUNT(*) FROM moz_places)) > :max_uris "
+ "UNION ALL "
+ "SELECT v.id, IFNULL(h_t.url, h.url) AS url, "
+ "v.visit_date AS visit_date, "
+ ":limit_visits AS expected_results "
+ "SELECT v.id, h.url, v.visit_date, :limit_visits "
+ "FROM moz_historyvisits v "
+ "LEFT JOIN moz_places_temp AS h_t ON h_t.id = v.place_id "
+ "LEFT JOIN moz_places AS h ON h.id = v.place_id "
+ "WHERE ((SELECT COUNT(*) FROM moz_places_temp) + "
+ "(SELECT COUNT(*) FROM moz_places)) > :max_uris "
+ "JOIN moz_places h ON h.id = v.place_id "
+ "WHERE (SELECT COUNT(*) FROM moz_places) > :max_uris "
+ "ORDER BY v.visit_date ASC "
+ "LIMIT :limit_visits",
actions: ACTION.TIMED_OVERLIMIT | ACTION.SHUTDOWN | ACTION.IDLE |
@ -236,7 +223,7 @@ const EXPIRATION_QUERIES = {
// Removes the previously found visits.
QUERY_EXPIRE_VISITS: {
sql: "DELETE FROM moz_historyvisits_view WHERE id IN ( "
sql: "DELETE FROM moz_historyvisits WHERE id IN ( "
+ "SELECT v_id FROM expiration_notify WHERE v_id NOTNULL "
+ ")",
actions: ACTION.TIMED_OVERLIMIT | ACTION.SHUTDOWN | ACTION.IDLE |
@ -249,26 +236,13 @@ const EXPIRATION_QUERIES = {
QUERY_FIND_URIS_TO_EXPIRE: {
sql: "INSERT INTO expiration_notify "
+ "(p_id, url, visit_date, expected_results) "
+ "SELECT h.id, h.url, h.last_visit_date AS visit_date, "
+ ":limit_uris AS expected_results "
+ "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 h.ROWID <> IFNULL(:null_skips_last, (SELECT MAX(ROWID) FROM moz_places_temp)) "
+ "UNION ALL "
+ "SELECT h.id, h.url, h.last_visit_date AS visit_date, "
+ ":limit_uris AS expected_results "
+ "SELECT h.id, h.url, h.last_visit_date, :limit_uris "
+ "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 h.ROWID <> IFNULL(:null_skips_last, (SELECT MAX(ROWID) FROM moz_places)) "
+ "LIMIT :limit_uris",
actions: ACTION.TIMED | ACTION.TIMED_OVERLIMIT | ACTION.SHUTDOWN |
ACTION.IDLE | ACTION.DEBUG
@ -276,7 +250,7 @@ const EXPIRATION_QUERIES = {
// Expire found URIs from the database.
QUERY_EXPIRE_URIS: {
sql: "DELETE FROM moz_places_view WHERE id IN ( "
sql: "DELETE FROM moz_places WHERE id IN ( "
+ "SELECT p_id FROM expiration_notify WHERE p_id NOTNULL "
+ ")",
actions: ACTION.TIMED | ACTION.TIMED_OVERLIMIT | ACTION.SHUTDOWN |
@ -285,26 +259,13 @@ const EXPIRATION_QUERIES = {
// Expire orphan URIs from the database.
QUERY_SILENT_EXPIRE_ORPHAN_URIS: {
sql: "DELETE FROM moz_places_view WHERE id IN ( "
+ "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, 1, 6) <> 'place:' "
+ "UNION ALL "
sql: "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, 1, 6) <> 'place:' "
+ "LIMIT :limit_uris "
+ ")",
actions: ACTION.CLEAR_HISTORY
@ -315,9 +276,7 @@ const EXPIRATION_QUERIES = {
sql: "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 "
+ "LIMIT :limit_favicons "
+ ")",
actions: ACTION.TIMED | ACTION.TIMED_OVERLIMIT | ACTION.CLEAR_HISTORY |
@ -329,12 +288,9 @@ const EXPIRATION_QUERIES = {
sql: "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 <> :expire_never) "
+ "WHERE h.id IS NULL "
+ "OR (v.id IS NULL AND a.expiration <> :expire_never) "
+ "LIMIT :limit_annos "
+ ")",
actions: ACTION.TIMED | ACTION.TIMED_OVERLIMIT | ACTION.CLEAR_HISTORY |
@ -371,8 +327,6 @@ const EXPIRATION_QUERIES = {
QUERY_EXPIRE_ANNOS_WITH_HISTORY: {
sql: "DELETE FROM moz_annos "
+ "WHERE expiration = :expire_with_history "
+ "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)",
actions: ACTION.TIMED | ACTION.TIMED_OVERLIMIT | ACTION.CLEAR_HISTORY |
@ -408,9 +362,7 @@ const EXPIRATION_QUERIES = {
sql: "DELETE FROM moz_inputhistory WHERE place_id IN ( "
+ "SELECT i.place_id FROM moz_inputhistory 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 "
+ "WHERE h.id IS NULL "
+ "AND h_t.id IS NULL "
+ "LIMIT :limit_inputhistory "
+ ")",
actions: ACTION.CLEAR_HISTORY | ACTION.SHUTDOWN | ACTION.IDLE | ACTION.DEBUG
@ -610,8 +562,7 @@ nsPlacesExpiration.prototype = {
// Check if we are over history capacity, if so visits must be expired.
if (!this._cachedStatements["LIMIT_COUNT"]) {
this._cachedStatements["LIMIT_COUNT"] = this._db.createAsyncStatement(
"SELECT (SELECT COUNT(*) FROM moz_places_temp) + "
+ "(SELECT COUNT(*) FROM moz_places)"
"SELECT COUNT(*) FROM moz_places"
);
}
let self = this;

View File

@ -49,55 +49,31 @@
/**
* moz_places
*/
#define CREATE_IDX_MOZ_PLACES_TEMP_URL \
CREATE_PLACES_IDX( \
"url_uniqueindex", "moz_places_temp", "url", "UNIQUE" \
)
#define CREATE_IDX_MOZ_PLACES_URL \
CREATE_PLACES_IDX( \
"url_uniqueindex", "moz_places", "url", "UNIQUE" \
)
#define CREATE_IDX_MOZ_PLACES_TEMP_FAVICON \
CREATE_PLACES_IDX( \
"faviconindex", "moz_places_temp", "favicon_id", "" \
)
#define CREATE_IDX_MOZ_PLACES_FAVICON \
CREATE_PLACES_IDX( \
"faviconindex", "moz_places", "favicon_id", "" \
)
#define CREATE_IDX_MOZ_PLACES_TEMP_REVHOST \
CREATE_PLACES_IDX( \
"hostindex", "moz_places_temp", "rev_host", "" \
)
#define CREATE_IDX_MOZ_PLACES_REVHOST \
CREATE_PLACES_IDX( \
"hostindex", "moz_places", "rev_host", "" \
)
#define CREATE_IDX_MOZ_PLACES_TEMP_VISITCOUNT \
CREATE_PLACES_IDX( \
"visitcount", "moz_places_temp", "visit_count", "" \
)
#define CREATE_IDX_MOZ_PLACES_VISITCOUNT \
CREATE_PLACES_IDX( \
"visitcount", "moz_places", "visit_count", "" \
)
#define CREATE_IDX_MOZ_PLACES_TEMP_FRECENCY \
CREATE_PLACES_IDX( \
"frecencyindex", "moz_places_temp", "frecency", "" \
)
#define CREATE_IDX_MOZ_PLACES_FRECENCY \
CREATE_PLACES_IDX( \
"frecencyindex", "moz_places", "frecency", "" \
)
#define CREATE_IDX_MOZ_PLACES_TEMP_LASTVISITDATE \
CREATE_PLACES_IDX( \
"lastvisitdateindex", "moz_places_temp", "last_visit_date", "" \
)
#define CREATE_IDX_MOZ_PLACES_LASTVISITDATE \
CREATE_PLACES_IDX( \
"lastvisitdateindex", "moz_places", "last_visit_date", "" \
@ -107,28 +83,16 @@
* moz_historyvisits
*/
#define CREATE_IDX_MOZ_HISTORYVISITS_TEMP_PLACEDATE \
CREATE_PLACES_IDX( \
"placedateindex", "moz_historyvisits_temp", "place_id, visit_date", "" \
)
#define CREATE_IDX_MOZ_HISTORYVISITS_PLACEDATE \
CREATE_PLACES_IDX( \
"placedateindex", "moz_historyvisits", "place_id, visit_date", "" \
)
#define CREATE_IDX_MOZ_HISTORYVISITS_TEMP_FROMVISIT \
CREATE_PLACES_IDX( \
"fromindex", "moz_historyvisits_temp", "from_visit", "" \
)
#define CREATE_IDX_MOZ_HISTORYVISITS_FROMVISIT \
CREATE_PLACES_IDX( \
"fromindex", "moz_historyvisits", "from_visit", "" \
)
#define CREATE_IDX_MOZ_HISTORYVISITS_TEMP_VISITDATE \
CREATE_PLACES_IDX( \
"dateindex", "moz_historyvisits_temp", "visit_date", "" \
)
#define CREATE_IDX_MOZ_HISTORYVISITS_VISITDATE \
CREATE_PLACES_IDX( \
"dateindex", "moz_historyvisits", "visit_date", "" \

View File

@ -40,8 +40,9 @@
#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" \
@ -54,22 +55,12 @@
", last_visit_date INTEGER " \
")" \
)
#define CREATE_MOZ_PLACES CREATE_MOZ_PLACES_BASE("moz_places", "")
#define CREATE_MOZ_PLACES_TEMP CREATE_MOZ_PLACES_BASE("moz_places_temp", "TEMP")
#define MOZ_PLACES_COLUMNS \
"id, url, title, rev_host, visit_count, hidden, typed, favicon_id, " \
"frecency, last_visit_date"
#define CREATE_MOZ_PLACES_VIEW NS_LITERAL_CSTRING( \
"CREATE TEMPORARY VIEW moz_places_view AS " \
"SELECT " MOZ_PLACES_COLUMNS " FROM moz_places_temp " \
"UNION ALL " \
"SELECT " MOZ_PLACES_COLUMNS " 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" \
@ -78,19 +69,9 @@
", 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 MOZ_HISTORYVISITS_COLUMNS \
"id, from_visit, place_id, visit_date, visit_type, session"
#define CREATE_MOZ_HISTORYVISITS_VIEW NS_LITERAL_CSTRING( \
"CREATE TEMPORARY VIEW moz_historyvisits_view AS " \
"SELECT " MOZ_HISTORYVISITS_COLUMNS " FROM moz_historyvisits_temp " \
"UNION ALL " \
"SELECT " MOZ_HISTORYVISITS_COLUMNS " FROM moz_historyvisits " \
"WHERE id NOT IN (SELECT id FROM moz_historyvisits_temp) " \
)
#define CREATE_MOZ_INPUTHISTORY NS_LITERAL_CSTRING( \
"CREATE TABLE moz_inputhistory (" \

View File

@ -73,198 +73,33 @@
)
/**
* 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.
* We have both sync and async users for this trigger, so it could happen that
* an async statement tries to insert a page when a sync statement just added
* it. We should ignore the insertion in such a case, the async implementer
* will fetch the id of the existing entry.
* This triggers update visit_count and last_visit_date based on historyvisits
* table changes.
*/
#define CREATE_PLACES_VIEW_INSERT_TRIGGER NS_LITERAL_CSTRING( \
"CREATE TEMPORARY TRIGGER moz_places_view_insert_trigger " \
"INSTEAD OF INSERT " \
"ON moz_places_view " \
#define CREATE_HISTORYVISITS_AFTERINSERT_TRIGGER NS_LITERAL_CSTRING( \
"CREATE TRIGGER moz_historyvisits_afterinsert_v2_trigger " \
"AFTER INSERT ON moz_historyvisits FOR EACH ROW " \
"BEGIN " \
"INSERT OR IGNORE INTO moz_places_temp (" MOZ_PLACES_COLUMNS ") " \
"VALUES (MAX(IFNULL((SELECT MAX(id) FROM moz_places_temp), 0), " \
"IFNULL((SELECT MAX(id) FROM moz_places), 0)) + 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, " \
"NEW.last_visit_date);" \
"END" \
)
/**
* This trigger allows for the deletion of a record in moz_places_view. It
* removes any entry in the temporary table, the permanent table, and any
* associated entry in moz_openpages_temp.
*/
#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; " \
"DELETE FROM moz_openpages_temp " \
"WHERE url = OLD.url; " \
"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 (" MOZ_PLACES_COLUMNS ") " \
"SELECT " MOZ_PLACES_COLUMNS " 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), " \
"last_visit_date = IFNULL(NEW.last_visit_date, OLD.last_visit_date) " \
"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.
* In this case when updating last_visit_date we can simply check the maximum
* between new visit date and the actual cached value (or 0 if it is NULL).
*/
#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 (" MOZ_HISTORYVISITS_COLUMNS ") " \
"VALUES (MAX(IFNULL((SELECT MAX(id) FROM moz_historyvisits_temp), 0), " \
"IFNULL((SELECT MAX(id) FROM moz_historyvisits), 0)) + 1, " \
"NEW.from_visit, NEW.place_id, NEW.visit_date, NEW.visit_type, " \
"NEW.session); " \
"INSERT OR IGNORE INTO moz_places_temp (" MOZ_PLACES_COLUMNS ") " \
"SELECT " MOZ_PLACES_COLUMNS " FROM moz_places " \
"WHERE id = NEW.place_id " \
"AND NEW.visit_type NOT IN (" EXCLUDED_VISIT_TYPES "); " \
"UPDATE moz_places_temp " \
"SET visit_count = visit_count + 1 " \
"WHERE id = NEW.place_id " \
"AND NEW.visit_type NOT IN (" EXCLUDED_VISIT_TYPES "); " \
"UPDATE moz_places_temp " \
"SET last_visit_date = MAX(IFNULL(last_visit_date, 0), NEW.visit_date)" \
"UPDATE moz_places SET " \
"visit_count = visit_count + (SELECT NEW.visit_type NOT IN (" EXCLUDED_VISIT_TYPES ")), "\
"last_visit_date = MAX(IFNULL(last_visit_date, 0), NEW.visit_date) " \
"WHERE id = NEW.place_id;" \
"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 " \
#define CREATE_HISTORYVISITS_AFTERDELETE_TRIGGER NS_LITERAL_CSTRING( \
"CREATE TRIGGER moz_historyvisits_afterdelete_v2_trigger " \
"AFTER DELETE ON moz_historyvisits FOR EACH ROW " \
"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 (" MOZ_PLACES_COLUMNS ") " \
"SELECT " MOZ_PLACES_COLUMNS " FROM moz_places " \
"WHERE id = OLD.place_id " \
"AND OLD.visit_type NOT IN (" EXCLUDED_VISIT_TYPES "); " \
"UPDATE moz_places_temp " \
"SET visit_count = visit_count - 1 " \
"WHERE id = OLD.place_id " \
"AND OLD.visit_type NOT IN (" EXCLUDED_VISIT_TYPES "); " \
"UPDATE moz_places_temp " \
"SET last_visit_date = " \
"(SELECT visit_date FROM moz_historyvisits_temp " \
"WHERE place_id = OLD.place_id " \
"UNION ALL " \
"SELECT visit_date FROM moz_historyvisits " \
"WHERE place_id = OLD.place_id " \
"ORDER BY visit_date DESC LIMIT 1) " \
"WHERE id = OLD.place_id; " \
"UPDATE moz_places SET " \
"visit_count = visit_count - (SELECT OLD.visit_type NOT IN (" EXCLUDED_VISIT_TYPES ")), "\
"last_visit_date = (SELECT visit_date FROM moz_historyvisits " \
"WHERE place_id = OLD.place_id " \
"ORDER BY visit_date DESC LIMIT 1) " \
"WHERE id = OLD.place_id;" \
"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 (" MOZ_HISTORYVISITS_COLUMNS ") " \
"SELECT " MOZ_HISTORYVISITS_COLUMNS " 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, __columns) NS_LITERAL_CSTRING( \
"CREATE TEMPORARY TRIGGER " __table "_beforedelete_trigger " \
"BEFORE DELETE ON " __table "_temp FOR EACH ROW " \
"BEGIN " \
"INSERT OR REPLACE INTO " __table " (" __columns ") " \
"SELECT " __columns " FROM " __table "_temp " \
"WHERE id = OLD.id;" \
"END" \
)
#define CREATE_MOZ_PLACES_SYNC_TRIGGER \
CREATE_TEMP_SYNC_TRIGGER_BASE("moz_places", MOZ_PLACES_COLUMNS)
#define CREATE_MOZ_HISTORYVISITS_SYNC_TRIGGER \
CREATE_TEMP_SYNC_TRIGGER_BASE("moz_historyvisits", MOZ_HISTORYVISITS_COLUMNS)
/**
* This trigger removes a row from moz_openpages_temp when open_count reaches 0.
*/

View File

@ -8,12 +8,6 @@ contract @mozilla.org/browser/tagging-service;1 {bbc23860-2553-479d-8b78-94d9038
component {1dcc23b0-d4cb-11dc-9ad6-479d56d89593} nsTaggingService.js
contract @mozilla.org/autocomplete/search;1?name=places-tag-autocomplete {1dcc23b0-d4cb-11dc-9ad6-479d56d89593}
# nsPlacesDBFlush.js
component {c1751cfc-e8f1-4ade-b0bb-f74edfb8ef6a} nsPlacesDBFlush.js
contract @mozilla.org/places/sync;1 {c1751cfc-e8f1-4ade-b0bb-f74edfb8ef6a}
category bookmark-observers nsPlacesDBFlush @mozilla.org/places/sync;1
category history-observers nsPlacesDBFlush @mozilla.org/places/sync;1
# nsPlacesExpiration.js
component {705a423f-2f69-42f3-b9fe-1517e0dee56f} nsPlacesExpiration.js
contract @mozilla.org/places/expiration;1 {705a423f-2f69-42f3-b9fe-1517e0dee56f}

View File

@ -49,7 +49,6 @@ MODULE = test_places
XPCSHELL_TESTS = \
autocomplete \
expiration \
sync \
bookmarks \
queries \
unit \

View File

@ -72,7 +72,7 @@ function run_test()
// open the result container
queryRes.root.containerOpen = true;
// debug queries
// dump_table("moz_places_view");
// dump_table("moz_places");
do_check_eq(queryRes.root.childCount, 1);
// call the untested code path
listener.onValueRemoved(null, uri.spec, true);

View File

@ -36,8 +36,6 @@ var conn = PlacesUtils.history.QueryInterface(Ci.nsPIPlacesDatabase).DBConnectio
function getColumn(table, column, fromColumnName, fromColumnValue)
{
var stmt = conn.createStatement(
"SELECT " + column + " FROM " + table + "_temp WHERE " + fromColumnName + "=:val " +
"UNION ALL " +
"SELECT " + column + " FROM " + table + " WHERE " + fromColumnName + "=:val " +
"LIMIT 1");
try {

View File

@ -51,8 +51,6 @@ var conn = PlacesUtils.history.QueryInterface(Ci.nsPIPlacesDatabase).DBConnectio
function getColumn(table, column, fromColumnName, fromColumnValue)
{
var stmt = conn.createStatement(
"SELECT " + column + " FROM " + table + "_temp WHERE " + fromColumnName + "=:val " +
"UNION ALL " +
"SELECT " + column + " FROM " + table + " WHERE " + fromColumnName + "=:val " +
"LIMIT 1");
try {

View File

@ -182,16 +182,12 @@ do_get_place(nsIURI* aURI, PlaceRecord& result)
do_check_success(rv);
rv = dbConn->CreateStatement(NS_LITERAL_CSTRING(
"SELECT id, hidden, typed, visit_count FROM moz_places_temp "
"WHERE url=?1 "
"UNION ALL "
"SELECT id, hidden, typed, visit_count FROM moz_places "
"WHERE url=?1 "
"LIMIT 1"
), getter_AddRefs(stmt));
do_check_success(rv);
rv = stmt->BindUTF8StringParameter(0, spec);
rv = stmt->BindUTF8StringByIndex(0, spec);
do_check_success(rv);
PRBool hasResults;
@ -222,16 +218,13 @@ do_get_lastVisit(PRInt64 placeId, VisitRecord& result)
nsCOMPtr<mozIStorageStatement> stmt;
nsresult rv = dbConn->CreateStatement(NS_LITERAL_CSTRING(
"SELECT id, from_visit, visit_type FROM moz_historyvisits_temp "
"WHERE place_id=?1 "
"UNION ALL "
"SELECT id, from_visit, visit_type FROM moz_historyvisits "
"WHERE place_id=?1 "
"LIMIT 1"
), getter_AddRefs(stmt));
do_check_success(rv);
rv = stmt->BindInt64Parameter(0, placeId);
rv = stmt->BindInt64ByIndex(0, placeId);
do_check_success(rv);
PRBool hasResults;

View File

@ -90,7 +90,7 @@ function add_old_anno(aIdentifier, aName, aValue, aExpirePolicy,
// Update dateAdded for the last added annotation.
sql = "UPDATE moz_annos SET dateAdded = :expire_date, lastModified = :last_modified " +
"WHERE id = (SELECT a.id FROM moz_annos a " +
"LEFT JOIN moz_places_view h on h.id = a.place_id " +
"LEFT JOIN moz_places h on h.id = a.place_id " +
"WHERE h.url = :id " +
"ORDER BY a.dateAdded DESC LIMIT 1)";
}

View File

@ -88,7 +88,7 @@ function add_old_anno(aIdentifier, aName, aValue, aExpirePolicy,
"WHERE id = ( " +
"SELECT a.id FROM moz_annos a " +
"JOIN moz_anno_attributes n ON n.id = a.anno_attribute_id " +
"JOIN moz_places_view h on h.id = a.place_id " +
"JOIN moz_places h on h.id = a.place_id " +
"WHERE h.url = :id " +
"AND n.name = :anno_name " +
"ORDER BY a.dateAdded DESC LIMIT 1 " +

View File

@ -257,7 +257,7 @@ function dump_table(aName)
function page_in_database(aUrl)
{
let stmt = DBConn().createStatement(
"SELECT id FROM moz_places_view WHERE url = :url"
"SELECT id FROM moz_places WHERE url = :url"
);
stmt.params.url = aUrl;
try {
@ -477,34 +477,3 @@ function is_time_ordered(before, after) {
let skew = isWindows ? 20000000 : 0;
return after - before > -skew;
}
// These tests are known to randomly fail due to bug 507790 when database
// flushes are active, so we turn off syncing for them.
let (randomFailingSyncTests = [
"test_multi_word_tags.js",
"test_removeVisitsByTimeframe.js",
"test_utils_getURLsForContainerNode.js",
"test_exclude_livemarks.js",
"test_402799.js",
"test_results-as-visit.js",
"test_sorting.js",
"test_redirectsMode.js",
"test_384228.js",
"test_395593.js",
"test_containersQueries_sorting.js",
"test_browserGlue_smartBookmarks.js",
"test_browserGlue_distribution.js",
"test_331487.js",
"test_tags.js",
"test_385829.js",
"test_405938_restore_queries.js",
]) {
let currentTestFilename = do_get_file(_TEST_FILE[0], true).leafName;
if (randomFailingSyncTests.indexOf(currentTestFilename) != -1) {
print("Test " + currentTestFilename +
" is known random due to bug 507790, disabling PlacesDBFlush.");
let sync = Cc["@mozilla.org/places/sync;1"].getService(Ci.nsIObserver);
sync.observe(null, "places-debug-stop-sync", null);
}
}

View File

@ -158,11 +158,11 @@ function checkDB(data){
ghist.addURI(this.mChannel.URI, true, true, referrer);
// 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);

View File

@ -109,8 +109,8 @@ function run_test() {
function continue_test() {
let stmt = DBConn().createStatement(
"SELECT v.id, h.url, v.from_visit, v.visit_date, v.visit_type, v.session " +
"FROM moz_historyvisits_view v " +
"JOIN moz_places_view h on h.id = v.place_id " +
"FROM moz_historyvisits v " +
"JOIN moz_places h on h.id = v.place_id " +
"ORDER BY v.id ASC");
const EXPECTED = [
{ id: 1,

View File

@ -85,7 +85,7 @@ function populateDB(aArray) {
if (qdata.title && !qdata.isDetails) {
// Set the page title synchronously, otherwise setPageTitle is LAZY.
let stmt = DBConn().createStatement(
"UPDATE moz_places_view SET title = :title WHERE url = :url"
"UPDATE moz_places SET title = :title WHERE url = :url"
);
stmt.params.title = qdata.title;
stmt.params.url = qdata.uri;
@ -102,7 +102,7 @@ function populateDB(aArray) {
// Set a fake visit_count, this is not a real count but can be used
// to test sorting by visit_count.
let stmt = DBConn().createStatement(
"UPDATE moz_places_view SET visit_count = :vc WHERE url = :url");
"UPDATE moz_places SET visit_count = :vc WHERE url = :url");
stmt.params.vc = qdata.visitCount;
stmt.params.url = qdata.uri;
try {

View File

@ -100,10 +100,8 @@ function run_test() {
testData[i].title = null;
}
dump_table("moz_places");
dump_table("moz_places_temp");
dump_table("moz_historyvisits");
dump_table("moz_historyvisits_temp");
//dump_table("moz_places");
//dump_table("moz_historyvisits");
var numSortFunc = function (a,b) { return (a - b); };
var arrs = testDataTyped.concat(testDataDownload).concat(testDataBookmark)

View File

@ -1,136 +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 <bryner@brianryner.com>
* Dietrich Ayala <dietrich@mozilla.com>
* Shawn Wilsher <me@shawnwilsher.com>
* Marco Bonardo <mak77@bonardo.net>
*
* 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 Ci = Components.interfaces;
const Cc = Components.classes;
const Cr = Components.results;
const Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
// Import common head.
let (commonFile = do_get_file("../head_common.js", false)) {
let uri = Services.io.newFileURI(commonFile);
Services.scriptloader.loadSubScript(uri.spec, this);
}
// Put any other stuff relative to this test folder below.
/**
* Function tests to see if the place associated with the bookmark with id
* aBookmarkId has the uri aExpectedURI. The event will call do_test_finished()
* 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 stmt = DBConn().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)
do_test_finished();
}
/**
* Function tests to see if the place associated with the visit with id aVisitId
* has the uri aExpectedURI. The event will call do_test_finished() 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 stmt = DBConn().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)
do_test_finished();
}

View File

@ -1,126 +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) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Marco Bonardo <mak77@bonardo.net> (Original Author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/**
* Bug 493933 - When sorting bookmarks BY NONE we should take in count partitioning.
*
* When we have a bookmarks results sorted BY NONE, could be the order depends
* on current status of disk and temp tables due to how the query executes the
* UNION. We must ensure their order is correct.
*/
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.");
var os = Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService);
const kSyncPrefName = "syncDBTableIntervalInSecs";
const SYNC_INTERVAL = 600;
const kSyncFinished = "places-sync-finished";
var observer = {
_runCount: 0,
one: null,
two: null,
observe: function(aSubject, aTopic, aData) {
if (aTopic == kSyncFinished) {
// Skip the first sync.
if (++this._runCount < 2)
return;
os.removeObserver(this, kSyncFinished);
// Sanity check positions.
do_check_true(this.one < this.two);
do_check_eq(bs.getItemIndex(this.one), 0);
do_check_eq(bs.getItemIndex(this.two), 1);
check_results();
// Now add a visit to the second bookmark, so that it is in temp table.
hs.addVisit(uri("http://2.mozilla.org/"), Date.now() * 1000, null,
hs.TRANSITION_TYPED, false, 0);
// Nothing should change in results.
check_results();
// Cleanup.
bs.removeFolderChildren(bs.toolbarFolder);
do_test_finished();
}
}
}
os.addObserver(observer, kSyncFinished, false);
function check_results() {
// Create a bookmarks query.
var options = hs.getNewQueryOptions();
options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS;
var query = hs.getNewQuery();
query.setFolders([bs.toolbarFolder], 1);
query.searchTerms = "mozilla";
var result = hs.executeQuery(query, options);
var root = result.root;
root.containerOpen = true;
do_check_eq(root.childCount, 2);
do_check_eq(root.getChild(0).title, "mozilla 1");
do_check_eq(root.getChild(1).title, "mozilla 2");
root.containerOpen = false;
}
function run_test()
{
// First set the preference for the timer to a large value so we don't sync
prefs.setIntPref(kSyncPrefName, SYNC_INTERVAL);
// Add two bookmarks and check their index
observer.one = bs.insertBookmark(bs.toolbarFolder,
uri("http://1.mozilla.org/"),
bs.DEFAULT_INDEX, "mozilla 1");
observer.two = bs.insertBookmark(bs.toolbarFolder,
uri("http://2.mozilla.org/"),
bs.DEFAULT_INDEX, "mozilla 2");
do_test_pending();
}

View File

@ -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 <me@shawnwilsher.com> (Original Author)
* Marco Bonardo <mak77@bonardo.net>
*
* 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();
}

View File

@ -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 <me@shawnwilsher.com> (Original Author)
* Marco Bonardo <mak77@bonardo.net>
*
* 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();
}

View File

@ -1,96 +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 <me@shawnwilsher.com> (Original Author)
* Marco Bonardo <mak77@bonardo.net>
*
* 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.");
var os = Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService);
const TEST_URI = "http://test.com/";
const kSyncPrefName = "syncDBTableIntervalInSecs";
const SYNC_INTERVAL = 1;
const kSyncFinished = "places-sync-finished";
var observer = {
visitId: -1,
observe: function(aSubject, aTopic, aData) {
if (aTopic == kSyncFinished && this.visitId != -1) {
// sanity check: visitId set by history observer should be the same we
// have added
do_check_eq(this.visitId, visitId);
// remove the observer, we don't need to observe sync on quit
os.removeObserver(this, kSyncFinished);
// Check the visit
new_test_visit_uri_event(this.visitId, TEST_URI, true, true);
}
}
}
os.addObserver(observer, kSyncFinished, false);
// Used to update observer visitId
var historyObserver = {
onVisit: function(aURI, aVisitId, aTime, aSessionId, aReferringId,
aTransitionType, aAdded) {
observer.visitId = aVisitId;
hs.removeObserver(this, false);
}
}
hs.addObserver(historyObserver, false);
// used for sanity check
var visitId = -1;
function run_test()
{
// First set the preference for the timer to a small value
prefs.setIntPref(kSyncPrefName, SYNC_INTERVAL);
// Now add the visit
visitId = hs.addVisit(uri(TEST_URI), Date.now() * 1000, null,
hs.TRANSITION_TYPED, false, 0);
do_test_pending();
}

View File

@ -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 <me@shawnwilsher.com> (Original Author)
* Marco Bonardo <mak77@bonardo.net>
*
* 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();
}

View File

@ -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 <me@shawnwilsher.com> (Original Author)
* Marco Bonardo <mak77@bonardo.net>
*
* 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, aItemType) {
observer.itemId = aItemId;
},
onItemChanged: function(aItemId, aProperty, aNewValue, aLastModified,
aItemType) {
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();
}

View File

@ -1,94 +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 <me@shawnwilsher.com> (Original Author)
* Marco Bonardo <mak77@bonardo.net>
*
* 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 TOPIC_CONNECTION_CLOSED = "places-connection-closed";
var historyObserver = {
onVisit: function(aURI, aVisitId, aTime, aSessionId, aReferringId,
aTransitionType, aAdded) {
observer.visitId = aVisitId;
hs.removeObserver(this);
}
}
hs.addObserver(historyObserver, false);
var observer = {
visitId: -1,
observe: function(aSubject, aTopic, aData) {
if (aTopic == TOPIC_CONNECTION_CLOSED) {
os.removeObserver(this, aTopic);
// visit id must be valid
do_check_neq(this.visitId, -1);
// Check that tables have been correctly synced
new_test_visit_uri_event(this.visitId, TEST_URI, true, true);
}
}
}
os.addObserver(observer, TOPIC_CONNECTION_CLOSED, 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!
shutdownPlaces();
// Test will continue on sync notification.
do_test_pending();
}

View File

@ -1,152 +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):
* Marco Bonardo <mak77@bonardo.net> (Original Author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
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);
var bh = hs.QueryInterface(Ci.nsIBrowserHistory);
var bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
getService(Ci.nsINavBookmarksService);
const TEST_URI = "http://test.com/";
const PREF_SYNC_INTERVAL = "syncDBTableIntervalInSecs";
const SYNC_INTERVAL = 600; // ten minutes
const TOPIC_SYNC_FINISHED = "places-sync-finished";
const TOPIC_CONNECTION_CLOSED = "places-connection-closed";
var historyObserver = {
visitId: -1,
cleared: false,
onVisit: function(aURI, aVisitId, aTime, aSessionId, aReferringId,
aTransitionType, aAdded) {
this.visitId = aVisitId;
},
onClearHistory: function() {
// check browserHistory returns no entries
do_check_eq(0, bh.count);
this.cleared = true;
hs.removeObserver(this);
}
}
hs.addObserver(historyObserver, false);
var observer = {
_runCount: 0,
observe: function(aSubject, aTopic, aData) {
if (aTopic == TOPIC_SYNC_FINISHED) {
if (++this._runCount == 1) {
// The first sync is due to the insert bookmark.
// Simulate a clear private data just before shutdown.
bh.removeAllPages();
os.addObserver(shutdownObserver, TOPIC_CONNECTION_CLOSED, false);
// Immediately notify shutdown.
shutdownPlaces();
return;
}
// Remove the observer, we don't need it anymore.
os.removeObserver(this, TOPIC_SYNC_FINISHED);
// Visit id must be valid.
do_check_neq(historyObserver.visitId, -1);
// History must have been cleared.
do_check_true(historyObserver.cleared);
}
}
}
os.addObserver(observer, TOPIC_SYNC_FINISHED, false);
let shutdownObserver = {
observe: function(aSubject, aTopic, aData) {
os.removeObserver(this, aTopic);
do_check_false(PlacesUtils.history.QueryInterface(Ci.nsPIPlacesDatabase)
.DBConnection.connectionReady);
let dbConn = DBConn();
do_check_true(dbConn.connectionReady);
// Check that frecency for not cleared items (bookmarks) has been
// converted to -MAX(visit_count, 1), so we will be able to
// recalculate frecency starting from most frecent bookmarks.
let stmt = dbConn.createStatement(
"SELECT id FROM moz_places WHERE frecency > 0 LIMIT 1");
do_check_false(stmt.executeStep());
stmt.finalize();
stmt = dbConn.createStatement(
"SELECT h.id FROM moz_places h WHERE h.frecency = -2 " +
"AND EXISTS (SELECT id FROM moz_bookmarks WHERE fk = h.id) LIMIT 1");
do_check_true(stmt.executeStep());
stmt.finalize();
// Check that all visit_counts have been brought to 0
stmt = dbConn.createStatement(
"SELECT id FROM moz_places WHERE visit_count <> 0 LIMIT 1");
do_check_false(stmt.executeStep());
stmt.finalize();
dbConn.asyncClose(function() {
do_check_false(dbConn.connectionReady);
do_test_finished();
});
}
}
function run_test()
{
do_test_pending();
// Set the preference for the timer to a really large value, so it won't
// run before the test finishes.
prefs.setIntPref(PREF_SYNC_INTERVAL, SYNC_INTERVAL);
// Now add a visit before creating bookmark, and one later
hs.addVisit(uri(TEST_URI), Date.now() * 1000, null,
hs.TRANSITION_TYPED, false, 0);
bs.insertBookmark(bs.unfiledBookmarksFolder, uri(TEST_URI),
bs.DEFAULT_INDEX, "bookmark");
hs.addVisit(uri(TEST_URI), Date.now() * 1000, null,
hs.TRANSITION_TYPED, false, 0);
}

View File

@ -1,173 +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):
* Marco Bonardo <mak77@bonardo.net> (Original Author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* This test checks that embed visits are not synced down to disk, we hold
* them in memory since they're going to be purged at session close
*
* We instead sync to disk FRAMED_LINK visits.
*/
var hs = Cc["@mozilla.org/browser/nav-history-service;1"].
getService(Ci.nsINavHistoryService);
var dbConn = hs.QueryInterface(Ci.nsPIPlacesDatabase).DBConnection;
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.");
var os = Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService);
const TEST_URI = "http://test.com/";
const EMBED_URI = "http://embed.test.com/";
const PLACE_URI = "place:test.com/";
const kSyncPrefName = "syncDBTableIntervalInSecs";
const SYNC_INTERVAL = 1;
const kSyncFinished = "places-sync-finished";
var transitions = [ hs.TRANSITION_LINK,
hs.TRANSITION_TYPED,
hs.TRANSITION_BOOKMARK,
hs.TRANSITION_EMBED,
hs.TRANSITION_FRAMED_LINK,
hs.TRANSITION_REDIRECT_PERMANENT,
hs.TRANSITION_REDIRECT_TEMPORARY,
hs.TRANSITION_DOWNLOAD ];
var observer = {
observe: function(aSubject, aTopic, aData) {
if (aTopic == kSyncFinished && this.visitId != -1) {
// remove the observer, we don't need to observe sync on quit
os.removeObserver(this, kSyncFinished);
// Check that moz_places table has been correctly synced
var stmt = dbConn.createStatement(
"SELECT id FROM moz_places WHERE url = :url");
stmt.params["url"] = TEST_URI;
do_check_true(stmt.executeStep());
stmt.finalize();
stmt = dbConn.createStatement(
"SELECT id FROM moz_places_temp WHERE url = :url");
stmt.params["url"] = TEST_URI;
do_check_false(stmt.executeStep());
stmt.finalize();
stmt = dbConn.createStatement(
"SELECT id FROM moz_places WHERE url = :url");
stmt.params["url"] = EMBED_URI;
do_check_false(stmt.executeStep());
stmt.finalize();
stmt = dbConn.createStatement(
"SELECT id FROM moz_places_temp WHERE url = :url");
stmt.params["url"] = EMBED_URI;
do_check_true(stmt.executeStep());
stmt.finalize();
stmt = dbConn.createStatement(
"SELECT id FROM moz_places WHERE url = :url");
stmt.params["url"] = PLACE_URI;
do_check_true(stmt.executeStep());
stmt.finalize();
stmt = dbConn.createStatement(
"SELECT id FROM moz_places_temp WHERE url = :url");
stmt.params["url"] = PLACE_URI;
do_check_false(stmt.executeStep());
stmt.finalize();
// Check that all visits but embed ones are in disk table
stmt = dbConn.createStatement(
"SELECT count(*) FROM moz_historyvisits h WHERE visit_type <> :t_embed");
stmt.params["t_embed"] = hs.TRANSITION_EMBED;
do_check_true(stmt.executeStep());
do_check_eq(stmt.getInt32(0), (transitions.length - 1) * 2);
stmt.finalize();
stmt = dbConn.createStatement(
"SELECT id FROM moz_historyvisits h WHERE visit_type = :t_embed");
stmt.params["t_embed"] = hs.TRANSITION_EMBED;
do_check_false(stmt.executeStep());
stmt.finalize();
stmt = dbConn.createStatement(
"SELECT id FROM moz_historyvisits_temp h WHERE visit_type = :t_embed");
stmt.params["t_embed"] = hs.TRANSITION_EMBED;
do_check_true(stmt.executeStep());
stmt.finalize();
stmt = dbConn.createStatement(
"SELECT id FROM moz_historyvisits_temp h WHERE visit_type <> :t_embed");
stmt.params["t_embed"] = hs.TRANSITION_EMBED;
do_check_false(stmt.executeStep());
stmt.finalize();
do_test_finished();
}
}
}
function run_test()
{
// First set the preference for the timer to a small value
prefs.setIntPref(kSyncPrefName, SYNC_INTERVAL);
// Add a visit for every transition type on TEST_URI
// Embed visit should stay in temp table, while other should be synced
// Place entry for this uri should be synced to disk table
transitions.forEach(function addVisit(aTransition) {
hs.addVisit(uri(TEST_URI), Date.now() * 1000, null,
aTransition, false, 0);
});
// Add an embed visit for EMBED_URI
// Embed visit should stay in temp table
// Place entry for this uri should stay in temp table
hs.addVisit(uri(EMBED_URI), Date.now() * 1000, null,
hs.TRANSITION_EMBED, false, 0);
// Add a visit for every transition type on PLACE_URI
// Embed visit should stay in temp table
// Place entry for this uri should be synced to disk table
transitions.forEach(function addVisit(aTransition) {
hs.addVisit(uri(PLACE_URI), Date.now() * 1000, null,
aTransition, false, 0);
});
os.addObserver(observer, kSyncFinished, false);
do_test_pending();
}

View File

@ -1,134 +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) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Marco Bonardo <mak77@bonardo.net> (Original Author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* This test ensures favicons are correctly expired by expireAllFavicons API,
* both synced and unsynced favicons should be expired.
*/
var hs = Cc["@mozilla.org/browser/nav-history-service;1"].
getService(Ci.nsINavHistoryService);
var dbConn = hs.QueryInterface(Ci.nsPIPlacesDatabase).DBConnection;
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.");
var os = Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService);
var icons = Cc["@mozilla.org/browser/favicon-service;1"].
getService(Ci.nsIFaviconService);
const TEST_URI = "http://test.com/";
const TEST_ICON_URI = "http://test.com/favicon.ico";
const TEST_NOSYNC_URI = "http://nosync.test.com/";
const TEST_NOSYNC_ICON_URI = "http://nosync.test.com/favicon.ico";
const kSyncPrefName = "syncDBTableIntervalInSecs";
const SYNC_INTERVAL = 600;
const kSyncFinished = "places-sync-finished";
const kExpirationFinished = "places-favicons-expired";
var observer = {
observe: function(aSubject, aTopic, aData) {
if (aTopic == kSyncFinished) {
os.removeObserver(this, kSyncFinished);
// Add a not synced page with a visit.
hs.addVisit(uri(TEST_NOSYNC_URI), Date.now() * 1000, null,
hs.TRANSITION_TYPED, false, 0);
// Set a favicon for the page.
icons.setFaviconUrlForPage(uri(TEST_NOSYNC_URI), uri(TEST_NOSYNC_ICON_URI));
// Check both a synced and a not-synced favicons exist.
let stmt = dbConn.createStatement(
"SELECT id FROM moz_places WHERE url = :url AND favicon_id NOT NULL");
stmt.params["url"] = TEST_URI;
do_check_true(stmt.executeStep());
stmt.finalize();
stmt = dbConn.createStatement(
"SELECT id FROM moz_places_temp WHERE url = :url AND favicon_id NOT NULL");
stmt.params["url"] = TEST_NOSYNC_URI;
do_check_true(stmt.executeStep());
stmt.finalize();
// Expire all favicons.
icons.expireAllFavicons();
}
else if (aTopic == kExpirationFinished) {
os.removeObserver(this, kExpirationFinished);
// Check all favicons have been removed.
let stmt = dbConn.createStatement(
"SELECT id FROM moz_favicons");
do_check_false(stmt.executeStep());
stmt.finalize();
stmt = dbConn.createStatement(
"SELECT id FROM moz_places_view WHERE favicon_id NOT NULL");
do_check_false(stmt.executeStep());
stmt.finalize();
do_test_finished();
}
}
}
os.addObserver(observer, kSyncFinished, false);
os.addObserver(observer, kExpirationFinished, false);
function run_test()
{
// First set the preference for the timer to a large value so we don't sync.
prefs.setIntPref(kSyncPrefName, SYNC_INTERVAL);
// Add a page with a visit.
let visitId = hs.addVisit(uri(TEST_URI), Date.now() * 1000, null,
hs.TRANSITION_TYPED, false, 0);
// Set a favicon for the page.
icons.setFaviconUrlForPage(uri(TEST_URI), uri(TEST_ICON_URI));
// Now add a bookmark to force a sync.
bs.insertBookmark(bs.toolbarFolder, uri(TEST_URI), bs.DEFAULT_INDEX, "visited");
do_test_pending();
}

View File

@ -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):
* Marco Bonardo <mak77@bonardo.net> (Original Author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* This test checks that when we add an item we sync only if its type is
* TYPE_BOOKMARKS
*/
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.");
var os = Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService);
const TEST_URI = "http://test.com/";
const kSyncPrefName = "syncDBTableIntervalInSecs";
const SYNC_INTERVAL = 600;
const kSyncFinished = "places-sync-finished";
var syncObserver = {
_numSyncs: 0,
finalSync: false,
observe: function(aSubject, aTopic, aData) {
if (aTopic == kSyncFinished) {
if (++this._numSyncs > 1 || !this.finalSync)
do_throw("We synced too many times: " + this._numSyncs);
// remove the observers
os.removeObserver(this, kSyncFinished);
bs.removeObserver(bookmarksObserver, false);
do_test_finished();
}
}
}
os.addObserver(syncObserver, kSyncFinished, false);
var bookmarksObserver = {
onItemAdded: function(aItemId, aNewParent, aNewIndex) {
if (bs.getItemType(aItemId) == bs.TYPE_BOOKMARK)
syncObserver.finalSync = true;
}
}
bs.addObserver(bookmarksObserver, false);
function run_test()
{
// dynamic container sample
do_load_manifest("../unit/nsDynamicContainerServiceSample.manifest");
// First set the preference for the timer to a large value, so it won't sync
prefs.setIntPref(kSyncPrefName, SYNC_INTERVAL);
// Add a folder
bs.createFolder(bs.toolbarFolder, "folder", bs.DEFAULT_INDEX);
// Add a dynamic container
bs.createDynamicContainer(bs.toolbarFolder, "dynamic",
"@mozilla.org/browser/remote-container-sample;1",
bs.DEFAULT_INDEX);
// Add a separator
bs.insertSeparator(bs.toolbarFolder, bs.DEFAULT_INDEX);
// Add a bookmark, this will trigger final sync
bs.insertBookmark(bs.toolbarFolder, uri(TEST_URI), bs.DEFAULT_INDEX, "bookmark");
do_test_pending();
}

View File

@ -1,116 +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):
* Marco Bonardo <mak77@bonardo.net> (Original Author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
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.");
var os = Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService);
const TEST_URI = "http://test.com/";
const kSyncPrefName = "syncDBTableIntervalInSecs";
const SYNC_INTERVAL = 600;
const kSyncFinished = "places-sync-finished";
var observer = {
observe: function(aSubject, aTopic, aData) {
if (aTopic == kSyncFinished) {
// Set the preference for the timer to a large value so we don't sync.
prefs.setIntPref(kSyncPrefName, SYNC_INTERVAL);
// Now add another visit, be sure to use a different session, so we
// will also test grouping by uri.
hs.addVisit(uri(TEST_URI), Date.now() * 1000, null,
hs.TRANSITION_TYPED, false, 1);
// Create the history menu query.
var options = hs.getNewQueryOptions();
options.maxResults = 10;
options.resultType = options.RESULTS_AS_URI;
options.sortingMode = options.SORT_BY_DATE_DESCENDING;
var query = hs.getNewQuery();
var result = hs.executeQuery(query, options);
var root = result.root;
root.containerOpen = true;
do_check_eq(root.childCount, 1);
root.containerOpen = false;
// Create the most visited query.
options = hs.getNewQueryOptions();
options.maxResults = 10;
options.resultType = options.RESULTS_AS_URI;
options.sortingMode = options.SORT_BY_VISITCOUNT_DESCENDING;
query = hs.getNewQuery();
result = hs.executeQuery(query, options);
root = result.root;
root.containerOpen = true;
do_check_eq(root.childCount, 1);
root.containerOpen = false;
// Create basic uri query.
options = hs.getNewQueryOptions();
query = hs.getNewQuery();
result = hs.executeQuery(query, options);
root = result.root;
root.containerOpen = true;
do_check_eq(root.childCount, 1);
root.containerOpen = false;
os.removeObserver(this, kSyncFinished);
do_test_finished();
}
}
}
os.addObserver(observer, kSyncFinished, false);
function run_test()
{
// First set the preference for the timer to a small value so we sync
prefs.setIntPref(kSyncPrefName, 1);
// Now add the visit
let visitId = hs.addVisit(uri(TEST_URI), Date.now() * 1000, null,
hs.TRANSITION_TYPED, false, 0);
do_test_pending();
}

View File

@ -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 <me@shawnwilsher.com> (Original Author)
* Marco Bonardo <mak77@bonardo.net>
*
* 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
do_test_finished();
}
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();
}

View File

@ -1,152 +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 <me@shawnwilsher.com> (Original Author)
* Marco Bonardo <mak77@bonardo.net>
*
* 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.");
var os = Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService);
const TEST_URI = "http://test.com/";
const kSyncPrefName = "syncDBTableIntervalInSecs";
const SYNC_INTERVAL = 1;
const kSyncFinished = "places-sync-finished";
var observer = {
visitId: -1,
_runCount: 0,
_placeId: -1,
_lastVisitId: -1,
observe: function(aSubject, aTopic, aData) {
if (aTopic == kSyncFinished && this.visitId != -1) {
// Check the visit
new_test_visit_uri_event(this.visitId, TEST_URI, true);
// sanity check: visitId set by history observer should be the same we
// have added
do_check_eq(this.visitId, visitIds[this._runCount]);
if (++this._runCount == 1) {
// Get the place_id and pass it on
let stmt = db.createStatement(
"SELECT place_id " +
"FROM moz_historyvisits " +
"WHERE id = ?1"
);
stmt.bindInt64Parameter(0, this.visitId);
do_check_true(stmt.executeStep());
this._placeId = stmt.getInt64(0);
this._lastVisitId = this.visitId;
stmt.finalize();
stmt = null;
// clear cached value before continue test
this.visitId = -1;
continue_test();
}
else if (this._runCount == 2) {
do_check_neq(this.visitId, this._lastVisitId);
// Get the place_id and check for equality
let stmt = db.createStatement(
"SELECT place_id " +
"FROM moz_historyvisits " +
"WHERE id = ?1"
);
stmt.bindInt64Parameter(0, this.visitId);
do_check_true(stmt.executeStep());
do_check_eq(this._placeId, stmt.getInt64(0));
stmt.finalize();
stmt = null;
// remove the observers
os.removeObserver(this, kSyncFinished);
hs.removeObserver(historyObserver, false);
do_test_finished();
}
else
do_throw("bad runCount!");
}
}
}
os.addObserver(observer, kSyncFinished, false);
// Used to update observer visitId
var historyObserver = {
onVisit: function(aURI, aVisitId, aTime, aSessionId, aReferringId,
aTransitionType, aAdded) {
do_check_true(aVisitId > 0);
observer.visitId = aVisitId;
}
}
hs.addObserver(historyObserver, false);
// used for sanity checks
var visitIds = [];
function run_test()
{
// First set the preference for the timer to a small value
prefs.setIntPref(kSyncPrefName, SYNC_INTERVAL);
// Now add the first visit
visitIds[0] = hs.addVisit(uri(TEST_URI), Date.now() * 1000, null,
hs.TRANSITION_TYPED, false, 0);
do_test_pending();
}
function continue_test()
{
// Now we add another visit
visitIds[1] = hs.addVisit(uri(TEST_URI), Date.now() * 1000, null,
hs.TRANSITION_TYPED, false, 0);
}

View File

@ -45,8 +45,6 @@ var histsvc = Cc["@mozilla.org/browser/nav-history-service;1"].
var bhist = histsvc.QueryInterface(Ci.nsIBrowserHistory);
var bmsvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
getService(Ci.nsINavBookmarksService);
var ios = Cc["@mozilla.org/network/io-service;1"].
getService(Components.interfaces.nsIIOService);
/**
* Function prohibits an attempt to pop up a confirmation
@ -249,22 +247,13 @@ function run_test() {
var pb = get_PBSvc();
if (pb) { // Private Browsing might not be available
// need to catch places sync notifications
var os = Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService);
const kSyncFinished = "places-sync-finished";
do_test_pending();
var prefBranch = Cc["@mozilla.org/preferences-service;1"].
getService(Ci.nsIPrefBranch);
prefBranch.setBoolPref("browser.privatebrowsing.keep_current_session", true);
var bookmark_A_URI = ios.newURI("http://google.com/", null, null);
var bookmark_B_URI = ios.newURI("http://bugzilla.mozilla.org/", null, null);
var onBookmarkAAdded = {
observe: function (aSubject, aTopic, aData) {
os.removeObserver(this, kSyncFinished);
Services.prefs.setBoolPref("browser.privatebrowsing.keep_current_session", true);
var bookmark_A_URI = NetUtil.newURI("http://google.com/");
var bookmark_B_URI = NetUtil.newURI("http://bugzilla.mozilla.org/");
var onBookmarkAAdded = function() {
check_placesItem_Count();
// Bookmark-A should be bookmarked, data should be retrievable
@ -298,16 +287,11 @@ function run_test() {
do_check_true(bmsvc.isBookmarked(bookmark_A_URI));
do_check_eq("google",bmsvc.getKeywordForURI(bookmark_A_URI));
os.addObserver(onBookmarkBAdded, kSyncFinished, false);
// Create Bookmark-B
myBookmarks[1] = create_bookmark(bookmark_B_URI,"title 2", "bugzilla");
}
onBookmarkBAdded();
};
var onBookmarkBAdded = {
observe: function (aSubject, aTopic, aData) {
os.removeObserver(this, kSyncFinished);
var onBookmarkBAdded = function() {
// A check on the history count should be same as before, 7 history entries with
// now 2 bookmark items (A) and bookmark (B), so we set num_places_entries to 9
num_places_entries = 10; // Bookmark-B successfully added but not the history entries.
@ -330,9 +314,8 @@ function run_test() {
do_check_true(bhist.isVisited(uri(visited_uri)));
}
prefBranch.clearUserPref("browser.privatebrowsing.keep_current_session");
Services.prefs.clearUserPref("browser.privatebrowsing.keep_current_session");
do_test_finished();
}
};
// History database should be empty
@ -344,8 +327,6 @@ function run_test() {
// History database should have entries
do_check_true(histsvc.hasHistoryEntries);
os.addObserver(onBookmarkAAdded, kSyncFinished, false);
// Create Bookmark-A
myBookmarks[0] = create_bookmark(bookmark_A_URI,"title 1", "google");
@ -354,5 +335,7 @@ function run_test() {
do_check_true(bhist.isVisited(uri(visited_uri)));
do_check_true(uri_in_db(uri(visited_uri)));
}
onBookmarkAAdded();
}
}

View File

@ -292,7 +292,7 @@ function getFrecency(url)
var stmt;
var frecency;
sql = "SELECT frecency FROM moz_places_view WHERE url = ?1";
sql = "SELECT frecency FROM moz_places WHERE url = ?1";
stmt = dbConn.createStatement(sql);
stmt.bindUTF8StringParameter(0, url);
do_check_true(stmt.executeStep());
@ -307,7 +307,7 @@ function prepTest(testName, callback)
{
print("Test: " + testName);
waitForClearHistory(function() {
dbConn.executeSimpleSQL("DELETE FROM moz_places_view");
dbConn.executeSimpleSQL("DELETE FROM moz_places");
dbConn.executeSimpleSQL("DELETE FROM moz_bookmarks WHERE id > " +
defaultBookmarksMaxId);
callback();

View File

@ -57,7 +57,7 @@ function add_visit(aURI, aVisitDate, aVisitType) {
aVisitType != hs.TRANSITION_DOWNLOAD)
visit_count ++;
// Get the place id
var sql = "SELECT place_id FROM moz_historyvisits_view WHERE id = ?1";
var sql = "SELECT place_id FROM moz_historyvisits WHERE id = ?1";
var stmt = mDBConn.createStatement(sql);
stmt.bindInt64Parameter(0, visitId);
do_check_true(stmt.executeStep());

View File

@ -138,8 +138,8 @@ let historyObserver = {
return;
// dump tables, useful if the test fails.
dump_table("moz_places_temp");
dump_table("moz_favicons");
//dump_table("moz_places");
//dump_table("moz_favicons");
// Ensure we have been called by the last test.
do_check_true(pageURI.equals(uri("http://test4.bar/")));

View File

@ -51,12 +51,8 @@ let os = Cc["@mozilla.org/observer-service;1"].
let lms = Cc["@mozilla.org/browser/livemark-service;2"].
getService(Ci.nsILivemarkService);
const kSyncFinished = "places-sync-finished";
const kExpirationFinished = "places-expiration-finished";
// Number of expected sync notifications, we expect one per bookmark.
const EXPECTED_SYNCS = 4;
function add_fake_livemark() {
let lmId = lms.createLivemarkFolderOnly(bs.toolbarFolder,
"Livemark",
@ -91,42 +87,84 @@ let observer = {
// check browserHistory returns no entries
do_check_eq(0, bh.count);
// Check that frecency for not cleared items (bookmarks) has been converted
// to -MAX(visit_count, 1), so we will be able to recalculate frecency
// starting from most frecent bookmarks.
stmt = mDBConn.createStatement(
"SELECT h.id FROM moz_places h WHERE h.frecency > 0 " +
"AND EXISTS (SELECT id FROM moz_bookmarks WHERE fk = h.id) LIMIT 1");
do_check_false(stmt.executeStep());
stmt.finalize();
stmt = mDBConn.createStatement(
"SELECT h.id FROM moz_places h WHERE h.frecency = -2 " +
"AND EXISTS (SELECT id FROM moz_bookmarks WHERE fk = h.id) LIMIT 1");
do_check_true(stmt.executeStep());
stmt.finalize();
let expirationObserver = {
observe: function (aSubject, aTopic, aData) {
os.removeObserver(this, kExpirationFinished, false);
// Check that frecency for not cleared items (bookmarks) has been converted
// to -MAX(visit_count, 1), so we will be able to recalculate frecency
// starting from most frecent bookmarks.
// Memory table has been updated, disk table has not
stmt = mDBConn.createStatement(
"SELECT id FROM moz_places_temp WHERE frecency > 0 LIMIT 1");
do_check_false(stmt.executeStep());
stmt.finalize();
stmt = mDBConn.createStatement(
"SELECT h.id FROM moz_places_temp h WHERE h.frecency = -2 " +
"AND EXISTS (SELECT id FROM moz_bookmarks WHERE fk = h.id) LIMIT 1");
do_check_true(stmt.executeStep());
stmt.finalize();
// Check that all visit_counts have been brought to 0
stmt = mDBConn.createStatement(
"SELECT id FROM moz_places_temp WHERE visit_count <> 0 LIMIT 1");
"SELECT id FROM moz_places WHERE visit_count <> 0 LIMIT 1");
do_check_false(stmt.executeStep());
stmt.finalize();
// Check that history tables are empty
stmt = mDBConn.createStatement(
"SELECT * FROM (SELECT id FROM moz_historyvisits_temp LIMIT 1) " +
"UNION ALL " +
"SELECT * FROM (SELECT id FROM moz_historyvisits LIMIT 1)");
do_check_false(stmt.executeStep());
stmt.finalize();
// force a sync and check again disk tables, insertBookmark will do that
bs.insertBookmark(bs.unfiledBookmarksFolder, uri("place:folder=4"),
bs.DEFAULT_INDEX, "shortcut");
// Check that all moz_places entries except bookmarks and place: have been removed
stmt = mDBConn.createStatement(
"SELECT h.id FROM moz_places h WHERE SUBSTR(h.url, 1, 6) <> 'place:' "+
"AND NOT EXISTS (SELECT id FROM moz_bookmarks WHERE fk = h.id) LIMIT 1");
do_check_false(stmt.executeStep());
stmt.finalize();
// Check that we only have favicons for retained places
stmt = mDBConn.createStatement(
"SELECT f.id FROM moz_favicons f WHERE NOT EXISTS " +
"(SELECT id FROM moz_places WHERE favicon_id = f.id) LIMIT 1");
do_check_false(stmt.executeStep());
stmt.finalize();
// Check that we only have annotations for retained places
stmt = mDBConn.createStatement(
"SELECT a.id FROM moz_annos a WHERE NOT EXISTS " +
"(SELECT id FROM moz_places WHERE id = a.place_id) LIMIT 1");
do_check_false(stmt.executeStep());
stmt.finalize();
// Check that we only have inputhistory for retained places
stmt = mDBConn.createStatement(
"SELECT i.place_id FROM moz_inputhistory i WHERE NOT EXISTS " +
"(SELECT id FROM moz_places WHERE id = i.place_id) LIMIT 1");
do_check_false(stmt.executeStep());
stmt.finalize();
// Check that place:uris have frecency 0
stmt = mDBConn.createStatement(
"SELECT h.id FROM moz_places h " +
"WHERE SUBSTR(h.url, 1, 6) = 'place:' AND h.frecency <> 0 LIMIT 1");
do_check_false(stmt.executeStep());
stmt.finalize();
// Check that livemarks children don't have frecency <> 0
stmt = mDBConn.createStatement(
"SELECT h.id FROM moz_places h " +
"JOIN moz_bookmarks b ON h.id = b.fk " +
"JOIN moz_bookmarks bp ON bp.id = b.parent " +
"JOIN moz_items_annos t ON t.item_id = bp.id " +
"JOIN moz_anno_attributes n ON t.anno_attribute_id = n.id " +
"WHERE n.name = 'livemark/feedURI' AND h.frecency <> 0 LIMIT 1");
do_check_false(stmt.executeStep());
stmt.finalize();
do_test_finished();
}
}
os.addObserver(expirationObserver, kExpirationFinished, false);
@ -137,105 +175,12 @@ let observer = {
onDeleteVisits: function() {
},
QueryInterface: function(iid) {
if (iid.equals(Ci.nsINavHistoryObserver) ||
iid.equals(Ci.nsISupports)) {
return this;
}
throw Cr.NS_ERROR_NO_INTERFACE;
}
QueryInterface: XPCOMUtils.generateQI([
Ci.nsINavHistoryObserver,
]),
}
hs.addObserver(observer, false);
let syncObserver = {
_runCount: 0,
observe: function (aSubject, aTopic, aData) {
if (++this._runCount < EXPECTED_SYNCS)
return;
if (this._runCount == EXPECTED_SYNCS) {
bh.removeAllPages();
return;
}
os.removeObserver(this, kSyncFinished, false);
// Sanity: check that places temp table is empty
stmt = mDBConn.createStatement(
"SELECT id FROM moz_places_temp LIMIT 1");
do_check_false(stmt.executeStep());
stmt.finalize();
// Check that frecency for not cleared items (bookmarks) has been converted
// to -MAX(visit_count, 1), so we will be able to recalculate frecency
// starting from most frecent bookmarks.
stmt = mDBConn.createStatement(
"SELECT id FROM moz_places WHERE frecency > 0 LIMIT 1");
do_check_false(stmt.executeStep());
stmt.finalize();
stmt = mDBConn.createStatement(
"SELECT h.id FROM moz_places h WHERE h.frecency = -2 " +
"AND EXISTS (SELECT id FROM moz_bookmarks WHERE fk = h.id) LIMIT 1");
do_check_true(stmt.executeStep());
stmt.finalize();
// Check that all visit_counts have been brought to 0
stmt = mDBConn.createStatement(
"SELECT id FROM moz_places WHERE visit_count <> 0 LIMIT 1");
do_check_false(stmt.executeStep());
stmt.finalize();
// Check that all moz_places entries except bookmarks and place: have been removed
stmt = mDBConn.createStatement(
"SELECT h.id FROM moz_places h WHERE SUBSTR(h.url, 1, 6) <> 'place:' "+
"AND NOT EXISTS (SELECT id FROM moz_bookmarks WHERE fk = h.id) LIMIT 1");
do_check_false(stmt.executeStep());
stmt.finalize();
// Check that we only have favicons for retained places
stmt = mDBConn.createStatement(
"SELECT f.id FROM moz_favicons f WHERE NOT EXISTS " +
"(SELECT id FROM moz_places WHERE favicon_id = f.id) LIMIT 1");
do_check_false(stmt.executeStep());
stmt.finalize();
// Check that we only have annotations for retained places
stmt = mDBConn.createStatement(
"SELECT a.id FROM moz_annos a WHERE NOT EXISTS " +
"(SELECT id FROM moz_places WHERE id = a.place_id) LIMIT 1");
do_check_false(stmt.executeStep());
stmt.finalize();
// Check that we only have inputhistory for retained places
stmt = mDBConn.createStatement(
"SELECT i.place_id FROM moz_inputhistory i WHERE NOT EXISTS " +
"(SELECT id FROM moz_places WHERE id = i.place_id) LIMIT 1");
do_check_false(stmt.executeStep());
stmt.finalize();
// Check that place:uris have frecency 0
stmt = mDBConn.createStatement(
"SELECT h.id FROM moz_places h " +
"WHERE SUBSTR(h.url, 1, 6) = 'place:' AND h.frecency <> 0 LIMIT 1");
do_check_false(stmt.executeStep());
stmt.finalize();
// Check that livemarks children don't have frecency <> 0
stmt = mDBConn.createStatement(
"SELECT h.id FROM moz_places h " +
"JOIN moz_bookmarks b ON h.id = b.fk " +
"JOIN moz_bookmarks bp ON bp.id = b.parent " +
"JOIN moz_items_annos t ON t.item_id = bp.id " +
"JOIN moz_anno_attributes n ON t.anno_attribute_id = n.id " +
"WHERE n.name = 'livemark/feedURI' AND h.frecency <> 0 LIMIT 1");
do_check_false(stmt.executeStep());
stmt.finalize();
do_test_finished();
}
}
os.addObserver(syncObserver, kSyncFinished, false);
// main
function run_test() {
// Add a livemark with a visited and an unvisited child
add_fake_livemark();
@ -269,13 +214,23 @@ function run_test() {
// Add a bookmark
// Bookmarked page should have history cleared and frecency = -old_visit_count
// This will also finally sync temp tables to disk
bs.insertBookmark(bs.unfiledBookmarksFolder, uri("http://typed.mozilla.org"),
bs.DEFAULT_INDEX, "bookmark");
// this visit is not synced to disk
hs.addVisit(uri("http://typed.mozilla.org"), Date.now(), null,
hs.TRANSITION_BOOKMARK, false, 0);
// Since we are checking frecency, we have to disable some stuff that could
// change values during test run. On idle-daily frecencies are updated.
Services.obs.removeObserver(hs, "idle-daily");
// executeSoon allows us to fire the places-init-complete notification before
// the removeAllPages call. Since we are creating a new database, on that
// notification we will act on initial frecency, and that could disturb
// this test's frecency checks.
do_execute_soon(function () {
bh.removeAllPages();
});
do_test_pending();
}

View File

@ -72,7 +72,7 @@ function run_test() {
_("Now that places has migrated, check that it calculated frecencies");
var stmt = places.DBConnection.createStatement(
"SELECT COUNT(*) FROM moz_places_view WHERE frecency < 0");
"SELECT COUNT(*) FROM moz_places WHERE frecency < 0");
stmt.executeAsync({
handleResult: function(results) {
_("Should always get a result from COUNT(*)");

View File

@ -390,7 +390,7 @@ function deleteAllHistoryAndBookmarks() {
* @return the frecency of aURI
*/
function getFrecencyForURI(aURI) {
let sql = "SELECT frecency FROM moz_places_view WHERE url = :url";
let sql = "SELECT frecency FROM moz_places WHERE url = :url";
let stmt = dbConn.createStatement(sql);
stmt.params.url = aURI.spec;
do_check_true(stmt.executeStep());
@ -407,7 +407,7 @@ function getFrecencyForURI(aURI) {
* the URI of a place
*/
function uriExistsInMozPlaces(aURI) {
let sql = "SELECT id FROM moz_places_view WHERE url = :url";
let sql = "SELECT id FROM moz_places WHERE url = :url";
let stmt = dbConn.createStatement(sql);
stmt.params.url = aURI.spec;
var exists = stmt.executeStep();

View File

@ -345,7 +345,7 @@ function createLivemark(aLmChildItemURI) {
* @return the frecency of aURL
*/
function getFrecency(aURL) {
let sql = "SELECT frecency FROM moz_places_view WHERE url = :url";
let sql = "SELECT frecency FROM moz_places WHERE url = :url";
let stmt = dbConn.createStatement(sql);
stmt.params.url = aURL;
do_check_true(stmt.executeStep());