📄 absbaseengine.pas
字号:
function CanInsertRecord(
SessionID: TABSSessionID;
RecordBuffer: TABSRecordBuffer
): Boolean; virtual; abstract;
function CanUpdateRecord(
SessionID: TABSSessionID;
OldRecordBuffer, NewRecordBuffer: TABSRecordBuffer
): Boolean; virtual; abstract;
procedure InsertRecord(Cursor: TABSCursor); virtual; abstract;
procedure DeleteRecord(Cursor: TABSCursor); virtual; abstract;
procedure UpdateRecord(Cursor: TABSCursor; BeforeNewRecordIsStored: Boolean); virtual; abstract;
function GetMaxEntriesPerPage: Integer; virtual; abstract;
procedure GetRecordIDByIndexPosition(SessionID: TABSSessionID; IndexPos: TABSIndexPosition; var RecordID: TABSRecordID); virtual; abstract;
property IndexDef: TABSIndexDef read FIndexDef;
property IndexManager: TABSBaseIndexManager read FIndexManager;
end; // TABSIndex
////////////////////////////////////////////////////////////////////////////////
//
// TABSBaseConstraintManager
//
////////////////////////////////////////////////////////////////////////////////
TABSBaseConstraintManager = class (TObject)
private
FConstraintDefs: TABSConstraintDefs;
FTableData: TABSTableData;
public
procedure LoadMetadata(Stream: TStream);
procedure SaveMetadata(Stream: TStream);
constructor Create(aTableData: TABSTableData); //virtual;
destructor Destroy; override;
// check constraint conditions
function CheckConstraints(
SessionID: TABSSessionID;
NewRecordBuffer: TABSRecordBuffer;
OldRecordBuffer: TABSRecordBuffer;
ToInsert: Boolean;
CurrentRecordID: TABSRecordID;
RaiseException: Boolean
): Boolean;
// Link object id
procedure LinkObjectId(ConstraintDef: TABSConstraintDef);
// Link object ids between constraints and fields
procedure LinkObjectIds;
// Generate Constraint Names for empty constraints
procedure FillConstraintAutoNames;
// add constraint for primary or Unique index
procedure AddConstraintFromIndex(IndexDef: TABSIndexDef);
// Delete Constraint Linked with deleted index
procedure DeleteConstraintForIndexID(IndexObjectID: TABSObjectID);
public
property ConstraintDefs: TABSConstraintDefs read FConstraintDefs write FConstraintDefs;
end; // TABSBaseConstraintManager
////////////////////////////////////////////////////////////////////////////////
//
// TABSRecordBitmap
//
////////////////////////////////////////////////////////////////////////////////
TABSRecordBitmap = class (TObject)
private
FBitmap: TABSBitsArray;
FTableData: TABSTableData;
FActive: Boolean;
FIndexBased: Boolean;
FTableState: Integer;
protected
function GetSize: TABSRecordNo;
procedure SetSize(NewSize: TABSRecordNo);
function GetOutdated: Boolean;
public
constructor Create(aTableData: TABSTableData);
destructor Destroy; override;
function GetRecordCount: TABSRecordNo;
function GetRecNoByRecordID(RecordID: TABSRecordID): TABSRecordNo;
function GetRecNoByIndexPos(IndexID: TABSObjectID; IndexPos: TABSIndexPosition): TABSRecordNo;
function GetRecordIDByRecNo(RecNo: TABSRecordNo): TABSRecordID;
procedure GetIndexPosByRecNo(IndexID: TABSObjectID; RecNo: TABSRecordNo; IndexPos: TABSIndexPosition);
function IsRecordVisible(RecordID: TABSRecordID): Boolean; overload;
function IsRecordVisible(IndexID: TABSObjectID; IndexPos: TABSIndexPosition): Boolean; overload;
procedure ShowRecord(RecordID: TABSRecordID); overload;
procedure ShowRecord(IndexID: TABSObjectID; IndexPos: TABSIndexPosition); overload;
procedure HideRecord(RecordID: TABSRecordID); overload;
procedure HideRecord(IndexID: TABSObjectID; IndexPos: TABSIndexPosition); overload;
procedure SetAllBits;
procedure Clear;
function FindRecord(Restart, GoForward: Boolean; CurRecordID: TABSRecordID;
var FoundRecordID: TABSRecordID): Boolean; overload;
function FindRecord(Restart, GoForward: Boolean; CurIndexPos, FoundRecordIndexPos: TABSIndexPosition;
IndexID: TABSObjectID): Boolean; overload;
public
property Active: Boolean read FActive write FActive;
property Size: TABSRecordNo read GetSize write SetSize;
property Outdated: Boolean read GetOutdated;
property IndexBased: Boolean read FIndexBased write FIndexBased;
property TableState: Integer read FTableState write FTableState;
end; // TABSRecordBitmap
////////////////////////////////////////////////////////////////////////////////
//
// TABSTableData
//
////////////////////////////////////////////////////////////////////////////////
TABSTableData = class (TObject)
private
FCSect: TRTLCriticalSection;
FIsRepairing: Boolean;
protected
FPageManager: TABSPageManager;
FDatabaseData: TABSDatabaseData;
FTableName: String;
FBLOBCompression: TABSCompression;
FActive: Boolean;
FFieldManager: TABSBaseFieldManager;
FConstraintManager: TABSBaseConstraintManager;
FIndexManager: TABSBaseIndexManager;
FRecordManager: TABSBaseRecordManager;
FCursorList: TList;
FDisableTempFiles: Boolean;
// Fill New ObjectID for all defs
procedure FillDefsByObjectId(Defs: TABSMetaObjectDefs);
function GetRecordBufferSize: Integer;
procedure CreateRecordManager; virtual; abstract;
procedure CreateFieldManager(FieldDefs: TABSFieldDefs); virtual;
procedure CreateIndexManager(IndexDefs: TABSIndexDefs); virtual;
procedure CreateConstraintManager(ConstraintDefs: TABSConstraintDefs); virtual;
procedure InitCursor(Cursor: TABSCursor); virtual;
public
constructor Create(aDatabaseData: TABSDatabaseData);
destructor Destroy; override;
// lock
procedure Lock;
// unlock
procedure Unlock;
procedure ApplyChanges(SessionID: TABSSessionID; InTransaction: Boolean); virtual;
procedure CancelChanges(SessionID: TABSSessionID; InTransaction: Boolean); virtual;
// table operations
procedure CreateTable(
Cursor: TABSCursor;
FieldDefs: TABSFieldDefs;
IndexDefs: TABSIndexDefs;
ConstraintDefs: TABSConstraintDefs
); virtual; abstract;
procedure DeleteTable(Cursor: TABSCursor; DesignMode: Boolean = False); virtual;
procedure EmptyTable(Cursor: TABSCursor); virtual;
procedure RenameTable(NewTableName: String; Cursor: TABSCursor); virtual;
procedure OpenTable(Cursor: TABSCursor); virtual;
procedure CloseTable(Cursor: TABSCursor); virtual;
// Rename Field by Field Index in FieldDefs
procedure RenameField(FieldName, NewFieldName: String); virtual;
procedure AddIndex(IndexDef: TABSIndexDef; Cursor: TABSCursor); virtual;
procedure DeleteIndex(IndexID: TABSObjectID; Cursor: TABSCursor); virtual;
procedure EmptyIndex(IndexID: TABSObjectID; SessionID: TABSSessionID);
procedure DeleteAllIndexes(Cursor: TABSCursor);
procedure EmptyAllIndexes(SessionID: TABSSessionID);
// return index name
function FindOrCreateIndex(
Cursor: TABSCursor;
FieldNamesList,
AscDescList,
CaseSensitivityList: TStringList;
var IsCreated: Boolean
): String;
function IndexExists(Cursor: TABSCursor;
FieldNamesList, AscDescList, CaseSensitivityList: TStringList): Boolean;
// return true if Unique Constraint Failed
function IsUniqueConstraintFailed(
SessionID: TABSSessionID;
IndexID: TABSObjectID;
NewRecordBuffer: TABSRecordBuffer;
OldRecordBuffer: TABSRecordBuffer;
ToInsert: Boolean;
CurrentRecordID: TABSRecordID
): Boolean;
//---------------- Search and navigation methods ---------------------------
protected
// clear bitmap and set state and indexbased
procedure InitRecordBitmap(RecordBitmap: TABSRecordBitmap; IndexID: TABSObjectID);
// if necessary - build record bitmap for cursor
procedure RefreshCursorRecordBitmap(Cursor: TABSCursor);
// build record bitmap for cursor
procedure BuildCursorRecordBitmap(Cursor: TABSCursor);
// return filter bitmap rec count
function GetBitmapRecordCount(SessionID: TABSSessionID): TABSRecordNo; virtual; abstract;
// return filter bitmap rec no by record id
function GetBitmapRecNoByRecordID(RecordID: TABSRecordID): TABSRecordNo; virtual; abstract;
// return filter bitmap rec no by record id
function GetRecordIDByBitmapRecNo(RecordNo: TABSRecordNo): TABSRecordID; virtual; abstract;
// return filter bitmap rec no by record id
function GetBitmapRecNoByIndexPosition(IndexID: TABSObjectID; IndexPos: TABSIndexPosition): TABSRecordNo;
// return filter bitmap rec no by record id
procedure GetIndexPositionByBitmapRecNo(IndexID: TABSObjectID; RecordNo: TABSRecordNo; IndexPos: TABSIndexPosition);
// return index position by record id
function GetIndexPositionByRecordID(SessionID: TABSSessionID; IndexID: TABSObjectID; RecordID: TABSRecordID; IndexPos: TABSIndexPosition): Boolean;
// return record id by index position
procedure GetRecordIDByIndexPosition(SessionID: TABSSessionID; IndexID: TABSObjectID; IndexPos: TABSIndexPosition; var RecordID: TABSRecordID);
// return true if record is in specified range
function IsRecordInRange(Cursor: TABSCursor): Boolean;
// return true if record is not equal to the previous record
function IsRecordInDistinct(Cursor: TABSCursor): Boolean;
// return true if record is visible (with applied filters, ranges, OnFilterRecord)
function IsRecordVisible(Cursor: TABSCursor): Boolean;
procedure MergeAndCheckSearchConditionsCompatibility(
var Condition1: TABSScanSearchCondition;
var Condition2: TABSScanSearchCondition;
out Incompatible: Boolean;
out HaveBeenMerged: Boolean
);
// returns true if conditions are equal
function IsEqualConditions(
var Condition1: TABSScanSearchCondition;
var Condition2: TABSScanSearchCondition
): Boolean;
// removes duplicate conditions
procedure RemoveDuplicateConditions(Conditions: TABSScanSearchConditionArray);
// sorts Conditions array and removes unnecessary conditions
procedure OptimizeSearchConditions(
var Conditions: TABSScanSearchConditionArray;
out NonCompatibleConditions: Boolean
);
// prepare conditions array
procedure PrepareConditions(
Cursor: TABSCursor;
Conditions: TABSScanSearchConditionArray;
KeyCondition: TABSScanSearchCondition;
SearchExpression: TABSExpression;
GoForward: Boolean
);
// try to find the best scan condition with min range record count
function ChooseScanConditionsWithMinScanCost(
SessionID: TABSSessionID;
Conditions: TABSScanSearchConditionArray;
CurrentIndexID: TABSObjectID;
CurrentRecordID: TABSRecordID;
FilterRecordPtr: Pointer;
var ScanConditionNo: Integer;
var ScanEndConditionNo: Integer
): Boolean;
// if index is defined as unique or contain unique field
function IsIndexUnique(IndexID: TABSObjectID): Boolean;
// try to find the best scan condition using heuristics
function ChooseScanConditionsByHeuristsics(
Conditions: TABSScanSearchConditionArray;
CurrentIndexID: TABSObjectID;
var ScanConditionNo: Integer;
var ScanEndConditionNo: Integer
): Boolean;
// try to find the best scan condition
procedure ChooseScanConditions(
SessionID: TABSSessionID;
Conditions: TABSScanSearchConditionArray;
CurrentIndexID: TABSObjectID;
CurrentRecordID: TABSRecordID;
GoForward: Boolean;
FilterRecordPtr: Pointer;
var ScanConditionNo: Integer;
var ScanEndConditionNo: Integer
);
// scan records bitmap to find record
function FindRecordByBitmapScan(SessionID: TABSSessionID;
Restart, GoForward: Boolean;
CurrentRecordID: TABSRecordID;
var ResultRecordID: TABSRecordID;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -