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