custom SQL condition #369

This commit is contained in:
Jan Prochazka 2022-09-17 21:42:20 +02:00
parent a89c6810aa
commit 973f64f4d7
4 changed files with 51 additions and 3 deletions

View File

@ -190,6 +190,16 @@ const unaryCondition = conditionType => () => {
};
};
const sqlTemplate = templateSql => {
return {
conditionType: 'rawTemplate',
templateSql,
expr: {
exprType: 'placeholder',
},
};
};
const createParser = () => {
const langDef = {
comma: () => word(','),
@ -198,6 +208,11 @@ const createParser = () => {
notNull: r => r.not.then(r.null).map(unaryCondition('isNotNull')),
null: () => word('NULL').map(unaryCondition('isNull')),
sql: () =>
token(P.regexp(/\{(.*?)\}/, 1))
.map(sqlTemplate)
.desc('sql literal'),
yearNum: () => P.regexp(/\d\d\d\d/).map(yearCondition()),
yearMonthNum: () => P.regexp(/\d\d\d\d-\d\d?/).map(yearMonthCondition()),
yearMonthDayNum: () => P.regexp(/\d\d\d\d-\d\d?-\d\d?/).map(yearMonthDayCondition()),
@ -282,7 +297,8 @@ const createParser = () => {
r.le,
r.lt,
r.ge,
r.gt
r.gt,
r.sql
).trim(whitespace),
factor: r => r.element.sepBy(whitespace).map(compoudCondition('$and')),
list: r => r.factor.sepBy(r.comma).map(compoudCondition('$or')),

View File

@ -68,6 +68,16 @@ const negateCondition = condition => {
};
};
const sqlTemplate = templateSql => {
return {
conditionType: 'rawTemplate',
templateSql,
expr: {
exprType: 'placeholder',
},
};
};
const createParser = (filterType: FilterType) => {
const langDef = {
string1: () =>
@ -97,6 +107,11 @@ const createParser = (filterType: FilterType) => {
noQuotedString: () => P.regexp(/[^\s^,^'^"]+/).desc('string unquoted'),
sql: () =>
token(P.regexp(/\{(.*?)\}/, 1))
.map(sqlTemplate)
.desc('sql literal'),
value: r => P.alt(...allowedValues.map(x => r[x])),
valueTestEq: r => r.value.map(binaryCondition('=')),
valueTestStr: r => r.value.map(likeCondition('like', '%#VALUE#%')),
@ -139,7 +154,7 @@ const createParser = (filterType: FilterType) => {
allowedValues.push('string1Num', 'string2Num', 'number');
}
const allowedElements = ['null', 'notNull', 'eq', 'ne', 'ne2'];
const allowedElements = ['null', 'notNull', 'eq', 'ne', 'ne2', 'sql'];
if (filterType == 'number' || filterType == 'datetime' || filterType == 'eval') {
allowedElements.push('le', 'ge', 'lt', 'gt');
}

View File

@ -72,5 +72,15 @@ export function dumpSqlCondition(dmp: SqlDumper, condition: Condition) {
dumpSqlExpression(dmp, condition.expr);
dmp.put(' ^in (%,v)', condition.values);
break;
case 'rawTemplate':
let was = false;
for (const item of condition.templateSql.split('$$')) {
if (was) {
dumpSqlExpression(dmp, condition.expr);
}
dmp.putRaw(item);
was = true;
}
break;
}
}

View File

@ -105,6 +105,12 @@ export interface InCondition {
values: any[];
}
export interface RawTemplateCondition {
conditionType: 'rawTemplate';
templateSql: string;
expr: Expression;
}
export type Condition =
| BinaryCondition
| NotCondition
@ -114,7 +120,8 @@ export type Condition =
| ExistsCondition
| NotExistsCondition
| BetweenCondition
| InCondition;
| InCondition
| RawTemplateCondition;
export interface Source {
name?: NamedObjectInfo;