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

📄 absrelationalalgebra.pas

📁 Absolute Database 是来替代BDE[Borland数据库引擎]的用于Delphi 和 C++ Builder 开发用的数据库引擎. 它小巧, 高速, 健壮, 易于使用. 它能直接编译进
💻 PAS
📖 第 1 页 / 共 5 页
字号:
        FExpressionsExists := True;
        FResultFieldsOrder.Append(FFieldCount-1);
        // update fieldrefs
        if ((not FIsAOGroupBy) and (not TABSExpression(FieldRefs[i].ValueExpr).IsAggregated)) then
          begin
            FieldRefs[i].IsExpression := False;
            FieldRefs[i].ValueExpr := nil;
            FieldRefs[i].FieldName := FFieldLinks[FFieldCount-1].FieldName;
          end
        else
          FieldRefs[i].ValueExpr := nil;

        continue;
       end; // Expression

    if (fname <> '') then
      begin
        res := FieldExists(fname,tname,true,FResultFieldsOrder);
        if (res = 1) then
         begin
          x := FResultFieldsOrder.Items[FResultFieldsOrder.ItemCount-1];
         if (FieldRefs[i].Pseudonym <> '') then
          // set pseudonym
           FFieldLinks[x].DisplayName := FieldRefs[i].Pseudonym
         else
          // use name like it was written in query
          if (fname <> '*') then
            FFieldLinks[x].DisplayName := fname;
         end // res = 0
        else
        if (res = 0) then
          raise EABSException.Create(10305, ErrorLCannotFindField, [fname])
    // result dataset
        else
         if (res > 1) then
          if (fname <> '*') then
           begin
            for x := 0 to res-2 do
             FResultFieldsOrder.Delete(FResultFieldsOrder.ItemCount-1);
            x := FResultFieldsOrder.Items[FResultFieldsOrder.ItemCount-1];
            if (FieldRefs[i].Pseudonym <> '') then
             // set pseudonym
             FFieldLinks[x].DisplayName := FieldRefs[i].Pseudonym
            else
             // use name like it was written in query
             if (fname <> '*') then
              FFieldLinks[x].DisplayName := fname;
           end; // DUPLICATE NAMES IN SELECT LIST REMOVED
      end;
   end;
 for i := 0 to FResultFieldsOrder.ItemCount - 1 do
  begin
   k := FResultFieldsOrder.Items[i];
   if (bDistinct) then
    begin
     if (aDistinctFields = '') then
      aDistinctFields := FFieldLinks[k].FieldName
     else
      aDistinctFields := aDistinctFields + ';' + FFieldLinks[k].FieldName;
    end;

   if (FFieldLinks[k].DisplayName = '') then
    FFieldLinks[k].DisplayName :=
      FFieldLinks[k].FieldName;
  end;

  if (bDistinct) then
   ApplyDistinct(aDistinctFields);
 FHasSetResultFields := True;
end;// SetResultFields


//------------------------------------------------------------------------------
// mapping function - return number of found fields and found field No
// also optionally unhides fields in AO
//------------------------------------------------------------------------------
function TABSAO.FieldExists(
                  FieldName, TableName: string;
                  Unhide: Boolean;
                  FieldNumbers: TABSIntegerArray = nil;
                  UnhideChildrenOnly: Boolean = false;
                  ScanOnlyVisibleFields: Boolean = false
                  ): Integer;
var i,j,k: integer;
    fname: string;
    tempArray: TABSIntegerArray;
