Bug 1310525 - don't exceed sqlite's max variable limit when many changed bookmarks exist. r?kitcambridge
MozReview-Commit-ID: H2l2L9fZm9t
--- a/services/sync/modules/engines/bookmarks.js
+++ b/services/sync/modules/engines/bookmarks.js
@@ -544,18 +544,18 @@ BookmarksEngine.prototype = {
// Filter out tags, organizer queries, and other descendants that we're
// not tracking. We chunk `modifiedGUIDs` because SQLite limits the number
// of bound parameters per query.
for (let startIndex = 0;
startIndex < modifiedGUIDs.length;
startIndex += SQLITE_MAX_VARIABLE_NUMBER) {
- let chunkLength = Math.min(startIndex + SQLITE_MAX_VARIABLE_NUMBER,
- modifiedGUIDs.length);
+ let chunkLength = Math.min(SQLITE_MAX_VARIABLE_NUMBER,
+ modifiedGUIDs.length - startIndex);
let query = `
WITH RECURSIVE
modifiedGuids(guid) AS (
VALUES ${new Array(chunkLength).fill("(?)").join(", ")}
),
syncedItems(id) AS (
VALUES ${getChangeRootIds().map(id => `(${id})`).join(", ")}
--- a/services/sync/tests/unit/test_bookmark_tracker.js
+++ b/services/sync/tests/unit/test_bookmark_tracker.js
@@ -176,16 +176,43 @@ add_task(function* test_nested_batch_tra
}, null);
// Out of both batches - tracker should be the same, but score should be up.
yield verifyTrackedCount(2);
do_check_eq(tracker.score, SCORE_INCREMENT_XLARGE);
yield cleanup();
});
+add_task(function* test_tracker_sql_batching() {
+ _("Test tracker does the correct thing when it is forced to batch SQL queries");
+
+ const SQLITE_MAX_VARIABLE_NUMBER = 999;
+ let numItems = SQLITE_MAX_VARIABLE_NUMBER * 2 + 10;
+ let createdIDs = [];
+
+ yield startTracking();
+
+ PlacesUtils.bookmarks.runInBatchMode({
+ runBatched: function() {
+ for (let i = 0; i < numItems; i++) {
+ let syncBmkID = PlacesUtils.bookmarks.insertBookmark(
+ PlacesUtils.bookmarks.unfiledBookmarksFolder,
+ Utils.makeURI("https://example.org/" + i),
+ PlacesUtils.bookmarks.DEFAULT_INDEX,
+ "Sync Bookmark " + i);
+ createdIDs.push(syncBmkID);
+ }
+ }
+ }, null);
+
+ do_check_eq(createdIDs.length, numItems);
+ yield verifyTrackedCount(numItems + 1); // the folder is also tracked.
+ yield cleanup();
+});
+
add_task(function* test_onItemAdded() {
_("Items inserted via the synchronous bookmarks API should be tracked");
try {
yield startTracking();
_("Insert a folder using the sync API");
let syncFolderID = PlacesUtils.bookmarks.createFolder(