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

📄 myldbmemengine.pas

📁 一个本地database引擎,支持中文T_Sql查询,兼容DELPHI标准数据库控件
💻 PAS
📖 第 1 页 / 共 5 页
字号:
   if (FRecordCount = 0) then
    RecordID.PageNo := 0
   else
    RecordID.PageNo := FLastRecordID+1;
   RecordID.PageItemNo := 0;
   if (FAllocatedRecordCount <= RecordID.PageNo) then
    begin
     // increase record buffer size
     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 TMYLDBMemoryRecordManager.UpdateRecord(
            SessionID: TMYLDBSessionID;
            RecordBuffer: TMYLDBRecordBuffer; RecordID: TMYLDBRecordID): 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 TMYLDBMemoryRecordManager.DeleteRecord(SessionID: TMYLDBSessionID;
                                           var RecordID: TMYLDBRecordID): 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 TMYLDBMemoryRecordManager.GetRecordBuffer(SessionID: TMYLDBSessionID;
                                        var NavigationInfo: TMYLDBNavigationInfo);
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 EMYLDBException.Create(10019,ErrorLRetreivingRecord);
   end;
  end; // record retrieved successfully
end; // GetRecordBuffer


//------------------------------------------------------------------------------
// return 0,1, or -1 if (1 = 2), (1 > 2) or (1 < 2)
//------------------------------------------------------------------------------
function TMYLDBMemoryRecordManager.CompareRecordID(RecordID1: TMYLDBRecordID; RecordID2: TMYLDBRecordID): 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 TMYLDBMemoryRecordManager.GetApproximateRecNo(SessionID: TMYLDBSessionID;
                                          RecordID: TMYLDBRecordID): TMYLDBRecordNo;
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 TMYLDBMemoryRecordManager.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 TMYLDBMemoryRecordManager.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 TMYLDBMemoryRecordManager.AddLoadedRecord(RecordBuffer: TMYLDBRecordBuffer);
var RecPos: TMYLDBRecordNo;
begin
 Inc(FRecordCount);
 RecPos := FindRecord(FRecordCount-1);
 if (RecPos = INVALID_ID8) then
  raise EMYLDBException.Create(10454,ErrorLInvalidRecordNo,[FRecordCount]);
 Move(RecordBuffer^,PChar(FRecordBuffer + RecPos * FRecordBufferSize)^,FRecordBufferSize);
end; // AddLoadedRecord
}

////////////////////////////////////////////////////////////////////////////////
//
// TMYLDBMemoryTableData
//
////////////////////////////////////////////////////////////////////////////////


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


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


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


//------------------------------------------------------------------------------
// Create ConstraintManager
//------------------------------------------------------------------------------
procedure TMYLDBMemoryTableData.CreateConstraintManager(ConstraintDefs: TMYLDBConstraintDefs);
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:
      TMYLDBConstraintDefNotNull(ConstraintDefs[i]).TableName := FTableName;
    ctCheck:
      TMYLDBConstraintDefCheck(ConstraintDefs[i]).TableName := FTableName;
    ctPK:
      TMYLDBConstraintDefPrimary(ConstraintDefs[i]).TableName := FTableName;
    ctUnique:
      TMYLDBConstraintDefUnique(ConstraintDefs[i]).TableName := FTableName;
    else
      raise EMYLDBException.Create(30040, ErrorGNotImplementedYet);
   end;
  // Create ConstraintManager
  FConstraintManager := TMYLDBBaseConstraintManager.Create(Self);
  FConstraintManager.ConstraintDefs.Assign(ConstraintDefs);
  // Links ObjectIds
  FConstraintManager.LinkObjectIds;
  // Set enpty Names
  FConstraintManager.FillConstraintAutoNames;
end;//CreateConstraintManager


//------------------------------------------------------------------------------
// load table header
//------------------------------------------------------------------------------
procedure TMYLDBMemoryTableData.LoadTableHeader(
              Stream:             TStream;
              var BLOBDescriptor: TMYLDBBLOBDescriptor
                                             );
var FileHeader: TMYLDBMemoryTableFileHeader;
    DatabaseID: TMYLDBSequenceValue;
begin
  LoadDataFromStream(FileHeader,sizeof(FileHeader),Stream,10160);
  if (FileHeader.Signature <> MYLDBSignature) then
    raise EMYLDBException.Create(10161,ErrorLInvalidSignature,
      [FileHeader.Signature,MYLDBSignature]);
  if (FileHeader.Version > MYLDBVersion + 0.0001) then
    raise EMYLDBException.Create(10162,ErrorLInvalidVersion,
      [FileHeader.Version,MYLDBVersion]);
  if (FileHeader.Version < 0.99) then
    raise EMYLDBException.Create(10443,ErrorLInvalidVersion,
      [FileHeader.Version,MYLDBVersion]);
  SetLength(FTableName,FileHeader.NameLength);
  LoadDataFromStream(PChar(@FTableName[1])^,FileHeader.NameLength,Stream,10163);
  LoadDataFromStream(DatabaseID,sizeof(DatabaseID),Stream,10417);


  if (TMYLDBMemoryDatabaseData(FDatabaseData).FLastObjectID < DatabaseID) then
    TMYLDBMemoryDatabaseData(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
//------------------------------------------------------------------------------

⌨️ 快捷键说明

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