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

📄 absrelationalalgebra.pas

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

     // insert into result table is unavailable due to possible hidden fields
     if (not FIsRootAO) or (not FResultImmediate) then
       begin
         FResultTableName := '';
         FResultDatabaseName := '';
       end;

     // perpare projection
     for i := 0 to FResultFieldsOrder.ItemCount-1 do
      begin
       j := FResultFieldsOrder.Items[i];
       if (FFieldLinks[j].IsHidden) then
        raise EABSException.Create(10312,ErrorLCannotAccessHiddenField,[FTableName,
                FFieldLinks[j].FieldName,FFieldLinks[j].DisplayName,j]);
       if (FFieldLinks[j].DisplayName <> '') then
        begin
         FieldList.Add(FFieldLinks[j].FieldName);
         AliasList.Add(FFieldLinks[j].DisplayName);
        end;
      end;

     // prepare visible fields
     for i := 0 to FFieldCount-1 do
      begin
       if (FFieldLinks[i].IsHidden) then continue;


        (*DuplicateCount := 0;*)
        Name := FFieldLinks[i].FieldName;
        (*// 5.05 rename duplicate fields
        if TABSTable(FResultDataset).AdvFieldDefs.Find(FFieldLinks[i].FieldName) <> nil then
        repeat
          Name := FFieldLinks[i].FieldName + '_' + IntToStr(DuplicateCount + 1);
          Inc(DuplicateCount);
        until TABSTable(FResultDataset).AdvFieldDefs.Find(Name) = nil;*)

        FieldDef := TABSTable(FResultDataset).AdvFieldDefs.AddFieldDef;
        FieldDef.Name := Name;

        (*if FResultFieldsOrder.IndexOf(i) > -1 then
          FieldList[FResultFieldsOrder.IndexOf(i)] := Name;*)

        //FieldDef := TABSTable(FResultDataset).AdvFieldDefs.AddFieldDef;
        //FieldDef.Name := FFieldLinks[i].FieldName;
        
        if (FFieldLinks[i].FieldType = aftAutoInc) then
         FieldDef.DataType := aftInteger
        else
         FieldDef.DataType := FFieldLinks[i].FieldType;
        FieldDef.Size := FFieldLinks[i].FieldSize;
        FieldDef.BLOBCompressionAlgorithm :=
          TCompressionAlgorithm(FFieldLinks[i].BLOBCompressionAlgorithm);
        FieldDef.BLOBCompressionMode := FFieldLinks[i].BLOBCompressionMode;
        FieldDef.BLOBBlockSize := FFieldLinks[i].BLOBBlockSize;
      end;
    end; // result table
   if (FTopRowCount > -1) then
    if (FResultIndexFieldsList <> nil) then
     TABSTable(FResultDataset).IndexName := CreateIndexForMaterialize(True);
   // create table
   if (FResultTableName <> '') then
    begin
     TABSTable(FResultDataset).DatabaseName := FResultDatabaseName;
     TABSTable(FResultDataset).TableName := FResultTableName;
     TABSTable(FResultDataset).InMemory := FResultInMemory;
     TABSTable(FResultDataset).Temporary := False;
    end // result table
   else
    begin
     TABSTable(FResultDataset).InMemory := False;
     TABSTable(FResultDataset).Temporary := True;
     TABSTable(FResultDataset).DisableTempFiles := FDisableTempFiles;
     repeat
       TABSTable(FResultDataset).TableName := GetTemporaryName(ABSTemporaryTableName);
     until (not (TABSTable(FResultDataset).Exists));
    end; // temporary table

   if (FDistinctApplied) then
     CreateIndexForDistinct;

   TABSTable(FResultDataset).CreateTable;
   TABSTable(FResultDataset).Open;

end; // CreateTableForMaterialize


//------------------------------------------------------------------------------
// fill table
//------------------------------------------------------------------------------
{$DEFINE PROFILE}
procedure TABSAO.FillTableForMaterialize;
var i,j,k,d:   Integer;
    values:    array of TABSVariant;
    bOK:       Boolean;

{$IFDEF PROFILE}
  StartTime: Cardinal;
{$ENDIF}
begin
 if (FDistinctApplied) then
  begin
   SetLength(values,FDistinctFieldCount);
   for i := 0 to FDistinctFieldCount-1 do
     values[i] := TABSVariant.Create;
  end
 else
  FDistinctFieldCount := 0;

 try
   // filling table with data
   First;
   k := 0;
   while Not Eof do
    begin
  {$IFDEF PROFILE}
  StartTime := GetTickCount;
  {$ENDIF}

     inc(k);
     // check TOP n?
      // TOP n?
      if (FTopRowCount > -1) then
      begin
       if (TABSDataset(FResultDataset).RecordCount >= FTopRowCount) then
        break;
      end;
      // TOP first_row
      if (FFirstRowNo > -1)  then
      begin
       if (k < FFirstRowNo) then
        begin
         Next;
         continue;
        end;
      end;

     if (FFilterExpr <> nil) then
      begin
       // check filter
       if (not TABSExpression(FFilterExpr).GetResult) then
        begin
         Next;
         continue;
        end;
      end;

     // check distinct
     if (FDistinctApplied) then
      begin
       bOK := True;
       for d := 0 to FDistinctFieldCount-1 do
        begin
         // read current record
         GetFieldValue(FValue,FDistinctFieldsMap[d],false,true);
         if (not TABSTable(FResultDataset).Bof) then
          if (FValue.Compare(values[d],False,False,False) <> cmprEqual) then
           bOK := False;
         values[d].Assign(FValue,True);
        end;//for

       if ((bOK) and (not TABSTable(FResultDataset).Bof)) then
        begin
         // skip this record
         Next;
         Continue;
        end;
      end;

     TABSTable(FResultDataset).Insert;

       // not result table
       j := 0;
       for i := 0 to FFieldCount-1 do
        begin
         if (FFieldLinks[i].IsHidden) then continue;
         CopyFieldValue(i,j);
         inc(j);
        end; // not result table
     // insert record
     if (not FDistinctApplied) then
       TABSTable(FResultDataset).Post
     else
       // check distinct
       if (TABSTable(FResultDataset).Handle.CheckConstraints(True)) then
         TABSTable(FResultDataset).Post
       else
         TABSTable(FResultDataset).Cancel;
     // go to next record

     Next;

   {$IFDEF PROFILE}
   StartTime := GetTickCount - StartTime;
   if StartTime > 0 then OutputDebugString(PChar(IntToStr(k) + ': ' + IntToStr(StartTime)));
   //OutputDebugString(PChar(IntToStr(k)));
   {$ENDIF}

    end; // enf of inserting records loop
   if (FTopRowCount > -1) then
    FTopRowCount := -1;
 finally
   if (FDistinctApplied) then
     begin
       for i := 0 to FDistinctFieldCount-1 do
         values[i].Free;
       values := nil;
     end;
 end;

end; // FillTableForMaterialize


//------------------------------------------------------------------------------
// ReplaceInIndexAliasesToFields
//------------------------------------------------------------------------------
procedure TABSAO.ReplaceInIndexAliasesToFields(FieldList, AliasList,
                                          FResultIndexFieldsList: TStringList);
var
  i,j,k: Integer;
  IsField: Boolean;
begin
  for i := 0 to AliasList.Count-1 do
  begin
     // first check if alias is a real field name
     IsField := False;
     for j := 0 to FieldList.Count-1 do
       if (AnsiUpperCase(AliasList[i]) = AnsiUpperCase(FieldList[j])) then
       begin
         IsField := True;
         Break;
       end;
     if IsField then Continue;
     //
     for j := 0 to FResultIndexFieldsList.Count-1 do
       if (AnsiUpperCase(AliasList[i]) = AnsiUpperCase(FResultIndexFieldsList[j])) then
         FResultIndexFieldsList[j] := FieldList[i];
  end;
end;// ReplaceInIndexAliasesToFields


//------------------------------------------------------------------------------
// finalize materialize
//------------------------------------------------------------------------------
procedure TABSAO.FinalizeMaterialize(
                                            FieldList:  TStringList;
                                            AliasList:  TStringList
                                    );
