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

📄 absdiskengine.~pas

📁 Absolute Database 是来替代BDE[Borland数据库引擎]的用于Delphi 和 C++ Builder 开发用的数据库引擎. 它小巧, 高速, 健壮, 易于使用. 它能直接编译进
💻 ~PAS
📖 第 1 页 / 共 5 页
字号:
    procedure WriteFile(SessionID: TABSSessionID; const Buffer; const Count: Integer;
                        const Algorithm: TABSCompressionAlgorithm = acaNone;
                        const CompressionMode: Integer = 0);

    function LockFile: Boolean;
    function UnlockFile: Boolean;
   public
    property PageManager: TABSDiskPageManager read LPageManager;
    property StartPageNo: TABSPageNo read FStartPageNo;
  end;// TABSInternalDBTransactedAccessFile



////////////////////////////////////////////////////////////////////////////////
//
// TABSInternalDBDirectAccessFile
//
////////////////////////////////////////////////////////////////////////////////

  TABSInternalDBDirectAccessFile = class(TObject)
   private
    LPageManager: TABSDiskPageManager;
    FStartPageNo: TABSPageNo;
    FPageTypeID:  TABSPageTypeID;
    FFileSize: Integer;
    FFilePages: TABSIntegerArray;

   private
    // SetStartPageNo
    procedure SetStartPageNo(StartPageNo: TABSPageNo);
    procedure ReadPageHeader(PageNo: TABSPageNo; var PageHeader: TABSDiskPageHeader;
                                             SkipFirstByte: Boolean = False);
    // raise if file is Closed
    procedure CheckFileOpened(OperationName: String);
    // return Count of File Pages
    function GetPageCountForDataSize(DataSize: Integer): Integer;
    // return Count of File Pages
    procedure GetPageNoAndOffsetForPosition(Position: Integer; var PagePosition: Integer; var Offset: word);
    procedure ReadPageList;
    // return real page No for file page (firstPageNo=0)
    function GoToPage(PagePosition: TABSPageNo): TABSPageNo;
    procedure InternalSeek(FileOffset: Integer; out PageNo: TABSPageNo; out PageOffset: Word);
   public
    // Constructor
    constructor Create(PageManager: TABSDiskPageManager; PageTypeID: TABSPageTypeID);
    // Destructor
    destructor Destroy; override;

    // Create file
    procedure CreateFile(Size: Integer);
    // Delete file. And free all file pages
    procedure DeleteFile(StartPageNo: TABSPageNo = INVALID_PAGE_NO);
    // Open file (reading file header)
    procedure OpenFile(StartPageNo: TABSPageNo);

    // Get File Size
    function GetSize: Integer;

    // direct (without sessions and transactions) Read buffer from file
    procedure ReadBuffer(var Buffer; const Count: Integer; const Position: Integer = -1);
    // direct (without sessions and transactions) Write buffer from file
    procedure WriteBuffer(const Buffer; const Count: Integer; const Position: Integer = -1);

    function LockFile: Boolean;
    function UnlockFile: Boolean;
    function LockByte(ByteNo: Integer): Boolean;
    function UnlockByte(ByteNo: Integer): Boolean;
    function IsByteLocked(ByteNo: Integer): Boolean;
    function IsRegionLocked(ByteNo, ByteCount: Integer): Boolean;
   public
    property PageManager: TABSDiskPageManager read LPageManager;
    property StartPageNo: TABSPageNo read FStartPageNo;
  end;// TABSInternalDBDirectAccessFile



////////////////////////////////////////////////////////////////////////////////
//
// TABSActiveSessionsFile
//
////////////////////////////////////////////////////////////////////////////////

  TABSActiveSessionsFile = class(TObject)
   private
    LPageManager:     TABSDiskPageManager;
    FHandle:          TABSInternalDBDirectAccessFile;
    FMaxSessionCount: Integer;

    function GetStartPageNo: TABSPageNo;
   public
    constructor Create(PageManager: TABSPageManager);
    destructor Destroy; override;
    function CreateFile(aMaxSessionCount: Integer): TABSPageNo;
    procedure OpenFile(aStartPageNo: TABSPageNo);
    procedure CloseFile;
    function MultiUserConnect: TABSSessionID;
    procedure MultiUserDisconnect(SessionID: TABSSessionID);
    function SingleUserConnect: Boolean;
    procedure SingleUserDisconnect;
    function GetDBFileConnectionsCount: Integer;

    property StartPageNo: TABSPageNo read GetStartPageNo;
    property MaxSessionCount: Integer read FMaxSessionCount;
  end;// TABSActiveSessionsFile



////////////////////////////////////////////////////////////////////////////////
//
// TABSTableListFile
//
////////////////////////////////////////////////////////////////////////////////

  TABSTableListFile = class(TObject)
   private
    LPageManager: TABSDiskPageManager;
    FHandle:      TABSInternalDBTransactedAccessFile;
    FTableList: array of TABSTableListItem;

    function GetStartPageNo: TABSPageNo;
    function GetTableIndex(TableName: String): Integer;
   public
    constructor Create(PageManager: TABSPageManager);
    destructor Destroy; override;

    function CreateFile: TABSPageNo;
    procedure OpenFile(aStartPageNo: TABSPageNo);
    procedure CloseFile;

    procedure Load;
    procedure Save;

    procedure AddTable(
           TableID: TABSTableID;
           TableName: String;
           MetadataFilePageNo,
           MostUpdatedFilePageNo,
           LocksFilePageNo: TABSPageNo
                         );
    procedure RemoveTable(TableName: String);
    procedure OpenTable(
           TableName: String;
           out TableID: TABSTableID;
           out MetadataFilePageNo: TABSPageNo;
           out MostUpdatedFilePageNo: TABSPageNo;
           out LocksFilePageNo: TABSPageNo
                         );
    procedure RenameTable(TableName, NewTableName: String);
    function TableExists(TableName: String): Boolean;
    procedure GetTablesList(List: TStrings);

   public
    property StartPageNo: TABSPageNo read GetStartPageNo;
  end;// TABSTableListFile



////////////////////////////////////////////////////////////////////////////////
//
// TABSTableLocksFile
//
////////////////////////////////////////////////////////////////////////////////

  TABSTableLocksFile = class(TObject)
   private
    LPageManager:     TABSDiskPageManager;
    FHandle:          TABSInternalDBDirectAccessFile;
    FMaxSessionCount: Integer;

    function GetStartPageNo: TABSPageNo;
    function GetTableLockByteNo(
                    SessionID: TABSSessionID; LockType: TABSLockType): Integer;
    function GetRecordLockByteNo(SessionID: TABSSessionID): Integer;
    function GetRecordLockRecordIDByteNo(SessionID: TABSSessionID): Integer;
   public
    constructor Create(PageManager: TABSPageManager);
    destructor Destroy; override;
    function CreateFile(aMaxSessionCount: Integer): TABSPageNo;
    procedure DeleteFile;
    procedure OpenFile(aStartPageNo: TABSPageNo);
    procedure CloseFile;

    function LockTable(SessionID: TABSSessionID; LockType: TABSLockType): Boolean;
    function UnlockTable(SessionID: TABSSessionID; LockType: TABSLockType): Boolean;
    function IsTableLockedByAnyOtherSession(SessionID: TABSSessionID;
                                            LockType: TABSLockType): Boolean;
    function IsTableLockAllowed(SessionID: TABSSessionID;
                                LockType: TABSLockType;
                                AllowXIRWAfterSIRW: Boolean = True): Boolean;

    function LockRecord(
                        SessionID:  TABSSessionID;
                        RecordID:   TABSRecordID
                       ): Boolean;
    function UnlockRecord(
                          SessionID:  TABSSessionID;
                          RecordID:   TABSRecordID
                         ): Boolean;
    function IsRecordLockedByAnyOtherSession(
                          SessionID:  TABSSessionID;
                          RecordID:   TABSRecordID
                         ): Boolean;
    function LockFile: Boolean;
    function UnlockFile: Boolean;

    property MaxSessionCount: Integer read FMaxSessionCount;
    property StartPageNo: TABSPageNo read GetStartPageNo;
  end;// TABSTableLocksFile



////////////////////////////////////////////////////////////////////////////////
//
// TABSSystemDirectory
//
////////////////////////////////////////////////////////////////////////////////


  TABSSystemDirectory = class(TObject)
   private
    LPageManager: TABSDiskPageManager;
    FHandle:      TABSInternalDBTransactedAccessFile;

    FFileList:    array of TABSSystemDirectoryListItem;
   public
    constructor Create(PageManager: TABSDiskPageManager);
    destructor Destroy; override;
    procedure CreateDirectory;
    procedure LoadDirectory;
    procedure SaveDirectory;
    procedure CreateFile(FileType: TABSDBFileType; FirstPageNo: TABSPageNo);
    function GetFileFirstPageNo(FileType: TABSDBFileType): TABSPageNo;
   public
    property PageManager: TABSDiskPageManager read LPageManager;
  end;// TABSSystemDirectory


////////////////////////////////////////////////////////////////////////////////
//
// TABSTableLockList
//
////////////////////////////////////////////////////////////////////////////////

  TABSTableLock = record
    LockType:         TABSLockType;
    LocksFilePageNo:  TABSPageNo;
    LockCount:        Integer;
    HasPhysicalLock:  Boolean;
    IsXIRWAfterSIRWAllowed: Boolean;
  end;
  PABSTableLock = ^TABSTableLock;

  TABSTableLockList = class(TObject)
   private
     FLockList: TList;

     function FindLock(LockType: TABSLockType; LocksFilePageNo: TABSPageNo;
                       var ItemNo: Integer): Boolean; overload;
     function FindLock(LockType: TABSLockType; LocksFilePageNo: TABSPageNo; IsXIRWAfterSIRWAllowed: Boolean;
                       var ItemNo: Integer): Boolean; overload;
     // is lock1 stronger than lock2
     function IsLockStronger(LockType1, LockType2: TABSLockType): Boolean;
   public
     constructor Create;
     destructor Destroy; override;
     procedure AddLock(LockType: TABSLockType; LocksFilePageNo: TABSPageNo; HasPhysicalLock: Boolean; IsXIRWAfterSIRWAllowed: Boolean = True);
     procedure RemoveLock(LockType: TABSLockType; LocksFilePageNo: TABSPageNo;
                          var HasPhysicalLock: Boolean; IgnoreCount: Boolean);
     function LockExists(LockType: TABSLockType; LocksFilePageNo: TABSPageNo): Boolean; overload;
     function LockExists(LockType: TABSLockType; LocksFilePageNo: TABSPageNo; IsXIRWAfterSIRWAllowed: Boolean): Boolean;overload;
     function StrongerLockExists(LockType: TABSLockType; LocksFilePageNo: TABSPageNo): Boolean;
     procedure SetPhysicalLock(ItemNo: Integer);
     function IsWeakerNonPhysicalLock(ItemNo: Integer; LockType: TABSLockType): Boolean;
  end;// TABSTableLockList


////////////////////////////////////////////////////////////////////////////////
//
// TABSDatabaseTableLockManager
//
////////////////////////////////////////////////////////////////////////////////

  TABSDatabaseTableLockManager = class(TObject)
   private
     FSessionLockList: TList;
     FMaxSessionCount: Integer;
     FCSect: TRTLCriticalSection;
     LPageManager: TABSPageManager;

     procedure Lock;
     procedure Unlock;
     function AddSIRWLocksToULocks(SessionID: TABSSessionID): Boolean;
     function SetPhysicalLockForWeakerLocks(SessionID: TABSSessionID; LockType: TABSLockType;
                        TableLocksFile: TABSTableLocksFile): Boolean;

   public
     constructor Create(MaxSessionCount: Integer; PageManager: TABSPageManager);
     destructor Destroy; override;
     function LockTable(SessionID: TABSSessionID; LockType: TABSLockType;
                        TableLocksFile: TABSTableLocksFile;
                        aTryCount: Integer;
                        aDelayMS:  Integer;
                        NoThreadLock: Boolean = False;
                        AllowXIRWAfterSIRW: Boolean = True): Boolean;
     function UnlockTable(SessionID: TABSSessionID; LockType: TABSLockType;
                        TableLocksFile: TABSTableLocksFile;
                        IgnoreIfNoLock: Boolean=False; IgnoreCount: Boolean=False): Boolean;
     function LockRecord(SessionID: TABSSessionID;
                        TableLocksFile: TABSTableLocksFile;
                        RecordID: TABSRecordID;
                        aTryCount: Integer;
                        aDelayMS:  Integer): Boolean;
     function UnlockRecord(SessionID: TABSSessionID;
                        TableLocksFile: TABSTableLocksFile;
                        RecordID: TABSRecordID): Boolean;
     function AddRWLocksBeforeCommit(SessionID: TABSSessionID): Boolean;
     function ClearTransactionLocks(SessionID: TABSSessionID): Boolean;
  end;// TABSDatabaseTableLockManager



type
  TBooleanFunctionForTimeOutCall = function: Boolean of object;

  // convert PageTypeID to String (for exceptions messages)
  function PageTypeToStr(PageType: TABSPageTypeID): String;
  function TryUsingTimeOut(Func: TBooleanFunctionForTimeOutCall; TryCount: Integer; DelayMS: Integer): Boolean;
  procedure CheckPageType(FoundType, WantedType: TABSPageTypeID; ErrorCode: Integer);

  // encrypts specified buffer
  function ABSInternalEncryptBuffer(
                                      CryptoAlg:              TABSCryptoAlgorithm;

⌨️ 快捷键说明

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