From 111de8d803ac416f392ab350975f13dcb593eaf4 Mon Sep 17 00:00:00 2001 From: Slava Kim Date: Mon, 28 Oct 2013 14:45:29 -0700 Subject: [PATCH] Oplog observe handles 'drop collection' or db.c.drop() --- packages/mongo-livedata/mongo_driver.js | 11 +++++++++-- packages/mongo-livedata/oplog.js | 15 ++++++++++++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/packages/mongo-livedata/mongo_driver.js b/packages/mongo-livedata/mongo_driver.js index b749682988..a9f549f923 100644 --- a/packages/mongo-livedata/mongo_driver.js +++ b/packages/mongo-livedata/mongo_driver.js @@ -258,8 +258,10 @@ MongoConnection.prototype._startOplogTailing = function (oplogUrl, var baseOplogSelector = _.once(function () { return { ns: new RegExp('^' + quotemeta(dbNameFuture.wait()) + '\\.'), - // XXX also handle drop collection, etc - op: {$in: ['i', 'u', 'd']} + $or: [ + { op: {$in: ['i', 'u', 'd']} }, + // If it is not db.collection.drop(), ignore it + { op: 'c', 'o.drop': { $exists: true } }] }; }); // XXX doc @@ -403,6 +405,11 @@ MongoConnection.prototype._startOplogTailing = function (oplogUrl, var collectionName = doc.ns.substr(dbName.length + 1); + // Is it a special command and the collection name is hidden somewhere in + // operator? + if (collectionName === "$cmd") + collectionName = doc.o.drop; + _.each(callbacksByCollection[collectionName], function (callback) { callback(EJSON.clone(doc)); }); diff --git a/packages/mongo-livedata/oplog.js b/packages/mongo-livedata/oplog.js index 07706cd1dd..163e01590b 100644 --- a/packages/mongo-livedata/oplog.js +++ b/packages/mongo-livedata/oplog.js @@ -14,6 +14,9 @@ var idForOp = function (op) { return op.o._id; else if (op.op === 'u') return op.o2._id; + else if (op.op === 'c') + throw Error("Operator 'c' doesn't supply an object with id: " + + EJSON.stringify(op)); else throw Error("Unknown op: " + EJSON.stringify(op)); }; @@ -192,7 +195,17 @@ MongoConnection.prototype._observeChangesWithOplog = function ( var oplogEntryHandle = self._oplogHandle.onOplogEntry( cursorDescription.collectionName, function (op) { - oplogEntryHandlers[phase](op); + if (op.op === 'c') { + // If it is not db.collection.drop(), ignore it + if (op.o && _.isEqual(_.keys(op.o), ['drop'])) { + published.each(function (fields, id) { + remove(id); + }); + } + } else { + // All other operators should be handled depending on phase + oplogEntryHandlers[phase](op); + } } );