Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 58 additions & 45 deletions cache.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,28 @@
import { addMigration, autoMigrate, migrate } from './migrations.js';
import _ from 'lodash';
import clone from 'lodash/clone';
import difference from 'lodash/difference';
import each from 'lodash/each';
import findIndex from 'lodash/findIndex';
import flatten from 'lodash/flatten';
import get from 'lodash/get';
import includes from 'lodash/includes';
import intersection from 'lodash/intersection';
import isEqual from 'lodash/isEqual';
import map from 'lodash/map';
import pick from 'lodash/pick';
import pull from 'lodash/pull';
import union from 'lodash/union';
import uniq from 'lodash/uniq';
import { check, Match } from 'meteor/check';

export { migrate, autoMigrate };

function flattenFields(object, prefix) {
prefix = prefix || '';
let fields = [];
_.each(object, (val, key) => {
each(object, (val, key) => {
if (typeof val == 'object') {
fields = _.union(fields, flattenFields(val, prefix + key + '.'));
fields = union(fields, flattenFields(val, prefix + key + '.'));
} else {
fields.push(prefix + key);
}
Expand Down Expand Up @@ -59,15 +72,15 @@ Mongo.Collection.prototype.cache = function (options) {
watchedFields = flattenFields(watchedFields);
}

let childFields = _.clone(watchedFields);
let childFields = clone(watchedFields);
if (type !== 'one') {
if (!_.includes(childFields, '_id')) {
if (!includes(childFields, '_id')) {
childFields.push('_id');
}
_.pull(childFields, referenceField);
pull(childFields, referenceField);
}
let childOpts = { transform: null, fields: { _id: 0 } };
_.each(childFields, (field) => (childOpts.fields[field] = 1));
each(childFields, (field) => (childOpts.fields[field] = 1));

let parentOpts = { transform: null, fields: { _id: 1, [cacheField]: 1 } };
if (type !== 'inversed' && type !== 'many-inversed') {
Expand All @@ -83,27 +96,27 @@ Mongo.Collection.prototype.cache = function (options) {

if (
type == 'inversed' ||
(type == 'many-inversed' && !_.includes(watchedFields, referencePath))
(type == 'many-inversed' && !includes(watchedFields, referencePath))
) {
watchedFields.push(referencePath || referenceField);
}

let topFields = _.uniq(watchedFields.map((field) => field.split('.')[0]));
let topFields = uniq(watchedFields.map((field) => field.split('.')[0]));

function getNestedReferences(document) {
//Used for nested references in "many" links
let references = _.get(document, referenceField) || [];
let references = get(document, referenceField) || [];
if (idField && references.length) {
references = _.map(references, (item) => _.get(item, idField));
references = map(references, (item) => get(item, idField));
}
return _.uniq(_.flatten(references));
return uniq(flatten(references));
}

if (type == 'one') {
let insert = async function insert(userId, parent) {
if (_.get(parent, referenceField)) {
if (get(parent, referenceField)) {
let child = await childCollection.findOneAsync(
_.get(parent, referenceField),
get(parent, referenceField),
childOpts,
);
if (child) {
Expand All @@ -121,11 +134,11 @@ Mongo.Collection.prototype.cache = function (options) {
parent,
changedFields,
) {
if (_.includes(changedFields, referenceField.split('.')[0])) {
if (includes(changedFields, referenceField.split('.')[0])) {
let child =
_.get(parent, referenceField) &&
get(parent, referenceField) &&
(await childCollection.findOneAsync(
_.get(parent, referenceField),
get(parent, referenceField),
childOpts,
));
if (child) {
Expand All @@ -141,7 +154,7 @@ Mongo.Collection.prototype.cache = function (options) {
});

childCollection.after.insert(async function (userId, child) {
let pickedChild = _.pick(child, childFields);
let pickedChild = pick(child, childFields);
await parentCollection.updateAsync(
{ [referenceField]: child._id },
{ $set: { [cacheField]: pickedChild } },
Expand All @@ -150,11 +163,11 @@ Mongo.Collection.prototype.cache = function (options) {
});

childCollection.after.update(async function (userId, child, changedFields) {
if (_.intersection(changedFields, topFields).length) {
let pickedChild = _.pick(child, childFields);
if (intersection(changedFields, topFields).length) {
let pickedChild = pick(child, childFields);
// test if the object has been modified
let previousPickedChild = _.pick(this.previous, childFields);
if (!_.isEqual(previousPickedChild, pickedChild)){
let previousPickedChild = pick(this.previous, childFields);
if (!isEqual(previousPickedChild, pickedChild)){
await parentCollection.updateAsync(
{ [referenceField]: child._id },
{ $set: { [cacheField]: pickedChild } },
Expand Down Expand Up @@ -195,7 +208,7 @@ Mongo.Collection.prototype.cache = function (options) {
parent,
changedFields,
) {
if (_.includes(changedFields, referencePath.split('.')[0])) {
if (includes(changedFields, referencePath.split('.')[0])) {
let references = getNestedReferences(parent);
if (references.length) {
let children = await childCollection
Expand All @@ -213,7 +226,7 @@ Mongo.Collection.prototype.cache = function (options) {
});

childCollection.after.insert(async function (userId, child) {
let pickedChild = _.pick(child, childFields);
let pickedChild = pick(child, childFields);
await parentCollection.updateAsync(
{ [referencePath]: child._id },
{ $push: { [cacheField]: pickedChild } },
Expand All @@ -222,12 +235,12 @@ Mongo.Collection.prototype.cache = function (options) {
});

childCollection.after.update(async function (userId, child, changedFields) {
if (_.intersection(changedFields, topFields).length) {
let pickedChild = _.pick(child, childFields);
if (intersection(changedFields, topFields).length) {
let pickedChild = pick(child, childFields);
await parentCollection
.find({ [referencePath]: child._id }, parentOpts)
.forEachAsync(async (parent) => {
let index = _.findIndex(_.get(parent, cacheField), {
let index = findIndex(get(parent, cacheField), {
_id: child._id,
});
if (index > -1) {
Expand Down Expand Up @@ -268,8 +281,8 @@ Mongo.Collection.prototype.cache = function (options) {
parent,
changedFields,
) {
if (_.includes(changedFields, referenceField.split('.')[0])) {
if (_.get(parent, referenceField)) {
if (includes(changedFields, referenceField.split('.')[0])) {
if (get(parent, referenceField)) {
let children = await childCollection
.find({ [referenceField]: parent._id }, childOpts)
.fetchAsync();
Expand All @@ -285,29 +298,29 @@ Mongo.Collection.prototype.cache = function (options) {
});

childCollection.after.insert(async function (userId, child) {
let pickedChild = _.pick(child, childFields);
if (_.get(child, referenceField)) {
let pickedChild = pick(child, childFields);
if (get(child, referenceField)) {
await parentCollection.updateAsync(
{ _id: _.get(child, referenceField) },
{ _id: get(child, referenceField) },
{ $push: { [cacheField]: pickedChild } },
);
}
});

childCollection.after.update(async function (userId, child, changedFields) {
if (_.intersection(changedFields, topFields).length) {
let pickedChild = _.pick(child, childFields);
let previousId = this.previous && _.get(this.previous, referenceField);
if (previousId && previousId !== _.get(child, referenceField)) {
if (intersection(changedFields, topFields).length) {
let pickedChild = pick(child, childFields);
let previousId = this.previous && get(this.previous, referenceField);
if (previousId && previousId !== get(child, referenceField)) {
await parentCollection.updateAsync(
{ _id: previousId },
{ $pull: { [cacheField]: { _id: child._id } } },
);
}
await parentCollection
.find({ _id: _.get(child, referenceField) }, parentOpts)
.find({ _id: get(child, referenceField) }, parentOpts)
.forEachAsync(async (parent) => {
let index = _.findIndex(_.get(parent, cacheField), {
let index = findIndex(get(parent, cacheField), {
_id: child._id,
});
if (index > -1) {
Expand All @@ -325,7 +338,7 @@ Mongo.Collection.prototype.cache = function (options) {

childCollection.after.remove(async function (userId, child) {
await parentCollection.updateAsync(
{ _id: _.get(child, referenceField) },
{ _id: get(child, referenceField) },
{ $pull: { [cacheField]: { _id: child._id } } },
);
});
Expand All @@ -347,7 +360,7 @@ Mongo.Collection.prototype.cache = function (options) {
parent,
changedFields,
) {
if (_.includes(changedFields, referencePath.split('.')[0])) {
if (includes(changedFields, referencePath.split('.')[0])) {
let children = await childCollection
.find({ [referencePath]: parent._id }, childOpts)
.fetchAsync();
Expand All @@ -360,7 +373,7 @@ Mongo.Collection.prototype.cache = function (options) {
childCollection.after.insert(async function (userId, child) {
let references = getNestedReferences(child);
if (references.length) {
let pickedChild = _.pick(child, childFields);
let pickedChild = pick(child, childFields);
await parentCollection.updateAsync(
{ _id: { $in: references } },
{ $push: { [cacheField]: pickedChild } },
Expand All @@ -370,10 +383,10 @@ Mongo.Collection.prototype.cache = function (options) {
});

childCollection.after.update(async function (userId, child, changedFields) {
if (_.intersection(changedFields, topFields).length) {
if (intersection(changedFields, topFields).length) {
let references = getNestedReferences(child);
let previousIds = this.previous && getNestedReferences(this.previous);
previousIds = _.difference(previousIds, references);
previousIds = difference(previousIds, references);
if (previousIds.length) {
await parentCollection.updateAsync(
{ _id: { $in: previousIds } },
Expand All @@ -382,11 +395,11 @@ Mongo.Collection.prototype.cache = function (options) {
);
}
if (references.length) {
let pickedChild = _.pick(child, childFields);
let pickedChild = pick(child, childFields);
await parentCollection
.find({ _id: { $in: references } }, parentOpts)
.forEachAsync(async (parent) => {
let index = _.findIndex(_.get(parent, cacheField), {
let index = findIndex(get(parent, cacheField), {
_id: child._id,
});
if (index > -1) {
Expand Down
17 changes: 17 additions & 0 deletions cache.js.new
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Instead of: import _ from 'lodash';
import clone from 'lodash/clone';
import difference from 'lodash/difference';
import each from 'lodash/each';
import findIndex from 'lodash/findIndex';
import flatten from 'lodash/flatten';
import get from 'lodash/get';
import includes from 'lodash/includes';
import intersection from 'lodash/intersection';
import isEqual from 'lodash/isEqual';
import map from 'lodash/map';
import pick from 'lodash/pick';
import pull from 'lodash/pull';
import union from 'lodash/union';
import uniq from 'lodash/uniq';

// Then replace all _.<func> with <func>
18 changes: 11 additions & 7 deletions cacheCount.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import _ from 'lodash';
import get from 'lodash/get';
import intersection from 'lodash/intersection';
import merge from 'lodash/merge';
import union from 'lodash/union';
import uniq from 'lodash/uniq';
import { addMigration } from './migrations.js';
import { check, Match } from 'meteor/check';

Expand All @@ -19,8 +23,8 @@ Mongo.Collection.prototype.cacheCount = function (options) {
let selector = options.selector || {};
let cacheField = options.cacheField;
let referenceField = options.referenceField;
let watchedFields = _.union([referenceField], Object.keys(selector));
const topFields = _.uniq(watchedFields.map(field => field.split('.')[0]));
let watchedFields = union([referenceField], Object.keys(selector));
const topFields = uniq(watchedFields.map(field => field.split('.')[0]));

if (referenceField.split(/[.:]/)[0] == cacheField.split(/[.:]/)[0]) {
throw new Error(
Expand All @@ -29,9 +33,9 @@ Mongo.Collection.prototype.cacheCount = function (options) {
}

async function update(child) {
let ref = _.get(child, referenceField);
let ref = get(child, referenceField);
if (ref) {
let select = _.merge(selector, { [referenceField]: ref });
let select = merge(selector, { [referenceField]: ref });
await parentCollection.updateAsync(
{ _id: ref },
{
Expand All @@ -44,7 +48,7 @@ Mongo.Collection.prototype.cacheCount = function (options) {
}

async function insert(userId, parent) {
let select = _.merge(selector, { [referenceField]: parent._id });
let select = merge(selector, { [referenceField]: parent._id });
await parentCollection.updateAsync(parent._id, {
$set: { [cacheField]: await childCollection.find(select).countAsync() },
});
Expand All @@ -59,7 +63,7 @@ Mongo.Collection.prototype.cacheCount = function (options) {
});

childCollection.after.update(async function (userId, child, changedFields) {
if (_.intersection(changedFields, topFields).length) {
if (intersection(changedFields, topFields).length) {
await update(child);
await update(this.previous);
}
Expand Down
20 changes: 13 additions & 7 deletions cacheField.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import _ from 'lodash';
import compact from 'lodash/compact';
import get from 'lodash/get';
import includes from 'lodash/includes';
import intersection from 'lodash/intersection';
import map from 'lodash/map';
import pick from 'lodash/pick';
import uniq from 'lodash/uniq';
import { addMigration } from './migrations.js';
import { check, Match } from 'meteor/check';
import { Meteor } from 'meteor/meteor';
Expand All @@ -17,23 +23,23 @@ Mongo.Collection.prototype.cacheField = async function (options) {
: this;
let cacheField = options.cacheField;
let fields = options.fields;
let topFields = _.uniq(_.map(fields, (field) => field.split('.')[0]));
let topFields = uniq(map(fields, (field) => field.split('.')[0]));
let transform = options.transform;
if (!transform) {
transform = function (doc) {
return _.compact(_.map(fields, (field) => _.get(doc, field))).join(', ');
return compact(map(fields, (field) => get(doc, field))).join(', ');
};
}

if (_.includes(topFields, cacheField.split(/[.:]/)[0])) {
if (includes(topFields, cacheField.split(/[.:]/)[0])) {
throw new Error(
'watching the cacheField for changes would cause an infinite loop',
);
}

async function insertHook(userid, doc) {
await collection.updateAsync(doc._id, {
$set: { [cacheField]: await transform(_.pick(doc, fields)) },
$set: { [cacheField]: await transform(pick(doc, fields)) },
});
}

Expand All @@ -42,10 +48,10 @@ Mongo.Collection.prototype.cacheField = async function (options) {
collection.after.insert(insertHook);

collection.after.update(function (userId, doc, changedFields) {
if (_.intersection(changedFields, topFields).length) {
if (intersection(changedFields, topFields).length) {
Meteor.defer(async () => {
await collection.updateAsync(doc._id, {
$set: { [cacheField]: await transform(_.pick(doc, fields)) },
$set: { [cacheField]: await transform(pick(doc, fields)) },
});
});
}
Expand Down
Loading