Optimizing pointer CLP query decoration done by DatabaseController#addPointerPermissions (#6747)

* Optimize CLP pointer query

* remove console log

* Update changelog

* Fix flow type checker issues

* Remove unused properties

* Fix typo, add one more test case for coverage

* Add support for CLP entry of type Object

Co-authored-by: Musa Yassin-Fort <musa.yassin@bureapr.com>
Co-authored-by: Diamond Lewis <findlewis@gmail.com>
This commit is contained in:
mess-lelouch
2020-07-17 14:14:43 -04:00
committed by GitHub
parent 78239ac907
commit d69833332c
3 changed files with 299 additions and 19 deletions

View File

@@ -1567,23 +1567,42 @@ class DatabaseController {
objectId: userId,
};
const ors = permFields.flatMap(key => {
// constraint for single pointer setup
const q = {
[key]: userPointer,
};
// constraint for users-array setup
const qa = {
[key]: { $all: [userPointer] },
};
const queries = permFields.map((key) => {
const fieldDescriptor = schema.getExpectedType(className, key);
const fieldType =
fieldDescriptor &&
typeof fieldDescriptor === 'object' &&
Object.prototype.hasOwnProperty.call(fieldDescriptor, 'type')
? fieldDescriptor.type
: null;
let queryClause;
if (fieldType === 'Pointer') {
// constraint for single pointer setup
queryClause = { [key]: userPointer };
} else if (fieldType === 'Array') {
// constraint for users-array setup
queryClause = { [key]: { $all: [userPointer] } };
} else if (fieldType === 'Object') {
// constraint for object setup
queryClause = { [key]: userPointer };
} else {
// This means that there is a CLP field of an unexpected type. This condition should not happen, which is
// why is being treated as an error.
throw Error(
`An unexpected condition occurred when resolving pointer permissions: ${className} ${key}`
);
}
// if we already have a constraint on the key, use the $and
if (Object.prototype.hasOwnProperty.call(query, key)) {
return [{ $and: [q, query] }, { $and: [qa, query] }];
return { $and: [queryClause, query] };
}
// otherwise just add the constaint
return [Object.assign({}, query, q), Object.assign({}, query, qa)];
return Object.assign({}, query, queryClause);
});
return { $or: ors };
return queries.length === 1 ? queries[0] : { $or: queries };
} else {
return query;
}