📄 myldbmemengine.pas
字号:
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 + -