begin
 result := 0;
 if (FIsAOTable) then
   if (TableName <> '') then
    if (AnsiUpperCase(TableName) <> AnsiUpperCase(FTableName)) and
      (AnsiUpperCase(TableName) <> AnsiUpperCase(FTableAlias)) then
     Exit; // another table

 // all fields
 if (FieldName = '*') then
  begin
   // unhide or field numbers
   tempArray := TABSIntegerArray.Create(0,1,100);
   if (FLeftAO <> nil) then
     FLeftAO.FieldExists(FieldName,TableName,Unhide, tempArray);

   for i := 0 to FFieldCount-1 do
    if (FIsAOTable) or
       ((AnsiUpperCase(TableName) = AnsiUpperCase(FTableName)) and
       (FFieldLinks[i].IsExpression)) or
       ((FLeftAO <> nil) and
          (FFieldLinks[i].AO = FLeftAO) and
          (tempArray.IsValueExists(FFieldLinks[i].FieldNo))) then
     begin
      inc(result);
      if (FieldNumbers <> nil) then
       FieldNumbers.Append(i);
      // group by does not needs in unhiding
      // it will cause hidden fields to be appeared in result dataset
      if (Unhide) and (not UnhideChildrenOnly) then
       if (not FIsAOGroupBy) then
        FFieldLinks[i].IsHidden := false;
     end;
   tempArray.SetSize(0);

   if (FRightAO <> nil) then
    begin
      FRightAO.FieldExists(FieldName,TableName,Unhide, tempArray);
      for i := 0 to FFieldCount-1 do
      if ((FRightAO <> nil) and
            (FFieldLinks[i].AO = FRightAO) and
            (tempArray.IsValueExists(FFieldLinks[i].FieldNo))) then
       begin
        inc(result);
        if (FieldNumbers <> nil) then
         FieldNumbers.Append(i);
        // group by does not needs in unhiding
        // it will cause hidden fields to be appeared in result dataset
        if (Unhide) and (not UnhideChildrenOnly) then
         FFieldLinks[i].IsHidden := false;
       end;
    end;
   tempArray.Free;
   Exit;
  end; // all fields

 fname := AnsiUpperCase(FieldName);
   // not TABSAOTable
   tempArray := nil;
   if (FieldNumbers <> nil) then
    tempArray := TABSIntegerArray.Create(0,1,100);
   if (FLeftAO <> nil) then
    begin
     FLeftAO.FieldExists(FieldName,TableName,Unhide,tempArray);
     for i := 0 to tempArray.ItemCount-1 do
      begin
       k := tempArray.Items[i];
       for j := 0 to FFieldCount-1 do
        if (FFieldLinks[j].AO = FLeftAO) then
         if (FFieldLinks[j].FieldNo = k) and
            ((not ScanOnlyVisibleFields) or (not FFieldLinks[j].IsHidden)) then
          begin
           Inc(Result);
           // return FieldNo in current FFieldLinks
           if (FieldNumbers <> nil) then
             FieldNumbers.Append(j);
           // group by does not needs in unhiding
           // it will cause hidden fields to be appeared in result dataset
           if (Unhide) and (not UnhideChildrenOnly) then
            FFieldLinks[j].IsHidden := false;
          end;
      end;
     tempArray.SetSize(0); // empty temp array
    end; // LeftAO
   if (FRightAO <> nil) then
    begin
     FRightAO.FieldExists(FieldName,TableName,Unhide,tempArray);
     for i := 0 to tempArray.ItemCount-1 do
      begin
       k := tempArray.Items[i];
       for j := 0 to FFieldCount-1 do
        if (FFieldLinks[j].AO = FRightAO) then
         if (FFieldLinks[j].FieldNo = k) and
            ((not ScanOnlyVisibleFields) or (not FFieldLinks[j].IsHidden)) then
          begin
           Inc(Result);
           // return FieldNo in current FFieldLinks
           if (FieldNumbers <> nil) then
             FieldNumbers.Append(j);
           // group by does not needs in unhiding
           // it will cause hidden fields to be appeared in result dataset
           if (Unhide) and (not UnhideChildrenOnly) then
            FFieldLinks[j].IsHidden := false;
          end;
      end;
      tempArray.SetSize(0);
    end; // RightAO
   if (tempArray <> nil) then
    tempArray.Free;

   // find field
   for i := 0 to FFieldCount-1 do
    if (AnsiUpperCase(FFieldLinks[i].FieldName) = fname) or
       (AnsiUpperCase(FFieldLinks[i].DisplayName) = fname) then
     if (TableName = '') or
        (AnsiUpperCase(TableName) = AnsiUpperCase(FTableName)) or
        (AnsiUpperCase(TableName) = AnsiUpperCase(FTableAlias)) then
      if ((not ScanOnlyVisibleFields) or (not FFieldLinks[i].IsHidden)) then
        begin
         if (FieldNumbers <> nil) then
          if (not FieldNumbers.IsValueExists(i)) then
           begin
            FieldNumbers.Append(i);
            inc(result);
           end;
         // group by does not needs in unhiding
         // it will cause hidden fields to be appeared in result dataset
         if (Unhide) and (not UnhideChildrenOnly) then
          FFieldLinks[i].IsHidden := false;
         break;
        end;
end;// FieldExists


//------------------------------------------------------------------------------
// FindFieldInFieldLinks
//------------------------------------------------------------------------------
function TABSAO.FindFieldInFieldLinks(FieldName: String; var FieldNo: Integer): Boolean;
var
  i: Integer;
begin
  Result := False;
  for i := 0 to FFieldCount-1 do
    if (AnsiUpperCase(FFieldLinks[i].FieldName) = AnsiUpperCase(FieldName)) or
       (AnsiUpperCase(FFieldLinks[i].DisplayName) = AnsiUpperCase(FieldName)) then
      begin
        FieldNo := i;
        Result := True;
        break;
      end;
end;// FindFieldInFieldLinks


