📄 myldbmemengine.pas
字号:
procedure TMYLDBMemoryTableData.SaveTableHeader(
Stream: TStream;
var BLOBDescriptor: TMYLDBBLOBDescriptor
);
var FileHeader: TMYLDBMemoryTableFileHeader;
DatabaseID: TMYLDBSequenceValue;
i:integer;
begin
// FileHeader.Signature := MYLDBSignature;
for i:=0 to 3 do
FileHeader.Signature[i] := MYLDBSignature[i+1];
FileHeader.Version := MYLDBVersion;
FileHeader.RecordCount := FRecordManager.RecordCount;
FileHeader.UncompressedSize := BLOBDescriptor.UncompressedSize;
FileHeader.NumBlocks := BLOBDescriptor.NumBlocks;
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 := TMYLDBMemoryDatabaseData(FDatabaseData).FLastObjectID;
SaveDataToStream(DatabaseID,sizeof(DatabaseID),Stream,10416);
BLOBDescriptor.StartPosition := Stream.Position;
end; // SaveTableHeader
//------------------------------------------------------------------------------
// load blob data
//------------------------------------------------------------------------------
procedure TMYLDBMemoryTableData.LoadBLOBDataFromStream(
RecordBuffer: TMYLDBRecordBuffer;
FieldNo: Integer;
Stream: TStream
);
var Buffer: PChar;
FBLOBPosition: Int64;
Offset,Offset2: Integer;
BLOBPartialDescriptor: TMYLDBPartialTemporaryBLOBDescriptor;
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(TMYLDBPartialBLOBDescriptor);
Buffer := MemoryManager.GetMem(BLOBPartialDescriptor.CompressedSize + Offset2);
PMYLDBPartialBLOBDescriptor(Buffer)^.NumBlocks :=
BLOBPartialDescriptor.NumBlocks;
PMYLDBPartialBLOBDescriptor(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 TMYLDBMemoryTableData.LoadRecordFromStream(
RecordBuffer: TMYLDBRecordBuffer;
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 TMYLDBMemoryTableData.PrepareRecordBufferForSave(
RecordBuffer: TMYLDBRecordBuffer;
BLOBDescriptorList: TList;
BLOBDataList: TList;
BLOBPosition: Int64
);
var FBLOBPosition: Int64;
i: Integer;
BLOBDataSize: Integer;
Offset: Integer;
Buffer: PChar;
PBLOBPartialDescriptor: PMYLDBPartialTemporaryBLOBDescriptor;
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 EMYLDBException.Create(10196,ErrorLNilPointer);
// calculate size of blob data
BLOBDataSize := MemoryManager.GetMemoryBufferSize(Buffer) -
sizeof(TMYLDBPartialBLOBDescriptor) +
sizeof(TMYLDBPartialTemporaryBLOBDescriptor);
PBLOBPartialDescriptor :=
MemoryManager.GetMem(sizeof(TMYLDBPartialTemporaryBLOBDescriptor));
PBLOBPartialDescriptor^.NumBlocks :=
PMYLDBPartialBLOBDescriptor(Buffer)^.NumBlocks;
PBLOBPartialDescriptor^.UncompressedSize :=
PMYLDBPartialBLOBDescriptor(Buffer)^.UncompressedSize;
PBLOBPartialDescriptor^.CompressedSize := BLOBDataSize -
sizeof(TMYLDBPartialTemporaryBLOBDescriptor);
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 TMYLDBMemoryTableData.SaveRecordToStream(
RecordBuffer: TMYLDBRecordBuffer;
Stream: TStream
);
var i: Integer;
BLOBDataSize: Integer;
Buffer: PChar;
PBLOBPartialDescriptor: PMYLDBPartialTemporaryBLOBDescriptor;
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(TMYLDBPartialTemporaryBLOBDescriptor),Stream,10198);
Buffer := BLOBDataList.Items[i];
BLOBDataSize := PBLOBPartialDescriptor^.CompressedSize;
SaveDataToStream(PChar(Buffer + sizeof(TMYLDBPartialBLOBDescriptor))^,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 TMYLDBMemoryTableData.LoadRecordManager(Stream: TStream);
var RecordBuffer: TMYLDBRecordBuffer;
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 TMYLDBMemoryTableData.SaveRecordManager(Stream: TStream);
var RecordBuffer: TMYLDBRecordBuffer;
NavigationInfo: TMYLDBNavigationInfo;
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 TMYLDBMemoryTableData.GetBitmapRecordCount(SessionID: TMYLDBSessionID): TMYLDBRecordNo;
begin
Result := FRecordManager.RecordCount;
end;// GetBitmapRecordCount
//------------------------------------------------------------------------------
// return filter bitmap rec no by record id
//------------------------------------------------------------------------------
function TMYLDBMemoryTableData.GetBitmapRecNoByRecordID(RecordID: TMYLDBRecordID): TMYLDBRecordNo;
begin
Result := RecordID.PageNo;
end; // GetBitmapRecNoByRecordID
//------------------------------------------------------------------------------
// return filter bitmap rec no by record id
//------------------------------------------------------------------------------
function TMYLDBMemoryTableData.GetRecordIDByBitmapRecNo(RecordNo: TMYLDBRecordNo): TMYLDBRecordID;
begin
Result.PageNo := RecordNo;
Result.PageItemNo := 0;
end; // GetRecordIDByBitmapRecNo
//------------------------------------------------------------------------------
// create
//------------------------------------------------------------------------------
constructor TMYLDBMemoryTableData.Create(
aDatabaseData: TMYLDBDatabaseData;
AllocRecordsBy: Integer
);
begin
inherited Create(aDatabaseData);
FPageManager := TMYLDBMemoryPageManager.Create;
FAllocRecordsBy := AllocRecordsBy;
FDisableTempFiles := True;
end; // Create;
//------------------------------------------------------------------------------
// destroy
//------------------------------------------------------------------------------
destructor TMYLDBMemoryTableData.Destroy;
begin
EmptyTable(nil);
DeleteAllIndexes(nil);
FPageManager.ApplyChanges(SYSTEM_SESSION_ID);
FPageManager.Free;
inherited Destroy;
end; // Destroy
//------------------------------------------------------------------------------
// create table
//------------------------------------------------------------------------------
procedure TMYLDBMemoryTableData.CreateTable(
Cursor: TMYLDBCursor;
FieldDefs: TMYLDBFieldDefs;
IndexDefs: TMYLDBIndexDefs;
ConstraintDefs: TMYLDBConstraintDefs
);
begin
{$IFDEF DEBUG_TRACE_DATASET}
aaWriteToLog('TMYLDBMemoryTableData.CreateTable start');
aaWriteToLog('TMYLDBMemoryTableData.CreateTable FieldDefs.Count = '+IntToStr(FieldDefs.Count));
{$ENDIF}
if ((FieldDefs.Count <= 0) and (not IsDesignMode)) then
raise EMYLDBException.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('TMYLDBMemoryTableData.CreateTable finish');
{$ENDIF}
end;// CreateTable
//------------------------------------------------------------------------------
// delete table
//------------------------------------------------------------------------------
procedure TMYLDBMemoryTableData.DeleteTable(Cursor: TMYLDBCursor; DesignMode: Boolean = False);
begin
inherited DeleteTable(Cursor, DesignMode);
if ((not DesignMode) or (FCursorList.Count = 0)) then
Free;
end; // DeleteTable
//------------------------------------------------------------------------------
// empty table
//------------------------------------------------------------------------------
procedure TMYLDBMemoryTableData.EmptyTable(Cursor: TMYLDBCursor);
var
NavigationInfo: TMYLDBNavigationInfo;
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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -