mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-08-26 17:28:38 +09:00
141 lines
5 KiB
JavaScript
141 lines
5 KiB
JavaScript
Cu.importGlobalProperties(["URL", "crypto"]);
|
|
|
|
const { TYPE_BOOKMARK, TYPE_FOLDER } = Ci.nsINavBookmarksService;
|
|
const { EXPIRE_NEVER, TYPE_INT32 } = Ci.nsIAnnotationService;
|
|
|
|
function makeGuid() {
|
|
return ChromeUtils.base64URLEncode(crypto.getRandomValues(new Uint8Array(9)), {
|
|
pad: false,
|
|
});
|
|
}
|
|
|
|
// These queries are more or less copied directly from Bookmarks.jsm, but
|
|
// operate on the old, pre-migration DB. We can't use any of the Places SQL
|
|
// functions yet, because those are only registered for the main connection.
|
|
function* insertItem(db, info) {
|
|
let [parentInfo] = yield db.execute(`
|
|
SELECT b.id, (SELECT count(*) FROM moz_bookmarks
|
|
WHERE parent = b.id) AS childCount
|
|
FROM moz_bookmarks b
|
|
WHERE b.guid = :parentGuid`,
|
|
{ parentGuid: info.parentGuid });
|
|
|
|
let guid = makeGuid();
|
|
yield db.execute(`
|
|
INSERT INTO moz_bookmarks (fk, type, parent, position, guid)
|
|
VALUES ((SELECT id FROM moz_places WHERE url = :url),
|
|
:type, :parent, :position, :guid)`,
|
|
{ url: info.url || "nonexistent", type: info.type, guid,
|
|
// Just append items.
|
|
position: parentInfo.getResultByName("childCount"),
|
|
parent: parentInfo.getResultByName("id") });
|
|
|
|
let id = (yield db.execute(`
|
|
SELECT id FROM moz_bookmarks WHERE guid = :guid LIMIT 1`,
|
|
{ guid }))[0].getResultByName("id");
|
|
|
|
return { id, guid };
|
|
}
|
|
|
|
function insertBookmark(db, info) {
|
|
return db.executeTransaction(function* () {
|
|
if (info.type == TYPE_BOOKMARK) {
|
|
// We don't have access to the hash function here, so we omit the
|
|
// `url_hash` column. These will be fixed up automatically during
|
|
// migration.
|
|
let url = new URL(info.url);
|
|
let placeGuid = makeGuid();
|
|
yield db.execute(`
|
|
INSERT INTO moz_places (url, rev_host, hidden, frecency, guid)
|
|
VALUES (:url, :rev_host, 0, -1, :guid)`,
|
|
{ url: url.href, guid: placeGuid,
|
|
rev_host: PlacesUtils.getReversedHost(url) });
|
|
}
|
|
return yield* insertItem(db, info);
|
|
});
|
|
}
|
|
|
|
function* insertAnno(db, itemId, name, value) {
|
|
yield db.execute(`INSERT OR IGNORE INTO moz_anno_attributes (name)
|
|
VALUES (:name)`, { name });
|
|
yield db.execute(`
|
|
INSERT INTO moz_items_annos
|
|
(item_id, anno_attribute_id, content, flags,
|
|
expiration, type, dateAdded, lastModified)
|
|
VALUES (:itemId,
|
|
(SELECT id FROM moz_anno_attributes
|
|
WHERE name = :name),
|
|
1, 0, :expiration, :type, 0, 0)
|
|
`, { itemId, name, expiration: EXPIRE_NEVER, type: TYPE_INT32 });
|
|
}
|
|
|
|
function insertMobileFolder(db) {
|
|
return db.executeTransaction(function* () {
|
|
let item = yield* insertItem(db, {
|
|
type: TYPE_FOLDER,
|
|
parentGuid: "root________",
|
|
});
|
|
yield* insertAnno(db, item.id, "mobile/bookmarksRoot", 1);
|
|
return item;
|
|
});
|
|
}
|
|
|
|
var mobileId, mobileGuid, fxGuid;
|
|
var dupeMobileId, dupeMobileGuid, tbGuid;
|
|
|
|
add_task(function* setup() {
|
|
yield setupPlacesDatabase("places_v34.sqlite");
|
|
// Setup database contents to be migrated.
|
|
let path = OS.Path.join(OS.Constants.Path.profileDir, DB_FILENAME);
|
|
let db = yield Sqlite.openConnection({ path });
|
|
|
|
do_print("Create mobile folder with bookmarks");
|
|
({ id: mobileId, guid: mobileGuid } = yield insertMobileFolder(db));
|
|
({ guid: fxGuid } = yield insertBookmark(db, {
|
|
type: TYPE_BOOKMARK,
|
|
url: "http://getfirefox.com",
|
|
parentGuid: mobileGuid,
|
|
}));
|
|
|
|
// We should only have one mobile folder, but, in case an old version of Sync
|
|
// did the wrong thing and created multiple mobile folders, we should merge
|
|
// their contents into the new mobile root.
|
|
do_print("Create second mobile folder with different bookmarks");
|
|
({ id: dupeMobileId, guid: dupeMobileGuid } = yield insertMobileFolder(db));
|
|
({ guid: tbGuid } = yield insertBookmark(db, {
|
|
type: TYPE_BOOKMARK,
|
|
url: "http://getthunderbird.com",
|
|
parentGuid: dupeMobileGuid,
|
|
}));
|
|
|
|
yield db.close();
|
|
});
|
|
|
|
add_task(function* database_is_valid() {
|
|
// Accessing the database for the first time triggers migration.
|
|
Assert.equal(PlacesUtils.history.databaseStatus,
|
|
PlacesUtils.history.DATABASE_STATUS_UPGRADED);
|
|
|
|
let db = yield PlacesUtils.promiseDBConnection();
|
|
Assert.equal((yield db.getSchemaVersion()), CURRENT_SCHEMA_VERSION);
|
|
});
|
|
|
|
add_task(function* test_mobile_root() {
|
|
let fxBmk = yield PlacesUtils.bookmarks.fetch(fxGuid);
|
|
equal(fxBmk.parentGuid, PlacesUtils.bookmarks.mobileGuid,
|
|
"Firefox bookmark should be moved to new mobile root");
|
|
equal(fxBmk.index, 0, "Firefox bookmark should be first child of new root");
|
|
|
|
let tbBmk = yield PlacesUtils.bookmarks.fetch(tbGuid);
|
|
equal(tbBmk.parentGuid, PlacesUtils.bookmarks.mobileGuid,
|
|
"Thunderbird bookmark should be moved to new mobile root");
|
|
equal(tbBmk.index, 1,
|
|
"Thunderbird bookmark should be second child of new root");
|
|
|
|
let mobileRootId = PlacesUtils.promiseItemId(
|
|
PlacesUtils.bookmarks.mobileGuid);
|
|
let annoItemIds = PlacesUtils.annotations.getItemsWithAnnotation(
|
|
PlacesUtils.MOBILE_ROOT_ANNO, {});
|
|
deepEqual(annoItemIds, [mobileRootId],
|
|
"Only mobile root should have mobile anno");
|
|
});
|