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

📄 myldbbaseengine.pas

📁 一个本地database引擎,支持中文T_Sql查询,兼容DELPHI标准数据库控件
💻 PAS
📖 第 1 页 / 共 5 页
字号:
unit MYLDBBaseEngine;

{$I MYLDBVer.inc}

interface


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

// MYLDBoluteDatabase units

     {$IFDEF DEBUG_LOG}
     MYLDBDebug,
     {$ENDIF}
     MYLDBPage,
     MYLDBExcept,
     MYLDBBase,
     MYLDBMemory,
     MYLDBCompression,
     MYLDBSecurity,
     MYLDBTypes,
     MYLDBConverts,
     MYLDBVariant,
     MYLDBConst,
     MYLDBExpressions;

type


  TMYLDBDatabaseData = class;
  TMYLDBTableData = class;
  TMYLDBIndex = class;
  TMYLDBRecordBitmap = class;

////////////////////////////////////////////////////////////////////////////////
//
// TMYLDBBaseRecordManager
//
////////////////////////////////////////////////////////////////////////////////


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


////////////////////////////////////////////////////////////////////////////////
//
// TMYLDBBaseFieldManager
//
////////////////////////////////////////////////////////////////////////////////


  TMYLDBBaseFieldManager = class (TObject)
   private
    FFieldDefs:       TMYLDBFieldDefs;
    FTableData:       TMYLDBTableData;
   protected
    FLastAutoIncValues: array of Int64;
    function GetNextAutoincVal(FieldNo: Integer): TMYLDBSequenceValue; virtual;
   public
    constructor Create(TableData: TMYLDBTableData);
    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: TMYLDBRecordBuffer): Boolean;
    function BlobFieldsPresent: Boolean;

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

    function GetNextAutoinc(Session: TMYLDBBaseSession; FieldNo: Integer): TMYLDBSequenceValue; virtual;
    function GetLastAutoinc(Session: TMYLDBBaseSession; FieldNo: Integer): TMYLDBSequenceValue; virtual;
    procedure UpdateLastAutoinc(Session: TMYLDBBaseSession; FieldNo: Integer; InsertedValue: Int64);

   public
    property FieldDefs: TMYLDBFieldDefs read FFieldDefs;
  end; // TMYLDBBaseFieldManager



////////////////////////////////////////////////////////////////////////////////
//
// TMYLDBBaseIndexManager
//
////////////////////////////////////////////////////////////////////////////////


  TMYLDBBaseIndexManager = class (TObject)
   protected
    FTableData:       TMYLDBTableData;
    FIndexDefs:       TMYLDBIndexDefs;
    FOpenIndexList:   TList; // list of TMYLDBIndex objects
    FPageManager:          TMYLDBPageManager;
    FTemporaryPageManager: TMYLDBPageManager;
    FSynchronizingTemporaryIndexes:  Boolean;

    procedure InternalCreateIndex(
            Cursor: TMYLDBCursor;
            IndexDef: TMYLDBIndexDef
                                  );
    function InternalOpenIndex(
            IndexID: TMYLDBObjectID
                               ): TMYLDBIndex;

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

    function GetPageManager(Index: TMYLDBIndex): TMYLDBPageManager;

    procedure DropTemporaryIndexes(SessionID: TMYLDBSessionID);
    function IsIndexExists(FieldNames, AscDescList, CaseSensitivityList: TStringList;
                   SessionID: TMYLDBSessionID; FieldDefs: TMYLDBFieldDefs): Boolean;
    function FindIndex(FieldNames, AscDescList, CaseSensitivityList: TStringList;
                       SessionID: TMYLDBSessionID; FieldDefs: TMYLDBFieldDefs): TMYLDBObjectID;
    function CreateTemporaryIndex(
                    Cursor:         TMYLDBCursor;
                    FieldNamesList, AscDescList, CaseSensitivityList: TStringList
                                 ): TMYLDBObjectID;
    function FindOrCreateIndex(Cursor: TMYLDBCursor; FieldNamesList, AscDescList, CaseSensitivityList: TStringList; var IsCreated: Boolean): TMYLDBObjectID;

    // create index definitions list
    procedure CreateIndexDefs(aIndexDefs: TMYLDBIndexDefs); virtual;
    procedure CreateIndexesByIndexDefs(Cursor: TMYLDBCursor);

    function FindOpenIndex(IndexID: TMYLDBObjectID): TMYLDBIndex;
    function CreateIndex(
                         Cursor: TMYLDBCursor;
                         IndexDef: TMYLDBIndexDef
                        ): TMYLDBObjectID;
    function OpenIndex(IndexID: TMYLDBObjectID): TMYLDBIndex;
    procedure CloseIndex(IndexID: TMYLDBObjectID);
    procedure DropIndex(SessionID: TMYLDBSessionID; IndexID: TMYLDBObjectID);
    procedure DropAllIndexes(SessionID: TMYLDBSessionID);
    procedure EmptyIndex(SessionID: TMYLDBSessionID; IndexID: TMYLDBObjectID);
    procedure EmptyAllIndexes(SessionID: TMYLDBSessionID);

    procedure GetRecordBuffer(
                               SessionID: TMYLDBSessionID;
                               var NavigationInfo: TMYLDBNavigationInfo;
                               IndexPositionCache: TMYLDBIndexPositionCache;
                               TableState:         Integer
                             );
    procedure InsertRecord(Cursor: TMYLDBCursor);
    procedure UpdateRecord(Cursor: TMYLDBCursor; BeforeNewRecordIsStored: Boolean);
    procedure DeleteRecord(Cursor: TMYLDBCursor);

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

    property IndexDefs: TMYLDBIndexDefs read FIndexDefs;
    property TableData: TMYLDBTableData read FTableData;
    property PageManager: TMYLDBPageManager read FPageManager;
  end; // TMYLDBBaseIndexManager


////////////////////////////////////////////////////////////////////////////////
//
// TMYLDBIndex
//
////////////////////////////////////////////////////////////////////////////////

  TMYLDBIndex = class (TObject)
   protected
    FIndexDef:      TMYLDBIndexDef;
    FIndexManager:  TMYLDBBaseIndexManager;
   public
    constructor Create(aIndexManager: TMYLDBBaseIndexManager);
    destructor Destroy; override;
    procedure CreateIndex(Cursor: TMYLDBCursor; aIndexDef: TMYLDBIndexDef); virtual;
    procedure DropIndex(SessionID: TMYLDBSessionID); virtual; abstract;
    procedure EmptyIndex(SessionID: TMYLDBSessionID); virtual; abstract;
    procedure OpenIndex(aIndexDef: TMYLDBIndexDef); virtual;
    procedure RebuildTemporaryIndex(Cursor: TMYLDBCursor); virtual; abstract;

    procedure GetRecordBuffer(SessionID:          TMYLDBSessionID;
                              var NavigationInfo: TMYLDBNavigationInfo;
                              IndexPositionCache: TMYLDBIndexPositionCache;
                              TableState:         Integer); virtual; abstract;
    procedure GetClosestRecordBuffer(
                              SessionID:          TMYLDBSessionID;
                              var NavigationInfo: TMYLDBNavigationInfo;
                               IndexPositionCache: TMYLDBIndexPositionCache;
                               TableState:         Integer
                               ); virtual; abstract;
    function CreateIndexPosition: TMYLDBIndexPosition; virtual; abstract;
    procedure FreeIndexPosition(var IndexPosition: TMYLDBIndexPosition); virtual; abstract;
    function GetIndexPosition(
                               SessionID:      TMYLDBSessionID;
                               RecordID:       TMYLDBRecordID;
                               RecordBuffer:   TMYLDBRecordBuffer;
                               IndexPosition:  TMYLDBIndexPosition
                             ): Boolean; virtual; abstract;
    // return 0, 1, -1 if (Pos1 = Pos2), (Pos1 > Pos2), (Pos1 < Pos2)
    function CompareRecordPositionsInIndex(
                        RecordPosition1: TMYLDBIndexPosition;
                        RecordPosition2: TMYLDBIndexPosition
                                          ): Integer; virtual; abstract;
    function GetRecNoByRecordID(
                                SessionID:      TMYLDBSessionID;
                                RecordID:       TMYLDBRecordID;
                                RecordBuffer:   TMYLDBRecordBuffer
                               ): TMYLDBRecordNo; virtual; abstract;
    function GetRecordIDByRecNo(
                                SessionID:      TMYLDBSessionID;
                                RecNo:          TMYLDBRecordNo
                               ): TMYLDBRecordID; virtual; abstract;
    procedure ApplyDistinctToRecordBitmap(
                                SessionID:      TMYLDBSessionID;
                                Bitmap:         TMYLDBRecordBitmap;
                                DistinctFieldCount: Integer
                                         ); virtual; abstract;
    function CreateSearchInfo: TMYLDBSearchInfo; virtual; abstract;
    procedure FreeSearchInfo(SearchInfo: TMYLDBSearchInfo); virtual; abstract;
    function FindRecord(
                       SessionID:           TMYLDBSessionID;
                       Restart:             Boolean;
                       GoForward:           Boolean;
                       StartScanCondition:  TMYLDBScanSearchCondition;
                       EndScanCondition:    TMYLDBScanSearchCondition;
                       RecordBuffer:        TMYLDBRecordBuffer;
                       var RecordID:        TMYLDBRecordID;
                       SearchInfo:          TMYLDBSearchInfo
                      ): 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: TMYLDBRecordBuffer;
                        Buffer2: TMYLDBRecordBuffer;
                        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:   TMYLDBScanSearchCondition;
                    Condition2:   TMYLDBScanSearchCondition
                              ): Integer; virtual; abstract;
    // approximate record count berween range conditions
    function GetApproxRangeRecordCount(
                    SessionID:         TMYLDBSessionID;
                    TableRecordCount:  TMYLDBRecordNo;
                    RangeCondition1:   TMYLDBScanSearchCondition;
                    RangeCondition2:   TMYLDBScanSearchCondition
                                      ): TMYLDBRecordNo; virtual; abstract;
    function CanInsertRecord(

⌨️ 快捷键说明

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