Bug 1453994 - Add a places maintenance task to ensure built-in bookmark folders have the correct parents. r?mak
MozReview-Commit-ID: LOVhGphAmDA
--- a/toolkit/components/places/PlacesDBUtils.jsm
+++ b/toolkit/components/places/PlacesDBUtils.jsm
@@ -278,16 +278,32 @@ var PlacesDBUtils = {
{ query:
`DELETE FROM moz_annos WHERE id IN (
SELECT id FROM moz_annos a
WHERE NOT EXISTS
(SELECT id FROM moz_places WHERE id = a.place_id LIMIT 1)
)`
},
+ // C.1 Fix built-in folders with incorrect parents.
+ { query:
+ `UPDATE moz_bookmarks SET parent = :rootId
+ WHERE guid IN (
+ :menuGuid, :toolbarGuid, :unfiledGuid, :tagsGuid, :mobileGuid
+ ) AND parent <> :rootId`,
+ params: {
+ rootId: PlacesUtils.placesRootId,
+ menuGuid: PlacesUtils.bookmarks.menuGuid,
+ toolbarGuid: PlacesUtils.bookmarks.toolbarGuid,
+ unfiledGuid: PlacesUtils.bookmarks.unfiledGuid,
+ tagsGuid: PlacesUtils.bookmarks.tagsGuid,
+ mobileGuid: PlacesUtils.bookmarks.mobileGuid,
+ }
+ },
+
// D.1 remove items without a valid place
// If fk IS NULL we fix them in D.7
{ query:
`DELETE FROM moz_bookmarks WHERE guid NOT IN (
:rootGuid, :menuGuid, :toolbarGuid, :unfiledGuid, :tagsGuid /* skip roots */
) AND id IN (
SELECT b.id FROM moz_bookmarks b
WHERE fk NOT NULL AND b.type = :bookmark_type
--- a/toolkit/components/places/tests/head_common.js
+++ b/toolkit/components/places/tests/head_common.js
@@ -236,18 +236,21 @@ function clearDB() {
/**
* Dumps the rows of a table out to the console.
*
* @param aName
* The name of the table or view to output.
*/
-function dump_table(aName) {
- let stmt = DBConn().createStatement("SELECT * FROM " + aName);
+function dump_table(aName, dbConn) {
+ if (!dbConn) {
+ dbConn = DBConn();
+ }
+ let stmt = dbConn.createStatement("SELECT * FROM " + aName);
print("\n*** Printing data from " + aName);
let count = 0;
while (stmt.executeStep()) {
let columns = stmt.numEntries;
if (count == 0) {
// Print the column names.
--- a/toolkit/components/places/tests/unit/test_preventive_maintenance.js
+++ b/toolkit/components/places/tests/unit/test_preventive_maintenance.js
@@ -370,16 +370,47 @@ tests.push({
Assert.equal(bs.getFolderIdForItem(bs.placesRoot), 0);
Assert.equal(bs.getFolderIdForItem(bs.bookmarksMenuFolder), bs.placesRoot);
Assert.equal(bs.getFolderIdForItem(bs.tagsFolder), bs.placesRoot);
Assert.equal(bs.getFolderIdForItem(bs.unfiledBookmarksFolder), bs.placesRoot);
Assert.equal(bs.getFolderIdForItem(bs.toolbarFolder), bs.placesRoot);
}
});
+tests.push({
+ name: "C.1",
+ desc: "fix invalid parents for Places folders",
+
+ setup() {
+ // Reparent the roots to something invalid.
+ mDBConn.executeSimpleSQL(`
+ UPDATE moz_bookmarks SET parent = 2
+ WHERE parent = (SELECT id from moz_bookmarks WHERE guid = "${PlacesUtils.bookmarks.rootGuid}")
+ `);
+ },
+
+ async check() {
+ let db = await PlacesUtils.promiseDBConnection();
+
+ let rows = await db.executeCached(`
+ SELECT guid FROM moz_bookmarks
+ WHERE parent = (SELECT id from moz_bookmarks WHERE guid = "${PlacesUtils.bookmarks.rootGuid}")
+ `);
+
+ let guids = rows.map(row => row.getResultByName("guid"));
+ Assert.deepEqual(guids, [
+ PlacesUtils.bookmarks.menuGuid,
+ PlacesUtils.bookmarks.toolbarGuid,
+ PlacesUtils.bookmarks.tagsGuid,
+ PlacesUtils.bookmarks.unfiledGuid,
+ PlacesUtils.bookmarks.mobileGuid,
+ ]);
+ }
+});
+
// ------------------------------------------------------------------------------
tests.push({
name: "D.1",
desc: "Remove items without a valid place",
_validItemId: null,
_invalidItemId: null,