📄 absmemengine.pas
字号:
//------------------------------------------------------------------------------
procedure TABSMemoryTableData.OpenTable(Cursor: TABSCursor);
begin
TableName := Cursor.TableName;
inherited OpenTable(Cursor);
end;// OpenTable
//------------------------------------------------------------------------------
// close table
//------------------------------------------------------------------------------
procedure TABSMemoryTableData.CloseTable(Cursor: TABSCursor);
begin
inherited CloseTable(Cursor);
end;// CloseTable
//------------------------------------------------------------------------------
// AddIndex
//------------------------------------------------------------------------------
procedure TABSMemoryTableData.AddIndex(IndexDef: TABSIndexDef; Cursor: TABSCursor);
begin
Lock;
try
inherited AddIndex(IndexDef, Cursor);
if (not Cursor.Session.InTransaction) then
PageManager.ApplyChanges(Cursor.Session.SessionID);
finally
Unlock;
end;
end;// AddIndex
//------------------------------------------------------------------------------
// DeleteIndex
//------------------------------------------------------------------------------
procedure TABSMemoryTableData.DeleteIndex(IndexID: TABSObjectID; Cursor: TABSCursor);
begin
Lock;
try
inherited DeleteIndex(IndexID, Cursor);
if (Cursor <> nil) then
begin
if (not Cursor.Session.InTransaction) then
PageManager.ApplyChanges(Cursor.Session.SessionID);
end
else
PageManager.ApplyChanges(SYSTEM_SESSION_ID);
finally
Unlock;
end;
end;// DeleteIndex
//------------------------------------------------------------------------------
// Write BLOB Field To Record Buffer
//------------------------------------------------------------------------------
procedure TABSMemoryTableData.WriteBLOBFieldToRecordBuffer(
Cursor: TABSCursor;
FieldNo: Integer;
BLOBStream: TABSStream
);
var Buffer: PChar;
BufferSize,Offset: Integer;
ReadBytes: Integer;
begin
Lock;
try
Buffer := Cursor.CurrentRecordBuffer;
if (BLOBStream.Modified) then
begin
if (BLOBStream.Size = 0) then
begin
// empty stream
ClearBLOBFieldInRecordBuffer(Buffer,FieldNo);
Buffer := nil;
Move(Buffer,PChar(Cursor.CurrentRecordBuffer +
FieldManager.FieldDefs[FieldNo].MemoryOffset)^,sizeof(Buffer));
SetNullFlag(True,FieldNo,Cursor.CurrentRecordBuffer);
end
else
begin
ClearBLOBFieldInRecordBuffer(Buffer,FieldNo);
Offset := sizeof(TABSPartialBLOBDescriptor);
BufferSize := Integer(TABSCompressedBLOBStream(
TABSLocalBLOBStream(BLOBStream).TemporaryStream).CompressedStream.Size) +
Offset;
Buffer := MemoryManager.GetMem(BufferSize);
PABSPartialBLOBDescriptor(Buffer)^.NumBlocks := TABSCompressedBLOBStream(
TABSLocalBLOBStream(BLOBStream).TemporaryStream).BLOBDescriptor.NumBlocks;
PABSPartialBLOBDescriptor(Buffer)^.UncompressedSize := TABSCompressedBLOBStream(
TABSLocalBLOBStream(BLOBStream).TemporaryStream).BLOBDescriptor.UncompressedSize;
TABSCompressedBLOBStream(
TABSLocalBLOBStream(BLOBStream).TemporaryStream).CompressedStream.
Position := 0;
ReadBytes := TABSCompressedBLOBStream(
TABSLocalBLOBStream(BLOBStream).TemporaryStream).CompressedStream.
Read(PChar(Buffer + Offset)^,(BufferSize - Offset));
if (ReadBytes <> (BufferSize - Offset)) then
begin
MemoryManager.FreeAndNillMem(Buffer);
raise EABSException.Create(10117,ErrorLCannotReadFromStream,
[0,(BufferSize - Offset),(BufferSize - Offset),ReadBytes]);
end;
//Move(Buffer,PChar(Cursor.CurrentRecordBuffer +
// FieldManager.FieldDefs[FieldNo].MemoryOffset)^, sizeof(Buffer));
PCardinal(Cursor.CurrentRecordBuffer + FieldManager.FieldDefs[FieldNo].MemoryOffset)^ := Cardinal(Buffer);
SetNullFlag(False,FieldNo,Cursor.CurrentRecordBuffer);
end; // not empty stream
end; // Modified
finally
Unlock;
end;
end; // WriteBLOBFieldToRecordBuffer
//------------------------------------------------------------------------------
// create blob stream
//------------------------------------------------------------------------------
procedure TABSMemoryTableData.ClearBLOBFieldInRecordBuffer(
RecordBuffer: TABSRecordBuffer;
FieldNo: Integer);
var Buffer: PChar;
begin
Lock;
try
if (FFieldManager.BlobFieldsPresent) then
begin
// check null
if (not ((PByte(RecordBuffer + (FieldNo div 8))^) and
(1 shl (FieldNo mod 8)) <> 0)) then
begin
Move(PChar(RecordBuffer +
FieldManager.FieldDefs[FieldNo].MemoryOffset)^,Buffer,sizeof(Buffer));
if (Buffer = nil) then
raise EABSException.Create(10118,ErrorLNilPointer);
MemoryManager.FreeAndNillMem(Buffer);
// set null
PByte(RecordBuffer + (FieldNo div 8))^ := PByte(RecordBuffer + (FieldNo div 8))^ or
(1 shl (FieldNo mod 8));
end;
end;
finally
Unlock;
end;
end; // ClearBLOBFieldInRecordBuffer
//------------------------------------------------------------------------------
// create blob stream
//------------------------------------------------------------------------------
function TABSMemoryTableData.InternalCreateBlobStream(
Cursor: TABSCursor;
ToInsert: Boolean;
FieldNo: Integer;
OpenMode: TABSBLOBOpenMode
): TABSStream;
var
TempStream: TABSTemporaryStream;
CompressedStream: TABSCompressedBLOBStream;
Buffer: PChar;
Offset,BufferSize: Integer;
BLOBDescriptor: TABSBLOBDescriptor;
begin
Lock;
try
Result := nil;
BLOBDescriptor.CompressionAlgorithm :=
Byte(FieldManager.FieldDefs[FieldNo].BLOBCompressionAlgorithm);
BLOBDescriptor.CompressionMode := FieldManager.FieldDefs[FieldNo].BLOBCompressionMode;
BLOBDescriptor.BlockSize := FieldManager.FieldDefs[FieldNo].BLOBBlockSize;
if (BLOBDescriptor.BlockSize = 0) then
raise EABSException.Create(10420,ErrorLZeroBlockSizeIsNotAllowed);
BLOBDescriptor.StartPosition := 0;
TempStream := TABSTemporaryStream.Create(FDisableTempFiles);
// create new compressed stream
if ((ToInsert and (OpenMode = bomWrite)) or (OpenMode = bomWrite) or
(Cursor.CurrentRecordBuffer = nil) or
(CheckNullFlag(FieldNo,Cursor.CurrentRecordBuffer))) then
begin
// empty stream
BLOBDescriptor.NumBlocks := 0;
BLOBDescriptor.UncompressedSize := 0;
CompressedStream := TABSCompressedBLOBStream.Create(TempStream,
BLOBDescriptor,True);
Result := TABSLocalBLOBStream.Create(CompressedStream,Cursor,OpenMode,FieldNo);
end // empty stream
else
begin
// copy value from TableData
Offset := FieldManager.FieldDefs[FieldNo].MemoryOffset;
// get pointer to memory buffer with blob stream content
//Move(PChar(Cursor.CurrentRecordBuffer + Offset)^,Buffer,Sizeof(Buffer));
Buffer := PChar(PCardinal(Cursor.CurrentRecordBuffer + Offset)^);
if (Buffer = nil) then
raise EABSException.Create(10112,ErrorLNilPointer);
// creating source memory stream
Offset := sizeof(TABSPartialBLOBDescriptor);
BufferSize := MemoryManager.GetMemoryBufferSize(Buffer) - Offset;
// copy partial blob descriptor
BLOBDescriptor.NumBlocks := PABSPartialBLOBDescriptor(Buffer)^.NumBlocks;
BLOBDescriptor.UncompressedSize := PABSPartialBLOBDescriptor(Buffer)^.UncompressedSize;
TempStream.Write(PChar(Buffer + Offset)^,BufferSize);
TempStream.Position := 0;
CompressedStream := TABSCompressedBLOBStream.Create(TempStream,
BLOBDescriptor,False);
Result := TABSLocalBLOBStream.Create(CompressedStream,Cursor,OpenMode,FieldNo);
end; // copy value from TableData
finally
Unlock;
end;
end; // InternalCreateBlobStream
//------------------------------------------------------------------------------
// GetDirectBlobData
//------------------------------------------------------------------------------
procedure TABSMemoryTableData.GetDirectBlobData(
Cursor: TABSCursor;
FieldNo: Integer;
RecordBuffer: TABSRecordBuffer;
var BLOBDescriptor: TABSPartialTemporaryBLOBDescriptor;
var pBlobData: PChar);
var
Buffer: PChar;
Offset,BufferSize: Integer;
begin
Lock;
try
if (CheckNullFlag(FieldNo,RecordBuffer)) then
begin
BLOBDescriptor.NumBlocks := 0;
BLOBDescriptor.UncompressedSize := 0;
BLOBDescriptor.CompressedSize := 0;
pBlobData := nil;
end
else
begin
// copy value from TableData
Offset := FieldManager.FieldDefs[FieldNo].MemoryOffset;
// get pointer to memory buffer with blob stream content
Buffer := PChar(PCardinal(RecordBuffer + Offset)^);
if (Buffer = nil) then
raise EABSException.Create(10511,ErrorLNilPointer);
// creating source memory stream
Offset := sizeof(TABSPartialBLOBDescriptor);
BufferSize := MemoryManager.GetMemoryBufferSize(Buffer) - Offset;
// copy partial blob descriptor
BLOBDescriptor.NumBlocks := PABSPartialBLOBDescriptor(Buffer)^.NumBlocks;
BLOBDescriptor.UncompressedSize := PABSPartialBLOBDescriptor(Buffer)^.UncompressedSize;
BLOBDescriptor.CompressedSize := BufferSize;
// get blob data
pBlobData := MemoryManager.GetMem(BufferSize);
Move(PChar(Buffer + Offset)^,pBlobData^,BufferSize);
end; // copy value from TableData
finally
Unlock;
end;
end;// GetDirectBlobData
//------------------------------------------------------------------------------
// SetDirectBlobData
//------------------------------------------------------------------------------
procedure TABSMemoryTableData.SetDirectBlobData(
Cursor: TABSCursor;
FieldNo: Integer;
RecordBuffer: TABSRecordBuffer;
var BLOBDescriptor: TABSPartialTemporaryBLOBDescriptor;
var pBlobData: PChar);
var
Buffer: PChar;
BufferSize,Offset: Integer;
begin
Lock;
try
if (BLOBDescriptor.CompressedSize = 0) then
begin
// empty stream
ClearBLOBFieldInRecordBuffer(RecordBuffer,FieldNo);
Buffer := nil;
Move(Buffer,PChar(RecordBuffer +
FieldManager.FieldDefs[FieldNo].MemoryOffset)^,sizeof(Buffer));
SetNullFlag(True,FieldNo,RecordBuffer);
end
else
begin
ClearBLOBFieldInRecordBuffer(RecordBuffer,FieldNo);
Offset := sizeof(TABSPartialBLOBDescriptor);
BufferSize := BLOBDescriptor.CompressedSize + Offset;
Buffer := MemoryManager.GetMem(BufferSize);
PABSPartialBLOBDescriptor(Buffer)^.NumBlocks := BLOBDescriptor.NumBlocks;
PABSPartialBLOBDescriptor(Buffer)^.UncompressedSize := BLOBDescriptor.UncompressedSize;
Move(pBlobData^,PChar(Buffer + Offset)^,(BufferSize - Offset));
PCardinal(RecordBuffer + FieldManager.FieldDefs[FieldNo].MemoryOffset)^ := Cardinal(Buffer);
SetNullFlag(False,FieldNo,RecordBuffer);
end; // not empty stream
finally
Unlock;
end;
end;// SetDirectBlobData
//------------------------------------------------------------------------------
// FreeDirectBlobData
//------------------------------------------------------------------------------
procedure TABSMemoryTableData.FreeDirectBlobData(
Cursor: TABSCursor;
FieldNo: Integer;
RecordBuffer: TABSRecordBuffer;
var BLOBDescriptor: TABSPartialTemporaryBLOBDescriptor;
var pBlobData: PChar);
begin
Lock;
try
if (pBlobData <> nil) then
MemoryManager.FreeAndNillMem(pBlobData);
finally
Unlock;
end;
end;// FreeDirectBlobData
//------------------------------------------------------------------------------
// insert record
//------------------------------------------------------------------------------
function TABSMemoryTableData.InsertRecord(var Cursor: TABSCursor): Boolean;
begin
Result := False;
Lock;
try
if (FRecordManager = nil) then
raise EABSException.Create(10010,ErrorLNilPointer);
if (Cursor.CurrentRecordBuffer = nil) then
raise EABSException.Create(10018,ErrorLNilPointer);
// add record to first empty space
Result := FRecordManager.AddRecord(Cursor.Session.SessionID,
Cursor.CurrentRecordBuffer,Cursor.CurrentRecordID);
// current record id will be the same as position as we insert in first empty record
Cursor.CurrentRecordID.PageItemNo := 0;
if (Result) then
begin
if (TABSRecordBitmap(Cursor.RecordBitmap).Active) then
begin
if (IsRecordVisible(Cu
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -