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

📄 absexpressions.pas

📁 Absolute Database 是来替代BDE[Borland数据库引擎]的用于Delphi 和 C++ Builder 开发用的数据库引擎. 它小巧, 高速, 健壮, 易于使用. 它能直接编译进
💻 PAS
📖 第 1 页 / 共 5 页
字号:
var
  Value: TABSVariant;
begin
  Value := GetValue(false);
  if Value = nil then
    raise EABSException.Create(30110, ErrorGValueIsNull);
  Result := Value.AsBoolean;
end;//GetResult


//------------------------------------------------------------------------------
// calc subquery field values again
//------------------------------------------------------------------------------
procedure TABSExpression.ResetSubqueryFieldValues;
begin
  if FRootExprNode <> nil then
    FRootExprNode.ResetSubqueryFieldValues;
end;// ResetSubqueryFieldValues


//------------------------------------------------------------------------------
// Return subquery field value
//------------------------------------------------------------------------------
function TABSExpression.GetSubqueryFieldValue(FieldNo: Integer): TABSVariant;
begin
  if FRootExprNode <> nil then
    Result := FRootExprNode.GetSubqueryFieldValue(FieldNo)
  else
    Result := nil;
end;// GetSubqueryFieldValue


//------------------------------------------------------------------------------
// is expression contains aggregated function
//------------------------------------------------------------------------------
function TABSExpression.IsAggregated: Boolean;
begin
 if FRootExprNode <> nil then
   Result := FRootExprNode.IsAggregated
 else
   Result := False;
end;//IsAggregated


//------------------------------------------------------------------------------
// is Count(*)
//------------------------------------------------------------------------------
function TABSExpression.IsAggregatedCountAll: Boolean;
begin
 if FRootExprNode <> nil then
   Result := FRootExprNode.IsAggregatedCountAll
 else
   Result := False;
end;// IsAggregatedCountAll


//------------------------------------------------------------------------------
// Init for aggregated functions
//------------------------------------------------------------------------------
procedure TABSExpression.Init;
begin
  if FRootExprNode <> nil then
    FRootExprNode.Init;
end;//Init


//------------------------------------------------------------------------------
// Accumulate for group functions
//------------------------------------------------------------------------------
procedure TABSExpression.Accumulate;
begin
  if FRootExprNode <> nil then
    FRootExprNode.Accumulate;
end;//Accumulate


//------------------------------------------------------------------------------
// SetCountAll
//------------------------------------------------------------------------------
procedure TABSExpression.SetCountAll(RecordCount: Integer);
begin
  if FRootExprNode <> nil then
    FRootExprNode.SetCountAll(RecordCount);
end;// SetCountAll


//------------------------------------------------------------------------------
// process assign AO
//------------------------------------------------------------------------------
procedure TABSExpression.AssignAO(AO, ParentQueryAO: TABSAO; ParentCursor: TABSCursor);
begin
  if (FRootExprNode <> nil) then
    begin
      FRootExprNode.AssignAO(AO, ParentQueryAO, ParentCursor);
      FRootExprNode.PatchWideStrings;
    end;
end;//AssignAO


//------------------------------------------------------------------------------
// process assign Cursor and its RecordBuffer
//------------------------------------------------------------------------------
procedure TABSExpression.AssignCursor(Cursor: TABSCursor; ParentQueryAO: TABSAO; ParentCursor: TABSCursor);
begin
  if (FRootExprNode <> nil) then
    begin
      FRootExprNode.AssignCursor(Cursor, ParentQueryAO, ParentCursor);
      FRootExprNode.PatchWideStrings;
    end;
end;//AssignCursor


//------------------------------------------------------------------------------
// process assign New Cursor Buffer
//------------------------------------------------------------------------------
procedure TABSExpression.AssignCursorBuffer(Buffer: TABSRecordBuffer; ApplyToParentQueryFields: Boolean);
begin
  if (FRootExprNode <> nil) then
    begin
      FRootExprNode.AssignCursorBuffer(Buffer, ApplyToParentQueryFields);
      FRootExprNode.PatchWideStrings;
    end;
end;//AssignCursorBuffer


//------------------------------------------------------------------------------
// return Expression DataSize
//------------------------------------------------------------------------------
function TABSExpression.GetDataSize: Integer;
begin
 if FRootExprNode <> nil then
   Result := FRootExprNode.getDataSize
 else
   Result := 0;
end;//getDataSize


//------------------------------------------------------------------------------
// return Size of Data (for strings and arrays)
//------------------------------------------------------------------------------
function TABSExpression.GetPrecision: Integer;
begin
 if FRootExprNode <> nil then
   Result := FRootExprNode.GetPrecision
 else
   Result := 0;
end;//GetPrecision


//------------------------------------------------------------------------------
// return Expression DataType
//------------------------------------------------------------------------------
function TABSExpression.GetDataType: TABSAdvancedFieldType;
begin
 if FRootExprNode <> nil then
   Result := FRootExprNode.getDataType
 else
   Result := aftUnknown;
end;//GetDataType


//------------------------------------------------------------------------------
// is expression contains no nodes
//------------------------------------------------------------------------------
function TABSExpression.IsEmpty: Boolean;
begin
  Result := (FRootExprNode = nil);
  if (not Result) then
    if (FRootExprNode is TABSExprNodeBoolean) then
      Result := (FRootExprNode.Children.Count = 0);
end;//IsEmpty


//------------------------------------------------------------------------------
// is expression a Field (for join)
//------------------------------------------------------------------------------
function TABSExpression.IsField: Boolean;
begin
  Result := False;
  if FRootExprNode <> nil then
    Result := FRootExprNode is TABSExprNodeField;
