Improve recursive filtering (#4493)

* Use lowercase chars only

* Fix join alias mapping

* Pass keys as array in delete

* Cleanup delete controller

* Don't catch unexpected errors
This commit is contained in:
Rijk van Zanten
2021-03-11 17:56:04 -05:00
committed by GitHub
parent 7bd5dc5c9f
commit b613ce1d18
4 changed files with 31 additions and 31 deletions

View File

@@ -1,11 +1,13 @@
import { Knex } from 'knex';
import { Query, Filter, Relation, SchemaOverview } from '../types';
import { clone, isPlainObject } from 'lodash';
import { clone, isPlainObject, get, set } from 'lodash';
import { systemRelationRows } from '../database/system-data/relations';
import { nanoid } from 'nanoid';
import { customAlphabet } from 'nanoid';
import getLocalType from './get-local-type';
import validate from 'uuid-validate';
const generateAlias = customAlphabet('abcdefghijklmnopqrstuvwxyz', 5);
export default function applyQuery(
collection: string,
dbQuery: Knex.QueryBuilder,
@@ -100,8 +102,9 @@ export function applyFilter(
const isM2O = relation.many_collection === parentCollection && relation.many_field === pathParts[0];
const alias = nanoid(8);
aliasMap[pathParts.join('+')] = alias;
const alias = generateAlias();
set(aliasMap, parentAlias ? [parentAlias, ...pathParts] : pathParts, alias);
if (isM2O) {
dbQuery.leftJoin(
@@ -275,13 +278,13 @@ export function applyFilter(
function getWhereColumn(path: string[], collection: string) {
path = clone(path);
let columnName = '';
return followRelation(path);
followRelation(path);
return columnName;
function followRelation(pathParts: string[], parentCollection: string = collection) {
function followRelation(
pathParts: string[],
parentCollection: string = collection,
parentAlias?: string
): string | void {
const relation = relations.find((relation) => {
return (
(relation.many_collection === parentCollection && relation.many_field === pathParts[0]) ||
@@ -292,18 +295,18 @@ export function applyFilter(
if (!relation) return;
const isM2O = relation.many_collection === parentCollection && relation.many_field === pathParts[0];
const alias = aliasMap[pathParts.join('+')];
const alias = get(aliasMap, parentAlias ? [parentAlias, ...pathParts] : pathParts);
pathParts.shift();
const remainingParts = pathParts.slice(1);
const parent = isM2O ? relation.one_collection! : relation.many_collection;
if (pathParts.length === 1) {
columnName = `${alias || parent}.${pathParts[0]}`;
if (remainingParts.length === 1) {
return `${alias || parent}.${remainingParts[0]}`;
}
if (pathParts.length) {
followRelation(pathParts, parent);
if (remainingParts.length) {
return followRelation(remainingParts, parent, alias);
}
}
}