mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
rename minimongo Collection => LocalCollection
This commit is contained in:
@@ -18,7 +18,7 @@ Meteor.Server = function (url) {
|
||||
self.unsatisfied_methods = {}; // map from method_id -> true
|
||||
self.pending_data = []; // array of pending data messages
|
||||
|
||||
self.subs = new Collection;
|
||||
self.subs = new LocalCollection;
|
||||
// keyed by subs._id. value is unset or an array. if set, sub is not
|
||||
// yet ready.
|
||||
self.sub_ready_callbacks = {};
|
||||
@@ -133,7 +133,7 @@ _.extend(Meteor.Server.prototype, {
|
||||
} else {
|
||||
// new sub, add object.
|
||||
// generate our own id so we can know it w/ a find afterwards.
|
||||
id = Collection.uuid();
|
||||
id = LocalCollection.uuid();
|
||||
self.subs.insert({_id: id, name: name, args: args, count: 1});
|
||||
|
||||
self.sub_ready_callbacks[id] = [];
|
||||
@@ -317,7 +317,7 @@ Meteor._Collection = function (name, server) {
|
||||
throw new Error("There is already a remote collection '" + name + "'");
|
||||
|
||||
self._name = name;
|
||||
self._collection = new Collection;
|
||||
self._collection = new LocalCollection;
|
||||
self._server = server;
|
||||
self._was_snapshot = false;
|
||||
|
||||
@@ -359,7 +359,7 @@ _.extend(Meteor._Collection.prototype, {
|
||||
if (_.keys(obj).length === 0)
|
||||
Meteor._debug("WARNING: inserting empty object.");
|
||||
|
||||
var _id = Collection.uuid();
|
||||
var _id = LocalCollection.uuid();
|
||||
obj._id = _id;
|
||||
|
||||
if (self._name) {
|
||||
|
||||
@@ -169,7 +169,7 @@ Meteor.ui.renderList = function (query, options) {
|
||||
// protect against old invocations passing in a Collection or a
|
||||
// LiveResultsSet.
|
||||
// XXX remove in a few releases
|
||||
if (!(query instanceof Collection.Cursor))
|
||||
if (!(query instanceof LocalCollection.Cursor))
|
||||
throw new Error("insert_before: at least one entry must exist");
|
||||
|
||||
// create the top-level document fragment/range that will be
|
||||
|
||||
@@ -347,7 +347,7 @@ test("render - events", function () {
|
||||
});
|
||||
|
||||
test("renderList - basics", function () {
|
||||
var c = new Collection();
|
||||
var c = new LocalCollection();
|
||||
|
||||
var r = Meteor.ui.renderList(c.find({}, {sort: ['id']}), {
|
||||
render: function (doc) {
|
||||
@@ -413,7 +413,7 @@ test("renderList - basics", function () {
|
||||
});
|
||||
|
||||
test("renderList - removal", function () {
|
||||
var c = new Collection();
|
||||
var c = new LocalCollection();
|
||||
// (test is written in this weird way for historical reasons; feel
|
||||
// free to refactor)
|
||||
c.insert({id: "D"});
|
||||
@@ -475,7 +475,7 @@ test("renderList - removal", function () {
|
||||
});
|
||||
|
||||
test("renderList - default render empty", function () {
|
||||
var c = new Collection();
|
||||
var c = new LocalCollection();
|
||||
|
||||
var r = Meteor.ui.renderList(c.find({}, {sort: ['id']}), {
|
||||
render: function (doc) {
|
||||
@@ -491,7 +491,7 @@ test("renderList - default render empty", function () {
|
||||
});
|
||||
|
||||
test("renderList - change and move", function () {
|
||||
var c = new Collection();
|
||||
var c = new LocalCollection();
|
||||
|
||||
var r = Meteor.ui.renderList(c.find({}, {sort: ['id']}), {
|
||||
render: function (doc) {
|
||||
@@ -523,7 +523,7 @@ test("renderList - change and move", function () {
|
||||
});
|
||||
|
||||
test("renderList - termination", function () {
|
||||
var c = new Collection();
|
||||
var c = new LocalCollection();
|
||||
|
||||
var r = Meteor.ui.renderList(c.find({}, {sort: ['id']}), {
|
||||
render: function (doc) {
|
||||
@@ -614,7 +614,7 @@ test("renderList - termination", function () {
|
||||
});
|
||||
|
||||
test("renderList - list items are reactive", function () {
|
||||
var c = new Collection();
|
||||
var c = new LocalCollection();
|
||||
|
||||
set_weather("here", "cloudy");
|
||||
set_weather("there", "cloudy");
|
||||
@@ -737,7 +737,7 @@ test("renderList - list items are reactive", function () {
|
||||
});
|
||||
|
||||
test("renderList - multiple elements in an item", function () {
|
||||
var c = new Collection();
|
||||
var c = new LocalCollection();
|
||||
var r;
|
||||
|
||||
var lengths = [];
|
||||
@@ -833,7 +833,7 @@ test("renderList - multiple elements in an item", function () {
|
||||
});
|
||||
|
||||
test("renderList - #each", function () {
|
||||
var c = new Collection();
|
||||
var c = new LocalCollection();
|
||||
|
||||
var render_count = 0;
|
||||
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
// XXX type checking on selectors (graceful error if malformed)
|
||||
// XXX merge ad-hoc live query object and Cursor
|
||||
|
||||
// Collection: a set of documents that supports queries and modifiers.
|
||||
// LocalCollection: a set of documents that supports queries and modifiers.
|
||||
|
||||
// Cursor: a specification for a particular subset of documents, w/
|
||||
// a defined order, limit, and offset. creating a Cursor with Collection.find(),
|
||||
// a defined order, limit, and offset. creating a Cursor with LocalCollection.find(),
|
||||
|
||||
// LiveResultsSet: the return value of a live query.
|
||||
|
||||
Collection = function () {
|
||||
LocalCollection = function () {
|
||||
this.docs = {}; // _id -> document (also containing id)
|
||||
|
||||
this.next_qid = 1; // live query id generator
|
||||
@@ -39,18 +39,18 @@ Collection = function () {
|
||||
// XXX sort does not yet support subkeys ('a.b') .. fix that!
|
||||
// XXX add one more sort form: "key"
|
||||
// XXX tests
|
||||
Collection.prototype.find = function (selector, options) {
|
||||
LocalCollection.prototype.find = function (selector, options) {
|
||||
// default syntax for everything is to omit the selector argument.
|
||||
// but if selector is explicitly passed in as false or undefined, we
|
||||
// want a selector that matches nothing.
|
||||
if (arguments.length === 0)
|
||||
selector = {};
|
||||
|
||||
return new Collection.Cursor(this, selector, options);
|
||||
return new LocalCollection.Cursor(this, selector, options);
|
||||
};
|
||||
|
||||
// don't call this ctor directly. use Collection.find().
|
||||
Collection.Cursor = function (collection, selector, options) {
|
||||
// don't call this ctor directly. use LocalCollection.find().
|
||||
LocalCollection.Cursor = function (collection, selector, options) {
|
||||
if (!options) options = {};
|
||||
|
||||
this.collection = collection;
|
||||
@@ -58,10 +58,10 @@ Collection.Cursor = function (collection, selector, options) {
|
||||
if ((typeof selector === "string") || (typeof selector === "number")) {
|
||||
// stash for fast path
|
||||
this.selector_id = selector;
|
||||
this.selector_f = Collection._compileSelector(selector);
|
||||
this.selector_f = LocalCollection._compileSelector(selector);
|
||||
} else {
|
||||
this.selector_f = Collection._compileSelector(selector);
|
||||
this.sort_f = options.sort ? Collection._compileSort(options.sort) : null;
|
||||
this.selector_f = LocalCollection._compileSelector(selector);
|
||||
this.sort_f = options.sort ? LocalCollection._compileSort(options.sort) : null;
|
||||
this.skip = options.skip;
|
||||
this.limit = options.limit;
|
||||
}
|
||||
@@ -74,13 +74,13 @@ Collection.Cursor = function (collection, selector, options) {
|
||||
this.reactive = (options.reactive === undefined) ? true : options.reactive;
|
||||
};
|
||||
|
||||
Collection.Cursor.prototype.rewind = function () {
|
||||
LocalCollection.Cursor.prototype.rewind = function () {
|
||||
var self = this;
|
||||
self.db_objects = null;
|
||||
self.cursor_pos = 0;
|
||||
};
|
||||
|
||||
Collection.prototype.findOne = function (selector, options) {
|
||||
LocalCollection.prototype.findOne = function (selector, options) {
|
||||
if (arguments.length === 0)
|
||||
selector = {};
|
||||
|
||||
@@ -91,7 +91,7 @@ Collection.prototype.findOne = function (selector, options) {
|
||||
return this.find(selector, options).fetch()[0];
|
||||
};
|
||||
|
||||
Collection.Cursor.prototype.forEach = function (callback) {
|
||||
LocalCollection.Cursor.prototype.forEach = function (callback) {
|
||||
var self = this;
|
||||
var doc;
|
||||
|
||||
@@ -105,10 +105,10 @@ Collection.Cursor.prototype.forEach = function (callback) {
|
||||
moved: true});
|
||||
|
||||
while (self.cursor_pos < self.db_objects.length)
|
||||
callback(Collection._deepcopy(self.db_objects[self.cursor_pos++]));
|
||||
callback(LocalCollection._deepcopy(self.db_objects[self.cursor_pos++]));
|
||||
};
|
||||
|
||||
Collection.Cursor.prototype.map = function (callback) {
|
||||
LocalCollection.Cursor.prototype.map = function (callback) {
|
||||
var self = this;
|
||||
var res = [];
|
||||
self.forEach(function (doc) {
|
||||
@@ -117,7 +117,7 @@ Collection.Cursor.prototype.map = function (callback) {
|
||||
return res;
|
||||
};
|
||||
|
||||
Collection.Cursor.prototype.fetch = function () {
|
||||
LocalCollection.Cursor.prototype.fetch = function () {
|
||||
var self = this;
|
||||
var res = [];
|
||||
self.forEach(function (doc) {
|
||||
@@ -126,7 +126,7 @@ Collection.Cursor.prototype.fetch = function () {
|
||||
return res;
|
||||
};
|
||||
|
||||
Collection.Cursor.prototype.count = function () {
|
||||
LocalCollection.Cursor.prototype.count = function () {
|
||||
var self = this;
|
||||
|
||||
if (self.reactive)
|
||||
@@ -139,7 +139,7 @@ Collection.Cursor.prototype.count = function () {
|
||||
};
|
||||
|
||||
// the handle that comes back from observe.
|
||||
Collection.LiveResultsSet = function () {};
|
||||
LocalCollection.LiveResultsSet = function () {};
|
||||
|
||||
// options to contain:
|
||||
// * callbacks:
|
||||
@@ -155,7 +155,7 @@ Collection.LiveResultsSet = function () {};
|
||||
// * collection: the collection this query is querying
|
||||
//
|
||||
// iff x is a returned query handle, (x instanceof
|
||||
// Collection.LiveResultsSet) is true
|
||||
// LocalCollection.LiveResultsSet) is true
|
||||
//
|
||||
// initial results delivered through added callback
|
||||
// XXX maybe callbacks should take a list of objects, to expose transactions?
|
||||
@@ -165,7 +165,7 @@ Collection.LiveResultsSet = function () {};
|
||||
// query, not just its id
|
||||
// XXX document that initial results will definitely be delivered before we return [do, add to asana]
|
||||
|
||||
Collection.Cursor.prototype.observe = function (options) {
|
||||
LocalCollection.Cursor.prototype.observe = function (options) {
|
||||
var self = this;
|
||||
|
||||
if (self.skip || self.limit)
|
||||
@@ -188,9 +188,9 @@ Collection.Cursor.prototype.observe = function (options) {
|
||||
query.removed = options.removed || function () {};
|
||||
if (!options._suppress_initial)
|
||||
for (var i = 0; i < query.results.length; i++)
|
||||
query.added(Collection._deepcopy(query.results[i]), i);
|
||||
query.added(LocalCollection._deepcopy(query.results[i]), i);
|
||||
|
||||
var handle = new Collection.LiveResultsSet;
|
||||
var handle = new LocalCollection.LiveResultsSet;
|
||||
_.extend(handle, {
|
||||
collection: self.collection,
|
||||
stop: function () {
|
||||
@@ -203,7 +203,7 @@ Collection.Cursor.prototype.observe = function (options) {
|
||||
// constructs sorted array of matching objects, but doesn't copy them.
|
||||
// respects sort, skip, and limit properties of the query.
|
||||
// if sort_f is falsey, no sort -- you get the natural order
|
||||
Collection.Cursor.prototype._getRawObjects = function () {
|
||||
LocalCollection.Cursor.prototype._getRawObjects = function () {
|
||||
var self = this;
|
||||
|
||||
// fast path for single ID value
|
||||
@@ -226,7 +226,7 @@ Collection.Cursor.prototype._getRawObjects = function () {
|
||||
return results.slice(idx_start, idx_end);
|
||||
};
|
||||
|
||||
Collection.Cursor.prototype._markAsReactive = function (options) {
|
||||
LocalCollection.Cursor.prototype._markAsReactive = function (options) {
|
||||
var self = this;
|
||||
|
||||
var context = Meteor.deps.Context.current;
|
||||
@@ -252,12 +252,12 @@ Collection.Cursor.prototype._markAsReactive = function (options) {
|
||||
// (real mongodb does in fact enforce this)
|
||||
// XXX possibly enforce that 'undefined' does not appear (we assume
|
||||
// this in our handling of null and $exists)
|
||||
Collection.prototype.insert = function (doc) {
|
||||
LocalCollection.prototype.insert = function (doc) {
|
||||
var self = this;
|
||||
doc = Collection._deepcopy(doc);
|
||||
doc = LocalCollection._deepcopy(doc);
|
||||
// XXX deal with mongo's binary id type?
|
||||
if (!('_id' in doc))
|
||||
doc._id = Collection.uuid();
|
||||
doc._id = LocalCollection.uuid();
|
||||
// XXX check to see that there is no object with this _id yet?
|
||||
self.docs[doc._id] = doc;
|
||||
|
||||
@@ -265,11 +265,11 @@ Collection.prototype.insert = function (doc) {
|
||||
for (var qid in self.queries) {
|
||||
var query = self.queries[qid];
|
||||
if (query.selector_f(doc))
|
||||
Collection._insertInResults(query, doc);
|
||||
LocalCollection._insertInResults(query, doc);
|
||||
}
|
||||
};
|
||||
|
||||
Collection.prototype.remove = function (selector) {
|
||||
LocalCollection.prototype.remove = function (selector) {
|
||||
var self = this;
|
||||
var remove = [];
|
||||
var query_remove = [];
|
||||
@@ -277,7 +277,7 @@ Collection.prototype.remove = function (selector) {
|
||||
if (arguments.length === 0)
|
||||
selector = {};
|
||||
|
||||
var selector_f = Collection._compileSelector(selector);
|
||||
var selector_f = LocalCollection._compileSelector(selector);
|
||||
for (var id in self.docs) {
|
||||
var doc = self.docs[id];
|
||||
if (selector_f(doc)) {
|
||||
@@ -295,18 +295,18 @@ Collection.prototype.remove = function (selector) {
|
||||
|
||||
// run live query callbacks _after_ we've removed the documents.
|
||||
for (var i = 0; i < query_remove.length; i++) {
|
||||
Collection._removeFromResults(query_remove[i][0], query_remove[i][1]);
|
||||
LocalCollection._removeFromResults(query_remove[i][0], query_remove[i][1]);
|
||||
}
|
||||
};
|
||||
|
||||
// XXX atomicity: if multi is true, and one modification fails, do
|
||||
// we rollback the whole operation, or what?
|
||||
Collection.prototype.update = function (selector, mod, options) {
|
||||
LocalCollection.prototype.update = function (selector, mod, options) {
|
||||
if (!options) options = {};
|
||||
|
||||
var self = this;
|
||||
var any = false;
|
||||
var selector_f = Collection._compileSelector(selector);
|
||||
var selector_f = LocalCollection._compileSelector(selector);
|
||||
for (var id in self.docs) {
|
||||
var doc = self.docs[id];
|
||||
if (selector_f(doc)) {
|
||||
@@ -324,37 +324,37 @@ Collection.prototype.update = function (selector, mod, options) {
|
||||
if (options.upsert && !any) {
|
||||
// XXX is this actually right? don't we have to resolve/delete
|
||||
// $-ops or something like that?
|
||||
insert = Collection._deepcopy(selector);
|
||||
Collection._modify(insert, mod);
|
||||
insert = LocalCollection._deepcopy(selector);
|
||||
LocalCollection._modify(insert, mod);
|
||||
self.insert(insert);
|
||||
}
|
||||
};
|
||||
|
||||
Collection.prototype._modifyAndNotify = function (doc, mod) {
|
||||
LocalCollection.prototype._modifyAndNotify = function (doc, mod) {
|
||||
var self = this;
|
||||
|
||||
var matched_before = {};
|
||||
for (var qid in self.queries)
|
||||
matched_before[qid] = self.queries[qid].selector_f(doc);
|
||||
|
||||
Collection._modify(doc, mod);
|
||||
LocalCollection._modify(doc, mod);
|
||||
|
||||
for (var qid in self.queries) {
|
||||
var query = self.queries[qid];
|
||||
var before = matched_before[qid];
|
||||
var after = query.selector_f(doc);
|
||||
if (before && !after)
|
||||
Collection._removeFromResults(query, doc);
|
||||
LocalCollection._removeFromResults(query, doc);
|
||||
else if (!before && after)
|
||||
Collection._insertInResults(query, doc);
|
||||
LocalCollection._insertInResults(query, doc);
|
||||
else if (before && after)
|
||||
Collection._updateInResults(query, doc);
|
||||
LocalCollection._updateInResults(query, doc);
|
||||
}
|
||||
};
|
||||
|
||||
// XXX findandmodify
|
||||
|
||||
Collection._deepcopy = function (v) {
|
||||
LocalCollection._deepcopy = function (v) {
|
||||
if (typeof v !== "object")
|
||||
return v;
|
||||
if (v === null)
|
||||
@@ -362,37 +362,37 @@ Collection._deepcopy = function (v) {
|
||||
if (_.isArray(v)) {
|
||||
var ret = v.slice(0);
|
||||
for (var i = 0; i < v.length; i++)
|
||||
ret[i] = Collection._deepcopy(ret[i]);
|
||||
ret[i] = LocalCollection._deepcopy(ret[i]);
|
||||
return ret;
|
||||
}
|
||||
var ret = {};
|
||||
for (var key in v)
|
||||
ret[key] = Collection._deepcopy(v[key]);
|
||||
ret[key] = LocalCollection._deepcopy(v[key]);
|
||||
return ret;
|
||||
};
|
||||
|
||||
// XXX the sorted-query logic below is laughably inefficient. we'll
|
||||
// need to come up with a better datastructure for this.
|
||||
|
||||
Collection._insertInResults = function (query, doc) {
|
||||
LocalCollection._insertInResults = function (query, doc) {
|
||||
if (!query.sort_f) {
|
||||
query.added(doc, query.results.length);
|
||||
query.results.push(doc);
|
||||
} else {
|
||||
var i = Collection._insertInSortedList(query.sort_f, query.results, doc);
|
||||
var i = LocalCollection._insertInSortedList(query.sort_f, query.results, doc);
|
||||
query.added(doc, i);
|
||||
}
|
||||
};
|
||||
|
||||
Collection._removeFromResults = function (query, doc) {
|
||||
var i = Collection._findInResults(query, doc);
|
||||
LocalCollection._removeFromResults = function (query, doc) {
|
||||
var i = LocalCollection._findInResults(query, doc);
|
||||
query.removed(doc._id, i);
|
||||
query.results.splice(i, 1);
|
||||
};
|
||||
|
||||
Collection._updateInResults = function (query, doc) {
|
||||
var orig_idx = Collection._findInResults(query, doc);
|
||||
query.changed(Collection._deepcopy(doc), orig_idx);
|
||||
LocalCollection._updateInResults = function (query, doc) {
|
||||
var orig_idx = LocalCollection._findInResults(query, doc);
|
||||
query.changed(LocalCollection._deepcopy(doc), orig_idx);
|
||||
|
||||
if (!query.sort_f)
|
||||
return;
|
||||
@@ -400,20 +400,20 @@ Collection._updateInResults = function (query, doc) {
|
||||
// just take it out and put it back in again, and see if the index
|
||||
// changes
|
||||
query.results.splice(orig_idx, 1);
|
||||
var new_idx = Collection._insertInSortedList(query.sort_f,
|
||||
var new_idx = LocalCollection._insertInSortedList(query.sort_f,
|
||||
query.results, doc);
|
||||
if (orig_idx !== new_idx)
|
||||
query.moved(doc, orig_idx, new_idx);
|
||||
};
|
||||
|
||||
Collection._findInResults = function (query, doc) {
|
||||
LocalCollection._findInResults = function (query, doc) {
|
||||
for (var i = 0; i < query.results.length; i++)
|
||||
if (query.results[i] === doc)
|
||||
return i;
|
||||
throw Error("object missing from query");
|
||||
};
|
||||
|
||||
Collection._insertInSortedList = function (cmp, array, value) {
|
||||
LocalCollection._insertInSortedList = function (cmp, array, value) {
|
||||
if (array.length === 0) {
|
||||
array.push(value);
|
||||
return 0;
|
||||
@@ -434,7 +434,7 @@ Collection._insertInSortedList = function (cmp, array, value) {
|
||||
// overwrite it.
|
||||
// XXX document (at some point)
|
||||
// XXX test
|
||||
Collection.prototype.snapshot = function () {
|
||||
LocalCollection.prototype.snapshot = function () {
|
||||
this.current_snapshot = _.clone(this.docs);
|
||||
};
|
||||
|
||||
@@ -442,7 +442,7 @@ Collection.prototype.snapshot = function () {
|
||||
// exception.
|
||||
// XXX document (at some point)
|
||||
// XXX test
|
||||
Collection.prototype.restore = function () {
|
||||
LocalCollection.prototype.restore = function () {
|
||||
if (!this.current_snapshot)
|
||||
throw new Error("No current snapshot");
|
||||
this.docs = this.current_snapshot;
|
||||
@@ -460,6 +460,6 @@ Collection.prototype.restore = function () {
|
||||
query.results = query.cursor._getRawObjects();
|
||||
|
||||
for (var i = 0; i < query.results.length; i++)
|
||||
query.added(Collection._deepcopy(query.results[i]), i);
|
||||
query.added(LocalCollection._deepcopy(query.results[i]), i);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -38,7 +38,7 @@ assert_ordering = function (f, values) {
|
||||
// XXX test shared structure in all MM entrypoints
|
||||
|
||||
test("minimongo - basics", function () {
|
||||
var c = new Collection();
|
||||
var c = new LocalCollection();
|
||||
|
||||
c.insert({type: "kitten", name: "fluffy"});
|
||||
c.insert({type: "kitten", name: "snookums"});
|
||||
@@ -129,7 +129,7 @@ test("minimongo - basics", function () {
|
||||
});
|
||||
|
||||
test("minimongo - cursors", function () {
|
||||
var c = new Collection();
|
||||
var c = new LocalCollection();
|
||||
var res;
|
||||
|
||||
for (var i = 0; i < 20; i++)
|
||||
@@ -176,8 +176,8 @@ test("minimongo - misc", function () {
|
||||
// deepcopy
|
||||
var a = {a: [1, 2, 3], b: "x", c: true, d: {x: 12, y: [12]},
|
||||
f: null};
|
||||
var b = Collection._deepcopy(a);
|
||||
assert.isTrue(Collection._f._equal(a, b));
|
||||
var b = LocalCollection._deepcopy(a);
|
||||
assert.isTrue(LocalCollection._f._equal(a, b));
|
||||
a.a.push(4);
|
||||
assert.length(b.a, 3);
|
||||
a.c = false;
|
||||
@@ -189,14 +189,14 @@ test("minimongo - misc", function () {
|
||||
assert.length(b.d.y, 1);
|
||||
|
||||
a = {x: function () {}};
|
||||
b = Collection._deepcopy(a);
|
||||
b = LocalCollection._deepcopy(a);
|
||||
a.x.a = 14;
|
||||
assert.equal(b.x.a, 14); // just to document current behavior
|
||||
});
|
||||
|
||||
test("minimongo - selector_compiler", function () {
|
||||
var matches = function (should_match, selector, doc) {
|
||||
var does_match = Collection._matches(selector, doc);
|
||||
var does_match = LocalCollection._matches(selector, doc);
|
||||
if (does_match != should_match) {
|
||||
// XXX super janky
|
||||
test.fail({type: "minimongo-ordering",
|
||||
@@ -508,7 +508,7 @@ test("minimongo - selector_compiler", function () {
|
||||
|
||||
test("minimongo - ordering", function () {
|
||||
// value ordering
|
||||
assert_ordering(Collection._f._cmp, [
|
||||
assert_ordering(LocalCollection._f._cmp, [
|
||||
null,
|
||||
1, 2.2, 3,
|
||||
"03", "1", "11", "2", "a", "aaa",
|
||||
@@ -521,7 +521,7 @@ test("minimongo - ordering", function () {
|
||||
// document ordering under a sort specification
|
||||
var verify = function (sorts, docs) {
|
||||
_.each(sorts, function (sort) {
|
||||
assert_ordering(Collection._compileSort(sort), docs);
|
||||
assert_ordering(LocalCollection._compileSort(sort), docs);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -539,18 +539,18 @@ test("minimongo - ordering", function () {
|
||||
[{c: 1}, {a: 1, b: 2}, {a: 1, b: 3}, {a: 2, b: 0}]);
|
||||
|
||||
assert.throws(function () {
|
||||
Collection._compileSort("a");
|
||||
LocalCollection._compileSort("a");
|
||||
});
|
||||
|
||||
assert.throws(function () {
|
||||
Collection._compileSort(123);
|
||||
LocalCollection._compileSort(123);
|
||||
});
|
||||
|
||||
assert.equal(Collection._compileSort({})({a:1}, {a:2}), 0);
|
||||
assert.equal(LocalCollection._compileSort({})({a:1}, {a:2}), 0);
|
||||
});
|
||||
|
||||
test("minimongo - sort", function () {
|
||||
var c = new Collection();
|
||||
var c = new LocalCollection();
|
||||
for (var i = 0; i < 50; i++)
|
||||
for (var j = 0; j < 2; j++)
|
||||
c.insert({a: i, b: j, _id: i + "_" + j});
|
||||
@@ -582,9 +582,9 @@ test("minimongo - sort", function () {
|
||||
|
||||
test("minimongo - modify", function () {
|
||||
var modify = function (doc, mod, result) {
|
||||
var copy = Collection._deepcopy(doc);
|
||||
Collection._modify(copy, mod);
|
||||
if (!Collection._f._equal(copy, result)) {
|
||||
var copy = LocalCollection._deepcopy(doc);
|
||||
LocalCollection._modify(copy, mod);
|
||||
if (!LocalCollection._f._equal(copy, result)) {
|
||||
// XXX super janky
|
||||
test.fail({type: "minimongo-modifier",
|
||||
message: "modifier test failure",
|
||||
@@ -599,7 +599,7 @@ test("minimongo - modify", function () {
|
||||
};
|
||||
var exception = function (doc, mod) {
|
||||
assert.throws(function () {
|
||||
Collection._modify(Collection._deepcopy(doc), mod);
|
||||
LocalCollection._modify(LocalCollection._deepcopy(doc), mod);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
//
|
||||
// XXX atomicity: if one modification fails, do we roll back the whole
|
||||
// change?
|
||||
Collection._modify = function (doc, mod) {
|
||||
LocalCollection._modify = function (doc, mod) {
|
||||
var is_modifier = false;
|
||||
for (var k in mod) {
|
||||
// IE7 doesn't support indexing into strings (eg, k[0]), so use substr.
|
||||
@@ -31,10 +31,10 @@ Collection._modify = function (doc, mod) {
|
||||
new_doc = mod;
|
||||
} else {
|
||||
// apply modifiers
|
||||
var new_doc = Collection._deepcopy(doc);
|
||||
var new_doc = LocalCollection._deepcopy(doc);
|
||||
|
||||
for (var op in mod) {
|
||||
var mod_func = Collection._modifiers[op];
|
||||
var mod_func = LocalCollection._modifiers[op];
|
||||
if (!mod_func)
|
||||
throw Error("Invalid modifier specified " + op);
|
||||
for (var keypath in mod[op]) {
|
||||
@@ -45,10 +45,10 @@ Collection._modify = function (doc, mod) {
|
||||
|
||||
var arg = mod[op][keypath];
|
||||
var keyparts = keypath.split('.');
|
||||
var no_create = !!Collection._noCreateModifiers[op];
|
||||
var no_create = !!LocalCollection._noCreateModifiers[op];
|
||||
var forbid_array = (op === "$rename");
|
||||
var target = Collection._findModTarget(new_doc, keyparts,
|
||||
no_create, forbid_array);
|
||||
var target = LocalCollection._findModTarget(new_doc, keyparts,
|
||||
no_create, forbid_array);
|
||||
var field = keyparts.pop();
|
||||
mod_func(target, field, arg, keypath, new_doc);
|
||||
}
|
||||
@@ -75,7 +75,7 @@ Collection._modify = function (doc, mod) {
|
||||
// different value to index into the returned object (for example,
|
||||
// ['a', '01'] -> ['a', 1]). if forbid_array is true, return null if
|
||||
// the keypath goes through an array.
|
||||
Collection._findModTarget = function (doc, keyparts, no_create,
|
||||
LocalCollection._findModTarget = function (doc, keyparts, no_create,
|
||||
forbid_array) {
|
||||
for (var i = 0; i < keyparts.length; i++) {
|
||||
var last = (i === keyparts.length - 1);
|
||||
@@ -116,7 +116,7 @@ Collection._findModTarget = function (doc, keyparts, no_create,
|
||||
// notreached
|
||||
};
|
||||
|
||||
Collection._noCreateModifiers = {
|
||||
LocalCollection._noCreateModifiers = {
|
||||
$unset: true,
|
||||
$pop: true,
|
||||
$rename: true,
|
||||
@@ -124,7 +124,7 @@ Collection._noCreateModifiers = {
|
||||
$pullAll: true
|
||||
};
|
||||
|
||||
Collection._modifiers = {
|
||||
LocalCollection._modifiers = {
|
||||
$inc: function (target, field, arg) {
|
||||
if (typeof arg !== "number")
|
||||
throw Error("Modifier $inc allowed for numbers only");
|
||||
@@ -137,7 +137,7 @@ Collection._modifiers = {
|
||||
}
|
||||
},
|
||||
$set: function (target, field, arg) {
|
||||
target[field] = Collection._deepcopy(arg);
|
||||
target[field] = LocalCollection._deepcopy(arg);
|
||||
},
|
||||
$unset: function (target, field, arg) {
|
||||
if (target !== undefined) {
|
||||
@@ -155,7 +155,7 @@ Collection._modifiers = {
|
||||
else if (!(x instanceof Array))
|
||||
throw Error("Cannot apply $push modifier to non-array");
|
||||
else
|
||||
x.push(Collection._deepcopy(arg));
|
||||
x.push(LocalCollection._deepcopy(arg));
|
||||
},
|
||||
$pushAll: function (target, field, arg) {
|
||||
if (!(typeof arg === "object" && arg instanceof Array))
|
||||
@@ -188,7 +188,7 @@ Collection._modifiers = {
|
||||
var values = isEach ? arg["$each"] : [arg];
|
||||
_.each(values, function (value) {
|
||||
for (var i = 0; i < x.length; i++)
|
||||
if (Collection._f._equal(value, x[i]))
|
||||
if (LocalCollection._f._equal(value, x[i]))
|
||||
return;
|
||||
x.push(value);
|
||||
});
|
||||
@@ -229,13 +229,13 @@ Collection._modifiers = {
|
||||
// to permit stuff like {$pull: {a: {$gt: 4}}}.. something
|
||||
// like {$gt: 4} is not normally a complete selector.
|
||||
// same issue as $elemMatch possibly?
|
||||
var match = Collection._compileSelector(arg);
|
||||
var match = LocalCollection._compileSelector(arg);
|
||||
for (var i = 0; i < x.length; i++)
|
||||
if (!match(x[i]))
|
||||
out.push(x[i])
|
||||
} else {
|
||||
for (var i = 0; i < x.length; i++)
|
||||
if (!Collection._f._equal(x[i], arg))
|
||||
if (!LocalCollection._f._equal(x[i], arg))
|
||||
out.push(x[i]);
|
||||
}
|
||||
target[field] = out;
|
||||
@@ -256,7 +256,7 @@ Collection._modifiers = {
|
||||
for (var i = 0; i < x.length; i++) {
|
||||
var exclude = false;
|
||||
for (var j = 0; j < arg.length; j++) {
|
||||
if (Collection._f._equal(x[i], arg[j])) {
|
||||
if (LocalCollection._f._equal(x[i], arg[j])) {
|
||||
exclude = true;
|
||||
break;
|
||||
}
|
||||
@@ -281,7 +281,7 @@ Collection._modifiers = {
|
||||
delete target[field];
|
||||
|
||||
var keyparts = arg.split('.');
|
||||
var target2 = Collection._findModTarget(doc, keyparts, false, true);
|
||||
var target2 = LocalCollection._findModTarget(doc, keyparts, false, true);
|
||||
if (target2 === null)
|
||||
throw Error("$rename target field invalid");
|
||||
var field2 = keyparts.pop();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// helpers used by compiled selector code
|
||||
Collection._f = {
|
||||
LocalCollection._f = {
|
||||
// XXX for _all and _in, consider building 'inquery' at compile time..
|
||||
|
||||
_all: function (x, qval) {
|
||||
@@ -38,7 +38,7 @@ Collection._f = {
|
||||
} else {
|
||||
// nope, have to use deep equality
|
||||
for (var i = 0; i < qval.length; i++)
|
||||
if (Collection._f._equal(x, qval[i]))
|
||||
if (LocalCollection._f._equal(x, qval[i]))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@@ -185,10 +185,10 @@ Collection._f = {
|
||||
return b === undefined ? 0 : -1;
|
||||
if (b === undefined)
|
||||
return 1;
|
||||
var ta = Collection._f._type(a);
|
||||
var tb = Collection._f._type(b);
|
||||
var oa = Collection._f._typeorder(ta);
|
||||
var ob = Collection._f._typeorder(tb);
|
||||
var ta = LocalCollection._f._type(a);
|
||||
var tb = LocalCollection._f._type(b);
|
||||
var oa = LocalCollection._f._typeorder(ta);
|
||||
var ob = LocalCollection._f._typeorder(tb);
|
||||
if (oa !== ob)
|
||||
return oa < ob ? -1 : 1;
|
||||
if (ta !== tb)
|
||||
@@ -209,7 +209,7 @@ Collection._f = {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
return Collection._f._cmp(to_array(a), to_array(b));
|
||||
return LocalCollection._f._cmp(to_array(a), to_array(b));
|
||||
}
|
||||
if (ta === 4) { // Array
|
||||
for (var i = 0; ; i++) {
|
||||
@@ -217,7 +217,7 @@ Collection._f = {
|
||||
return (i === b.length) ? 0 : -1;
|
||||
if (i === b.length)
|
||||
return 1;
|
||||
var s = Collection._f._cmp(a[i], b[i]);
|
||||
var s = LocalCollection._f._cmp(a[i], b[i]);
|
||||
if (s !== 0)
|
||||
return s;
|
||||
}
|
||||
@@ -248,14 +248,14 @@ Collection._f = {
|
||||
|
||||
// For unit tests. True if the given document matches the given
|
||||
// selector.
|
||||
Collection._matches = function (selector, doc) {
|
||||
return (Collection._compileSelector(selector))(doc);
|
||||
LocalCollection._matches = function (selector, doc) {
|
||||
return (LocalCollection._compileSelector(selector))(doc);
|
||||
};
|
||||
|
||||
// Given a selector, return a function that takes one argument, a
|
||||
// document, and returns true if the document matches the selector,
|
||||
// else false.
|
||||
Collection._compileSelector = function (selector) {
|
||||
LocalCollection._compileSelector = function (selector) {
|
||||
var literals = [];
|
||||
// you can pass a literal function instead of a selector
|
||||
if (selector instanceof Function)
|
||||
@@ -275,9 +275,9 @@ Collection._compileSelector = function (selector) {
|
||||
// should. Assign to a local to get the value, instead.
|
||||
var _func;
|
||||
eval("_func = (function(f,literals){return function(doc){return " +
|
||||
Collection._exprForSelector(selector, literals) +
|
||||
LocalCollection._exprForSelector(selector, literals) +
|
||||
";};})");
|
||||
return _func(Collection._f, literals);
|
||||
return _func(LocalCollection._f, literals);
|
||||
};
|
||||
|
||||
// XXX implement ordinal indexing: 'people.2.name'
|
||||
@@ -285,17 +285,17 @@ Collection._compileSelector = function (selector) {
|
||||
// Given an arbitrary Mongo-style query selector, return an expression
|
||||
// that evaluates to true if the document in 'doc' matches the
|
||||
// selector, else false.
|
||||
Collection._exprForSelector = function (selector, literals) {
|
||||
LocalCollection._exprForSelector = function (selector, literals) {
|
||||
var clauses = [];
|
||||
for (var key in selector) {
|
||||
var value = selector[key];
|
||||
|
||||
if (key.substr(0, 1) === '$') { // no indexing into strings on IE7
|
||||
// whole-document predicate like {$or: [{x: 12}, {y: 12}]}
|
||||
clauses.push(Collection._exprForDocumentPredicate(key, value, literals));
|
||||
clauses.push(LocalCollection._exprForDocumentPredicate(key, value, literals));
|
||||
} else {
|
||||
// else, it's a constraint on a particular key (or dotted keypath)
|
||||
clauses.push(Collection._exprForKeypathPredicate(key, value, literals));
|
||||
clauses.push(LocalCollection._exprForKeypathPredicate(key, value, literals));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -307,11 +307,11 @@ Collection._exprForSelector = function (selector, literals) {
|
||||
// selector, like '$or' in {$or: [{x: 12}, {y: 12}]}. 'value' is its
|
||||
// value in the selector. Return an expression that evaluates to true
|
||||
// if 'doc' matches this predicate, else false.
|
||||
Collection._exprForDocumentPredicate = function (op, value, literals) {
|
||||
LocalCollection._exprForDocumentPredicate = function (op, value, literals) {
|
||||
if (op === '$or') {
|
||||
var clauses = [];
|
||||
_.each(value, function (c) {
|
||||
clauses.push(Collection._exprForSelector(c, literals));
|
||||
clauses.push(LocalCollection._exprForSelector(c, literals));
|
||||
});
|
||||
if (clauses.length === 0) return 'true';
|
||||
return '(' + clauses.join('||') +')';
|
||||
@@ -320,7 +320,7 @@ Collection._exprForDocumentPredicate = function (op, value, literals) {
|
||||
if (op === '$and') {
|
||||
var clauses = [];
|
||||
_.each(value, function (c) {
|
||||
clauses.push(Collection._exprForSelector(c, literals));
|
||||
clauses.push(LocalCollection._exprForSelector(c, literals));
|
||||
});
|
||||
if (clauses.length === 0) return 'true';
|
||||
return '(' + clauses.join('&&') +')';
|
||||
@@ -329,7 +329,7 @@ Collection._exprForDocumentPredicate = function (op, value, literals) {
|
||||
if (op === '$nor') {
|
||||
var clauses = [];
|
||||
_.each(value, function (c) {
|
||||
clauses.push("!(" + Collection._exprForSelector(c, literals) + ")");
|
||||
clauses.push("!(" + LocalCollection._exprForSelector(c, literals) + ")");
|
||||
});
|
||||
if (clauses.length === 0) return 'true';
|
||||
return '(' + clauses.join('&&') +')';
|
||||
@@ -349,19 +349,19 @@ Collection._exprForDocumentPredicate = function (op, value, literals) {
|
||||
// Given a single 'dotted.key.path: value' constraint from a Mongo
|
||||
// query selector, return an expression that evaluates to true if the
|
||||
// document in 'doc' matches the constraint, else false.
|
||||
Collection._exprForKeypathPredicate = function (keypath, value, literals) {
|
||||
LocalCollection._exprForKeypathPredicate = function (keypath, value, literals) {
|
||||
var keyparts = keypath.split('.');
|
||||
|
||||
// get the inner predicate expression
|
||||
var predcode = '';
|
||||
if (value instanceof RegExp) {
|
||||
predcode = Collection._exprForOperatorTest(value, literals);
|
||||
predcode = LocalCollection._exprForOperatorTest(value, literals);
|
||||
} else if (
|
||||
!(typeof value === 'object') ||
|
||||
value === null ||
|
||||
value instanceof Array) {
|
||||
// it's something like {x.y: 12} or {x.y: [12]}
|
||||
predcode = Collection._exprForValueTest(value, literals);
|
||||
predcode = LocalCollection._exprForValueTest(value, literals);
|
||||
} else {
|
||||
// is it a literal document or a bunch of $-expressions?
|
||||
var is_literal = true;
|
||||
@@ -374,9 +374,9 @@ Collection._exprForKeypathPredicate = function (keypath, value, literals) {
|
||||
|
||||
if (is_literal) {
|
||||
// it's a literal document, like {x.y: {a: 12}}
|
||||
predcode = Collection._exprForValueTest(value, literals);
|
||||
predcode = LocalCollection._exprForValueTest(value, literals);
|
||||
} else {
|
||||
predcode = Collection._exprForOperatorTest(value, literals);
|
||||
predcode = LocalCollection._exprForOperatorTest(value, literals);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -407,7 +407,7 @@ Collection._exprForKeypathPredicate = function (keypath, value, literals) {
|
||||
// searching 'x' if it is an array. This doesn't include regular
|
||||
// expressions (that's because mongo's $not operator works with
|
||||
// regular expressions but not other kinds of scalar tests.)
|
||||
Collection._exprForValueTest = function (value, literals) {
|
||||
LocalCollection._exprForValueTest = function (value, literals) {
|
||||
var expr;
|
||||
|
||||
if (value === null) {
|
||||
@@ -437,14 +437,14 @@ Collection._exprForValueTest = function (value, literals) {
|
||||
// expression that evaluates to true if the value in 'x' matches the
|
||||
// operator, or else false. This includes searching 'x' if necessary
|
||||
// if it's an array. In {x: /a/}, we consider /a/ to be an operator.
|
||||
Collection._exprForOperatorTest = function (op, literals) {
|
||||
LocalCollection._exprForOperatorTest = function (op, literals) {
|
||||
if (op instanceof RegExp) {
|
||||
return Collection._exprForOperatorTest({$regex: op}, literals);
|
||||
return LocalCollection._exprForOperatorTest({$regex: op}, literals);
|
||||
} else {
|
||||
var clauses = [];
|
||||
for (var type in op)
|
||||
clauses.push(Collection._exprForConstraint(type, op[type],
|
||||
op, literals));
|
||||
clauses.push(LocalCollection._exprForConstraint(type, op[type],
|
||||
op, literals));
|
||||
if (clauses.length === 0)
|
||||
return 'true';
|
||||
return '(' + clauses.join('&&') + ')';
|
||||
@@ -456,8 +456,8 @@ Collection._exprForOperatorTest = function (op, literals) {
|
||||
// return an expression that evaluates to true if the value in 'x'
|
||||
// matches the constraint, or else false. This includes searching 'x'
|
||||
// if it's an array (and it's appropriate to the constraint.)
|
||||
Collection._exprForConstraint = function (type, arg, others,
|
||||
literals) {
|
||||
LocalCollection._exprForConstraint = function (type, arg, others,
|
||||
literals) {
|
||||
var expr;
|
||||
var search = '_matches';
|
||||
var negate = false;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
// XXX sort does not yet support subkeys ('a.b') .. fix that!
|
||||
|
||||
Collection._compileSort = function (spec) {
|
||||
LocalCollection._compileSort = function (spec) {
|
||||
var keys = [];
|
||||
var asc = [];
|
||||
|
||||
@@ -53,5 +53,5 @@ Collection._compileSort = function (spec) {
|
||||
code += "return x;};})";
|
||||
|
||||
eval(code);
|
||||
return _func(Collection._f._cmp);
|
||||
return _func(LocalCollection._f._cmp);
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// XXX dups packages/uuid/uuid.js
|
||||
|
||||
// Collection.random() -- known good PRNG, replaces Math.random()
|
||||
// Collection.uuid() -- returns RFC 4122 v4 UUID.
|
||||
// LocalCollection.random() -- known good PRNG, replaces Math.random()
|
||||
// LocalCollection.uuid() -- returns RFC 4122 v4 UUID.
|
||||
|
||||
// see http://baagoe.org/en/wiki/Better_random_numbers_for_javascript
|
||||
// for a full discussion and Alea implementation.
|
||||
@@ -28,7 +28,7 @@
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
Collection._Alea = function () {
|
||||
LocalCollection._Alea = function () {
|
||||
function Mash() {
|
||||
var n = 0xefc8249d;
|
||||
|
||||
@@ -102,14 +102,14 @@ Collection._Alea = function () {
|
||||
}
|
||||
|
||||
// instantiate RNG. use the default seed, which is current time.
|
||||
Collection.random = new Collection._Alea();
|
||||
LocalCollection.random = new LocalCollection._Alea();
|
||||
|
||||
// RFC 4122 v4 UUID.
|
||||
Collection.uuid = function () {
|
||||
LocalCollection.uuid = function () {
|
||||
var s = [];
|
||||
var hexDigits = "0123456789abcdef";
|
||||
for (var i = 0; i < 36; i++) {
|
||||
s[i] = hexDigits.substr(Math.floor(Collection.random() * 0x10), 1);
|
||||
s[i] = hexDigits.substr(Math.floor(LocalCollection.random() * 0x10), 1);
|
||||
}
|
||||
s[14] = "4";
|
||||
s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);
|
||||
|
||||
@@ -25,7 +25,9 @@ Meteor._hook_handlebars_each = function () {
|
||||
|
||||
var orig = Handlebars._default_helpers.each;
|
||||
Handlebars._default_helpers.each = function (context, options) {
|
||||
if (!(context instanceof Collection.Cursor))
|
||||
// XXX eliminate minimongo dependency -- use a Cursor base class,
|
||||
// or duck typing
|
||||
if (!(context instanceof LocalCollection.Cursor))
|
||||
return orig(context, options);
|
||||
|
||||
var id = Meteor._pending_partials_idx_nonce++;
|
||||
|
||||
@@ -52,7 +52,7 @@ test("template table assembly", function() {
|
||||
table = childWithTag(Template.test_table_b0(), "TABLE");
|
||||
assert.equal(table.rows.length, 3);
|
||||
|
||||
var c = new Collection();
|
||||
var c = new LocalCollection();
|
||||
c.insert({bar:'a'});
|
||||
c.insert({bar:'b'});
|
||||
c.insert({bar:'c'});
|
||||
|
||||
Reference in New Issue
Block a user