Bug 1448044 - kinto-storage-adapter.js chokes on large updates r?glasserc draft
authorMark Goodwin <mgoodwin@mozilla.com>
Thu, 22 Mar 2018 15:59:46 +0000
changeset 771155 b39f113710fee4c57eecd7c9025c34410ff475c6
parent 771093 7771df14ea181add1dc4133f0f5559bf620bf976
push id103586
push usermgoodwin@mozilla.com
push dateThu, 22 Mar 2018 16:13:22 +0000
reviewersglasserc
bugs1448044
milestone61.0a1
Bug 1448044 - kinto-storage-adapter.js chokes on large updates r?glasserc MozReview-Commit-ID: B8NZI5NhFzG
services/common/kinto-storage-adapter.js
--- a/services/common/kinto-storage-adapter.js
+++ b/services/common/kinto-storage-adapter.js
@@ -263,29 +263,48 @@ class FirefoxAdapter extends Kinto.adapt
 
   execute(callback, options = { preload: [] }) {
     let result;
     const conn = this._connection;
     const collection = this.collection;
 
     return conn.executeTransaction(async function doExecuteTransaction() {
       // Preload specified records from DB, within transaction.
-      const parameters = [
-        collection,
-        ...options.preload,
-      ];
-      const placeholders = options.preload.map(_ => "?");
-      const stmt = statements.listRecordsById + "(" + placeholders.join(",") + ");";
-      const rows = await conn.execute(stmt, parameters);
+
+      // if options.preload has more elements than the sqlite variable
+      // limit, split it up.
+      const limit = 100;
+      let length = options.preload.length;
+      let preloaded = {};
+      let preload;
 
-      const preloaded = rows.reduce((acc, row) => {
-        const record = JSON.parse(row.getResultByName("record"));
-        acc[row.getResultByName("record_id")] = record;
-        return acc;
-      }, {});
+      for (let remainder = options.preload; remainder.length > 0; length = remainder.length) {
+        if (length > limit) {
+          preload = remainder.slice(0, limit);
+          remainder = remainder.slice(limit, length);
+        } else {
+          preload = remainder;
+          remainder = [];
+        }
+
+        //
+        const parameters = [
+          collection,
+          ...preload,
+        ];
+        const placeholders = preload.map(_ => "?");
+        const stmt = statements.listRecordsById + "(" + placeholders.join(",") + ");";
+        const rows = await conn.execute(stmt, parameters);
+
+        preloaded = Object.assign(preloaded, rows.reduce((acc, row) => {
+          const record = JSON.parse(row.getResultByName("record"));
+          acc[row.getResultByName("record_id")] = record;
+          return acc;
+        }, {}));
+      }
 
       const proxy = transactionProxy(collection, preloaded);
       result = callback(proxy);
 
       for (let { statement, params } of proxy.operations) {
         await conn.executeCached(statement, params);
       }
     }, conn.TRANSACTION_EXCLUSIVE).then(_ => result);