⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 absexpressions.pas

📁 Absolute Database 是来替代BDE[Borland数据库引擎]的用于Delphi 和 C++ Builder 开发用的数据库引擎. 它小巧, 高速, 健壮, 易于使用. 它能直接编译进
💻 PAS
📖 第 1 页 / 共 5 页
字号:
  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 + -