?? myldbdiskengine.pas
字號:
unit MYLDBDiskEngine;
interface
{$I MYLDBVer.inc}
uses SysUtils, Classes, Windows, Math,
// MYLDBoluteDatabase units
{$IFDEF DEBUG_LOG}
MYLDBDebug,
{$ENDIF}
{$IFNDEF D5H}
MYLDBD4Routines,
{$ENDIF}
MYLDBExcept,
MYLDBBase,
MYLDBBaseEngine,
MYLDBBTree,
MYLDBMemory,
MYLDBPage,
MYLDBCompression,
MYLDBExpressions,
MYLDBSecurity,
MYLDBCipher,
MYLDBConverts,
MYLDBTypes,
MYLDBConst;
type
// forward decls
TMYLDBDiskPageManager = class;
TMYLDBDiskTableData = class;
TMYLDBSystemDirectory = class;
TMYLDBActiveSessionsFile = class;
TMYLDBTableListFile = class;
TMYLDBTableLocksFile = class;
TMYLDBInternalDBDirectAccessFile = class;
TMYLDBInternalDBTransactedAccessFile = class;
TMYLDBDatabaseTableLockManager = class;
////////////////////////////////////////////////////////////////////////////////
//
// TMYLDBDiskDatabaseData
//
////////////////////////////////////////////////////////////////////////////////
TMYLDBDiskDatabaseData = class (TMYLDBDatabaseData)
private
FSystemDir: TMYLDBSystemDirectory;
FActiveSessionsFile: TMYLDBActiveSessionsFile;
FTableListFile: TMYLDBTableListFile;
FPassword: TMYLDBPassword;
FMaxSessionCount: Integer;
FPageSize: Integer;
FPageCountInExtent: Integer;
FTableLockManager: TMYLDBDatabaseTableLockManager;
FSingleUserConnected: Boolean;
procedure OpenDatabase(Session: TMYLDBBaseSession; Exclusive: Boolean;
var RepairNeeded: Boolean);
procedure CloseDatabase;
function GetPassword: PMYLDBPassword;
function GetEncrypted: Boolean;
protected
procedure AddTable(
TableID: TMYLDBTableID;
TableName: String;
MetadataFilePageNo,
MostUpdatedFilePageNo,
LocksFilePageNo: TMYLDBPageNo
);
procedure RemoveTable(TableName: String);
procedure OpenTable(
TableName: String;
out TableID: TMYLDBTableID;
out MetadataFilePageNo: TMYLDBPageNo;
out MostUpdatedFilePageNo: TMYLDBPageNo;
out LocksFilePageNo: TMYLDBPageNo
);
procedure RenameTable(TableName, NewTableName: String);
public
constructor Create;
destructor Destroy; override;
// create table data
function CreateTableData(Cursor: TMYLDBCursor): TMYLDBTableData; override;
// database operations
procedure CreateDatabase; override;
procedure ConnectSession(Session: TMYLDBBaseSession); override;
procedure DisconnectSession(Session: TMYLDBBaseSession); override;
procedure FreeIfNoSessionsConnected; override;
procedure GetTablesList(List: TStrings); override;
// database operations
procedure TruncateDatabase;
function GetDBFileConnectionsCount: Integer;
// lock tables (virtual object)
procedure LockTables;
// unlock tables (virtual object)
procedure UnlockTables;
procedure Commit(SessionID: TMYLDBSessionID; DoFlushBuffers: Boolean=True); override;
procedure Rollback(SessionID: TMYLDBSessionID); override;
procedure FlushBuffers; override;
function GetNewObjectId: TMYLDBObjectID; override;
function GetSuppressDBHeaderErrors: Boolean;
procedure SetSuppressDBHeaderErrors(Value: boolean);
public
property Password: PMYLDBPassword read GetPassword;
property Encrypted: Boolean read GetEncrypted;
property MaxSessionCount: Integer read FMaxSessionCount write FMaxSessionCount;
property PageSize: Integer read FPageSize write FPageSize;
property PageCountInExtent: Integer read FPageCountInExtent write FPageCountInExtent;
end; // TMYLDBDiskDatabaseData
////////////////////////////////////////////////////////////////////////////////
//
// TMYLDBSmallRecordPage
//
////////////////////////////////////////////////////////////////////////////////
TMYLDBSmallRecordPage = class(TObject)
private
LPage: TMYLDBPage;
FRecordBufferSize: Integer;
FMaxRecordsOnPage: Integer;
FRecordDataOffset: Integer;
function FindUnusedRecordSlot(var SlotNo: Integer): Boolean;
function GetRecordCount: TMYLDBRecordNo;
public
constructor Create(Page: TMYLDBPage; RecordBufferSize: Integer;
MaxRecordsOnPage: Integer);
procedure AddRecord(RecordBuffer: PChar; var RecordID: TMYLDBRecordID);
function UpdateRecord(RecordBuffer: PChar; RecordID: TMYLDBRecordID): Boolean;
function DeleteRecord(RecordID: TMYLDBRecordID): Boolean;
function GetRecordBuffer(RecordID: TMYLDBRecordID; RecordBuffer: PChar): Boolean;
// navigation inside page
procedure GetFirstRecordID(var RecordID: TMYLDBRecordID);
procedure GetLastRecordID(var RecordID: TMYLDBRecordID);
function GetNextRecordID(var RecordID: TMYLDBRecordID): Boolean;
function GetPriorRecordID(var RecordID: TMYLDBRecordID): Boolean;
procedure GetRecordID(RecNoOnPage: Integer; var RecordID: TMYLDBRecordID);
procedure GetRecNoOnPage(RecordID: TMYLDBRecordID; var RecNoOnPage: Integer);
property RecordCount: TMYLDBRecordNo read GetRecordCount;
end;// TMYLDBSmallRecordPage
////////////////////////////////////////////////////////////////////////////////
//
// TMYLDBDiskRecordManager
//
////////////////////////////////////////////////////////////////////////////////
TMYLDBDiskRecordManager = class(TMYLDBBaseRecordManager)
private
FRecordPageIndex: TMYLDBBTreeRecordPageIndex;
LPageManager: TMYLDBPageManager;
LFieldManager: TMYLDBBaseFieldManager;
LMostUpdatedFile: TMYLDBInternalDBTransactedAccessFile;
FMaxRecordsOnPage: Integer;
FLastAutoIncValues: array of Int64;
FDiskRecordBufferSize: Integer;
FTempDiskRecordBuffer: PChar;
LTableData: TMYLDBDiskTableData;
function IsRecordPageValid(Page: TMYLDBPage): Boolean;
procedure GetFirstRecord(SessionID: TMYLDBSessionID;
var NavigationInfo: TMYLDBNavigationInfo);
procedure GetLastRecord(SessionID: TMYLDBSessionID;
var NavigationInfo: TMYLDBNavigationInfo);
procedure GetNextRecord(SessionID: TMYLDBSessionID;
var NavigationInfo: TMYLDBNavigationInfo);
procedure GetPriorRecord(SessionID: TMYLDBSessionID;
var NavigationInfo: TMYLDBNavigationInfo);
procedure GetCurrentRecord(SessionID: TMYLDBSessionID;
var NavigationInfo: TMYLDBNavigationInfo);
public
constructor Create(PageManager: TMYLDBPageManager;
FieldManager: TMYLDBBaseFieldManager; MostUpdatedFile: TMYLDBInternalDBTransactedAccessFile;
TableData: TMYLDBDiskTableData);
destructor Destroy; override;
procedure Init(RecordBufferSize: Integer; DiskRecordBufferSize: Integer;
FieldCount: Integer);
procedure LoadMostUpdated(Buf: PChar; var Offset: Integer);
procedure SaveMostUpdated(Buf: PChar; var Offset: Integer);
procedure LoadMetadata(Stream: TStream);
procedure SaveMetadata(Stream: TStream);
procedure CreateRecordPageIndex;
procedure Empty(SessionID: TMYLDBSessionID); override;
procedure Delete(SessionID: TMYLDBSessionID);
// add record and return its number
function AddRecord(SessionID: TMYLDBSessionID; RecordBuffer: TMYLDBRecordBuffer; var RecordID: TMYLDBRecordID): Boolean; override;
// update record, return true if record was updated, false if record was deleted
function UpdateRecord(SessionID: TMYLDBSessionID; RecordBuffer: TMYLDBRecordBuffer; RecordID: TMYLDBRecordID): Boolean; override;
// delete record, return true if record was deleted, false if record was deleted earlier
function DeleteRecord(SessionID: TMYLDBSessionID; var RecordID: TMYLDBRecordID): Boolean; override;
procedure GetRecordBuffer(SessionID: TMYLDBSessionID; var NavigationInfo: TMYLDBNavigationInfo); override;
// return 0,1, or -1 if (1 = 2), (1 > 2) or (1 < 2)
function CompareRecordID(RecordID1: TMYLDBRecordID; RecordID2: TMYLDBRecordID): Integer; override;
// return record no
function GetApproximateRecNo(SessionID: TMYLDBSessionID; RecordID: TMYLDBRecordID): TMYLDBRecordNo; override;
procedure SetRecNo(SessionID: TMYLDBSessionID; RecNo: TMYLDBRecordNo; var RecordID: TMYLDBRecordID);
procedure GetRecNo(SessionID: TMYLDBSessionID; RecordID: TMYLDBRecordID; var RecNo: TMYLDBRecordNo);
procedure RebuildRecordPageIndex(SessionID: TMYLDBSessionID);
procedure ValidateRecordPageIndex(SessionID: TMYLDBSessionID);
property RecordPageIndex: TMYLDBBTreeRecordPageIndex read FRecordPageIndex;
end;// TMYLDBDiskRecordManager
////////////////////////////////////////////////////////////////////////////////
//
// TMYLDBSmallBlobPage
//
////////////////////////////////////////////////////////////////////////////////
TMYLDBSmallBlobPage = class(TObject)
protected
LPage: TMYLDBPage;
procedure SetBlobCount(Value: Integer);
function GetBlobCount: Integer;
function BlobHeader(Index: Integer): PMYLDBDiskBlobHeader;
function BlobData(Index: Integer): PChar;
function GetNewBlobID: Word;
public
constructor Create(Page: TMYLDBPage);
procedure AddBlob(BlobCache: PMYLDBDiskBLOBCache;
var PageItemID: TMYLDBPageItemID);
procedure DeleteBlob(PageItemID: TMYLDBPageItemID; var BlobSize: Integer);
procedure ReadBlob(BlobCache: PMYLDBDiskBLOBCache;
PageItemID: TMYLDBPageItemID);
property BlobCount: Integer read GetBlobCount write SetBlobCount;
end;// TMYLDBSmallBlobPage
////////////////////////////////////////////////////////////////////////////////
//
// TMYLDBDiskBlobManager
//
////////////////////////////////////////////////////////////////////////////////
TMYLDBDiskBlobManager = class(TObject)
private
LPageManager: TMYLDBPageManager;
LFieldManager: TMYLDBBaseFieldManager;
LRecordManager: TMYLDBBaseRecordManager;
FBlobCacheList: TList;
FBlobPageIndex: TMYLDBBTreeBlobPageIndex;
procedure GetBlobInfo(RecordBuffer: TMYLDBRecordBuffer;
FieldNo: Integer;
var PageItemID: TMYLDBPageItemID;
var BlobCache: PMYLDBDiskBLOBCache);
procedure SetBlobInfo(RecordBuffer: TMYLDBRecordBuffer;
FieldNo: Integer; PageItemID: TMYLDBPageItemID);
procedure CreateBlobCache(RecordBuffer: TMYLDBRecordBuffer; FieldNo: Integer;
var BlobCache: PMYLDBDiskBLOBCache);
procedure FreeBlobCache(RecordBuffer: TMYLDBRecordBuffer; FieldNo: Integer;
ForceClear: Boolean = False);
procedure StreamToBlobCache(Stream: TMYLDBStream; BlobCache: PMYLDBDiskBLOBCache);
procedure BlobCacheToStream(BlobCache: PMYLDBDiskBLOBCache; Stream: TStream);
// blob <-> disk pages
procedure ReadBlobHeader(SessionID: TMYLDBSessionID; PageItemID: TMYLDBPageItemID;
var BlobHeader: TMYLDBDiskBlobHeader;
BlobCache: PMYLDBDiskBLOBCache);
procedure WriteBlobHeader(SessionID: TMYLDBSessionID;
BlobHeader: TMYLDBDiskBlobHeader; var PageItemID: TMYLDBPageItemID);
procedure ReadBlobData(
// in
SessionID: TMYLDBSessionID;
PageItemID: TMYLDBPageItemID;
BlobHeader: TMYLDBDiskBlobHeader;
BlobDataPageList: TMYLDBIntegerArray;
// out
BlobCache: PMYLDBDiskBLOBCache);
procedure ReadBlobDataPageList(
// in
SessionID: TMYLDBSessionID;
PageItemID: TMYLDBPageItemID;
const PageListLink: TMYLDBPageListLink;
// out
BlobDataPageList: TMYLDBIntegerArray;
BlobDataPageListPages: TMYLDBIntegerArray);
procedure ReadLinkToBlobDataPageList(
SessionID: TMYLDBSessionID;
PageItemID: TMYLDBPageItemID;
var PageListLink: TMYLDBPageListLink);
procedure ReadMultiPagesBlob(SessionID: TMYLDBSessionID;
PageItemID: TMYLDBPageItemID; BlobHeader: TMYLDBDiskBlobHeader;
BlobCache: PMYLDBDiskBLOBCache);
procedure WriteBlobData(
// in
SessionID: TMYLDBSessionID;
BlobCache: PMYLDBDiskBLOBCache; PageItemID: TMYLDBPageItemID;
BlobHeader: TMYLDBDiskBlobHeader;
// out
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -