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

📄 absmemengine.pas

📁 Absolute Database 是来替代BDE[Borland数据库引擎]的用于Delphi 和 C++ Builder 开发用的数据库引擎. 它小巧, 高速, 健壮, 易于使用. 它能直接编译进
💻 PAS
📖 第 1 页 / 共 5 页
字号:
     OldRecordCount := FAllocatedRecordCount;
     Inc(FAllocatedRecordCount,FAllocRecordsBy);
     i := FAllocatedRecordCount * FRecordBufferSize;
     if (OldRecordCount = 0) then
      FRecordBuffer := MemoryManager.GetMem(i)
     else
      MemoryManager.ReallocMem(Pointer(FRecordBuffer),i);
     i := FAllocatedRecordCount div 8;
     if (FAllocatedRecordCount mod 8 > 0) then
      Inc(i);
     if (OldRecordCount = 0) then
      FDeleteFlagBuffer := MemoryManager.GetMem(i)
     else
      MemoryManager.ReallocMem(Pointer(FDeleteFlagBuffer),i);
    end; // increase record buffer size
    Move(RecordBuffer^,PChar(FRecordBuffer + RecordID.PageNo * FRecordBufferSize)^,
          FRecordBufferSize);
    SetNullFlag(False,RecordID.PageNo,FDeleteFlagBuffer);
    Inc(FRecordCount);
    if (RecordID.PageNo < FFirstRecordID) then
     FFirstRecordID := RecordID.PageNo;
    if (RecordID.PageNo > FLastRecordID) then
     FLastRecordID := RecordID.PageNo;
    Result := True;
    Inc(FTableState);
   except
  Result := False;
 end; // try
end; // AddRecord


//------------------------------------------------------------------------------
// update record, return true if record was updated, false if record was deleted
//------------------------------------------------------------------------------
function TABSMemoryRecordManager.UpdateRecord(
            SessionID: TABSSessionID;
            RecordBuffer: TABSRecordBuffer; RecordID: TABSRecordID): Boolean;
begin
 Result := False;
 if (not ((RecordID.PageNo < FFirstRecordID) or (RecordID.PageNo > FLastRecordID))) then
  try
   Move(RecordBuffer^,PChar(FRecordBuffer + RecordID.PageNo * FRecordBufferSize)^,
          FRecordBufferSize);
   Result := True;
   Inc(FTableState);
  except
   Result := False;
  end;
end; // UpdateRecord


//------------------------------------------------------------------------------
// delete record, return true if record was deleted, false if record was deleted earlier
//------------------------------------------------------------------------------
function TABSMemoryRecordManager.DeleteRecord(SessionID: TABSSessionID;
                                           var RecordID: TABSRecordID): Boolean;
begin
 Result := False;
 RecordID.PageItemNo := 0;
 if (not (FRecordCount <= 0)) and
    (not ((RecordID.PageNo < FFirstRecordID) or (RecordID.PageNo > FLastRecordID))) and
    (not (CheckNullFlag(RecordID.PageNo,FDeleteFlagBuffer))) then
  try
   // set delete flag
   SetNullFlag(True,RecordID.PageNo,FDeleteFlagBuffer);
   Dec(FRecordCount);
   if (FRecordCount = 0) then
    begin
     // no records
     FFirstRecordID := 0;
     FLastRecordID := 0;
    end
   else
    begin
     // update first and last records ID
     if (RecordID.PageNo = FFirstRecordID) then
      GetRecordFromAnyPosition(grmNext,FFirstRecordID);
     if (RecordID.PageNo = FLastRecordID) then
      begin
       GetRecordFromAnyPosition(grmPrior,FLastRecordID);
       RecordID.PageNo := FLastRecordID;
      end;
    end;
   FNoRecordsDeleted := False;
   Result := True;
   Inc(FTableState);
 except
  Result := False;
 end;
end; // DeleteRecord


//------------------------------------------------------------------------------
// get record
//------------------------------------------------------------------------------
procedure TABSMemoryRecordManager.GetRecordBuffer(SessionID: TABSSessionID;
                                        var NavigationInfo: TABSNavigationInfo);
begin
 if (FRecordCount = 0) then
  begin
   NavigationInfo.GetRecordResult := grrEOF;
   Exit;
  end;
 // get record relatively to the first position
 if (NavigationInfo.FirstPosition) then
  begin
   NavigationInfo.GetRecordResult := GetRecordFromFirstPosition(
                                      NavigationInfo.GetRecordMode,
                                      NavigationInfo.RecordID.PageNo
                                                               );
   if (NavigationInfo.GetRecordResult = grrOK) then
    NavigationInfo.FirstPosition := False;
  end
 else
 // get record relatively to the last position
 if (NavigationInfo.LastPosition) then
  begin
   NavigationInfo.GetRecordResult := GetRecordFromLastPosition(
                                      NavigationInfo.GetRecordMode,
                                      NavigationInfo.RecordID.PageNo
                                                               );
   if (NavigationInfo.GetRecordResult = grrOK) then
    NavigationInfo.LastPosition := False;
  end
 else
  NavigationInfo.GetRecordResult := GetRecordFromAnyPosition(
                                      NavigationInfo.GetRecordMode,
                                      NavigationInfo.RecordID.PageNo
                                                               );
 if (NavigationInfo.GetRecordResult = grrOK) then
  begin
   try
     Move(
          PChar(FRecordBuffer + NavigationInfo.RecordID.PageNo * FRecordBufferSize)^,
          NavigationInfo.RecordBuffer^,
          FRecordBufferSize
         );
     NavigationInfo.GetRecordResult := grrOK;
   except
    raise EABSException.Create(10019,ErrorLRetreivingRecord);
   end;
  end; // record retrieved successfully
end; // GetRecordBuffer


//------------------------------------------------------------------------------
// return 0,1, or -1 if (1 = 2), (1 > 2) or (1 < 2)
//------------------------------------------------------------------------------
function TABSMemoryRecordManager.CompareRecordID(RecordID1: TABSRecordID; RecordID2: TABSRecordID): Integer;
begin
 if (RecordID1.PageNo = RecordID2.PageNo) then
  Result := 0
 else
 if (RecordID1.PageNo > RecordID2.PageNo) then
  Result := 1
 else
  Result := -1;
end; // CompareRecordID


//------------------------------------------------------------------------------
// return record no
//------------------------------------------------------------------------------
function TABSMemoryRecordManager.GetApproximateRecNo(SessionID: TABSSessionID;
                                          RecordID: TABSRecordID): TABSRecordNo;
begin
 if (RecordCount = 0) or (RecordID.PageNo < FFirstRecordID) or (RecordID.PageNo > FLastRecordID) then
  Result := -1
 else
 if (RecordCount = 1) then
  Result := 1
 else
  Result :=  Round((RecordID.PageNo - FFirstRecordID) / (FRecordCount) *
                   (FLastRecordID - FFirstRecordID)) + 1;
end; // GetApproximateRecNo

{
//------------------------------------------------------------------------------
// Load from stream
//------------------------------------------------------------------------------
procedure TABSMemoryRecordManager.LoadFromStream(Stream: TStream);
var i: Integer;
begin
 LoadDataFromStream(i,Sizeof(i),Stream,10449);
 SetRecordCount(i);
 i := (FAllocatedRecordCount div 8) + Integer((FAllocatedRecordCount mod 8) > 0);
 LoadDataFromStream(FNoRecordsDeleted,Sizeof(FNoRecordsDeleted),Stream,10450);
 LoadDataFromStream(FFirstRecordID,Sizeof(FFirstRecordID),Stream,10451);
 LoadDataFromStream(FLastRecordID,Sizeof(FLastRecordID),Stream,10452);
 if (FAllocatedRecordCount > 0) then
   LoadDataFromStream(FDeleteFlagBuffer^,i,Stream,10453);
end; // LoadFromStream


//------------------------------------------------------------------------------
// Save from stream
//------------------------------------------------------------------------------
procedure TABSMemoryRecordManager.SaveToStream(Stream: TStream);
var i: Integer;
begin
 i := (FAllocatedRecordCount div 8) + Integer((FAllocatedRecordCount mod 8) > 0);
 SaveDataToStream(FAllocatedRecordCount,Sizeof(FAllocatedRecordCount),Stream,10444);
 SaveDataToStream(FNoRecordsDeleted,Sizeof(FNoRecordsDeleted),Stream,10445);
 SaveDataToStream(FFirstRecordID,Sizeof(FFirstRecordID),Stream,10446);
 SaveDataToStream(FLastRecordID,Sizeof(FLastRecordID),Stream,10447);
 if (FAllocatedRecordCount > 0) then
  SaveDataToStream(FDeleteFlagBuffer^,i,Stream,10448);
end; // SaveToStream


//------------------------------------------------------------------------------
// add loaded record
//------------------------------------------------------------------------------
procedure TABSMemoryRecordManager.AddLoadedRecord(RecordBuffer: TABSRecordBuffer);
var RecPos: TABSRecordNo;
begin
 Inc(FRecordCount);
 RecPos := FindRecord(FRecordCount-1);
 if (RecPos = INVALID_ID8) then
  raise EABSException.Create(10454,ErrorLInvalidRecordNo,[FRecordCount]);
 Move(RecordBuffer^,PChar(FRecordBuffer + RecPos * FRecordBufferSize)^,FRecordBufferSize);
end; // AddLoadedRecord
}

////////////////////////////////////////////////////////////////////////////////
//
// TABSMemoryTableData
//
////////////////////////////////////////////////////////////////////////////////


//------------------------------------------------------------------------------
// create RecordManager
//------------------------------------------------------------------------------
procedure TABSMemoryTableData.CreateRecordManager;
begin
 if (FRecordManager <> nil) then
  FRecordManager.Free;
 FRecordManager := TABSMemoryRecordManager.Create(
                      GetRecordBufferSize,
                      FAllocRecordsBy
                                                 );
end;// CreateRecordManager


//------------------------------------------------------------------------------
// create field manager
//------------------------------------------------------------------------------
procedure TABSMemoryTableData.CreateFieldManager(FieldDefs: TABSFieldDefs);
begin
 if (FFieldManager <> nil) then
  FFieldManager.Free;
 FFieldManager := TABSBaseFieldManager.Create(Self);
 inherited CreateFieldManager(FieldDefs);
end;// CreateFieldManager


//------------------------------------------------------------------------------
// create
//------------------------------------------------------------------------------
procedure TABSMemoryTableData.CreateIndexManager(IndexDefs: TABSIndexDefs);
begin
 if (FIndexManager <> nil) then
  FIndexManager.Free;
 FIndexManager := TABSBaseIndexManager.Create(Self, FPageManager);
 inherited CreateIndexManager(IndexDefs);
end;// CreateIndexManager


//------------------------------------------------------------------------------
// Create ConstraintManager
//------------------------------------------------------------------------------
procedure TABSMemoryTableData.CreateConstraintManager(ConstraintDefs: TABSConstraintDefs);
var i: Integer;
begin
 if (FConstraintManager <> nil) then
   FConstraintManager.Free;
  // Fill New ObjectIds
  FillDefsByObjectId(ConstraintDefs);
  // Set TableName to Constraits
  for i:=0 to ConstraintDefs.Count-1 do
   case ConstraintDefs[i].ConstraintType of
    ctNotNull:
      TABSConstraintDefNotNull(ConstraintDefs[i]).TableName := FTableName;
    ctCheck:
      TABSConstraintDefCheck(ConstraintDefs[i]).TableName := FTableName;
    ctPK:
      TABSConstraintDefPrimary(ConstraintDefs[i]).TableName := FTableName;
    ctUnique:
      TABSConstraintDefUnique(ConstraintDefs[i]).TableName := FTableName;
    else
      raise EABSException.Create(30040, ErrorGNotImplementedYet);
   end;
  // Create ConstraintManager
  FConstraintManager := TABSBaseConstraintManager.Create(Self);
  FConstraintManager.ConstraintDefs.Assign(ConstraintDefs);
  // Links ObjectIds
  FConstraintManager.LinkObjectIds;
  // Set enpty Names
  FConstraintManager.FillConstraintAutoNames;
end;//CreateConstraintManager


//------------------------------------------------------------------------------
// load table header
//------------------------------------------------------------------------------
procedure TABSMemoryTableData.LoadTableHeader(
              Stream:             TStream;
              var BLOBDescriptor: TABSBLOBDescriptor
                                             );
var FileHeader: TABSMemoryTableFileHeader;
    DatabaseID: TABSSequenceValue;
begin
  LoadDataFromStream(FileHeader,sizeof(FileHeader),Stream,10160);
  if (FileHeader.Signature <> ABSSignature) then
    raise EABSException.Create(10161,ErrorLInvalidSignature,
      [FileHeader.Signature,ABSSignature]);
  if (FileHeader.Version > ABSVersion + 0.0001) then
    raise EABSException.Create(10162,ErrorLInvalidVersion,
      [FileHeader.Version,ABSVersion]);
  if (FileHeader.Version < 0.99) then
    raise EABSException.Create(10443,ErrorLInvalidVersion,
      [FileHeader.Version,ABSVersion]);
  SetLength(FTableName,FileHeader.NameLength);
  LoadDataFromStream(PChar(@FTableName[1])^,FileHeader.NameLength,Stream,10163);
  LoadDataFromStream(DatabaseID,sizeof(DatabaseID),Stream,10417);


  if (TABSMemoryDatabaseData(FDatabaseData).FLastObjectID < DatabaseID) then
    TABSMemoryDatabaseData(FDatabaseData).FLastObjectID := DatabaseID;

  BLOBDescriptor.StartPosition := Stream.Position;
  BLOBDescriptor.BlockSize := FileHeader.BlockSize;
  BLOBDescriptor.NumBlocks := FileHeader.NumBlocks;
  BLOBDescriptor.UncompressedSize := FileHeader.UncompressedSize;
  BLOBDescriptor.CompressionAlgorithm := FileHeader.CompressionAlgorithm;
  BLOBDescriptor.CompressionMode := FileHeader.CompressionMode;
  FLoadedRecordCount := FileHeader.RecordCount;
end; // LoadTableHeader


//------------------------------------------------------------------------------
// save table header
//------------------------------------------------------------------------------
procedure TABSMemoryTableData.SaveTableHeader(
              Stream:             TStream;
              var BLOBDescriptor: TABSBLOBDescriptor
              );
var FileHeader: TABSMemoryTableFileHeader;
    DatabaseID: TABSSequenceValue;
begin
  FileHeader.Signature := ABSSignature;
  FileHeader.Version := ABSVersion;
  FileHeader.RecordCount := FRecordManager.RecordCount;
  FileHeader.UncompressedSize := BLOBDescriptor.UncompressedSize;
  FileHeader.NumBlocks := BLOBDescriptor.NumBlocks;

⌨️ 快捷键说明

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