输入
{
"where": {
"number": {
"gt": 35
},
"OR": [
{
"name1": {
"startsWith": "ssss"
},
"name2": {
"not": {
"contains":"22"
}
},
"name3": "35"
},
{
"name1": "35"
}
]
}
}
转换代码
注:图中所使用的的函数是lodash的函数
import { concat, isArray, template } from 'lodash';
export class Builder {
static generateWhere(condition: object, name?: string, negate?: string) {
let arr = [];
// key是prisma where条件中的关键词,value值是lodash中模板字符串
const kvMap = new Map([
['contains', '(<%=negate%>@<%=key%>_ext:{<%=value%>})'],
['startsWith', '(<%=negate%>@<%=key%>_ext:{<%=value%>*})'],
['equals', '(<%=negate%>@<%=key%>:{<%=value%>})'],
['gt', '(<%=negate%>@<%=key%>:[(<%=value%> +inf])'],
['lt', '(<%=negate%>@<%=key%>:[-inf (<%=value%>])'],
['lte', '(<%=negate%>@<%=key%>:[-inf <%=value%>])'],
['gte', '(<%=negate%>@<%=key%>:[<%=value%> +inf])'],
['in', '(<%=negate%>@<%=key%>:{<%=value.join("|")%>})'],
]);
// 使用map简化if else代码
for (const [key, value] of Object.entries(condition)) {
if (kvMap.has(key)) {
const compiled = template(kvMap.get(key));
// 编译模板字符串
arr.push(
compiled({
key: name,
value: value,
negate: negate,
})
);
} else if (key === 'AND') {
/// 是AND,就继续递归
if (isArray(value)) {
if (value.length !== 1) {
arr.push('(');
}
for (const it of value) {
arr = concat(arr, this.generateWhere(it));
}
if (value.length !== 1) {
arr.push(')');
}
} else {
arr.push('(');
arr = concat(arr, this.generateWhere(value));
arr.push(')');
}
} else if (key === 'OR') {
/// 是OR,就继续递归
/// 如果是 OR:[{"name1":"222"}]
if (isArray(value) && value.length === 1) {
arr = concat(
arr,
this.generateWhere({
OR: value[0],
})
);
} else if (isArray(value) && value.length > 1) {
for (let i = 0; i < value.length; i++) {
arr = concat(arr, this.generateWhere({ OR: value[i] }));
}
} else if (UtilGroup.isObject(value)) {
if (Object.keys(value).length === 1) {
arr.push('|');
} else {
arr.push('|(');
}
arr = concat(arr, this.generateWhere(value));
if (Object.keys(value).length !== 1) {
arr.push(')');
}
}
} else if (key === 'not') {
/// 是对象,就继续递归
if (UtilGroup.isString(value)) {
const temp = {};
temp[`${name}`] = value;
arr = concat(arr, this.generateWhere(temp, undefined, '-'));
} else {
arr = concat(arr, this.generateWhere(value, name, '-'));
}
} else if (UtilGroup.isObject(value)) {
/// 是对象,就继续递归
arr = concat(arr, this.generateWhere(value, key));
} else {
if (negate) {
arr.push(`(${negate}@${key}:{${value}})`);
} else {
arr.push(`(@${key}:{${value}})`);
}
}
}
return arr;
}
/**
* 判断是否是对象
* @param value
*/
static isObject(value: any) {
return Object.prototype.toString.call(value) === '[object Object]';
}
/**
* 判断是否是字符串
* @param value
*/
static isString(value: any) {
return Object.prototype.toString.call(value) === '[object String]';
}
}
调用
const data: string = Builder.generateWhere(params).join('');
输出
(@number:[(35 +inf])|((@name1_ext:{ssss*})(-@name2_ext:{22})(@name3:{35}))|(@name1:{35})
推荐
redis-om
prisma