Skip to content

Commit

Permalink
Merge pull request #652 from share/memory-db-delete-ops
Browse files Browse the repository at this point in the history
✅ Allow deleting ops in `MemoryDb`
  • Loading branch information
alecgibson authored May 16, 2024
2 parents 8dd68f3 + 8c949cd commit 33ee4c1
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 16 deletions.
20 changes: 17 additions & 3 deletions lib/db/memory.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,12 @@ MemoryDB.prototype.getOps = function(collection, id, from, to, options, callback
if (typeof callback !== 'function') throw new Error('Callback required');
util.nextTick(function() {
var opLog = db._getOpLogSync(collection, id);
if (to == null) {
to = opLog.length;
if (!from) from = 0;
if (to == null) to = opLog.length;
var ops = clone(opLog.slice(from, to).filter(Boolean));
if (ops.length < to - from) {
return callback(new Error('Missing ops'));
}
var ops = clone(opLog.slice(from, to));
if (!includeMetadata) {
for (var i = 0; i < ops.length; i++) {
delete ops[i].m;
Expand All @@ -97,6 +99,18 @@ MemoryDB.prototype.getOps = function(collection, id, from, to, options, callback
});
};

MemoryDB.prototype.deleteOps = function(collection, id, from, to, options, callback) {
if (typeof callback !== 'function') throw new Error('Callback required');
var db = this;
util.nextTick(function() {
var opLog = db._getOpLogSync(collection, id);
if (!from) from = 0;
if (to == null) to = opLog.length;
for (var i = from; i < to; i++) opLog[i] = null;
callback(null);
});
};

// The memory database query function returns all documents in a collection
// regardless of query by default
MemoryDB.prototype.query = function(collection, query, fields, options, callback) {
Expand Down
13 changes: 12 additions & 1 deletion test/client/snapshot-version-request.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,18 @@ describe('SnapshotVersionRequest', function() {

it('errors if asking for a version that does not exist', function(done) {
backend.connect().fetchSnapshot('books', 'don-quixote', 4, function(error, snapshot) {
expect(error.code).to.equal('ERR_OP_VERSION_NEWER_THAN_CURRENT_SNAPSHOT');
expect(error).to.be.ok;
expect(snapshot).to.equal(undefined);
done();
});
});

it('errors if asking for a version that does not exist if the DB adapter does not error', function(done) {
sinon.stub(MemoryDb.prototype, 'getOps').callsFake(function(collection, id, from, to, options, callback) {
callback(null, []);
});
backend.connect().fetchSnapshot('books', 'don-quixote', 4, function(error, snapshot) {
expect(error).to.be.ok;
expect(snapshot).to.equal(undefined);
done();
});
Expand Down
92 changes: 80 additions & 12 deletions test/db-memory.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
var expect = require('chai').expect;
var Backend = require('../lib/backend');
var DB = require('../lib/db');
var BasicQueryableMemoryDB = require('./BasicQueryableMemoryDB');
var async = require('async');

describe('DB base class', function() {
it('can call db.close() without callback', function() {
Expand Down Expand Up @@ -54,17 +56,83 @@ describe('DB base class', function() {
});
});

// Run all the DB-based tests against the BasicQueryableMemoryDB.
require('./db')({
create: function(options, callback) {
if (typeof options === 'function') {
callback = options;
options = null;
describe('MemoryDB', function() {
// Run all the DB-based tests against the BasicQueryableMemoryDB.
require('./db')({
create: function(options, callback) {
if (typeof options === 'function') {
callback = options;
options = null;
}
var db = new BasicQueryableMemoryDB(options);
callback(null, db);
},
getQuery: function(options) {
return {filter: options.query, sort: options.sort};
}
var db = new BasicQueryableMemoryDB(options);
callback(null, db);
},
getQuery: function(options) {
return {filter: options.query, sort: options.sort};
}
});

describe('deleteOps', function() {
describe('with some ops', function() {
var backend;
var db;
var connection;
var doc;

beforeEach(function(done) {
backend = new Backend();
db = backend.db;
connection = backend.connect();
doc = connection.get('dogs', 'fido');

async.waterfall([
doc.create.bind(doc, {name: 'Fido'}),
doc.submitOp.bind(doc, [{p: ['tricks'], oi: ['fetch']}]),
db.getOps.bind(db, 'dogs', 'fido', null, null, null),
function(ops, next) {
expect(ops).to.have.length(2);
next();
}
], done);
});

it('deletes all ops', function(done) {
async.waterfall([
db.deleteOps.bind(db, 'dogs', 'fido', null, null, null),
function(next) {
db.getOps('dogs', 'fido', null, null, null, function(error) {
expect(error.message).to.equal('Missing ops');
next();
});
}
], done);
});

it('deletes some ops', function(done) {
async.waterfall([
db.deleteOps.bind(db, 'dogs', 'fido', 0, 1, null),
db.getOps.bind(db, 'dogs', 'fido', 1, 2, null),
function(ops, next) {
expect(ops).to.have.length(1);
expect(ops[0].op).to.eql([{p: ['tricks'], oi: ['fetch']}]);
db.getOps('dogs', 'fido', 0, 1, null, function(error) {
expect(error.message).to.equal('Missing ops');
next();
});
}
], done);
});

it('submits more ops after deleting ops', function(done) {
async.series([
db.deleteOps.bind(db, 'dogs', 'fido', null, null, null),
doc.submitOp.bind(doc, [{p: ['tricks', 1], li: 'sit'}]),
function(next) {
expect(doc.data.tricks).to.eql(['fetch', 'sit']);
next();
}
], done);
});
});
});
});

0 comments on commit 33ee4c1

Please sign in to comment.