Finish switching over to new observe API in core packages and tests.

This commit is contained in:
Naomi Seyfer
2013-02-05 14:26:23 -08:00
parent dd459e10a3
commit 8b737a7e39
4 changed files with 64 additions and 87 deletions

View File

@@ -185,14 +185,13 @@ LocalCollection.LiveResultsSet = function () {};
// options to contain:
// * callbacks for observe():
// - added (object, before_index)
// - changed (new_object, at_index, old_object)
// - moved (object, old_index, new_index) - can only fire with changed()
// - removed (object, at_index)
// * callbacks for _observeUnordered():
// - added (object)
// - changed (new_object)
// - removed (object)
// - addedAt (document, atIndex)
// - added (document)
// - changedAt (newDocument, oldDocument, atIndex)
// - changed (newDocument, oldDocument)
// - removedAt (document, atIndex)
// - removed (document)
// - movedTo (document, oldIndex, newIndex)
//
// attributes available on returned query handle:
// * stop(): end updates
@@ -208,20 +207,12 @@ LocalCollection.LiveResultsSet = function () {};
_.extend(LocalCollection.Cursor.prototype, {
observe: function (options) {
var self = this;
return LocalCollection._observeOrdered(self, options);
return LocalCollection._observe(self, options);
},
_observeUnordered: function (options) {
observeChanges: function (options) {
var self = this;
return LocalCollection._observeUnordered(self, options);
},
observeChanges: function (callbacks) {
var self = this;
return self._observeInternal(typeof callbacks.addedBefore == 'function' || typeof callbacks.movedBefore === 'function',
_.extend({observeChanges: true}, callbacks));
},
_observeInternal: function (ordered, options) {
var self = this;
var ordered = typeof options.addedBefore == 'function' || typeof options.movedBefore === 'function';
if (!ordered && (self.skip || self.limit))
throw new Error("must use ordered observe with skip or limit");
@@ -779,49 +770,6 @@ if (typeof Meteor !== 'undefined') {
Meteor.idStringify = LocalCollection._idStringify;
}
LocalCollection._observeChanges = function (cursor, callbacks) {
var ordered = (typeof callbacks.addedBefore === 'function'
|| typeof callbacks.movedBefore === 'function');
var positions = ordered ? [] : null;
var observeMethod = _.bind(ordered ? cursor.observe : cursor._observeUnordered,
cursor);
return observeMethod ({
added: function (doc, ind) {
var fields = _.omit(doc, '_id');
if (ordered) {
var before = positions[ind];
if (before === undefined)
before = null;
positions.splice(ind, 0, doc._id);
callbacks.addedBefore &&
callbacks.addedBefore(doc._id, fields, before);
} else {
callbacks.added &&
callbacks.added(doc._id, fields);
}
},
changed: function (newDoc, indOrOldDoc, oldDoc) {
var id = newDoc._id;
if (typeof indOrOldDoc === 'object')
oldDoc = indOrOldDoc;
var fields = LocalCollection._makeChangedFields(newDoc, oldDoc);
if (!_.isEmpty(fields)) {
callbacks.changed && callbacks.changed(id, fields);
}
},
moved: function (doc, oldInd, newInd) {
positions.splice(oldInd, 1);
positions.splice(newInd, 0, doc._id);
callbacks.movedBefore && callbacks.movedBefore(doc._id, positions[newInd + 1]);
},
removed: function (doc) {
callbacks.removed && callbacks.removed(doc._id);
positions = _.without(positions, doc._id);
}
});
};
LocalCollection._makeChangedFields = function (newDoc, oldDoc) {
var fields = {};
LocalCollection._diffObjects(oldDoc, newDoc, {
@@ -839,6 +787,14 @@ LocalCollection._makeChangedFields = function (newDoc, oldDoc) {
return fields;
};
LocalCollection._observe = function (cursor, callbacks) {
if (callbacks.addedAt || callbacks.movedTo ||
callbacks.changedAt || callbacks.removedAt)
return LocalCollection._observeOrdered(cursor, callbacks);
else
return LocalCollection._observeUnordered(cursor, callbacks);
};
LocalCollection._observeUnordered = function (cursor, callbacks) {
var docs = {};
var suppressed = !!callbacks._suppress_initial;
@@ -878,32 +834,58 @@ LocalCollection._observeOrdered = function (cursor, callbacks) {
var doc = EJSON.clone(fields);
doc._id = id;
docs.putBefore(strId, doc, before ? LocalCollection._idStringify(before) : null);
var index = docs.indexOf(strId);
suppressed || callbacks.addedAt && callbacks.addedAt(EJSON.clone(doc), index);
if (!suppressed) {
if (callbacks.addedAt) {
var index = docs.indexOf(strId);
callbacks.addedAt(EJSON.clone(doc), index);
} else if (callbacks.added) {
callbacks.added(EJSON.clone(doc));
}
}
},
changed: function (id, fields) {
var strId = LocalCollection._idStringify(id);
var doc = docs.get(strId);
var oldDoc = EJSON.clone(doc);
var index = docs.indexOf(strId);
// writes through to the doc set
LocalCollection._applyChanges(doc, fields);
suppressed || callbacks.changedAt && callbacks.changedAt(EJSON.clone(doc), oldDoc, index);
if (!suppressed) {
if (callbacks.changedAt) {
var index = docs.indexOf(strId);
callbacks.changedAt(EJSON.clone(doc), oldDoc, index);
} else if (callbacks.changed) {
callbacks.changed(EJSON.clone(doc), oldDoc);
}
}
},
movedBefore: function (id, before) {
var strId = LocalCollection._idStringify(id);
var doc = docs.get(strId);
var from = docs.indexOf(strId);
var from;
// only capture indexes if we're going to call the callback that needs them.
if (!suppressed && callbacks.movedTo)
from = docs.indexOf(strId);
docs.moveBefore(strId, before ? LocalCollection._idStringify(before) : null);
var to = docs.indexOf(strId);
suppressed || callbacks.movedTo && callbacks.movedTo(EJSON.clone(doc), from, to);
if (!suppressed) {
if (callbacks.movedTo) {
var to = docs.indexOf(strId);
callbacks.movedTo(EJSON.clone(doc), from, to);
} else if (callbacks.moved) {
callbacks.moved(EJSON.clone(doc));
}
}
},
removed: function (id) {
var strId = LocalCollection._idStringify(id);
var doc = docs.get(strId);
var index = docs.indexOf(strId);
var index;
if (!suppressed && callbacks.removedAt)
index = docs.indexOf(strId);
docs.remove(strId);
suppressed || callbacks.removedAt && callbacks.removedAt(doc, index);
if (!suppressed) {
callbacks.removedAt && callbacks.removedAt(doc, index);
callbacks.removed && callbacks.removed(doc);
}
}
});
suppressed = false;

View File

@@ -1249,15 +1249,15 @@ Tinytest.add("minimongo - observe ordered", function (test) {
handle.stop();
});
_.each(['observe', '_observeUnordered'], function (observeMethod) {
Tinytest.add("minimongo - observe (" + observeMethod + ")", function (test) {
_.each([true, false], function (ordered) {
Tinytest.add("minimongo - observe ordered: " + ordered, function (test) {
var c = new LocalCollection();
var ev = "";
var makecb = function (tag) {
var ret = {};
_.each(["added", "changed", "removed"], function (fn) {
var fnName = observeMethod == "observe" ? fn + "At" : fn;
var fnName = ordered ? fn + "At" : fn;
ret[fnName] = function (doc) {
ev = (ev + fn.substr(0, 1) + tag + doc._id + "_");
};
@@ -1276,7 +1276,7 @@ _.each(['observe', '_observeUnordered'], function (observeMethod) {
// This should work equally well for ordered and unordered observations
// (because the callbacks don't look at indices and there's no 'moved'
// callback).
var handle = c.find({tags: "flower"})[observeMethod](makecb('a'));
var handle = c.find({tags: "flower"}).observe(makecb('a'));
expect("aa3_");
c.update({name: "rose"}, {$set: {tags: ["bloom", "red", "squishy"]}});
expect("ra3_");
@@ -1294,7 +1294,7 @@ _.each(['observe', '_observeUnordered'], function (observeMethod) {
expect("");
// Test that observing a lookup by ID works.
handle = c.find(4)[observeMethod](makecb('b'));
handle = c.find(4).observe(makecb('b'));
expect('ab4_');
c.update(4, {$set: {eek: 5}});
expect('cb4_');

View File

@@ -297,8 +297,8 @@ _Mongo.prototype._ensureIndex = function (collectionName, index, options) {
// SynchronousCursor (lazily: it doesn't contact Mongo until you call a method
// like fetch or forEach on it).
//
// ObserveHandle is the "observe handle" returned from observe and
// _observeUnordered. It has a reference to a LiveResultsSet.
// ObserveHandle is the "observe handle" returned from observe. It has a
// reference to a LiveResultsSet.
//
// LiveResultsSet caches the results of a query and reruns it when necessary.
// It is hooked up to one or more ObserveHandles; a single LiveResultsSet
@@ -364,12 +364,7 @@ Cursor.prototype._publishCursor = function (sub) {
Cursor.prototype.observe = function (callbacks) {
var self = this;
return LocalCollection._observeOrdered(self, callbacks);
};
Cursor.prototype._observeUnordered = function (callbacks) {
var self = this;
return LocalCollection._observeUnordered(self, callbacks);
return LocalCollection._observe(self, callbacks);
};
Cursor.prototype.observeChanges = function (callbacks) {

View File

@@ -366,7 +366,7 @@ Tinytest.addAsync("mongo-livedata - stop handle in callback, " + idGeneration, f
var output = [];
var handle = coll.find()._observeUnordered({
var handle = coll.find().observe({
added: function (doc) {
output.push({added: doc._id});
},
@@ -415,11 +415,11 @@ if (Meteor.isServer) {
var coll = new Meteor.Collection("observeInCallback-"+run, collectionOptions);
var callbackCalled = false;
var handle = coll.find()._observeUnordered({
var handle = coll.find().observe({
added: function (newDoc) {
callbackCalled = true;
test.throws(function () {
coll.find()._observeUnordered({});
coll.find().observe({});
});
}
});