mirror of
https://github.com/dbgate/dbgate
synced 2024-11-07 20:26:23 +00:00
filter parser
This commit is contained in:
parent
064121376f
commit
2de6033dc9
@ -52,6 +52,29 @@ const compoudCondition = conditionType => conditions => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const unaryCondition = conditionType => () => {
|
||||||
|
return {
|
||||||
|
conditionType,
|
||||||
|
expr: {
|
||||||
|
exprType: 'placeholder',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const binaryFixedValueCondition = value => () => {
|
||||||
|
return {
|
||||||
|
conditionType: 'binary',
|
||||||
|
operator: '=',
|
||||||
|
left: {
|
||||||
|
exprType: 'placeholder',
|
||||||
|
},
|
||||||
|
right: {
|
||||||
|
exprType: 'value',
|
||||||
|
value,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
const parser = P.createLanguage({
|
const parser = P.createLanguage({
|
||||||
string1: () =>
|
string1: () =>
|
||||||
token(P.regexp(/"((?:\\.|.)*?)"/, 1))
|
token(P.regexp(/"((?:\\.|.)*?)"/, 1))
|
||||||
@ -72,16 +95,33 @@ const parser = P.createLanguage({
|
|||||||
.desc('number'),
|
.desc('number'),
|
||||||
|
|
||||||
noQuotedString: () =>
|
noQuotedString: () =>
|
||||||
P.regexp(/[^\s]+/)
|
P.regexp(/[^\s^,^'^"]+/)
|
||||||
.desc('string unquoted')
|
.desc('string unquoted')
|
||||||
.map(binaryCondition('=')),
|
.map(binaryCondition('=')),
|
||||||
|
|
||||||
comma: () => word(','),
|
comma: () => word(','),
|
||||||
not: () => word('NOT'),
|
not: () => word('NOT'),
|
||||||
notNull: r => r.not.then(r.null).map(() => 'NOT_NULL'),
|
notNull: r => r.not.then(r.null).map(unaryCondition('isNotNull')),
|
||||||
null: () => word('NULL'),
|
null: () => word('NULL').map(unaryCondition('isNull')),
|
||||||
|
empty: () => word('EMPTY').map(unaryCondition('isEmpty')),
|
||||||
|
notEmpty: r => r.not.then(r.empty).map(unaryCondition('isNotEmpty')),
|
||||||
|
true: () => word('TRUE').map(binaryFixedValueCondition(1)),
|
||||||
|
false: () => word('FALSE').map(binaryFixedValueCondition(0)),
|
||||||
|
|
||||||
element: r => P.alt(r.string1, r.string2, r.null, r.notNull, r.number, r.noQuotedString).trim(whitespace),
|
element: r =>
|
||||||
|
P.alt(
|
||||||
|
r.string1,
|
||||||
|
r.string2,
|
||||||
|
r.null,
|
||||||
|
r.notNull,
|
||||||
|
r.number,
|
||||||
|
r.empty,
|
||||||
|
r.notEmpty,
|
||||||
|
r.true,
|
||||||
|
r.false,
|
||||||
|
// must be last
|
||||||
|
r.noQuotedString
|
||||||
|
).trim(whitespace),
|
||||||
factor: r => r.element.sepBy(whitespace).map(compoudCondition('and')),
|
factor: r => r.element.sepBy(whitespace).map(compoudCondition('and')),
|
||||||
list: r => r.factor.sepBy(r.comma).map(compoudCondition('or')),
|
list: r => r.factor.sepBy(r.comma).map(compoudCondition('or')),
|
||||||
});
|
});
|
||||||
|
@ -5,11 +5,34 @@ import { dumpSqlExpression } from './dumpSqlExpression';
|
|||||||
export function dumpSqlCondition(dmp: SqlDumper, condition: Condition) {
|
export function dumpSqlCondition(dmp: SqlDumper, condition: Condition) {
|
||||||
switch (condition.conditionType) {
|
switch (condition.conditionType) {
|
||||||
case 'binary':
|
case 'binary':
|
||||||
dmp.put('(');
|
|
||||||
dumpSqlExpression(dmp, condition.left);
|
dumpSqlExpression(dmp, condition.left);
|
||||||
dmp.put(' %s ', condition.operator);
|
dmp.put(' %s ', condition.operator);
|
||||||
dumpSqlExpression(dmp, condition.right);
|
dumpSqlExpression(dmp, condition.right);
|
||||||
dmp.put(')');
|
|
||||||
break;
|
break;
|
||||||
|
case 'isNull':
|
||||||
|
dumpSqlExpression(dmp, condition.expr);
|
||||||
|
dmp.put(' ^is ^null');
|
||||||
|
break;
|
||||||
|
case 'isNotNull':
|
||||||
|
dumpSqlExpression(dmp, condition.expr);
|
||||||
|
dmp.put(' ^is ^not ^null');
|
||||||
|
break;
|
||||||
|
case 'isEmpty':
|
||||||
|
dmp.put('^trim(');
|
||||||
|
dumpSqlExpression(dmp, condition.expr);
|
||||||
|
dmp.put(") = ''");
|
||||||
|
break;
|
||||||
|
case 'isNotEmpty':
|
||||||
|
dmp.put('^trim(');
|
||||||
|
dumpSqlExpression(dmp, condition.expr);
|
||||||
|
dmp.put(") <> ''");
|
||||||
|
break;
|
||||||
|
case 'and':
|
||||||
|
case 'or':
|
||||||
|
dmp.putCollection(` ^${condition.conditionType} `, condition.conditions, cond => {
|
||||||
|
dmp.putRaw('(');
|
||||||
|
dumpSqlCondition(dmp, cond);
|
||||||
|
dmp.putRaw(')');
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,11 +34,21 @@ export interface BinaryCondition {
|
|||||||
right: Expression;
|
right: Expression;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface NotCondition extends UnaryCondition {
|
export interface NotCondition {
|
||||||
conditionType: 'not';
|
conditionType: 'not';
|
||||||
|
condition: Condition;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Condition = BinaryCondition | NotCondition;
|
export interface TestCondition extends UnaryCondition {
|
||||||
|
conditionType: 'isNull' | 'isNotNull' | 'isEmpty' | 'isNotEmpty';
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CompoudCondition {
|
||||||
|
conditionType: 'and' | 'or';
|
||||||
|
conditions: Condition[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Condition = BinaryCondition | NotCondition | TestCondition | CompoudCondition;
|
||||||
|
|
||||||
export interface Source {
|
export interface Source {
|
||||||
name?: NamedObjectInfo;
|
name?: NamedObjectInfo;
|
||||||
|
Loading…
Reference in New Issue
Block a user