Merge pull request #306 from cult-of-coders/bugfix/301

Fixes #301, #305, #303, #304
This commit is contained in:
Theodor Diaconu 2018-10-23 10:45:40 +03:00 committed by GitHub
commit 0462a21a71
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 56 additions and 21 deletions

View file

@ -103,17 +103,21 @@ export default class LinkManyMeta extends Link {
let modifier = {
$pull: {
[field]: {
$elemMatch: {
_id: {
$in: _ids
}
_id: {
$in: _ids
}
}
}
};
console.log(this.linker.mainCollection.findOne(this.object._id));
console.log(JSON.stringify(modifier));
this.linker.mainCollection.update(this.object._id, modifier);
console.log(this.linker.mainCollection.findOne(this.object._id));
return this;
}

View file

@ -10,8 +10,6 @@ import {Minimongo} from 'meteor/minimongo';
export default (node, params) => {
snapBackCaches(node);
storeOneResults(node, node.results);
applyReducers(node, params);
cleanReducerLeftovers(node);
_.each(node.collectionNodes, collectionNode => {
cloneMetaChildren(collectionNode, node.results)
@ -21,6 +19,9 @@ export default (node, params) => {
assembleMetadata(collectionNode, node.results)
});
applyReducers(node, params);
cleanReducerLeftovers(node);
removeLinkStorages(node, node.results);
applyPostFilters(node);
applyPostOptions(node);

View file

@ -3,6 +3,7 @@ export default class ReducerNode {
this.name = name;
this.body = body;
this.reduceFunction = reduce;
this.dependencies = []; // This is a list of the reducer this reducer uses.
}
/**

View file

@ -3,9 +3,32 @@ export default function applyReducers(root, params) {
applyReducers(node, params);
});
_.each(root.reducerNodes, reducerNode => {
root.results.forEach(result => {
reducerNode.compute(result, params);
});
});
}
const processedReducers = [];
let reducersQueue = [...root.reducerNodes];
// TODO: find out if there's an infinite reducer inter-deendency
while (reducersQueue.length) {
const reducerNode = reducersQueue.shift();
// If this reducer depends on other reducers
if (reducerNode.dependencies.length) {
// If there is an unprocessed reducer, move it at the end of the queue
const allDependenciesComputed = _.all(reducerNode.dependencies, dep => processedReducers.includes(dep));
if (allDependenciesComputed) {
root.results.forEach(result => {
reducerNode.compute(result, params);
});
processedReducers.push(reducerNode.name);
} else {
// Move it at the end of the queue
reducersQueue.push(reducerNode);
}
} else {
root.results.forEach(result => {
reducerNode.compute(result, params);
});
processedReducers.push(reducerNode.name);
}
}
}

View file

@ -44,8 +44,13 @@ function cleanNestedFields(parts, results, root) {
const snapCacheField = root.snapCaches[parts[0]];
const fieldName = snapCacheField ? snapCacheField : parts[0];
if (parts.length === 1) {
// We add this rule because if by any chance you use your reducer in conjunction with $options, $filters
// They are removed from the body and will no longer be present.
if (!root[fieldName]) {
return;
}
if (parts.length === 1) {
results.forEach(result => {
if (_.isObject(result) && fieldName !== '_id') {
delete result[fieldName];

View file

@ -9,7 +9,7 @@ export default function addReducers(root) {
// we add reducers last, after we have added all the fields.
root.reducerNodes.forEach(reducer => {
_.each(reducer.body, (body, fieldName) => {
handleAddElement(root, fieldName, body);
handleAddElement(reducer, root, fieldName, body);
})
});
}
@ -19,7 +19,7 @@ export default function addReducers(root) {
* @param fieldName
* @param body
*/
export function handleAddElement(root, fieldName, body) {
export function handleAddElement(reducerNode, root, fieldName, body) {
// if it's a link
const collection = root.collection;
const linker = collection.getLinker(fieldName);
@ -29,6 +29,7 @@ export function handleAddElement(root, fieldName, body) {
const reducer = collection.getReducer(fieldName);
if (reducer) {
reducerNode.dependencies.push(fieldName);
return handleAddReducer(fieldName, reducer, root);
}
@ -41,14 +42,14 @@ export function handleAddElement(root, fieldName, body) {
* @param reducer
* @param root
*/
export function handleAddReducer(fieldName, reducer, root) {
export function handleAddReducer(fieldName, {body, reduce}, root) {
if (!root.hasReducerNode(fieldName)) {
let reducerNode = new ReducerNode(fieldName, reducer);
root.add(reducerNode);
reducerNode.scheduledForDeletion = true;
let childReducerNode = new ReducerNode(fieldName, {body, reduce});
root.add(childReducerNode);
childReducerNode.scheduledForDeletion = true;
_.each(reducer.body, (body, fieldName) => {
handleAddElement(root, fieldName, body);
_.each(childReducerNode.body, (body, fieldName) => {
handleAddElement(childReducerNode, root, fieldName, body);
})
}
}