mirror of
https://github.com/strapi/strapi.git
synced 2025-11-03 03:17:11 +00:00
Type cast filters
This commit is contained in:
parent
74919aafee
commit
f73d302129
@ -8,16 +8,6 @@ class Field {
|
|||||||
this.config = config;
|
this.config = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: impl
|
|
||||||
validate() {
|
|
||||||
// // use config validators directly
|
|
||||||
// if (this.config.validators) {
|
|
||||||
// this.config.validators.forEach(validator => {
|
|
||||||
// validator(value)
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
toDB(value) {
|
toDB(value) {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
const _ = require('lodash/fp');
|
const _ = require('lodash/fp');
|
||||||
|
|
||||||
const types = require('../../types');
|
const types = require('../../types');
|
||||||
|
const { createField } = require('../../fields');
|
||||||
const { createJoin } = require('./join');
|
const { createJoin } = require('./join');
|
||||||
const { toColumnName } = require('./transform');
|
const { toColumnName } = require('./transform');
|
||||||
|
|
||||||
@ -32,6 +33,45 @@ const ARRAY_OPERATORS = ['$in', '$notIn', '$between'];
|
|||||||
|
|
||||||
const isOperator = key => OPERATORS.includes(key);
|
const isOperator = key => OPERATORS.includes(key);
|
||||||
|
|
||||||
|
const castValue = (value, attribute) => {
|
||||||
|
if (!attribute) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (types.isScalar(attribute.type)) {
|
||||||
|
const field = createField(attribute);
|
||||||
|
|
||||||
|
return value === null ? null : field.toDB(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
|
||||||
|
const processAttributeWhere = (attribute, where, ctx) => {
|
||||||
|
if (_.isArray(where)) {
|
||||||
|
return where.map(sub => processAttributeWhere(attribute, sub, ctx));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_.isPlainObject(where)) {
|
||||||
|
return castValue(where, attribute);
|
||||||
|
}
|
||||||
|
|
||||||
|
const filters = {};
|
||||||
|
|
||||||
|
for (const key in where) {
|
||||||
|
const value = where[key];
|
||||||
|
|
||||||
|
if (isOperator(key)) {
|
||||||
|
filters[key] = processAttributeWhere(attribute, value, ctx);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error(`Undefined attribute level operator ${key}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return filters;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process where parameter
|
* Process where parameter
|
||||||
* @param {Object} where
|
* @param {Object} where
|
||||||
@ -39,7 +79,7 @@ const isOperator = key => OPERATORS.includes(key);
|
|||||||
* @param {number} depth
|
* @param {number} depth
|
||||||
* @returns {Object}
|
* @returns {Object}
|
||||||
*/
|
*/
|
||||||
const processWhere = (where, ctx, depth = 0) => {
|
const processWhere = (where, ctx) => {
|
||||||
if (!_.isArray(where) && !_.isPlainObject(where)) {
|
if (!_.isArray(where) && !_.isPlainObject(where)) {
|
||||||
throw new Error('Where must be an array or an object');
|
throw new Error('Where must be an array or an object');
|
||||||
}
|
}
|
||||||
@ -53,7 +93,7 @@ const processWhere = (where, ctx, depth = 0) => {
|
|||||||
return where;
|
return where;
|
||||||
}
|
}
|
||||||
|
|
||||||
return processWhere(where, ctx, depth + 1);
|
return processWhere(where, ctx);
|
||||||
};
|
};
|
||||||
|
|
||||||
const { db, uid, qb, alias } = ctx;
|
const { db, uid, qb, alias } = ctx;
|
||||||
@ -64,7 +104,6 @@ const processWhere = (where, ctx, depth = 0) => {
|
|||||||
// for each key in where
|
// for each key in where
|
||||||
for (const key in where) {
|
for (const key in where) {
|
||||||
const value = where[key];
|
const value = where[key];
|
||||||
const attribute = meta.attributes[key];
|
|
||||||
|
|
||||||
// if operator $and $or then loop over them
|
// if operator $and $or then loop over them
|
||||||
if (GROUP_OPERATORS.includes(key)) {
|
if (GROUP_OPERATORS.includes(key)) {
|
||||||
@ -78,28 +117,17 @@ const processWhere = (where, ctx, depth = 0) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isOperator(key)) {
|
if (isOperator(key)) {
|
||||||
if (depth == 0) {
|
throw new Error(`Only $and, $or and $not can by used as root level operators. Found ${key}.`);
|
||||||
throw new Error(
|
|
||||||
`Only $and, $or and $not can by used as root level operators. Found ${key}.`
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
filters[key] = processNested(value, ctx);
|
const attribute = meta.attributes[key];
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!attribute) {
|
if (!attribute) {
|
||||||
filters[qb.aliasColumn(key, alias)] = processNested(value, ctx);
|
filters[qb.aliasColumn(key, alias)] = processAttributeWhere(null, value, ctx);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// throw new Error(`Attribute ${key} not found on model ${uid}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// move to if else to check for scalar / relation / components & throw for other types
|
if (types.isRelation(attribute.type)) {
|
||||||
if (attribute.type === 'relation') {
|
|
||||||
// TODO: pass down some filters (e.g published at)
|
|
||||||
|
|
||||||
// attribute
|
// attribute
|
||||||
const subAlias = createJoin(ctx, {
|
const subAlias = createJoin(ctx, {
|
||||||
alias: alias || qb.alias,
|
alias: alias || qb.alias,
|
||||||
@ -127,9 +155,10 @@ const processWhere = (where, ctx, depth = 0) => {
|
|||||||
|
|
||||||
if (types.isScalar(attribute.type)) {
|
if (types.isScalar(attribute.type)) {
|
||||||
const columnName = toColumnName(meta, key);
|
const columnName = toColumnName(meta, key);
|
||||||
|
const aliasedColumnName = qb.aliasColumn(columnName, alias);
|
||||||
|
|
||||||
|
filters[aliasedColumnName] = processAttributeWhere(attribute, value, ctx);
|
||||||
|
|
||||||
// TODO: cast to DB type
|
|
||||||
filters[qb.aliasColumn(columnName, alias)] = processNested(value, ctx);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,7 +282,7 @@ const applyOperator = (qb, column, operator, value) => {
|
|||||||
// TODO: relational operators every/some/exists/size ...
|
// TODO: relational operators every/some/exists/size ...
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
throw new Error(`Undefined operator ${operator}`);
|
throw new Error(`Undefined attribute level operator ${operator}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -267,7 +296,6 @@ const applyWhereToColumn = (qb, column, columnWhere) => {
|
|||||||
return qb.where(column, columnWhere);
|
return qb.where(column, columnWhere);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: handle casing
|
|
||||||
Object.keys(columnWhere).forEach(operator => {
|
Object.keys(columnWhere).forEach(operator => {
|
||||||
const value = columnWhere[operator];
|
const value = columnWhere[operator];
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user