//------------------------------------------------------------------------------
// return FieldName from AOTable for specified internal field
//------------------------------------------------------------------------------
function TABSAO.GetFieldName(FieldNo: Integer; ApplyOrderBy: Boolean = False): string;
begin
 if (FieldNo < 0) or (FieldNo >= FieldCount) then
  raise EABSException.Create(10306,ErrorLInvalidFieldNumber,[FieldNo,FieldCount]);
 Result := '';
 if (ApplyOrderBy) then
  begin
   // apply order by
   if (FFieldLinks[FieldNo].Dataset <> nil) then
    begin
     if (FFieldLinks[FieldNo].Dataset = FResultDataset) then
      Result := FFieldLinks[FieldNo].FieldName
     else
      Result := FFieldLinks[FieldNo].Dataset.Fields[FFieldLinks[FieldNo].FieldNo].FieldName;
    end
   else
    begin
      Result := FFieldLinks[FieldNo].FieldName;
    end;
  end
 else
  begin
   // set field names for join
   if (FFieldLinks[FieldNo].Dataset <> nil) then
    begin
     if (FFieldLinks[FieldNo].Dataset = FResultDataset) then
      Result := FFieldLinks[FieldNo].FieldName
     else
      Result := FFieldLinks[FieldNo].Dataset.Fields[FFieldLinks[FieldNo].FieldNo].FieldName
    end
   else
    Result := TABSAO(FFieldLinks[FieldNo].AO).GetFieldName(FFieldLinks[FieldNo].FieldNo)
  end;

end; // GetFieldName


//------------------------------------------------------------------------------
// return FieldName from AOTable for specified internal field
//------------------------------------------------------------------------------
function TABSAO.GetFieldNameByColumnName(ColumnName: String): string;
var i:    Integer;
    name: String;
begin
 Result := '';
 name := AnsiUpperCase(ColumnName);
 for i := 0 to FFieldCount - 1 do
  if ((name = AnsiUpperCase(FFieldLinks[i].FieldName)) or
      (name = AnsiUpperCase(FFieldLinks[i].DisplayName))) then
   begin
    Result := FFieldLinks[i].FieldName;
    break;
   end;
end; // GetFieldName


//------------------------------------------------------------------------------
// GetFieldNameByColumnNo
//------------------------------------------------------------------------------
function TABSAO.GetFieldNameByColumnNo(ColumnNo: Integer): string;
begin
  Result := FFieldLinks[ColumnNo].FieldName;
end;// GetFieldNameByColumnNo


//------------------------------------------------------------------------------
// GetFieldNameByVisibleNumber
//------------------------------------------------------------------------------
function TABSAO.GetFieldNameByVisibleNumber(VisibleFieldNo: Integer): String;
begin
  if (VisibleFieldNo < FResultFieldsOrder.ItemCount) then
    Result := FFieldLinks[FResultFieldsOrder.Items[VisibleFieldNo]].DisplayName
  else
    raise EABSException.Create(20243, ErrorAInvalidFieldNumberInOrderBy, [VisibleFieldNo+1]);
end;// GetFieldNameByVisibleNumber


//------------------------------------------------------------------------------
// GetFieldNoByVisibleNumber
//------------------------------------------------------------------------------
function TABSAO.GetFieldNoByVisibleNumber(VisibleFieldNo: Integer): Integer;
begin
  if (FResultFieldsOrder.ItemCount > 0) then
    Result := FResultFieldsOrder.Items[VisibleFieldNo]
  else
    Result := VisibleFieldNo;
end;// GetFieldNoByVisibleNumber


//------------------------------------------------------------------------------
// return field value
//------------------------------------------------------------------------------
procedure TABSAO.GetFieldValue(
                        Value:          TABSVariant;
                        FieldNo:        Integer;
                        bCopy:          Boolean = False;
                        AccessToHidden: Boolean = False
                              );
var
  TmpValue: TABSVariant;
  UseDirectFieldAccess: Boolean;
begin
  if ((FieldNo < 0) or (FieldNo >= FieldCount)) then
    raise EABSException.Create(10307, ErrorLInvalidFieldNumber,
                               [FieldNo,FieldCount]);

  Value.SetNull;

  // AO = Dataset = nil
  if ((FFieldLinks[FieldNo].Dataset = nil) and (FFieldLinks[FieldNo].AO = nil)) then
    raise EABSException.Create(10309, ErrorLInvalidFieldLink, [FTableName,FieldNo]);

  // hidden field
  if not AccessToHidden then
   if (FFieldLinks[FieldNo].IsHidden) then
     raise EABSException.Create(10310,ErrorLCannotAccessHiddenField,
                    [FTableName,FFieldLinks[FieldNo].FieldName,
                     FFieldLinks[FieldNo].DisplayName, FieldNo]);

 if (FFieldLinks[FieldNo].IsExpression) then
   begin
     TmpValue := TABSExpression(FFieldLinks[FieldNo].Expr).GetValue;
     if (TmpValue <> nil) then
       Value.Assign(TmpValue, False);
   end // Expression
 else
 if (FFieldLinks[FieldNo].Dataset <> nil) then
   begin
     if (not (FFieldLinks[FieldNo].Dataset.Eof and FFieldLinks[FieldNo].Dataset.Bof)) then
       begin
         UseDirectFieldAccess := not (Self is TABSAOUnion) or
                                (not FIsRootAO and FHasSetResultFields and not FIsAOTable);
         TABSTable(FFieldLinks[FieldNo].Dataset).GetFieldValue(value,
                               FFieldLinks[FieldNo].FieldNo, UseDirectFieldAccess)

⌨️ 快捷键说明

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