?? myldbexpressions.pas
字號:
doMAX: Result := 'MAX';
doCOUNT: Result := 'COUNT';
doCOUNTALL: Result := 'COUNT(*)';
else Result:='unknown';
end;
end;//GetOperatorName
//------------------------------------------------------------------------------
// Return FieldType
//------------------------------------------------------------------------------
function GetFieldType(const TypeName: string): TMYLDBAdvancedFieldType;
var
i: Integer;
s: String;
begin
Result := aftUnknown;
s := UpperCase(TypeName);
for i:=Low(SQLFieldTypes) to High(SQLFieldTypes) do
if SQLFieldTypes[i].SqlName = s then
begin
Result := SQLFieldTypes[i].AdvancedFieldType;
break;
end;
end;//GetFieldType
////////////////////////////////////////////////////////////////////////////////
//
// TMYLDBExpression
//
////////////////////////////////////////////////////////////////////////////////
//------------------------------------------------------------------------------
// Constructor
//------------------------------------------------------------------------------
constructor TMYLDBExpression.Create;
begin
FRootExprNode := nil;
LLex := nil;
FCaseInsensitive := False;
FPartialKey := False;
F3ValueLogic := True;
end;//Create
//------------------------------------------------------------------------------
// Constructor
//------------------------------------------------------------------------------
constructor TMYLDBExpression.Create(RootNode: TMYLDBExprNode);
begin
Create;
FRootExprNode := RootNode;
end;//Create
//------------------------------------------------------------------------------
// Constructor
//------------------------------------------------------------------------------
//constructor TMYLDBExpression.Create(Lexer: TMYLDBLexer);
//begin
// Create;
// LLex := Lexer;
//end;//Create
//------------------------------------------------------------------------------
// Destructor
//------------------------------------------------------------------------------
destructor TMYLDBExpression.Destroy;
begin
Clear;
inherited;
end;//Destroy
//------------------------------------------------------------------------------
// Clear all Variables
//------------------------------------------------------------------------------
procedure TMYLDBExpression.Clear;
begin
// free nodes tree
if (FRootExprNode <> nil) then
begin
FRootExprNode.Free;
FRootExprNode := nil;
end;
end;//Clear
//------------------------------------------------------------------------------
// Parsing for Locate
//------------------------------------------------------------------------------
procedure TMYLDBExpression.ParseForLocate(
Cursor: TMYLDBCursor;
FieldNames: String; // name1;name2
KeyValues: Variant; //
CaseInsensitive: boolean = true;
PartialKey: boolean = false
);
var
i, ArrLen: Integer;
FieldNamesList: TStringList;
//Arr: Pointer;
LeftNField: TMYLDBExprNodeField;
RightNConst: TMYLDBExprNodeConst;
EqNode: TMYLDBExprNodeComparison;
IsArray: Boolean;
//AndNode: TMYLDBExprNodeBoolean;
//val: TMYLDBVariant;
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 EMYLDBException.Create(30112, ErrorGNotEqualCountsOfFieldNamesAndKeyValues,
[FieldNamesList.Count, ArrLen]);
if (not IsArray) then
begin
// Field
LeftNField := TMYLDBExprNodeField.Create(LCursor, FieldNamesList[0]);
// Const
RightNConst := TMYLDBExprNodeConst.Create;
AssignConstValue(KeyValues);
// RootNode
FRootExprNode := TMYLDBExprNodeComparison.Create(doEQ, LeftNField,
RightNConst, F3ValueLogic, CaseInsensitive, PartialKey);
end
else
begin
FRootExprNode := TMYLDBExprNodeBoolean.Create(doAND);
for i:=0 to ArrLen-1 do
begin
// Field
LeftNField := TMYLDBExprNodeField.Create(LCursor, FieldNamesList[i]);
// Check FieldExists
// ...
// Const
RightNConst := TMYLDBExprNodeConst.Create;
AssignConstValue(VarArrayGet(KeyValues, i));
// EqNode
EqNode := TMYLDBExprNodeComparison.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 TMYLDBExpression.ParseForFilter(Cursor: TMYLDBCursor; Filter: String;
CaseInsensitive, PartialKey: boolean);
var
Lexer: TMYLDBLexer;
begin
LCursor := Cursor;
FCaseInsensitive := CaseInsensitive;
FPartialKey := PartialKey;
Lexer := TMYLDBLexer.Create(Filter);
try
if (Lexer.NumCommands = 0) then
raise EMYLDBException.Create(30119, ErrorGBlankSqlCommand);
Lexer.GetNextCommand;
ParseForBooleanExpression(nil, Lexer);
finally
Lexer.Free;
end;
end;//ParseForFilter
//------------------------------------------------------------------------------
// parse for IsAnyRecordMatchCondition (for quantified subquery comparison)
//------------------------------------------------------------------------------
procedure TMYLDBExpression.ParseForIsAnyRecordMatchCondition(
Cursor: TMYLDBCursor;
const FieldName: string;
const Operator: TMYLDBDataOperator;
const Value: TMYLDBVariant
);
var
LeftNField: TMYLDBExprNodeField;
RightNConst: TMYLDBExprNodeConst;
begin
Clear;
LCursor := Cursor;
F3ValueLogic := False;
// Field
LeftNField := TMYLDBExprNodeField.Create(LCursor, FieldName);
// Const
RightNConst := TMYLDBExprNodeConst.Create;
RightNConst.Value.Assign(Value);
// RootNode
FRootExprNode := TMYLDBExprNodeComparison.Create(Operator, LeftNField,
RightNConst, F3ValueLogic, False, False);
if LCursor <> nil then
FRootExprNode.PatchWideStrings;
end;// ParseForIsAnyRecordMatchCondition
//------------------------------------------------------------------------------
// Parse For Boolean Expression (Filter, Where-Clause)
//------------------------------------------------------------------------------
procedure TMYLDBExpression.ParseForBooleanExpression(
Dataset: TDataset;
Lexer: TMYLDBLexer
//CaseInsensitive: boolean = true;
//PartialKey: boolean = false
);
begin
Clear;
LDataset := Dataset;
LLex := Lexer;
if (not LLex.GetCurrentToken(Token)) then
raise EMYLDBException.Create(30118, ErrorGUnexpectedEndOfCommand,
[Token.LineNum, Token.ColumnNum]);
// Parse...
FRootExprNode := ParseSearchCondition;
if (FRootExprNode = nil) then
raise EMYLDBException.Create(30066, ErrorGBooleanExpressionExpected,
[Token.Text, Token.LineNum, Token.ColumnNum]);
MoveAndNodesToRoot;
if LCursor <> nil then
FRootExprNode.PatchWideStrings;
end;//ParseForBooleanExpression
//------------------------------------------------------------------------------
// Parse ValueExpression
//------------------------------------------------------------------------------
procedure TMYLDBExpression.ParseForValueExpression(
Dataset: TDataset;
Lexer: TMYLDBLexer
//CaseInsensitive: boolean = true;
//PartialKey: boolean = false
);
begin
LLex := Lexer;
LDataset := Dataset;
if (Dataset <> nil) then begin
FDatabaseName := TMYLDBDataset(Dataset).DatabaseName;
FSessionName := TMYLDBDataset(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 EMYLDBException.Create(30136, ErrorGUnexpectedEndOfCommand, [Token.LineNum, Token.ColumnNum]);
// parse
FRootExprNode := ParseValueExpression;
end;//ParseForValueExpression
//------------------------------------------------------------------------------
// default value: const or function
//------------------------------------------------------------------------------
function TMYLDBExpression.ParseForDefaultValueExpression(DefaultValue: String): Boolean;
var
Lexer: TMYLDBLexer;
Token: TToken;
begin
try
Lexer := TMYLDBLexer.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 TMYLDBExpression.ParseForRowSubqueryExpression(
Dataset: TDataset;
Lexer: TMYLDBLexer);
begin
LLex := Lexer;
LDataset := Dataset;
FDatabaseName := TMYLDBDataset(Dataset).DatabaseName;
FSessionName := TMYLDBDataset(Dataset).SessionName;
// get first token (for very beginning of the query) or current token
if (not LLex.GetCurrentToken(Token)) then
raise EMYLDBException.Create(30497, ErrorGUnexpectedEndOfCommand, [Token.LineNum, Token.ColumnNum]);
// parse
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -