Set min mongodb to 3.6 in prep for parse-server 4.0 (#6445)

* Set min mongodb to 3.6 in prep for parse-server 4.0

fixes: 6444

* don't use anonymous functions when we can just
pass the function.

Also remove the boolean argument in tests that no longer exists.

* generate the correct lock file.  ooops.
This commit is contained in:
Arthur Cinader
2020-02-27 10:56:14 -08:00
committed by GitHub
parent 9d7da58129
commit 5c7918980c
10 changed files with 60 additions and 207 deletions

View File

@@ -69,73 +69,14 @@ const isSpecialQueryKey = key => {
return specialQuerykeys.indexOf(key) >= 0;
};
const validateQuery = (
query: any,
skipMongoDBServer13732Workaround: boolean
): void => {
const validateQuery = (query: any): void => {
if (query.ACL) {
throw new Parse.Error(Parse.Error.INVALID_QUERY, 'Cannot query on ACL.');
}
if (query.$or) {
if (query.$or instanceof Array) {
query.$or.forEach(el =>
validateQuery(el, skipMongoDBServer13732Workaround)
);
if (!skipMongoDBServer13732Workaround) {
/* In MongoDB 3.2 & 3.4, $or queries which are not alone at the top
* level of the query can not make efficient use of indexes due to a
* long standing bug known as SERVER-13732.
*
* This bug was fixed in MongoDB version 3.6.
*
* For versions pre-3.6, the below logic produces a substantial
* performance improvement inside the database by avoiding the bug.
*
* For versions 3.6 and above, there is no performance improvement and
* the logic is unnecessary. Some query patterns are even slowed by
* the below logic, due to the bug having been fixed and better
* query plans being chosen.
*
* When versions before 3.4 are no longer supported by this project,
* this logic, and the accompanying `skipMongoDBServer13732Workaround`
* flag, can be removed.
*
* This block restructures queries in which $or is not the sole top
* level element by moving all other top-level predicates inside every
* subdocument of the $or predicate, allowing MongoDB's query planner
* to make full use of the most relevant indexes.
*
* EG: {$or: [{a: 1}, {a: 2}], b: 2}
* Becomes: {$or: [{a: 1, b: 2}, {a: 2, b: 2}]}
*
* The only exceptions are $near and $nearSphere operators, which are
* constrained to only 1 operator per query. As a result, these ops
* remain at the top level
*
* https://jira.mongodb.org/browse/SERVER-13732
* https://github.com/parse-community/parse-server/issues/3767
*/
Object.keys(query).forEach(key => {
const noCollisions = !query.$or.some(subq =>
Object.prototype.hasOwnProperty.call(subq, key)
);
let hasNears = false;
if (query[key] != null && typeof query[key] == 'object') {
hasNears = '$near' in query[key] || '$nearSphere' in query[key];
}
if (key != '$or' && noCollisions && !hasNears) {
query.$or.forEach(subquery => {
subquery[key] = query[key];
});
delete query[key];
}
});
query.$or.forEach(el =>
validateQuery(el, skipMongoDBServer13732Workaround)
);
}
query.$or.forEach(validateQuery);
} else {
throw new Parse.Error(
Parse.Error.INVALID_QUERY,
@@ -146,9 +87,7 @@ const validateQuery = (
if (query.$and) {
if (query.$and instanceof Array) {
query.$and.forEach(el =>
validateQuery(el, skipMongoDBServer13732Workaround)
);
query.$and.forEach(validateQuery);
} else {
throw new Parse.Error(
Parse.Error.INVALID_QUERY,
@@ -159,9 +98,7 @@ const validateQuery = (
if (query.$nor) {
if (query.$nor instanceof Array && query.$nor.length > 0) {
query.$nor.forEach(el =>
validateQuery(el, skipMongoDBServer13732Workaround)
);
query.$nor.forEach(validateQuery);
} else {
throw new Parse.Error(
Parse.Error.INVALID_QUERY,
@@ -487,21 +424,15 @@ class DatabaseController {
adapter: StorageAdapter;
schemaCache: any;
schemaPromise: ?Promise<SchemaController.SchemaController>;
skipMongoDBServer13732Workaround: boolean;
_transactionalSession: ?any;
constructor(
adapter: StorageAdapter,
schemaCache: any,
skipMongoDBServer13732Workaround: boolean
) {
constructor(adapter: StorageAdapter, schemaCache: any) {
this.adapter = adapter;
this.schemaCache = schemaCache;
// We don't want a mutable this.schema, because then you could have
// one request that uses different schemas for different parts of
// it. Instead, use loadSchema to get a schema.
this.schemaPromise = null;
this.skipMongoDBServer13732Workaround = skipMongoDBServer13732Workaround;
this._transactionalSession = null;
}
@@ -660,7 +591,7 @@ class DatabaseController {
if (acl) {
query = addWriteACL(query, acl);
}
validateQuery(query, this.skipMongoDBServer13732Workaround);
validateQuery(query);
return schemaController
.getOneSchema(className, true)
.catch(error => {
@@ -939,7 +870,7 @@ class DatabaseController {
if (acl) {
query = addWriteACL(query, acl);
}
validateQuery(query, this.skipMongoDBServer13732Workaround);
validateQuery(query);
return schemaController
.getOneSchema(className)
.catch(error => {
@@ -1460,7 +1391,7 @@ class DatabaseController {
query = addReadACL(query, aclGroup);
}
}
validateQuery(query, this.skipMongoDBServer13732Workaround);
validateQuery(query);
if (count) {
if (!classExists) {
return 0;
@@ -1893,7 +1824,7 @@ class DatabaseController {
]);
}
static _validateQuery: (any, boolean) => void;
static _validateQuery: any => void;
}
module.exports = DatabaseController;

View File

@@ -171,7 +171,6 @@ export function getDatabaseController(
const {
databaseURI,
databaseOptions,
skipMongoDBServer13732Workaround,
collectionPrefix,
schemaCacheTTL,
enableSingleSchemaCache,
@@ -195,8 +194,7 @@ export function getDatabaseController(
}
return new DatabaseController(
databaseAdapter,
new SchemaCache(cacheController, schemaCacheTTL, enableSingleSchemaCache),
skipMongoDBServer13732Workaround
new SchemaCache(cacheController, schemaCacheTTL, enableSingleSchemaCache)
);
}