Bug 887889 - Limit scope of executeTransaction closure r?mak draft
authorDoug Thayer <dothayer@mozilla.com>
Tue, 27 Mar 2018 10:30:37 -0700
changeset 788705 825867eb7878a6838ecc1d05bc3522407a631da0
parent 788704 0e590e6c27016ed02848a46a8494aa7f28e73407
child 788706 be5903304b63dffffa17f7e2305243464c537e16
push id108067
push userbmo:dothayer@mozilla.com
push dateThu, 26 Apr 2018 21:12:12 +0000
reviewersmak
bugs887889
milestone61.0a1
Bug 887889 - Limit scope of executeTransaction closure r?mak MozReview-Commit-ID: 9d2xh4Qxs3q
toolkit/components/contentprefs/ContentPrefService2.js
--- a/toolkit/components/contentprefs/ContentPrefService2.js
+++ b/toolkit/components/contentprefs/ContentPrefService2.js
@@ -44,16 +44,28 @@ cache.set = function CPS_cache_set(group
       if (groupCount < CACHE_MAX_GROUP_ENTRIES / 2)
         break;
     }
   }
 };
 
 const privModeStorage = new ContentPrefStore();
 
+function executeStatementsInTransaction(conn, stmts) {
+  return conn.executeTransaction(async () => {
+    let rows = [];
+    for (let {sql, params, cachable} of stmts) {
+      let execute = cachable ? conn.executeCached : conn.execute;
+      let stmtRows = await execute.call(conn, sql, params);
+      rows = rows.concat(stmtRows);
+    }
+    return rows;
+  });
+}
+
 ContentPrefService2.prototype = {
   // XPCOM Plumbing
 
   classID: Components.ID("{e3f772f3-023f-4b32-b074-36cf0fd5d414}"),
 
   // Destruction
 
   _destroy: function CPS2__destroy() {
@@ -765,48 +777,47 @@ ContentPrefService2.prototype = {
    *                     reasonOK: reason == nsIContentPrefService2.COMPLETE_OK.
    *                     didGetRow: True if onRow was ever called.
    *                   onError(nsresult) (optional)
    *                     Called on error.
    *                     nsresult: The error code.
    */
   _execStmts: async function CPS2__execStmts(stmts, callbacks) {
     let conn = await this.conn;
+    let rows;
     let ok = true;
-    let gotRow = false;
-    let { onRow, onError } = callbacks;
-    await conn.executeTransaction(async () => {
-      for (let {sql, params, cachable} of stmts) {
+    try {
+      rows = await executeStatementsInTransaction(conn, stmts);
+    } catch (e) {
+      ok = false;
+      if (callbacks.onError) {
         try {
-          let execute = cachable ? conn.executeCached : conn.execute;
-          await execute.call(conn, sql, params, row => {
-            gotRow = true;
-            if (onRow) {
-              try {
-                onRow(row);
-              } catch (e) {
-                Cu.reportError(e);
-              }
-            }
-          });
+          callbacks.onError(e);
         } catch (e) {
-          try {
-            onError(Cr.NS_ERROR_FAILURE);
-          } catch (err) {
-            ok = false;
-            Cu.reportError(e);
-          }
+          Cu.reportError(e);
+        }
+      } else {
+        Cu.reportError(e);
+      }
+    }
+
+    if (rows && callbacks.onRow) {
+      for (let row of rows) {
+        try {
+          callbacks.onRow(row);
+        } catch (e) {
+          Cu.reportError(e);
         }
       }
-    });
+    }
 
     try {
       callbacks.onDone(ok ? Ci.nsIContentPrefCallback2.COMPLETE_OK :
                        Ci.nsIContentPrefCallback2.COMPLETE_ERROR,
-                       ok, gotRow);
+                       ok, rows && rows.length > 0);
     } catch (e) {
       Cu.reportError(e);
     }
   },
 
   __grouper: null,
   get _grouper() {
     if (!this.__grouper)