New query condition support to match all strings that starts with some other given strings (#3864)
* feat: Convert $regex value to RegExp object
* feat: Add lib folder
* Revert "feat: Add lib folder"
This reverts commit c9dfbcbf699ff220baeb2df5586a944d19808e5e.
* feat: Add $regex test in $all array
* test: Test regex with $all only in MongoDB
* Revert "test: Test regex with $all only in MongoDB"
This reverts commit d7194c7869dee98d924fbc2502593a198385dba1.
* feat: Add tests for containsAllStartingWith
* feat: Add postgres support
Thanks to @dplewis
* feat: Check that all values in $all must be regex or none
* test: Check that $all vaules must be regex or none
* feat: Update tests to use only REST API
* refactor: Move $all regex check to adapter
* feat: Check for valid $all values in progres
* refactor: Update function name
* fix: Postgres $all values regex checking
* fix: Check starts with as string
* fix: Define contains all regex sql function
* fix: Wrong value check
* fix: Check valid data
* fix: Check regex when there is only one value
* fix: Constains all starting with string returns empty with bad params
* fix: Pass correct regex value
* feat: Add missing tests
* feat: Add missing tests
* feat: Add more tests
* fix: Unify MongoDB and PostgreSQL functionality
* fix: Lint checks
* fix: Test broken
$regex in $all list must be { $regex: "string" }
* test for empty $all
This commit is contained in:
committed by
Diamond Lewis
parent
2c357df33e
commit
c0e3672e32
@@ -123,6 +123,44 @@ const transformKeyValueForUpdate = (className, restKey, restValue, parseFormatSc
|
||||
return {key, value};
|
||||
}
|
||||
|
||||
const isRegex = value => {
|
||||
return value && (value instanceof RegExp)
|
||||
}
|
||||
|
||||
const isStartsWithRegex = value => {
|
||||
if (!isRegex(value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const matches = value.toString().match(/\/\^\\Q.*\\E\//);
|
||||
return !!matches;
|
||||
}
|
||||
|
||||
const isAllValuesRegexOrNone = values => {
|
||||
if (!values || !Array.isArray(values) || values.length === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const firstValuesIsRegex = isStartsWithRegex(values[0]);
|
||||
if (values.length === 1) {
|
||||
return firstValuesIsRegex;
|
||||
}
|
||||
|
||||
for (let i = 1, length = values.length; i < length; ++i) {
|
||||
if (firstValuesIsRegex !== isStartsWithRegex(values[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const isAnyValueRegex = values => {
|
||||
return values.some(function (value) {
|
||||
return isRegex(value);
|
||||
});
|
||||
}
|
||||
|
||||
const transformInteriorValue = restValue => {
|
||||
if (restValue !== null && typeof restValue === 'object' && Object.keys(restValue).some(key => key.includes('$') || key.includes('.'))) {
|
||||
throw new Parse.Error(Parse.Error.INVALID_NESTED_KEY, "Nested keys should not contain the '$' or '.' characters");
|
||||
@@ -469,6 +507,8 @@ const transformInteriorAtom = (atom) => {
|
||||
return DateCoder.JSONToDatabase(atom);
|
||||
} else if (BytesCoder.isValidJSON(atom)) {
|
||||
return BytesCoder.JSONToDatabase(atom);
|
||||
} else if (typeof atom === 'object' && atom && atom.$regex !== undefined) {
|
||||
return new RegExp(atom.$regex);
|
||||
} else {
|
||||
return atom;
|
||||
}
|
||||
@@ -740,6 +780,13 @@ function transformConstraint(constraint, field) {
|
||||
'bad ' + key + ' value');
|
||||
}
|
||||
answer[key] = arr.map(transformInteriorAtom);
|
||||
|
||||
const values = answer[key];
|
||||
if (isAnyValueRegex(values) && !isAllValuesRegexOrNone(values)) {
|
||||
throw new Parse.Error(Parse.Error.INVALID_JSON, 'All $all values must be of regex type or none: '
|
||||
+ values);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case '$regex':
|
||||
|
||||
Reference in New Issue
Block a user