⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 absbaseengine.pas

📁 Absolute Database 是来替代BDE[Borland数据库引擎]的用于Delphi 和 C++ Builder 开发用的数据库引擎. 它小巧, 高速, 健壮, 易于使用. 它能直接编译进
💻 PAS
📖 第 1 页 / 共 5 页
字号:
//------------------------------------------------------------------------------
//
// Local and File-Server Engine
// Server uses Local Engine
//
//------------------------------------------------------------------------------

unit ABSBaseEngine;

{$I ABSVer.inc}

interface


uses SysUtils, Classes, Windows {$IFNDEF NO_DIALOGS}, Dialogs, Controls{$ENDIF}, Math, DB,

// AbsoluteDatabase units

     {$IFDEF DEBUG_LOG}
     ABSDebug,
     {$ENDIF}
     ABSPage,
     ABSExcept,
     ABSBase,
     ABSMemory,
     ABSCompression,
     ABSSecurity,
     ABSTypes,
     ABSConverts,
     ABSVariant,
     ABSConst,
     ABSExpressions;

type


  TABSDatabaseData = class;
  TABSTableData = class;
  TABSIndex = class;
  TABSRecordBitmap = class;

////////////////////////////////////////////////////////////////////////////////
//
// TABSBaseRecordManager
//
////////////////////////////////////////////////////////////////////////////////


  TABSBaseRecordManager = class (TObject)
   protected
    FRecordCount:           TABSRecordNo;
    FTableState:            Integer;
    FRecordBufferSize:      Integer;
   public
    procedure Empty(SessionID: TABSSessionID); virtual; abstract;
    // add record and return its number
    function AddRecord(SessionID: TABSSessionID; RecordBuffer: TABSRecordBuffer; var RecordID: TABSRecordID): Boolean; virtual; abstract;
    // update record, return true if record was updated, false if record was deleted
    function UpdateRecord(SessionID: TABSSessionID; RecordBuffer: TABSRecordBuffer; RecordID: TABSRecordID): Boolean; virtual; abstract;
    // delete record, return true if record was deleted, false if record was deleted earlier
    function DeleteRecord(SessionID: TABSSessionID; var RecordID: TABSRecordID): Boolean; virtual; abstract;
    // get record using physical order
    procedure GetRecordBuffer(SessionID: TABSSessionID; var NavigationInfo: TABSNavigationInfo); virtual; abstract;
    // return 0,1, or -1 if (1 = 2), (1 > 2) or (1 < 2)
    function CompareRecordID(RecordID1: TABSRecordID; RecordID2: TABSRecordID): Integer; virtual; abstract;
    // return record no
    function GetApproximateRecNo(SessionID: TABSSessionID; RecordID: TABSRecordID): TABSRecordNo; virtual; abstract;
    //procedure LoadFromStream(Stream: TStream); virtual; abstract;
    //procedure SaveToStream(Stream: TStream); virtual; abstract;
    // add loaded record
    //procedure AddLoadedRecord(RecordBuffer: TABSRecordBuffer); virtual; abstract;
   public
    property RecordCount: TABSRecordNo read FRecordCount write FRecordCount;
    property TableState: Integer read FTableState write FTableState;
    property RecordBufferSize: Integer read FRecordBufferSize write FRecordBufferSize;
  end;


////////////////////////////////////////////////////////////////////////////////
//
// TABSBaseFieldManager
//
////////////////////////////////////////////////////////////////////////////////


  TABSBaseFieldManager = class (TObject)
   private
    FFieldDefs:       TABSFieldDefs;
    FTableData:       TABSTableData;
   protected
    FLastAutoIncValues: array of Int64;
    function GetNextAutoincVal(FieldNo: Integer): TABSSequenceValue; virtual;
   public
    constructor Create(TableData: TABSTableData);
    destructor Destroy; override;

    procedure LoadMetadata(Stream: TStream);
    procedure SaveMetadata(Stream: TStream);
    procedure LoadMostUpdated(Buf: PChar; var Offset: Integer);
    procedure SaveMostUpdated(Buf: PChar; var Offset: Integer);

    procedure RecalcFieldOffsets;
    procedure InitLastAutoIncValues;

    procedure DiskRecordBufferToMemRecordBuffer(DiskRecordBuffer, MemRecordBuffer: PChar);
    procedure MemRecordBufferToDiskRecordBuffer(MemRecordBuffer, DiskRecordBuffer: PChar);
    function CompareRecordBuffers(RecordBuffer1,RecordBuffer2: TABSRecordBuffer): Boolean;
    function BlobFieldsPresent: Boolean;

    // Set default values to fields
    procedure ApplyDefaultValuesToRecordBuffer(Session: TABSBaseSession; RecordBuffer: TABSRecordBuffer); virtual;
    // Set new values of Autioincs to fields
    procedure ApplyAutoincsToRecordBuffer(Session: TABSBaseSession; RecordBuffer: TABSRecordBuffer); virtual;

    function GetNextAutoinc(Session: TABSBaseSession; FieldNo: Integer): TABSSequenceValue; virtual;
    function GetLastAutoinc(Session: TABSBaseSession; FieldNo: Integer): TABSSequenceValue; virtual;
    procedure UpdateLastAutoinc(Session: TABSBaseSession; FieldNo: Integer; InsertedValue: Int64);

   public
    property FieldDefs: TABSFieldDefs read FFieldDefs;
  end; // TABSBaseFieldManager



////////////////////////////////////////////////////////////////////////////////
//
// TABSBaseIndexManager
//
////////////////////////////////////////////////////////////////////////////////


  TABSBaseIndexManager = class (TObject)
   protected
    FTableData:       TABSTableData;
    FIndexDefs:       TABSIndexDefs;
    FOpenIndexList:   TList; // list of TABSIndex objects
    FPageManager:          TABSPageManager;
    FTemporaryPageManager: TABSPageManager;
    FSynchronizingTemporaryIndexes:  Boolean;

    procedure InternalCreateIndex(
            Cursor: TABSCursor;
            IndexDef: TABSIndexDef
                                  );
    function InternalOpenIndex(
            IndexID: TABSObjectID
                               ): TABSIndex;

   public
    procedure LoadMetadata(Stream: TStream); virtual;
    procedure SaveMetadata(Stream: TStream); virtual;
    constructor Create(aTableData: TABSTableData; TempPageManager: TABSPageManager);
    destructor Destroy; override;

    function GetPageManager(Index: TABSIndex): TABSPageManager;

    procedure DropTemporaryIndexes(SessionID: TABSSessionID);
    function IsIndexExists(FieldNames, AscDescList, CaseSensitivityList: TStringList;
                   SessionID: TABSSessionID; FieldDefs: TABSFieldDefs): Boolean;
    function FindIndex(FieldNames, AscDescList, CaseSensitivityList: TStringList;
                       SessionID: TABSSessionID; FieldDefs: TABSFieldDefs): TABSObjectID;
    function CreateTemporaryIndex(
                    Cursor:         TABSCursor;
                    FieldNamesList, AscDescList, CaseSensitivityList: TStringList
                                 ): TABSObjectID;
    function FindOrCreateIndex(Cursor: TABSCursor; FieldNamesList, AscDescList, CaseSensitivityList: TStringList; var IsCreated: Boolean): TABSObjectID;

    // create index definitions list
    procedure CreateIndexDefs(aIndexDefs: TABSIndexDefs); virtual;
    procedure CreateIndexesByIndexDefs(Cursor: TABSCursor);

    function FindOpenIndex(IndexID: TABSObjectID): TABSIndex;
    function CreateIndex(
                         Cursor: TABSCursor;
                         IndexDef: TABSIndexDef
                        ): TABSObjectID;
    function OpenIndex(IndexID: TABSObjectID): TABSIndex;
    procedure CloseIndex(IndexID: TABSObjectID);
    procedure DropIndex(SessionID: TABSSessionID; IndexID: TABSObjectID);
    procedure DropAllIndexes(SessionID: TABSSessionID);
    procedure EmptyIndex(SessionID: TABSSessionID; IndexID: TABSObjectID);
    procedure EmptyAllIndexes(SessionID: TABSSessionID);

    procedure GetRecordBuffer(
                               SessionID: TABSSessionID;
                               var NavigationInfo: TABSNavigationInfo;
                               IndexPositionCache: TABSIndexPositionCache;
                               TableState:         Integer
                             );
    procedure InsertRecord(Cursor: TABSCursor);
    procedure UpdateRecord(Cursor: TABSCursor; BeforeNewRecordIsStored: Boolean);
    procedure DeleteRecord(Cursor: TABSCursor);

    procedure SynchronizeTemporaryIndexes(Cursor: TABSCursor; var IsChanged: Boolean);
    procedure RenameField(FieldName, NewFieldName: String);

    property IndexDefs: TABSIndexDefs read FIndexDefs;
    property TableData: TABSTableData read FTableData;
    property PageManager: TABSPageManager read FPageManager;
  end; // TABSBaseIndexManager


////////////////////////////////////////////////////////////////////////////////
//
// TABSIndex
//
////////////////////////////////////////////////////////////////////////////////

  TABSIndex = class (TObject)
   protected
    FIndexDef:      TABSIndexDef;
    FIndexManager:  TABSBaseIndexManager;
   public
    constructor Create(aIndexManager: TABSBaseIndexManager);
    destructor Destroy; override;
    procedure CreateIndex(Cursor: TABSCursor; aIndexDef: TABSIndexDef); virtual;
    procedure DropIndex(SessionID: TABSSessionID); virtual; abstract;
    procedure EmptyIndex(SessionID: TABSSessionID); virtual; abstract;
    procedure OpenIndex(aIndexDef: TABSIndexDef); virtual;
    procedure RebuildTemporaryIndex(Cursor: TABSCursor); virtual; abstract;

    procedure GetRecordBuffer(SessionID:          TABSSessionID;
                              var NavigationInfo: TABSNavigationInfo;
                              IndexPositionCache: TABSIndexPositionCache;
                              TableState:         Integer); virtual; abstract;
    procedure GetClosestRecordBuffer(
                              SessionID:          TABSSessionID;
                              var NavigationInfo: TABSNavigationInfo;
                               IndexPositionCache: TABSIndexPositionCache;
                               TableState:         Integer
                               ); virtual; abstract;
    function CreateIndexPosition: TABSIndexPosition; virtual; abstract;
    procedure FreeIndexPosition(var IndexPosition: TABSIndexPosition); virtual; abstract;
    function GetIndexPosition(
                               SessionID:      TABSSessionID;
                               RecordID:       TABSRecordID;
                               RecordBuffer:   TABSRecordBuffer;
                               IndexPosition:  TABSIndexPosition
                             ): Boolean; virtual; abstract;
    // return 0, 1, -1 if (Pos1 = Pos2), (Pos1 > Pos2), (Pos1 < Pos2)
    function CompareRecordPositionsInIndex(
                        RecordPosition1: TABSIndexPosition;
                        RecordPosition2: TABSIndexPosition
                                          ): Integer; virtual; abstract;
    function GetRecNoByRecordID(
                                SessionID:      TABSSessionID;
                                RecordID:       TABSRecordID;
                                RecordBuffer:   TABSRecordBuffer
                               ): TABSRecordNo; virtual; abstract;
    function GetRecordIDByRecNo(
                                SessionID:      TABSSessionID;
                                RecNo:          TABSRecordNo
                               ): TABSRecordID; virtual; abstract;
    procedure ApplyDistinctToRecordBitmap(
                                SessionID:      TABSSessionID;
                                Bitmap:         TABSRecordBitmap;
                                DistinctFieldCount: Integer
                                         ); virtual; abstract;
    function CreateSearchInfo: TABSSearchInfo; virtual; abstract;
    procedure FreeSearchInfo(SearchInfo: TABSSearchInfo); virtual; abstract;
    function FindRecord(
                       SessionID:           TABSSessionID;
                       Restart:             Boolean;
                       GoForward:           Boolean;
                       StartScanCondition:  TABSScanSearchCondition;
                       EndScanCondition:    TABSScanSearchCondition;
                       RecordBuffer:        TABSRecordBuffer;
                       var RecordID:        TABSRecordID;
                       SearchInfo:          TABSSearchInfo
                      ): Boolean; virtual; abstract;
    // return 0 if record buffers are equal in this index
    // return 1 if Buffer1 is higher than Buffer 2 (Pos1 > Pos2)
    // return -1 if Buffer1 is lower than Buffer 2 (Pos1 < Pos2)
    function CompareRecordBuffersByIndex(
                        Buffer1: TABSRecordBuffer;
                        Buffer2: TABSRecordBuffer;
                        IndexFieldCount: Integer
                                        ): Integer; virtual; abstract;

    // return 0 if conditions are equal in this index
    // return 1 if Condition1 is higher than Condition2
    // return -1 if Condition1 is lower than Condition2
    function CompareConditions(
                    Condition1:   TABSScanSearchCondition;
                    Condition2:   TABSScanSearchCondition
                              ): Integer; virtual; abstract;
    // approximate record count berween range conditions
    function GetApproxRangeRecordCount(
                    SessionID:         TABSSessionID;
                    TableRecordCount:  TABSRecordNo;
                    RangeCondition1:   TABSScanSearchCondition;
                    RangeCondition2:   TABSScanSearchCondition
                                      ): TABSRecordNo; virtual; abstract;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -