js/syncbase: Make RunInBatch work for readonly batches.

Change-Id: Ica9c8bb1317328ef40b05e2ebc06ad63adbc81fb
diff --git a/src/nosql/batch.js b/src/nosql/batch.js
index 15e9f3f..96c2f14 100644
--- a/src/nosql/batch.js
+++ b/src/nosql/batch.js
@@ -56,7 +56,7 @@
 /**
  * runInBatch runs a function with a newly created batch. If the function
  * errors, the batch is aborted. If the function succeeds, the batch is
- * committed.
+ * committed. A readonly batch is aborted either way.
  *
  * @param {module:vanadium.context.Context} ctx Vanadium context.
  * @param {module:syncbase.database.Database} db Database.
@@ -73,7 +73,7 @@
         return cb(err);
       }
       fn(batchDb, function(err) {
-        if (err) {
+        if (err || opts.readOnly) {
           return batchDb.abort(ctx, function() {
             return cb(err);  // return fn error, not abort error
           });
diff --git a/test/integration/test-run-in-batch.js b/test/integration/test-run-in-batch.js
index cc29d5a..f31786e 100644
--- a/test/integration/test-run-in-batch.js
+++ b/test/integration/test-run-in-batch.js
@@ -95,3 +95,22 @@
     t.end();
   });
 });
+
+test('runInBatch works with readonly batches', function(t) {
+  var ctx = {};
+  var db = new MockDb(true);
+
+  function willSucceed(db, cb) {
+    cb(null);
+  }
+
+  runInBatch(ctx, db, {readOnly: true}, willSucceed, function(err) {
+    t.notok(err, 'runInBatch should not return an error');
+
+    t.ok(db.batchDb, 'batch db is created');
+    t.notok(db.batchDb.commitCalled, 'batchDb.commit() was not called');
+    t.ok(db.batchDb.abortCalled, 'batchDb.abort() was called');
+
+    t.end();
+  });
+});