Patching up batch JS deficiencies and adding tests
Change-Id: Iea1e49bc2b9986c147a3c3e69c92967b54555504
diff --git a/src/nosql/batch-database.js b/src/nosql/batch-database.js
index 2329dde..ad017a1 100644
--- a/src/nosql/batch-database.js
+++ b/src/nosql/batch-database.js
@@ -81,5 +81,14 @@
* @returns {stream} Stream of rows.
*/
BatchDatabase.prototype.exec = function(ctx, query, cb) {
- this._db.exec(ctx, query, cb);
+ return this._db.exec(ctx, query, cb);
+};
+
+/**
+ * Gets the ResumeMarker that points to the current end of the event log.
+ * @param {module:vanadium.context.Context} ctx Vanadium context.
+ * @param {function} cb Callback.
+ */
+BatchDatabase.prototype.getResumeMarker = function(ctx, cb) {
+ this._db.getResumeMarker(ctx, cb);
};
diff --git a/test/integration/test-batch.js b/test/integration/test-batch.js
index c7e0b32..7093571 100644
--- a/test/integration/test-batch.js
+++ b/test/integration/test-batch.js
@@ -14,6 +14,7 @@
var testUtil = require('./util');
var assertScanRows = testUtil.assertScanRows;
+var assertSelectRows = testUtil.assertSelectRows;
var setupDatabase = testUtil.setupDatabase;
var setupTable = testUtil.setupTable;
var uniqueName = testUtil.uniqueName;
@@ -213,7 +214,7 @@
});
});
-test('readonly batches', function(t) {
+test('read-only batches', function(t) {
setupTable(t, function(err, o) {
if (err) {
return t.end(err);
@@ -267,10 +268,37 @@
function attemptBatchDeleteRow() {
batchTable.row(key).delete(ctx, function(err) {
assertReadOnlyBatchError(err);
- end();
+ batch.getResumeMarker(ctx, assertBatchResumeMarker);
});
}
+ function assertBatchResumeMarker(err, r) {
+ if (err) {
+ return end(err);
+ }
+ t.ok(r, 'should return a resume marker');
+
+ assertBatchScan();
+ }
+
+ var wantRows = [{
+ key: key,
+ value: value
+ }];
+
+ function assertBatchScan() {
+ assertScanRows(ctx, batchTable, range.prefix(''), wantRows,
+ assertBatchSelect);
+ }
+
+ function assertBatchSelect(err) {
+ if (err) {
+ return end(err);
+ }
+
+ assertSelectRows(ctx, batch, batchTable, '', wantRows, end);
+ }
+
function end(err) {
t.error(err);
o.teardown(t.end);
diff --git a/test/integration/util.js b/test/integration/util.js
index fecaa4b..954a92b 100644
--- a/test/integration/util.js
+++ b/test/integration/util.js
@@ -10,6 +10,7 @@
setupTable: setupTable,
assertScanRows: assertScanRows,
+ assertSelectRows: assertSelectRows,
testGetSetPermissions: testGetSetPermissions,
uniqueName: uniqueName
};
@@ -235,6 +236,25 @@
return 0;
}
+function assertRows(err, rows, wantRows, cb) {
+ if (err) {
+ return cb(err);
+ }
+
+ rows = rows || [];
+
+ rows.sort(compareRows);
+ wantRows.sort(compareRows);
+
+ if (!deepEqual(rows, wantRows)) {
+ var error = new Error('Expected rows to be ' + JSON.stringify(wantRows) +
+ ' but got ' + JSON.stringify(rows));
+ return cb(error);
+ }
+
+ return cb(null);
+}
+
function assertScanRows(ctx, table, range, wantRows, cb) {
var stream = table.scan(ctx, range, function(err) {
if (err) {
@@ -243,21 +263,27 @@
});
streamToArray(stream, function(err, rows) {
- if (err) {
- return cb(err);
+ assertRows(err, rows, wantRows, cb);
+ });
+}
+
+function assertSelectRows(ctx, db, table, prefix, wantRows, cb) {
+ var query = 'select k, v from ' + table.name;
+ if (prefix) {
+ query += ' where k like "' + prefix + '%"';
+ }
+ var isHeader = true;
+ var rows = [];
+ var streamErr;
+ db.exec(ctx, query, function(err) {
+ assertRows(streamErr || err, rows, wantRows, cb);
+ }).on('data', function(row) {
+ if (isHeader) {
+ isHeader = false;
+ } else {
+ rows.push({ key: row[0], value: row[1] });
}
-
- rows = rows || [];
-
- rows.sort(compareRows);
- wantRows.sort(compareRows);
-
- if (!deepEqual(rows, wantRows)) {
- var error = new Error('Expected rows to be ' + JSON.stringify(wantRows) +
- ' but got ' + JSON.stringify(rows));
- return cb(error);
- }
-
- cb(null);
+ }).on('error', function(err) {
+ streamErr = streamErr || err;
});
}