📄 absexpressions.pas
字号:
for i:=Low(SQLFieldTypes) to High(SQLFieldTypes) do
if SQLFieldTypes[i].SqlName = s then
begin
Result := SQLFieldTypes[i].AdvancedFieldType;
break;
end;
end;//GetFieldType
////////////////////////////////////////////////////////////////////////////////
//
// TABSExpression
//
////////////////////////////////////////////////////////////////////////////////
//------------------------------------------------------------------------------
// Constructor
//------------------------------------------------------------------------------
constructor TABSExpression.Create;
begin
FRootExprNode := nil;
LLex := nil;
FCaseInsensitive := False;
FPartialKey := False;
F3ValueLogic := True;
end;//Create
//------------------------------------------------------------------------------
// Constructor
//------------------------------------------------------------------------------
constructor TABSExpression.Create(RootNode: TABSExprNode);
begin
Create;
FRootExprNode := RootNode;
end;//Create
//------------------------------------------------------------------------------
// Constructor
//------------------------------------------------------------------------------
//constructor TABSExpression.Create(Lexer: TABSLexer);
//begin
// Create;
// LLex := Lexer;
//end;//Create
//------------------------------------------------------------------------------
// Destructor
//------------------------------------------------------------------------------
destructor TABSExpression.Destroy;
begin
Clear;
inherited;
end;//Destroy
//------------------------------------------------------------------------------
// Clear all Variables
//------------------------------------------------------------------------------
procedure TABSExpression.Clear;
begin
// free nodes tree
if (FRootExprNode <> nil) then
begin
FRootExprNode.Free;
FRootExprNode := nil;
end;
end;//Clear
//------------------------------------------------------------------------------
// Parsing for Locate
//------------------------------------------------------------------------------
procedure TABSExpression.ParseForLocate(
Cursor: TABSCursor;
FieldNames: String; // name1;name2
KeyValues: Variant; //
CaseInsensitive: boolean = true;
PartialKey: boolean = false
);
var
i, ArrLen: Integer;
FieldNamesList: TStringList;
//Arr: Pointer;
LeftNField: TABSExprNodeField;
RightNConst: TABSExprNodeConst;
EqNode: TABSExprNodeComparison;
IsArray: Boolean;
//AndNode: TABSExprNodeBoolean;
//val: TABSVariant;
procedure AssignConstValue(const Value: Variant);
begin
if (LeftNField.BaseFieldType in [bftDate, bftTime, bftDateTime]) and
(VarType(Value) in [varInteger, varDouble]) then
RightNConst.Value.AsVariant := TDateTime(Value)
else
RightNConst.Value.AsVariant := Value;
end;
begin
Clear;
LCursor := Cursor;
F3ValueLogic := False;
FieldNamesList := TStringList.Create;
try
FillFieldNames(FieldNamesList, FieldNames);
// Determinate KeyValues count (can be array)
if (VarType(KeyValues) and varArray ) <> 0 then
begin
IsArray := true;
ArrLen := VarArrayHighBound(KeyValues,1) - VarArrayLowBound(KeyValues,1) + 1
end
else
begin
IsArray := False;
ArrLen := 1;
end;
if (FieldNamesList.Count <> ArrLen) then
raise EABSException.Create(30112, ErrorGNotEqualCountsOfFieldNamesAndKeyValues,
[FieldNamesList.Count, ArrLen]);
if (not IsArray) then
begin
// Field
LeftNField := TABSExprNodeField.Create(LCursor, FieldNamesList[0]);
// Const
RightNConst := TABSExprNodeConst.Create;
AssignConstValue(KeyValues);
// RootNode
FRootExprNode := TABSExprNodeComparison.Create(doEQ, LeftNField,
RightNConst, F3ValueLogic, CaseInsensitive, PartialKey);
end
else
begin
FRootExprNode := TABSExprNodeBoolean.Create(doAND);
for i:=0 to ArrLen-1 do
begin
// Field
LeftNField := TABSExprNodeField.Create(LCursor, FieldNamesList[i]);
// Check FieldExists
// ...
// Const
RightNConst := TABSExprNodeConst.Create;
AssignConstValue(VarArrayGet(KeyValues, i));
// EqNode
EqNode := TABSExprNodeComparison.Create(doEQ, LeftNField, RightNConst,
F3ValueLogic, CaseInsensitive, PartialKey);
// Add to RootNode
FRootExprNode.Children.Add(EqNode);
end;
end;
finally
FieldNamesList.Free;
end;
if LCursor <> nil then
FRootExprNode.PatchWideStrings;
end;//ParseForLocate
//------------------------------------------------------------------------------
// Parsing for Filter
//------------------------------------------------------------------------------
procedure TABSExpression.ParseForFilter(Cursor: TABSCursor; Filter: String;
CaseInsensitive, PartialKey: boolean);
var
Lexer: TABSLexer;
begin
LCursor := Cursor;
FCaseInsensitive := CaseInsensitive;
FPartialKey := PartialKey;
Lexer := TABSLexer.Create(Filter);
try
if (Lexer.NumCommands = 0) then
raise EABSException.Create(30119, ErrorGBlankSqlCommand);
Lexer.GetNextCommand;
ParseForBooleanExpression(nil, Lexer);
finally
Lexer.Free;
end;
end;//ParseForFilter
//------------------------------------------------------------------------------
// parse for IsAnyRecordMatchCondition (for quantified subquery comparison)
//------------------------------------------------------------------------------
procedure TABSExpression.ParseForIsAnyRecordMatchCondition(
Cursor: TABSCursor;
const FieldName: string;
const Operator: TABSDataOperator;
const Value: TABSVariant
);
var
LeftNField: TABSExprNodeField;
RightNConst: TABSExprNodeConst;
begin
Clear;
LCursor := Cursor;
F3ValueLogic := False;
// Field
LeftNField := TABSExprNodeField.Create(LCursor, FieldName);
// Const
RightNConst := TABSExprNodeConst.Create;
RightNConst.Value.Assign(Value);
// RootNode
FRootExprNode := TABSExprNodeComparison.Create(Operator, LeftNField,
RightNConst, F3ValueLogic, False, False);
if LCursor <> nil then
FRootExprNode.PatchWideStrings;
end;// ParseForIsAnyRecordMatchCondition
//------------------------------------------------------------------------------
// Parse For Boolean Expression (Filter, Where-Clause)
//------------------------------------------------------------------------------
procedure TABSExpression.ParseForBooleanExpression(
Dataset: TDataset;
Lexer: TABSLexer
//CaseInsensitive: boolean = true;
//PartialKey: boolean = false
);
begin
Clear;
LDataset := Dataset;
LLex := Lexer;
if (not LLex.GetCurrentToken(Token)) then
raise EABSException.Create(30118, ErrorGUnexpectedEndOfCommand,
[Token.LineNum, Token.ColumnNum]);
// Parse...
FRootExprNode := ParseSearchCondition;
if (FRootExprNode = nil) then
raise EABSException.Create(30066, ErrorGBooleanExpressionExpected,
[Token.Text, Token.LineNum, Token.ColumnNum]);
MoveAndNodesToRoot;
if LCursor <> nil then
FRootExprNode.PatchWideStrings;
end;//ParseForBooleanExpression
//------------------------------------------------------------------------------
// Parse ValueExpression
//------------------------------------------------------------------------------
procedure TABSExpression.ParseForValueExpression(
Dataset: TDataset;
Lexer: TABSLexer
//CaseInsensitive: boolean = true;
//PartialKey: boolean = false
);
begin
LLex := Lexer;
LDataset := Dataset;
if (Dataset <> nil) then begin
FDatabaseName := TABSDataset(Dataset).DatabaseName;
FSessionName := TABSDataset(Dataset).SessionName;
end;
//LCursor := Cursor;
//FCaseInsensitive := CaseInsensitive;
//FPartialKey := PartialKey;
// get first token (for very beginning of the query) or current token
if (not LLex.GetCurrentToken(Token)) then
raise EABSException.Create(30136, ErrorGUnexpectedEndOfCommand, [Token.LineNum, Token.ColumnNum]);
// parse
FRootExprNode := ParseValueExpression;
end;//ParseForValueExpression
//------------------------------------------------------------------------------
// default value: const or function
//------------------------------------------------------------------------------
function TABSExpression.ParseForDefaultValueExpression(DefaultValue: String): Boolean;
var
Lexer: TABSLexer;
Token: TToken;
begin
try
Lexer := TABSLexer.Create(DefaultValue);
try
if (Lexer.NumCommands = 0) then
Result := False
else
begin
Lexer.GetNextCommand;
ParseForValueExpression(nil, Lexer);
Result := (Lexer.NumCommands = 1) and (not Lexer.LookNextToken(Token));
end;
finally
Lexer.Free;
end;
except
Result := False;
end;
end;// ParseForDefaultValueExpression
//------------------------------------------------------------------------------
// Parse RowSubqueryExpression
//------------------------------------------------------------------------------
procedure TABSExpression.ParseForRowSubqueryExpression(
Dataset: TDataset;
Lexer: TABSLexer);
begin
LLex := Lexer;
LDataset := Dataset;
FDatabaseName := TABSDataset(Dataset).DatabaseName;
FSessionName := TABSDataset(Dataset).SessionName;
// get first token (for very beginning of the query) or current token
if (not LLex.GetCurrentToken(Token)) then
raise EABSException.Create(30497, ErrorGUnexpectedEndOfCommand, [Token.LineNum, Token.ColumnNum]);
// parse
FRootExprNode := ParseRowSubquery(False, False);
end;// ParseForRowSubqueryExpression
//------------------------------------------------------------------------------
// Return Variant
//------------------------------------------------------------------------------
function TABSExpression.GetValue(TrueFalseNullLogic: boolean): TABSVariant;
begin
if FRootExprNode <> nil then
begin
Result := FRootExprNode.GetDataValue;
if ( Result.IsNull and (not TrueFalseNullLogic) ) then
Result.AsBoolean := False;
end
else
Result := nil;
end;//GetValue
//------------------------------------------------------------------------------
// Get Boolean result
//------------------------------------------------------------------------------
function TABSExpression.GetResult: Boolean;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -