📄 absbaseengine.pas
字号:
procedure Rollback(SessionID: TABSSessionID); virtual;
procedure FlushBuffers; virtual;
public
property DatabaseName: String read FDatabaseName write FDatabaseName;
property PageManager: TABSPageManager read FPageManager write FPageManager;
property ReadOnly: Boolean read FReadOnly write FReadOnly;
property SessionList: TList read FSessionList;
property MultiUser: Boolean read FMultiUser write FMultiUser;
// 5.12
property SessionName: string read FSessionName write FSessionName;
end; // TABSDatabaseData
////////////////////////////////////////////////////////////////////////////////
//
// General functions and procedures
//
////////////////////////////////////////////////////////////////////////////////
procedure ShowErrorMessage(ErrorMessage: String);
procedure ShowWarningMessage(WarningMessage: String);
// return false if field value is null
function GetFieldData(
// field number in FieldDefs
FieldNo: Integer;
// field definitions
FieldDefs: TABSFieldDefs;
// pointer to allocated buffer for storing field value
Buffer: Pointer;
// record buffer
RecordBuffer: TABSRecordBuffer
): Boolean;
// returns false if field value is null
procedure SetFieldData(
// physical field No
FieldNo: Integer;
// field definitions
FieldDefs: TABSFieldDefs;
// pointer to allocated buffer with new field value
Buffer: Pointer;
// record buffer
RecordBuffer: TABSRecordBuffer
);
// return true if record buffers are binary identical
function CompareRecordBuffers(RecordBuffer1,RecordBuffer2: TABSRecordBuffer;
RecordBufferSize: Integer): Boolean;
var
IsDesignMode: Boolean;
implementation
uses
// AbsoluteDatabase units
ABSMain,
ABSBTree,
ABSLocalEngine,
ABSDiskEngine;
////////////////////////////////////////////////////////////////////////////////
//
// TABSBaseFieldManager
//
////////////////////////////////////////////////////////////////////////////////
//------------------------------------------------------------------------------
// GetNextAutoincVal
//------------------------------------------------------------------------------
function TABSBaseFieldManager.GetNextAutoincVal(FieldNo: Integer): TABSSequenceValue;
begin
if (FieldNo >= FieldDefs.Count) then
raise EABSException.Create(30402, ErrorGFieldWithObjectIdNotFound, [FieldNo]);
if (FieldNo >= Length(FLastAutoIncValues)) then
raise EABSException.Create(30403, ErrorGFieldWithObjectIdNotFound, [FieldNo]);
if (FFieldDefs.Items[FieldNo].AutoincIncrement <> 0) then
Inc(FLastAutoIncValues[FieldNo], FFieldDefs.Items[FieldNo].AutoincIncrement)
else
Inc(FLastAutoIncValues[FieldNo]);
if ((FFieldDefs.Items[FieldNo].AutoincMaxValue <> 0) and
(FLastAutoIncValues[FieldNo] > FFieldDefs.Items[FieldNo].AutoincMaxValue)) then
if (FFieldDefs.Items[FieldNo].AutoincCycled) then
FLastAutoIncValues[FieldNo] := FFieldDefs.Items[FieldNo].AutoincMinValue
else
raise EABSException.Create(20160, ErrorAAutoincMaxValueExceeded, [FFieldDefs.Items[FieldNo].Name]);
Result := FLastAutoIncValues[FieldNo];
end;//GetNextAutoincVal
//------------------------------------------------------------------------------
// Constructor
//------------------------------------------------------------------------------
constructor TABSBaseFieldManager.Create(TableData: TABSTableData);
begin
FTableData := TableData;
FFieldDefs := TABSFieldDefs.Create;
end;//Create
//------------------------------------------------------------------------------
// Destructor
//------------------------------------------------------------------------------
destructor TABSBaseFieldManager.Destroy;
begin
FFieldDefs.Free;
end;//Destroy
//------------------------------------------------------------------------------
// load from stream
//------------------------------------------------------------------------------
procedure TABSBaseFieldManager.LoadMetadata(Stream: TStream);
begin
FieldDefs.LoadFromStream(Stream);
RecalcFieldOffsets;
InitLastAutoIncValues;
end; // LoadMetadata
//------------------------------------------------------------------------------
// save to stream
//------------------------------------------------------------------------------
procedure TABSBaseFieldManager.SaveMetadata(Stream: TStream);
begin
FieldDefs.SaveToStream(Stream);
end; // SaveMetadata
//------------------------------------------------------------------------------
// LoadMostUpdated
//------------------------------------------------------------------------------
procedure TABSBaseFieldManager.LoadMostUpdated(Buf: PChar; var Offset: Integer);
var cnt,i: Integer;
begin
cnt := PInteger(Buf+Offset)^;
Inc(Offset, sizeof(Integer));
SetLength(FLastAutoIncValues, cnt);
for i:=0 to cnt-1 do
begin
FLastAutoIncValues[i] := PInt64(Buf+Offset)^;
Inc(Offset, sizeof(Int64));
end;
end;// LoadMostUpdated
//------------------------------------------------------------------------------
// SaveMostUpdated
//------------------------------------------------------------------------------
procedure TABSBaseFieldManager.SaveMostUpdated(Buf: PChar; var Offset: Integer);
var cnt,i: Integer;
begin
cnt := Length(FLastAutoIncValues);
PInteger(Buf+Offset)^ := cnt;
Inc(Offset, sizeof(Integer));
for i:=0 to cnt-1 do
begin
PInt64(Buf+Offset)^ := FLastAutoIncValues[i];
Inc(Offset, sizeof(Int64));
end;
end;// SaveMostUpdated
//------------------------------------------------------------------------------
// RecalcFieldOffsets
//------------------------------------------------------------------------------
procedure TABSBaseFieldManager.RecalcFieldOffsets;
begin
FFieldDefs.RecalcFieldOffsets;
end;//RecalcFieldOffsets
//------------------------------------------------------------------------------
// InitLastAutoIncValues
//------------------------------------------------------------------------------
procedure TABSBaseFieldManager.InitLastAutoIncValues;
var
i: Integer;
begin
SetLength(FLastAutoIncValues, FieldDefs.Count);
for i:=0 to Length(FLastAutoIncValues)-1 do
if (IsAutoincFieldType(FieldDefs.Items[i].AdvancedFieldType)) then
FLastAutoIncValues[i] := FieldDefs.Items[i].AutoincInitialValue
else
FLastAutoIncValues[i] := 0;
end;// InitLastAutoIncValues
//------------------------------------------------------------------------------
// DiskRecordBufferToMemRecordBuffer
//------------------------------------------------------------------------------
procedure TABSBaseFieldManager.DiskRecordBufferToMemRecordBuffer(DiskRecordBuffer, MemRecordBuffer: PChar);
var
i: Integer;
NullFlagsSize: Integer;
begin
FillChar(MemRecordBuffer^, FFieldDefs.GetMemoryRecordBufferSize, #0);
// move NULL flags
NullFlagsSize := FFieldDefs.Count div 8;
if ((FFieldDefs.Count mod 8) > 0) then
Inc(NullFlagsSize);
Move(DiskRecordBuffer^, MemRecordBuffer^, NullFlagsSize);
// move fields
for i:=0 to FFieldDefs.Count-1 do
Move((DiskRecordBuffer+FFieldDefs[i].DiskOffset)^,
(MemRecordBuffer+FFieldDefs[i].MemoryOffset)^,
FFieldDefs[i].DiskDataSize);
end;// DiskRecordBufferToMemRecordBuffer
//------------------------------------------------------------------------------
// MemRecordBufferToDiskRecordBuffer
//------------------------------------------------------------------------------
procedure TABSBaseFieldManager.MemRecordBufferToDiskRecordBuffer(MemRecordBuffer, DiskRecordBuffer: PChar);
var
i: Integer;
NullFlagsSize: Integer;
begin
FillChar(DiskRecordBuffer^, FFieldDefs.GetDiskRecordBufferSize, #0);
// move NULL flags
NullFlagsSize := FFieldDefs.Count div 8;
if ((FFieldDefs.Count mod 8) > 0) then
Inc(NullFlagsSize);
Move(MemRecordBuffer^, DiskRecordBuffer^, NullFlagsSize);
// move fields
for i:=0 to FFieldDefs.Count-1 do
Move((MemRecordBuffer+FFieldDefs[i].MemoryOffset)^,
(DiskRecordBuffer+FFieldDefs[i].DiskOffset)^,
FFieldDefs[i].DiskDataSize);
end;// MemRecordBufferToDiskRecordBuffer
//------------------------------------------------------------------------------
// CompareRecordBuffers
//------------------------------------------------------------------------------
function TABSBaseFieldManager.CompareRecordBuffers(RecordBuffer1,
RecordBuffer2: TABSRecordBuffer): Boolean;
var
i: Integer;
NullFlagsSize: Integer;
begin
// compare NULL flags
NullFlagsSize := FFieldDefs.Count div 8;
if ((FFieldDefs.Count mod 8) > 0) then
Inc(NullFlagsSize);
Result := (StrLComp(RecordBuffer1, RecordBuffer2, NullFlagsSize) = 0);
// compare fields?
if (Result) then
for i:=0 to FFieldDefs.Count-1 do
begin
Result := (StrLComp(RecordBuffer1+FFieldDefs[i].MemoryOffset,
RecordBuffer2+FFieldDefs[i].MemoryOffset,
FFieldDefs[i].DiskDataSize) = 0);
if (not Result) then
break;
end;
end;// CompareRecordBuffers
//------------------------------------------------------------------------------
// BlobFieldsPresent
//------------------------------------------------------------------------------
function TABSBaseFieldManager.BlobFieldsPresent: Boolean;
var
i: Integer;
begin
Result := False;
for i := 0 to FieldDefs.Count - 1 do
if (IsBLOBFieldType(FieldDefs[i].BaseFieldType)) then
begin
Result := True;
if (FieldDefs[i].BLOBBlockSize = 0) then
raise EABSException.Create(10421,ErrorLZeroBlockSizeIsNotAllowedForField,[FieldDefs[i].Name]);
break;
end;
end;// BlobFieldsPresent
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -