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

📄 absmemengine.pas

📁 Absolute Database 是来替代BDE[Borland数据库引擎]的用于Delphi 和 C++ Builder 开发用的数据库引擎. 它小巧, 高速, 健壮, 易于使用. 它能直接编译进
💻 PAS
📖 第 1 页 / 共 5 页
字号:
  FileHeader.BlockSize := BLOBDescriptor.BlockSize;
  FileHeader.CompressionAlgorithm := BLOBDescriptor.CompressionAlgorithm;
  FileHeader.CompressionMode := BLOBDescriptor.CompressionMode;
  FileHeader.NameLength := Length(FTableName);
  SaveDataToStream(FileHeader,sizeof(FileHeader),Stream,10156);
  SaveDataToStream(PChar(@FTableName[1])^,FileHeader.NameLength,Stream,10157);
  DatabaseID := TABSMemoryDatabaseData(FDatabaseData).FLastObjectID;
  SaveDataToStream(DatabaseID,sizeof(DatabaseID),Stream,10416);
  BLOBDescriptor.StartPosition := Stream.Position;
end; // SaveTableHeader


//------------------------------------------------------------------------------
// load blob data
//------------------------------------------------------------------------------
procedure TABSMemoryTableData.LoadBLOBDataFromStream(
        RecordBuffer: TABSRecordBuffer;
        FieldNo:      Integer;
        Stream:       TStream
                             );
var Buffer:                 PChar;
    FBLOBPosition:          Int64;
    Offset,Offset2:         Integer;
    BLOBPartialDescriptor:  TABSPartialTemporaryBLOBDescriptor;
begin
  Offset := FFieldManager.FieldDefs[FieldNo].MemoryOffset;
  Move(PChar(RecordBuffer + Offset)^,FBLOBPosition,sizeof(FBLOBPosition));
  // load disk blob descriptor
  SetStreamPosition(Stream,FBLOBPosition,10202);
  LoadDataFromStream(BLOBPartialDescriptor,sizeof(BLOBPartialDescriptor),
    Stream,10203);
  Offset2 := sizeof(TABSPartialBLOBDescriptor);
  Buffer := MemoryManager.GetMem(BLOBPartialDescriptor.CompressedSize + Offset2);
  PABSPartialBLOBDescriptor(Buffer)^.NumBlocks :=
    BLOBPartialDescriptor.NumBlocks;
  PABSPartialBLOBDescriptor(Buffer)^.UncompressedSize :=
    BLOBPartialDescriptor.UncompressedSize;
  // load compresse blob data
  LoadDataFromStream(PChar(Buffer + Offset2)^,
    BLOBPartialDescriptor.CompressedSize,Stream,10204);
  Move(Buffer,PChar(RecordBuffer + Offset)^,sizeof(Buffer));
end; // LoadBLOBDataFromStream


//------------------------------------------------------------------------------
// load record
//------------------------------------------------------------------------------
procedure TABSMemoryTableData.LoadRecordFromStream(
            RecordBuffer: TABSRecordBuffer;
            Stream:       TStream
                                                  );
var i:                        Integer;
begin
  LoadDataFromStream(RecordBuffer^,GetRecordBufferSize,Stream,10201);
  if (FFieldManager.BlobFieldsPresent) then
   begin
     for i := 0 to FFieldManager.FieldDefs.Count - 1 do
      if (IsBLOBFieldType(FFieldManager.FieldDefs[i].BaseFieldType)) then
        if (not CheckNullFlag(i,RecordBuffer)) then
         begin
          // load blob
          LoadBLOBDataFromStream(RecordBuffer,i,Stream);
         end; // blob field not null
   end;
end; // LoadRecord


//------------------------------------------------------------------------------
// prepare record buffer for save
//------------------------------------------------------------------------------
procedure TABSMemoryTableData.PrepareRecordBufferForSave(
            RecordBuffer:             TABSRecordBuffer;
            BLOBDescriptorList:       TList;
            BLOBDataList:             TList;
            BLOBPosition:             Int64
                                                );
var FBLOBPosition:            Int64;
    i:                        Integer;
    BLOBDataSize:             Integer;
    Offset:                   Integer;
    Buffer:                   PChar;
    PBLOBPartialDescriptor:   PABSPartialTemporaryBLOBDescriptor;
begin
 FBLOBPosition := BLOBPosition;
 for i := 0 to FFieldManager.FieldDefs.Count - 1 do
  if (IsBLOBFieldType(FFieldManager.FieldDefs[i].BaseFieldType)) then
    if (not CheckNullFlag(i,RecordBuffer)) then
     begin
      // save blob field data
      Offset := FFieldManager.FieldDefs[i].MemoryOffset;
      Move(PChar(RecordBuffer + Offset)^,Buffer,Sizeof(Buffer));
      if (Buffer = nil) then
        raise EABSException.Create(10196,ErrorLNilPointer);
      // calculate size of blob data
      BLOBDataSize := MemoryManager.GetMemoryBufferSize(Buffer) -
        sizeof(TABSPartialBLOBDescriptor) +
        sizeof(TABSPartialTemporaryBLOBDescriptor);
      PBLOBPartialDescriptor :=
        MemoryManager.GetMem(sizeof(TABSPartialTemporaryBLOBDescriptor));
      PBLOBPartialDescriptor^.NumBlocks :=
        PABSPartialBLOBDescriptor(Buffer)^.NumBlocks;
      PBLOBPartialDescriptor^.UncompressedSize :=
        PABSPartialBLOBDescriptor(Buffer)^.UncompressedSize;
      PBLOBPartialDescriptor^.CompressedSize := BLOBDataSize -
        sizeof(TABSPartialTemporaryBLOBDescriptor);
      BLOBDataList.Add(Buffer);
      BLOBDescriptorList.Add(PBLOBPartialDescriptor);
      // store offset to blob data instead of pointer to memory buffer
      Move(FBLOBPosition,PChar(RecordBuffer + Offset)^,Sizeof(FBLOBPosition));
      Inc(FBLOBPosition,BLOBDataSize);
     end; // not null blob field
end;


//------------------------------------------------------------------------------
// save record
//------------------------------------------------------------------------------
procedure TABSMemoryTableData.SaveRecordToStream(
            RecordBuffer: TABSRecordBuffer;
            Stream:       TStream
                                                );
var i:                        Integer;
    BLOBDataSize:             Integer;
    Buffer:                   PChar;
    PBLOBPartialDescriptor:   PABSPartialTemporaryBLOBDescriptor;
    BLOBDescriptorList:       TList;
    BLOBDataList:             TList;
begin
 if (FFieldManager.BlobFieldsPresent) then
  begin
   BLOBDescriptorList := TList.Create;
   BLOBDataList := TList.Create;
   try
     PrepareRecordBufferForSave(RecordBuffer,BLOBDescriptorList,
        BLOBDataList,Int64(Stream.Position + Int64(GetRecordBufferSize)));
     SaveDataToStream(RecordBuffer^,GetRecordBufferSize,Stream,10197);
     // save blob fields
     for i := 0 to BLOBDataList.Count - 1 do
      begin
       PBLOBPartialDescriptor := BLOBDescriptorList.Items[i];
       SaveDataToStream(PBLOBPartialDescriptor^,
        sizeof(TABSPartialTemporaryBLOBDescriptor),Stream,10198);
       Buffer := BLOBDataList.Items[i];
       BLOBDataSize := PBLOBPartialDescriptor^.CompressedSize;
       SaveDataToStream(PChar(Buffer + sizeof(TABSPartialBLOBDescriptor))^,BLOBDataSize,Stream,10199);
       MemoryManager.FreeAndNillMem(PBLOBPartialDescriptor);
      end; // not null blob field
   finally
    BLOBDescriptorList.Free;
    BLOBDataList.Free;
   end;
  end // blob fields
 else
  // no blob fields
  SaveDataToStream(RecordBuffer^,GetRecordBufferSize,Stream,10200);
end; // SaveRecord

{
//------------------------------------------------------------------------------
// load all records
//------------------------------------------------------------------------------
procedure TABSMemoryTableData.LoadRecordManager(Stream: TStream);
var RecordBuffer:     TABSRecordBuffer;
    i:                Integer;
begin
  if (FLoadedRecordCount > 0) then
   begin
    FRecordManager.LoadFromStream(Stream);
    RecordBuffer := MemoryManager.GetMem(FRecordManager.RecordBufferSize);
    try
      for i := 0 to FLoadedRecordCount - 1 do
       begin
        LoadRecordFromStream(RecordBuffer,Stream);
        FRecordManager.AddLoadedRecord(RecordBuffer);
       end;
    finally
      MemoryManager.FreeAndNillMem(RecordBuffer);
    end;
   end;
end; // LoadRecordManager


//------------------------------------------------------------------------------
// save all records
//------------------------------------------------------------------------------
procedure TABSMemoryTableData.SaveRecordManager(Stream: TStream);
var RecordBuffer:     TABSRecordBuffer;
    NavigationInfo:   TABSNavigationInfo;
begin
  if (FRecordManager.RecordCount > 0) then
   begin
     FRecordManager.SaveToStream(Stream);
     RecordBuffer := MemoryManager.GetMem(FRecordManager.RecordBufferSize);
     NavigationInfo.LastPosition := False;
     NavigationInfo.FirstPosition := True;
     NavigationInfo.RecordBuffer := RecordBuffer;
     NavigationInfo.GetRecordMode := grmNext;
     try
       FRecordManager.GetRecordBuffer(SYSTEM_SESSION_ID, NavigationInfo);
       if (NavigationInfo.GetRecordResult = grrOK) then
        begin
         NavigationInfo.FirstPosition := False;
         repeat
          // save record buffer and blob fields
          SaveRecordToStream(RecordBuffer,Stream);
          FRecordManager.GetRecordBuffer(SYSTEM_SESSION_ID, NavigationInfo);
         until (NavigationInfo.GetRecordResult <> grrOK);
        end;
     finally
      MemoryManager.FreeAndNillMem(RecordBuffer);
     end;
   end;
end; // SaveRecordManager
}

//------------------------------------------------------------------------------
// return filter bitmap rec count
//------------------------------------------------------------------------------
function TABSMemoryTableData.GetBitmapRecordCount(SessionID: TABSSessionID): TABSRecordNo;
begin
  Result := FRecordManager.RecordCount;
end;// GetBitmapRecordCount


//------------------------------------------------------------------------------
// return filter bitmap rec no by record id
//------------------------------------------------------------------------------
function TABSMemoryTableData.GetBitmapRecNoByRecordID(RecordID: TABSRecordID): TABSRecordNo;
begin
  Result := RecordID.PageNo;
end; // GetBitmapRecNoByRecordID


//------------------------------------------------------------------------------
// return filter bitmap rec no by record id
//------------------------------------------------------------------------------
function TABSMemoryTableData.GetRecordIDByBitmapRecNo(RecordNo: TABSRecordNo): TABSRecordID;
begin
  Result.PageNo := RecordNo;
  Result.PageItemNo := 0;
end; // GetRecordIDByBitmapRecNo


//------------------------------------------------------------------------------
// create
//------------------------------------------------------------------------------
constructor TABSMemoryTableData.Create(
                        aDatabaseData: TABSDatabaseData;
                        AllocRecordsBy: Integer
                      );
begin
 inherited Create(aDatabaseData);
 FPageManager := TABSMemoryPageManager.Create;
 FAllocRecordsBy := AllocRecordsBy;
 FDisableTempFiles := True;
end; // Create;


//------------------------------------------------------------------------------
// destroy
//------------------------------------------------------------------------------
destructor TABSMemoryTableData.Destroy;
begin
 EmptyTable(nil);
 DeleteAllIndexes(nil);
 FPageManager.ApplyChanges(SYSTEM_SESSION_ID);
 FPageManager.Free;
 inherited Destroy;
end; // Destroy


//------------------------------------------------------------------------------
// create table
//------------------------------------------------------------------------------
procedure TABSMemoryTableData.CreateTable(
                          Cursor: TABSCursor;
                          FieldDefs: TABSFieldDefs;
                          IndexDefs: TABSIndexDefs;
                          ConstraintDefs: TABSConstraintDefs
                                         );
begin
{$IFDEF DEBUG_TRACE_DATASET}
 aaWriteToLog('TABSMemoryTableData.CreateTable start');
 aaWriteToLog('TABSMemoryTableData.CreateTable FieldDefs.Count = '+IntToStr(FieldDefs.Count));
{$ENDIF}
 if ((FieldDefs.Count <= 0) and (not IsDesignMode)) then
   raise EABSException.Create(10025, ErrorLNoFields);
 TableName := Cursor.TableName;

 //CreateSequenceManager;
 CreateFieldManager(FieldDefs);
 CreateIndexManager(IndexDefs);
 CreateConstraintManager(ConstraintDefs);
 //BuildSequences;
 CreateRecordManager;
 InitCursor(Cursor);
 FIndexManager.CreateIndexesByIndexDefs(Cursor);
 if (Cursor <> nil) then
  if (not Cursor.Session.InTransaction) then
   PageManager.ApplyChanges(Cursor.Session.SessionID);
{$IFDEF DEBUG_TRACE_DATASET}
 aaWriteToLog('TABSMemoryTableData.CreateTable finish');
{$ENDIF}
end;// CreateTable


//------------------------------------------------------------------------------
// delete table
//------------------------------------------------------------------------------
procedure TABSMemoryTableData.DeleteTable(Cursor: TABSCursor; DesignMode: Boolean = False);
begin
 inherited DeleteTable(Cursor, DesignMode);
 if ((not DesignMode) or (FCursorList.Count = 0)) then
   Free;
end; // DeleteTable


//------------------------------------------------------------------------------
// empty table
//------------------------------------------------------------------------------
procedure TABSMemoryTableData.EmptyTable(Cursor: TABSCursor);
var
    NavigationInfo:   TABSNavigationInfo;
begin
 inherited EmptyTable(nil);

 if (FRecordManager <> nil) then
   if (FFieldManager.BlobFieldsPresent and (FRecordManager.RecordCount > 0)) then
    begin
     NavigationInfo.LastPosition := False;
     NavigationInfo.FirstPosition := True;
     NavigationInfo.RecordBuffer := MemoryManager.GetMem(FRecordManager.RecordBufferSize);
     NavigationInfo.GetRecordMode := grmNext;
     try
       FRecordManager.GetRecordBuffer(SYSTEM_SESSION_ID, NavigationInfo);
       if (NavigationInfo.GetRecordResult = grrOk) then
        begin
         NavigationInfo.FirstPosition := False;
         repeat
          ClearBLOBFieldsInRecordBuffer(NavigationInfo.RecordBuffer);
          FRecordManager.GetRecordBuffer(SYSTEM_SESSION_ID, NavigationInfo);
         until (NavigationInfo.GetRecordResult <> grrOK);
        end;
     finally
      MemoryManager.FreeAndNillMem(NavigationInfo.RecordBuffer);
     end;
    end;
 if (FRecordManager <> nil) then
  FRecordManager.Empty(SYSTEM_SESSION_ID);

 FPageManager.ApplyChanges(SYSTEM_SESSION_ID);
end; // EmptyTable


//------------------------------------------------------------------------------
// open table

⌨️ 快捷键说明

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