📄 dbutilseh.pas
字号:
if S[Pos] = '''' then
begin
for i := Pos + 1 to Length(S) do
if S[i] = '''' then
begin
Result := Copy(S, Pos + 1, i - Pos - 1);
Pos := i + 1;
Exit;
end;
raise Exception.Create(SQuoteIsAbsentEh + S);
end
else
begin
for i := Pos to Length(S) do
begin
if ((S[i] in [' ']) and CheckForOperand(S, SkipBlanks(S, i))) or
((S[i] in [')', '('])) or
(PreferCommaForList and (S[i] = ',')) then
begin
Result := Copy(S, Pos, i - Pos);
Pos := i;
Exit;
end;
end;
Result := Copy(S, Pos, MAXINT);
Pos := Length(S) + 1;
end;
end;
function ReadValues(S: String; var Pos: Integer; PreferCommaForList: Boolean): Variant;
var
i: Integer;
vArr: Variant;
begin
i := 0;
vArr := VarArrayCreate([0, 0], varVariant);
while True do
begin
vArr[i] := ReadValue(S, Pos, PreferCommaForList);
if vArr[i] = Null then
Break;
if PreferCommaForList and (CharAtPos(S, Pos) = ',') then
Inc(Pos)
else
Break;
Inc(i);
VarArrayRedimEh(vArr, i);
end;
if i = 0 then
Result := vArr[0]
else
Result := vArr;
end;
function GetLexeme(S: String; var Pos: Integer; var Operator: TSTFilterOperatorEh;
PreferCommaForList: Boolean): Variant;
var
Oper: TOperator;
Operator1: TSTFilterOperatorEh;
TheWord: String;
function ReadWord(S: String; Pos: Integer): String;
var
c: Char;
NextPos: Integer;
begin
Result := '';
while True do
begin
c := CharAtPos(S, Pos);
if (c < #32) or (c in [' ','(',')','>','<','=','!','~','&','|','.',',','''','"','+','-']) then
Exit;
NextPos := NextCharIndex(S,Pos);
Result := Result + Copy(S,Pos,NextPos-Pos);
Pos := NextPos;
end;
end;
begin
Operator := foNon;
Oper := opNon;
Result := '';
if Length(S) < Pos then
Exit;
if S[Pos] = '''' then
begin
Result := ReadValues(S, Pos, PreferCommaForList);
Operator := foValue;
end
else
begin
case S[Pos] of
'!':
if CharAtPos(S, Pos + 1) = '=' then
SetOperatorPos(Pos, 2, Oper, opNotEqual)
else
SetOperatorPos(Pos, 1, Oper, opNot);
'=':
SetOperatorPos(Pos, 1, Oper, opEqual);
'(':
SetOperatorPos(Pos, 1, Oper, opOpenBracket);
'>':
if CharAtPos(S, Pos + 1) = '=' then
SetOperatorPos(Pos, 2, Oper, opGreaterOrEqual)
else
SetOperatorPos(Pos, 1, Oper, opGreaterThan);
'<':
if CharAtPos(S, Pos + 1) = '=' then
SetOperatorPos(Pos, 2, Oper, opLessOrEqual)
else if CharAtPos(S, Pos + 1) = '>' then
SetOperatorPos(Pos, 2, Oper, opNotEqual)
else
SetOperatorPos(Pos, 1, Oper, opLessThan);
'~':
SetOperatorPos(Pos, 1, Oper, opLike);
'&':
SetOperatorPos(Pos, 1, Oper, opAnd); //And
'|':
SetOperatorPos(Pos, 1, Oper, opOr); // Or
else
TheWord := ReadWord(S,Pos);
Oper := GetOperatorByWord(TheWord);
if Oper <> opNon then
Inc(Pos, Length(TheWord));
end; //case
if Oper = opNon then
begin
Result := ReadValues(S, Pos, PreferCommaForList);
if VarIsNull(Result) then
Operator := foNon
else
Operator := foValue;
Exit;
end;
Pos := SkipBlanks(S, Pos);
if Oper = opNot then
begin
GetLexeme(S, Pos, Operator1, PreferCommaForList);
case Operator1 of
foLike: Operator := foNotLike;
foIn: Operator := foNotIn;
foNull: Operator := foNotNull;
end
end
else if Oper = opIn then
begin
if CharAtPos(S, Pos) = '(' then
Inc(Pos)
else
raise Exception.Create(SLeftBracketExpectedEh + S);
Operator := foIn;
end
else
Operator := OperatorAdvFilterOperatorMap[Oper];
end;
end;
function ParseSTFilterExpression(Exp: String; var FExpression: TSTFilterExpressionEh): Boolean;
var
PreferCommaForList: Boolean;
procedure ResetPreferCommaForList;
begin
if (FExpression.ExpressionType = botNumber) and (DecimalSeparator = ',') then
PreferCommaForList := False
else
PreferCommaForList := True;
end;
var
v: Variant;
op, op1: TSTFilterOperatorEh;
p: Integer;
begin
Result := False;
ResetPreferCommaForList;
FExpression.Operator1 := foNon;
FExpression.Operand1 := Null;
FExpression.Relation := foNon;
FExpression.Operator2 := foNon;
FExpression.Operand2 := Null;
Exp := Trim(Exp);
if Exp = '' then
Exit;
// 1 [Oper] + Values
p := SkipBlanks(Exp, 1);
v := GetLexeme(Exp, p, op, PreferCommaForList);
if op = foValue then
begin
if VarIsArray(v) then
FExpression.Operator1 := foIn
else if FExpression.ExpressionType = botString then
FExpression.Operator1 := foLike
else
FExpression.Operator1 := foEqual;
FExpression.Operand1 := v;
end
else if (op = foNon) and (Length(Exp) <> 0) then
raise Exception.Create(SErrorInExpressionEh + Exp)
else
begin
if op in [foIn, foNotIn] then
PreferCommaForList := True;
p := SkipBlanks(Exp, p);
v := GetLexeme(Exp, p, op1, PreferCommaForList);
FExpression.Operator1 := op;
if op1 = foNull then
if op = foEqual then
FExpression.Operator1 := foNull
else if op = foNotEqual then
FExpression.Operator1 := foNotNull
else
raise Exception.Create(SUnexpectedExpressionBeforeNullEh + Exp)
else if op1 <> foValue then
raise Exception.Create(SUnexpectedExpressionAfterOperatorEh + Exp);
FExpression.Operand1 := v;
if op in [foIn, foNotIn] then
begin
p := SkipBlanks(Exp, p);
if CharAtPos(Exp, p) = ')' then
Inc(p)
else
raise Exception.Create(SRightBracketExpectedEh + Exp);
ResetPreferCommaForList;
end;
end;
while True do
begin
// 2 And or Or
p := SkipBlanks(Exp, p);
v := GetLexeme(Exp, p, op, PreferCommaForList);
if op = foNon then
if p <> Length(Exp) + 1 then
raise Exception.Create(SIncorrectExpressionEh + Exp)
else
Break;
if not (op in [foAND, foOR]) then
raise Exception.Create(SUnexpectedANDorOREh + Exp);
FExpression.Relation := op;
// 3 [Oper] + Values
p := SkipBlanks(Exp, p);
v := GetLexeme(Exp, p, op, PreferCommaForList);
if op = foNon then
if p <> Length(Exp) + 1 then
raise Exception.Create(SIncorrectExpressionEh + Exp)
else
Break;
if op = foValue then
begin
if VarIsArray(v) then
FExpression.Operator2 := foIn
else if FExpression.ExpressionType = botString then
FExpression.Operator2 := foLike
else
FExpression.Operator2 := foEqual;
FExpression.Operand2 := v;
end
else if (op = foNon) and (Length(Exp) <> 0) then
raise Exception.Create(SErrorInExpressionEh + Exp)
else
begin
if op in [foIn, foNotIn] then
PreferCommaForList := True;
p := SkipBlanks(Exp, p);
v := GetLexeme(Exp, p, op1, PreferCommaForList);
FExpression.Operator2 := op;
if op1 = foNull then
if op = foEqual then
FExpression.Operator2 := foNull
else if op = foNotEqual then
FExpression.Operator2 := foNotNull
else
raise Exception.Create(SUnexpectedExpressionBeforeNullEh + Exp)
else if op1 <> foValue then
raise Exception.Create(SUnexpectedExpressionAfterOperatorEh + Exp);
FExpression.Operand2 := v;
ResetPreferCommaForList;
end;
Result := True;
Break;
end;
if FExpression.Operator1 in [foEqual..foNotIn] then
ConvertVarStrValues(FExpression.Operand1, FExpression.ExpressionType)
else
FExpression.Operand1 := Null;
if FExpression.Operator2 in [foEqual..foNotIn] then
ConvertVarStrValues(FExpression.Operand2, FExpression.ExpressionType)
else
FExpression.Operand2 := Null;
end;
function ParseSTFilterExpressionEh(Exp: String; var FExpression: TSTFilterExpressionEh): Boolean;
var
PreferCommaForList: Boolean;
procedure ResetPreferCommaForList;
begin
if (FExpression.ExpressionType = botNumber) and (DecimalSeparator = ',') then
PreferCommaForList := False
else
PreferCommaForList := True;
end;
var
v: Variant;
op, op1: TSTFilterOperatorEh;
p: Integer;
begin
Result := False;
ResetPreferCommaForList;
FExpression.Operator1 := foNon;
FExpression.Operand1 := Null;
FExpression.Relation := foNon;
FExpression.Operator2 := foNon;
FExpression.Operand2 := Null;
Exp := Trim(Exp);
if Exp = '' then
Exit;
// 1 [Oper] + Values
p := SkipBlanks(Exp, 1);
v := GetLexeme(Exp, p, op, PreferCommaForList);
if op = foValue then
begin
if VarIsArray(v) then
FExpression.Operator1 := foIn
else if FExpression.ExpressionType = botString then
FExpression.Operator1 := foLike
else
FExpression.Operator1 := foEqual;
FExpression.Operand1 := v;
end
else if (op = foNon) and (Length(Exp) <> 0) then
raise Exception.Create(SErrorInExpressionEh + Exp)
else
begin
if op in [foIn, foNotIn] then
PreferCommaForList := True;
p := SkipBlanks(Exp, p);
v := GetLexeme(Exp, p, op1, PreferCommaForList);
FExpression.Operator1 := op;
if op1 = foNull then
if op = foEqual then
FExpression.Operator1 := foNull
else if op = foNotEqual then
FExpression.Operator1 := foNotNull
else
raise Exception.Create(SUnexpectedExpressionBeforeNullEh + Exp)
else if op1 <> foValue then
raise Exception.Create(SUnexpectedExpressionAfterOperatorEh + Exp);
FExpression.Operand1 := v;
if op in [foIn, foNotIn] then
begin
p := SkipBlanks(Exp, p);
if CharAtPos(Exp, p) = ')' then
Inc(p)
else
raise Exception.Create(SRightBracketExpectedEh + Exp);
ResetPreferCommaForList;
end;
end;
while True do
begin
// 2 And or Or
p := SkipBlanks(Exp, p);
v := GetLexeme(Exp, p, op, PreferCommaForList);
if op = foNon then
if p <> Length(Exp) + 1 then
raise Exception.Create(SIncorrectExpressionEh + Exp)
else
Break;
if not (op in [foAND, foOR]) then
raise Exception.Create(SUnexpectedANDorOREh + Exp);
FExpression.Relation := op;
// 3 [Oper] + Values
p := SkipBlanks(Exp, p);
v := GetLexeme(Exp, p, op, PreferCommaForList);
if op = foNon then
if p <> Length(Exp) + 1 then
raise Exception.Create(SIncorrectExpressionEh + Exp)
else
Break;
if op = foValue then
begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -