Bug 1753596 - Implement SnapshotGroups.updateUrls. r=mak

Differential Revision: https://phabricator.services.mozilla.com/D137832
This commit is contained in:
Mark Banner 2022-02-08 15:39:03 +00:00
parent 8ced363a3e
commit 75e9207a76
4 changed files with 97 additions and 51 deletions

View File

@ -88,28 +88,7 @@ const SnapshotGroups = new (class SnapshotGroups {
);
id = row[0].getResultByIndex(0);
// Construct the sql parameters for the urls
let params = {};
let SQLInFragment = [];
let i = 0;
for (let url of urls) {
params[`url${i}`] = url;
SQLInFragment.push(`hash(:url${i})`);
i++;
}
params.id = id;
await db.execute(
`
INSERT INTO moz_places_metadata_groups_to_snapshots (group_id, place_id)
SELECT :id, s.place_id
FROM moz_places h
JOIN moz_places_metadata_snapshots s
ON h.id = s.place_id
WHERE h.url_hash IN (${SQLInFragment.join(",")})
`,
params
);
await this.#insertUrls(db, id, urls);
}
);
@ -148,6 +127,8 @@ const SnapshotGroups = new (class SnapshotGroups {
/**
* Modifies the urls for a snapshot group.
* Note: This API does not manage deleting of groups if the number of urls is
* 0. If there are no urls in the group, consider calling `delete()` instead.
*
* @param {number} id
* The id of the group to modify.
@ -155,7 +136,21 @@ const SnapshotGroups = new (class SnapshotGroups {
* An array of snapshot urls for the group. If the urls do not have associated snapshots, then they are ignored.
*/
async updateUrls(id, urls) {
// TODO
await PlacesUtils.withConnectionWrapper(
"SnapshotsGroups.jsm:updateUrls",
async db => {
// Some entries need removing, others modifying or adding. The easiest
// way to do this is to remove the existing group information first and
// then add only what we need.
await db.executeCached(
`DELETE FROM moz_places_metadata_groups_to_snapshots WHERE group_id = :id`,
{ id }
);
await this.#insertUrls(db, id, urls);
}
);
Services.obs.notifyObservers(null, "places-snapshot-group-updated");
}
@ -306,6 +301,41 @@ const SnapshotGroups = new (class SnapshotGroups {
return snapshots;
}
/**
* Inserts a set of urls into the database for a given snapshot group.
*
* @param {object} db
* The database connection to use.
* @param {number} id
* The id of the group to add the urls to.
* @param {string[]} urls
* An array of urls to insert for the group.
*/
async #insertUrls(db, id, urls) {
// Construct the sql parameters for the urls
let params = {};
let SQLInFragment = [];
let i = 0;
for (let url of urls) {
params[`url${i}`] = url;
SQLInFragment.push(`hash(:url${i})`);
i++;
}
params.id = id;
await db.execute(
`
INSERT INTO moz_places_metadata_groups_to_snapshots (group_id, place_id)
SELECT :id, s.place_id
FROM moz_places h
JOIN moz_places_metadata_snapshots s
ON h.id = s.place_id
WHERE h.url_hash IN (${SQLInFragment.join(",")})
`,
params
);
}
/**
* Translates a snapshot group database row to a SnapshotGroup.
*

View File

@ -56,8 +56,14 @@ async function addGroupTest(shouldRebuild) {
title: "example",
builder: "domain",
builderMetadata: { domain: "example.com" },
urls: TEST_URLS,
});
let urls = await SnapshotGroups.getUrls({ id: groups[0].id });
Assert.deepEqual(
urls.sort(),
TEST_URLS.sort(),
"Should have inserted the expected URLs"
);
}
async function modifyGroupTest(shouldRebuild) {
@ -84,10 +90,13 @@ async function modifyGroupTest(shouldRebuild) {
title: "example",
builder: "domain",
builderMetadata: { domain: "example.com" },
// TODO: Replace when updateUrls API has been implemented.
urls: TEST_URLS,
// urls: [...TEST_URLS, TEST_URLS_EXTRA],
});
let urls = await SnapshotGroups.getUrls({ id: groups[0].id });
Assert.deepEqual(
urls.sort(),
[...TEST_URLS, TEST_URLS_EXTRA].sort(),
"Should have inserted the expected URLs"
);
}
async function deleteGroupTest(shouldRebuild) {

View File

@ -9,6 +9,7 @@ const TEST_URL1 = "https://example.com/";
const TEST_URL2 = "https://example.com/12345";
const TEST_URL3 = "https://example.com/67890";
const TEST_URL4 = "https://example.com/135246";
const TEST_URL5 = "https://example.com/531246";
async function delete_all_groups() {
let groups = await SnapshotGroups.query({ skipMinimum: true });
@ -159,6 +160,30 @@ add_task(async function test_update_metadata() {
});
});
add_task(async function test_update_urls() {
let groups = await SnapshotGroups.query({ skipMinimum: true });
Assert.equal(groups.length, 1, "Should return 1 snapshot group");
Assert.equal(
groups[0].title,
"Modified title",
"SnapshotGroup title should be retrieved"
);
await SnapshotGroups.updateUrls(groups[0].id, [
TEST_URL5,
TEST_URL3,
TEST_URL1,
]);
let updated_groups = await SnapshotGroups.query({ skipMinimum: true });
Assert.equal(updated_groups.length, 1, "Should return 1 SnapshotGroup");
assertSnapshotGroup(groups[0], {
title: "Modified title",
builder: "pinned",
snapshotCount: [TEST_URL5, TEST_URL3, TEST_URL1].length,
});
});
add_task(async function test_delete_group() {
let groups = await SnapshotGroups.query({ skipMinimum: true });
Assert.equal(groups.length, 1, "Should return 1 SnapshotGroup");
@ -268,6 +293,10 @@ add_task(async function test_get_snapshots_startIndex() {
});
add_task(async function test_minimum_size() {
let newGroup = { title: "Test Group 2", builder: "domain" };
let urls = [TEST_URL1, TEST_URL2, TEST_URL3];
let groupId = await SnapshotGroups.add(newGroup, urls);
let groups = await SnapshotGroups.query();
Assert.equal(
groups.length,
@ -275,15 +304,8 @@ add_task(async function test_minimum_size() {
"Should return no groups when they are under the snapshot size limit."
);
// TODO: Ideally this would use `updateUrls` to update 'Test Group' but that
// api is not implemented yet.
let newGroup = { title: "Test Group 2", builder: "domain" };
await SnapshotGroups.add(newGroup, [
TEST_URL1,
TEST_URL2,
TEST_URL3,
TEST_URL4,
]);
urls.push(TEST_URL4);
await SnapshotGroups.updateUrls(groupId, urls);
groups = await SnapshotGroups.query();
Assert.equal(

View File

@ -408,21 +408,6 @@
"WHERE id = OLD.place_id; " \
"END")
// This trigger removes orphan groups when snapshots are removed.
# define CREATE_PLACES_METADATA_SNAPSHOTS_GROUPS_AFTERDELETE_TRIGGER \
nsLiteralCString( \
"CREATE TEMP TRIGGER " \
"moz_places_metadata_groups_to_snapshots_afterdelete_trigger " \
"AFTER DELETE ON moz_places_metadata_groups_to_snapshots " \
"FOR EACH ROW " \
"BEGIN " \
"DELETE FROM moz_places_metadata_snapshots_groups " \
"WHERE id = OLD.group_id AND NOT EXISTS ( " \
"SELECT group_id FROM moz_places_metadata_groups_to_snapshots " \
"WHERE group_id = OLD.group_id " \
"); " \
"END")
// This trigger increments foreign_count when sessions are altered.
# define CREATE_PLACES_SESSION_TO_PLACE_AFTERINSERT_TRIGGER \
nsLiteralCString( \