var i,j: Integer;
begin
 if (FResultIndexFieldsList <> nil) then
  if (not ((FTopRowCount > -1) or (FDistinctApplied))) then
   begin
       ReplaceInIndexAliasesToFields(FieldList, AliasList, FResultIndexFieldsList);
     TABSTable(FResultDataset).IndexName := CreateIndexForMaterialize(False);
   end;
 TABSTable(FResultDataset).ApplyProjection(FieldList,AliasList);
 // move field links to the result dataset
 if (FResultFieldsOrder.ItemCount <= 0) then
  begin
   j := 0;
   // not result table
   for i := 0 to FFieldCount-1 do
    begin
     // field names will be 'Field'+n
     if (FFieldLinks[i].IsHidden) then continue;
     FFieldLinks[i].AO := nil;
     if (FFieldLinks[i].IsExpression) then
      if (FFieldLinks[i].Expr <> nil) then
        TABSExpression(FFieldLinks[i].Expr).Free;
     FFieldLinks[i].IsExpression := False;
     FFieldLinks[i].IsAggregate := False;
     FFieldLinks[i].Expr := nil;
     FFieldLinks[i].Dataset := FResultDataset;
     FFieldLinks[i].FieldNo := j;
     inc(j);
    end; // not result table
  end
 else
  begin
   //--- projection is set
   if (FIsRootAO) then
     for i := 0 to FResultFieldsOrder.ItemCount-1 do
      begin
       j := FResultFieldsOrder.Items[i];
       if (FFieldLinks[j].IsHidden) then
        raise EABSException.Create(10314,ErrorLCannotAccessHiddenField,
              [FTableName,FFieldLinks[j].FieldName,FFieldLinks[j].DisplayName,j]);

       FFieldLinks[j].AO := nil;
       if (FFieldLinks[j].IsExpression) then
        if (FFieldLinks[j].Expr <> nil) then
         TABSExpression(FFieldLinks[j].Expr).Free;
       FFieldLinks[j].IsExpression := False;
       FFieldLinks[j].IsAggregate := False;
       FFieldLinks[j].Expr := nil;
       FFieldLinks[j].Dataset := FResultDataset;
       FFieldLinks[j].FieldNo := i;
      end
   else
     begin
       j := 0;
       for i := 0 to FFieldCount-1 do
         if (not FFieldLinks[i].IsHidden) then
           begin
             FFieldLinks[i].AO := nil;
             if (FFieldLinks[i].IsExpression) then
              if (FFieldLinks[i].Expr <> nil) then
               TABSExpression(FFieldLinks[i].Expr).Free;
             FFieldLinks[i].IsExpression := False;
             FFieldLinks[i].IsAggregate := False;
             FFieldLinks[i].Expr := nil;
             FFieldLinks[i].Dataset := FResultDataset;
             FFieldLinks[i].FieldNo := j;
             Inc(j);
           end;
     end;
  end; // result table

 FIsMaterialized := True;
 //---------------------- destroy child operations -----------------------------
 if (FIsAOGroupBy) then
   if (TABSAOGroupBy(Self).FTempDataset <> nil) then
      begin
        TABSAOGroupBy(Self).FTempDataset.Free;
        TABSAOGroupBy(Self).FTempDataset := nil;
      end;
 if (FLeftAO <> nil) then
  FLeftAO.Free;
 if (FRightAO <> nil) then
  FRightAO.Free;
 FRightAO := nil;
 FLeftAO := nil;
end; // FinalizeMaterialize


//------------------------------------------------------------------------------
// materializes AO
//------------------------------------------------------------------------------
procedure TABSAO.DoMaterialize;
var FieldList,AliasList: TStringList;
begin
 if (not FIsMaterialized) then
  begin
   FieldList := TStringList.Create;
   AliasList := TStringList.Create;
   try
     CreateTableForMaterialize(FieldList,AliasList);
     FillTableForMaterialize;
     FinalizeMaterialize(FieldList,AliasList);
   finally
     FieldList.Free;
     AliasList.Free;
   end;
  end;
end; // DoMaterialize


//------------------------------------------------------------------------------
// destroy
//------------------------------------------------------------------------------
destructor TABSAO.Destroy;
var
  i: integer;
begin
  if (FIsAOTable) then
    if (FIsLocked) then
      if (ResultDataset.Active) then
        TABSTable(ResultDataset).Handle.UnlockTable(ltS, True);

  for i := 0 to Length(FFieldLinks)-1 do
    if (FFieldLinks[i].IsExpression) then
      if (FFieldLinks[i].Expr <> nil) then
        TABSExpression(FFieldLinks[i].Expr).Free;

  FFieldLinks := nil;
  if (FResultDataset <> nil) then

⌨️ 快捷键说明

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