Skip to content

Commit 33ee4c1

Browse files
authored
Merge pull request #652 from share/memory-db-delete-ops
✅ Allow deleting ops in `MemoryDb`
2 parents 8dd68f3 + 8c949cd commit 33ee4c1

File tree

3 files changed

+109
-16
lines changed

3 files changed

+109
-16
lines changed

lib/db/memory.js

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,12 @@ MemoryDB.prototype.getOps = function(collection, id, from, to, options, callback
8484
if (typeof callback !== 'function') throw new Error('Callback required');
8585
util.nextTick(function() {
8686
var opLog = db._getOpLogSync(collection, id);
87-
if (to == null) {
88-
to = opLog.length;
87+
if (!from) from = 0;
88+
if (to == null) to = opLog.length;
89+
var ops = clone(opLog.slice(from, to).filter(Boolean));
90+
if (ops.length < to - from) {
91+
return callback(new Error('Missing ops'));
8992
}
90-
var ops = clone(opLog.slice(from, to));
9193
if (!includeMetadata) {
9294
for (var i = 0; i < ops.length; i++) {
9395
delete ops[i].m;
@@ -97,6 +99,18 @@ MemoryDB.prototype.getOps = function(collection, id, from, to, options, callback
9799
});
98100
};
99101

102+
MemoryDB.prototype.deleteOps = function(collection, id, from, to, options, callback) {
103+
if (typeof callback !== 'function') throw new Error('Callback required');
104+
var db = this;
105+
util.nextTick(function() {
106+
var opLog = db._getOpLogSync(collection, id);
107+
if (!from) from = 0;
108+
if (to == null) to = opLog.length;
109+
for (var i = from; i < to; i++) opLog[i] = null;
110+
callback(null);
111+
});
112+
};
113+
100114
// The memory database query function returns all documents in a collection
101115
// regardless of query by default
102116
MemoryDB.prototype.query = function(collection, query, fields, options, callback) {

test/client/snapshot-version-request.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,18 @@ describe('SnapshotVersionRequest', function() {
145145

146146
it('errors if asking for a version that does not exist', function(done) {
147147
backend.connect().fetchSnapshot('books', 'don-quixote', 4, function(error, snapshot) {
148-
expect(error.code).to.equal('ERR_OP_VERSION_NEWER_THAN_CURRENT_SNAPSHOT');
148+
expect(error).to.be.ok;
149+
expect(snapshot).to.equal(undefined);
150+
done();
151+
});
152+
});
153+
154+
it('errors if asking for a version that does not exist if the DB adapter does not error', function(done) {
155+
sinon.stub(MemoryDb.prototype, 'getOps').callsFake(function(collection, id, from, to, options, callback) {
156+
callback(null, []);
157+
});
158+
backend.connect().fetchSnapshot('books', 'don-quixote', 4, function(error, snapshot) {
159+
expect(error).to.be.ok;
149160
expect(snapshot).to.equal(undefined);
150161
done();
151162
});

test/db-memory.js

Lines changed: 80 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
var expect = require('chai').expect;
2+
var Backend = require('../lib/backend');
23
var DB = require('../lib/db');
34
var BasicQueryableMemoryDB = require('./BasicQueryableMemoryDB');
5+
var async = require('async');
46

57
describe('DB base class', function() {
68
it('can call db.close() without callback', function() {
@@ -54,17 +56,83 @@ describe('DB base class', function() {
5456
});
5557
});
5658

57-
// Run all the DB-based tests against the BasicQueryableMemoryDB.
58-
require('./db')({
59-
create: function(options, callback) {
60-
if (typeof options === 'function') {
61-
callback = options;
62-
options = null;
59+
describe('MemoryDB', function() {
60+
// Run all the DB-based tests against the BasicQueryableMemoryDB.
61+
require('./db')({
62+
create: function(options, callback) {
63+
if (typeof options === 'function') {
64+
callback = options;
65+
options = null;
66+
}
67+
var db = new BasicQueryableMemoryDB(options);
68+
callback(null, db);
69+
},
70+
getQuery: function(options) {
71+
return {filter: options.query, sort: options.sort};
6372
}
64-
var db = new BasicQueryableMemoryDB(options);
65-
callback(null, db);
66-
},
67-
getQuery: function(options) {
68-
return {filter: options.query, sort: options.sort};
69-
}
73+
});
74+
75+
describe('deleteOps', function() {
76+
describe('with some ops', function() {
77+
var backend;
78+
var db;
79+
var connection;
80+
var doc;
81+
82+
beforeEach(function(done) {
83+
backend = new Backend();
84+
db = backend.db;
85+
connection = backend.connect();
86+
doc = connection.get('dogs', 'fido');
87+
88+
async.waterfall([
89+
doc.create.bind(doc, {name: 'Fido'}),
90+
doc.submitOp.bind(doc, [{p: ['tricks'], oi: ['fetch']}]),
91+
db.getOps.bind(db, 'dogs', 'fido', null, null, null),
92+
function(ops, next) {
93+
expect(ops).to.have.length(2);
94+
next();
95+
}
96+
], done);
97+
});
98+
99+
it('deletes all ops', function(done) {
100+
async.waterfall([
101+
db.deleteOps.bind(db, 'dogs', 'fido', null, null, null),
102+
function(next) {
103+
db.getOps('dogs', 'fido', null, null, null, function(error) {
104+
expect(error.message).to.equal('Missing ops');
105+
next();
106+
});
107+
}
108+
], done);
109+
});
110+
111+
it('deletes some ops', function(done) {
112+
async.waterfall([
113+
db.deleteOps.bind(db, 'dogs', 'fido', 0, 1, null),
114+
db.getOps.bind(db, 'dogs', 'fido', 1, 2, null),
115+
function(ops, next) {
116+
expect(ops).to.have.length(1);
117+
expect(ops[0].op).to.eql([{p: ['tricks'], oi: ['fetch']}]);
118+
db.getOps('dogs', 'fido', 0, 1, null, function(error) {
119+
expect(error.message).to.equal('Missing ops');
120+
next();
121+
});
122+
}
123+
], done);
124+
});
125+
126+
it('submits more ops after deleting ops', function(done) {
127+
async.series([
128+
db.deleteOps.bind(db, 'dogs', 'fido', null, null, null),
129+
doc.submitOp.bind(doc, [{p: ['tricks', 1], li: 'sit'}]),
130+
function(next) {
131+
expect(doc.data.tricks).to.eql(['fetch', 'sit']);
132+
next();
133+
}
134+
], done);
135+
});
136+
});
137+
});
70138
});

0 commit comments

Comments
 (0)