end;//IsField

//------------------------------------------------------------------------------
// is expression a combination of fields
//------------------------------------------------------------------------------
function TABSExpression.IsFieldsExpression: Boolean;
var
  I: Integer;
begin
  Result := False;
  if FRootExprNode <> nil then
  begin
    if (FRootExprNode is TABSExprNodeField) then
    begin
      Result := True;
      Exit;
    end;
    for I := 0 to FRootExprNode.Children.Count - 1 do
    begin
      if (TABSExprNode(FRootExprNode.Children[I]) is TABSExprNodeField) then
      begin
        Result := True;
        Exit;
      end;
    end;
  end;
end;



//------------------------------------------------------------------------------
// Move AndNodes To RootNode
//------------------------------------------------------------------------------
procedure TABSExpression.MoveAndNodesToRoot;
var
  i: Integer;
begin
  if (FRootExprNode.Operator = doAND) then
   begin
    i := 0;
    while i < FRootExprNode.Children.Count do
     begin
      if (TABSExprNode(FRootExprNode.Children[i]).Operator = doAND) then
       begin
        while TABSExprNode(FRootExprNode.Children[i]).Children.Count > 0 do
         begin
          FRootExprNode.Children.Add(TABSExprNode(FRootExprNode.Children[i]).Children[0]);
          TABSExprNode(FRootExprNode.Children[i]).Children.Delete(0);
         end;
        TABSExprNode(FRootExprNode.Children[i]).Free;
        FRootExprNode.Children.Delete(i);
        Continue;
       end;
      Inc(i);
     end;
   end;
end;//MoveAndNodesToRoot


//------------------------------------------------------------------------------
// Field Name, Table Name
//------------------------------------------------------------------------------
procedure TABSExpression.GetFieldInfo(var TableName, FieldName: String);
begin
  if (IsField) then
   begin
    TableName := TABSExprNodeField(FRootExprNode).FTableName;
    FieldName := TABSExprNodeField(FRootExprNode).FFieldName;
   end
  else
   raise EABSException.Create(30198, ErrorGNodeIsNotField);
end;// GetFieldInfo


//------------------------------------------------------------------------------
// makes filter from related parts and sets it to AO
//------------------------------------------------------------------------------
procedure TABSExpression.ApplyFilterParts(AO: TABSAO; ParentQueryAO: TABSAO;
                ParentCursor: TABSCursor;
                AllowRecurse: Boolean = True; ForHavingClause: Boolean = False);
var
  NodesToDelete: TList;
  Node: TABSExprNode;
  bRecurse: Boolean;
  i: Integer;
  FilterRootNode: TABSExprNode;
begin
  FilterRootNode := nil;
  bRecurse := AllowRecurse;
  // don't set filter to outer join childs
  if bRecurse and (AO is TABSAOJoin) then
    bRecurse := not TABSAOJoin(AO).OuterJoin;

  // try to apply to AO children
  if (bRecurse) then
   begin
    if (AO.FLeftAO <> nil) then
     ApplyFilterParts(AO.FLeftAO, ParentQueryAO, ParentCursor, AllowRecurse, ForHavingClause);
    if (AO.FRightAO <> nil) then
     ApplyFilterParts(AO.FRightAO, ParentQueryAO, ParentCursor, AllowRecurse, ForHavingClause);
   end;

  // traverse tree by factors: (...) AND (...) AND (...)
  if (FRootExprNode <> nil) then
   begin
     NodesToDelete := TList.Create;
     try
      // -> (...) AND (...) AND (...) ?
      if (FRootExprNode is TABSExprNodeBoolean) and
         (FRootExprNode.Operator = doAND) then
        for i:=0 to FRootExprNode.Children.Count-1 do
         begin
          Node := FRootExprNode.Children[i];
          // (...) can be used by the AO?
          if (Node.CanBeAssigned(AO, ParentQueryAO, ParentCursor, ForHavingClause)) then
           begin
            // no FilterRootNode
            if FilterRootNode = nil then
              FilterRootNode := Node
            else
            // FilterRootNode=AND ( ex: a=b AND c=d )
            if (FilterRootNode is TABSExprNodeBoolean) and
               (FilterRootNode.Operator = doAND) then
               FilterRootNode.Children.Add(Node)
            else
              // single FilterRootNode ( ex: a=b ) - converting to AND
              FilterRootNode := TABSExprNodeBoolean.Create(doAND,
                                                FilterRootNode, Node);
            NodesToDelete.Add(Node);
           end;
          // -> AND (...)
         end
      else
        // (...)
        begin
          if (FRootExprNode.CanBeAssigned(AO, ParentQueryAO, ParentCursor, ForHavingClause)) then
            begin
              FilterRootNode := FRootExprNode;
              FRootExprNode := nil;
            end;
        end;
      // delete used nodes
      for i:=0 to NodesToDelete.Count-1 do
       begin
        FRootExprNode.Children.Delete(
          FRootExprNode.Children.IndexOf(NodesToDelete[i]));
       end;
      // set extracted filter
      if FilterRootNode <> nil then
       AO.SetFilter(TABSExpression.Create(FilterRootNode));

      // no children?
      if (FRootExprNode <> nil) then
       if (FRootExprNode.Children.Count = 0) then
        begin
         FRootExprNode.Free;
         FRootExprNode := nil;
        end;
     finally
      NodesToDelete.Free;
     end;
   end;
end;// ApplyFilterParts


//------------------------------------------------------------------------------
// gets current token
//------------------------------------------------------------------------------
procedure TABSExpression.ReplacePseudonyms(SelectList: array of 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -