?? myldbtempengine.pas
字號:
unit MYLDBTempEngine;
{$I MYLDBVer.inc}
interface
uses SysUtils, Classes,
// MYLDBoluteDatabase units
{$IFNDEF D5H}
MYLDBD4Routines,
{$ENDIF}
{$IFDEF DEBUG_LOG}
MYLDBDebug,
{$ENDIF}
MYLDBExcept,
MYLDBBase,
MYLDBPage,
MYLDBBaseEngine,
MYLDBMemory,
MYLDBCompression,
MYLDBSecurity,
MYLDBTypes,
MYLDBConst;
type
TMYLDBTemporaryTableData = class;
////////////////////////////////////////////////////////////////////////////////
//
// TMYLDBTemporaryRecordManager
//
////////////////////////////////////////////////////////////////////////////////
TMYLDBTemporaryRecordManager = class (TMYLDBBaseRecordManager)
private
FRecordsPerPage: Integer;
FPageSize: Integer;
FCachedRecordCount: Integer;
FCache: PChar;
FAllocatedRecordCount: Integer;
FTempPage: PChar;
FTempPageRecordCount: Integer;
FTempPageFile: TMYLDBFileStream;
FMaxCachedRecordCount: Integer;
FAllocRecordsBy: Integer;
FDisableTempFiles: Boolean;
procedure SaveTempPage;
function ReadRecord(
var RecordBuffer: TMYLDBRecordBuffer;
RecordID: TMYLDBRecordNo
): Boolean;
// return result for attempt of getting record relatively to first position
// and set RecordID to new record ID
function GetRecordFromFirstPosition(
GetRecordMode: TMYLDBGetRecordMode;
var RecordID: TMYLDBRecordNo
): TMYLDBGetRecordResult;
// return result for attempt of getting record relatively to last position
// and set RecordID to new record ID
function GetRecordFromLastPosition(
GetRecordMode: TMYLDBGetRecordMode;
var RecordID: TMYLDBRecordNo
): TMYLDBGetRecordResult;
// return result for attempt of getting record relatively any position
// and set RecordID to new record ID
function GetRecordFromAnyPosition(
GetRecordMode: TMYLDBGetRecordMode;
var RecordID: TMYLDBRecordNo
): TMYLDBGetRecordResult;
public
constructor Create(
RecordBufferSize: Integer;
RecordsPerPage: Integer;
AllocRecordsBy: Integer;
DisableTempFiles: Boolean
);
destructor Destroy; override;
procedure Empty(SessionID: TMYLDBSessionID); override;
// 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;
end; // TMYLDBTemporaryRecordManager
////////////////////////////////////////////////////////////////////////////////
//
// TMYLDBTemporaryPageManager
//
////////////////////////////////////////////////////////////////////////////////
TMYLDBTemporaryPageManager = class (TMYLDBPageManager)
protected
FAllocatedPageMap: TMYLDBBitsArray;
FAllocatedPageCount: TMYLDBPageNo;
FTempPageFile: TMYLDBFileStream;
FMaxMemoryPageCount: TMYLDBPageNo;
FMemoryPageManager: TMYLDBPageManager;
FDisableTempFiles: Boolean;
public
procedure InternalAddPage(aPage: TMYLDBPage); override;
procedure InternalRemovePage(PageNo: TMYLDBPageNo); override;
function InternalReadPage(aPage: TMYLDBPage): Boolean; override;
procedure InternalWritePage(aPage: TMYLDBPage); override;
constructor Create(DisableTempFiles: Boolean);
destructor Destroy; override;
end; // TMYLDBMemoryPageManager
////////////////////////////////////////////////////////////////////////////////
//
// TMYLDBTemporaryDatabaseData
//
////////////////////////////////////////////////////////////////////////////////
TMYLDBTemporaryDatabaseData = class (TMYLDBDatabaseData)
private
FLastObjectID: TMYLDBLastObjectID;
public
constructor Create;
destructor Destroy; override;
// create table data
function CreateTableData(Cursor: TMYLDBCursor): TMYLDBTableData; override;
function GetNewObjectId: TMYLDBObjectID; override;
end; // TMYLDBTemporaryDatabaseData
////////////////////////////////////////////////////////////////////////////////
//
// TMYLDBTemporaryTableData
//
////////////////////////////////////////////////////////////////////////////////
TMYLDBTemporaryTableData = class (TMYLDBTableData)
private
FRecordsPerPage: Integer;
FAllocRecordsBy: Integer;
protected
procedure CreateRecordManager; override;
procedure CreateFieldManager(FieldDefs: TMYLDBFieldDefs); override;
procedure CreateIndexManager(IndexDefs: TMYLDBIndexDefs); override;
procedure CreateConstraintManager(ConstraintDefs: TMYLDBConstraintDefs); override;
procedure CreateBLOBFile;
procedure DeleteBLOBFile;
// return filter bitmap rec count
function GetBitmapRecordCount(SessionID: TMYLDBSessionID): TMYLDBRecordNo; override;
// return filter bitmap rec no by record id
function GetBitmapRecNoByRecordID(RecordID: TMYLDBRecordID): TMYLDBRecordNo; override;
// return filter bitmap rec no by record id
function GetRecordIDByBitmapRecNo(RecordNo: TMYLDBRecordNo): TMYLDBRecordID; override;
public
constructor Create(
aDatabaseData: TMYLDBDatabaseData;
RecordsPerPage: Integer = 10;
AllocRecordsBy: Integer = 1000
);
destructor Destroy; override;
procedure CreateTable(
Cursor: TMYLDBCursor;
FieldDefs: TMYLDBFieldDefs;
IndexDefs: TMYLDBIndexDefs;
ConstraintDefs: TMYLDBConstraintDefs
); override;
procedure DeleteTable(Cursor: TMYLDBCursor; DesignMode: Boolean = False); override;
procedure EmptyTable(Cursor: TMYLDBCursor); override;
procedure OpenTable(Cursor: TMYLDBCursor); override;
procedure CloseTable(Cursor: TMYLDBCursor); override;
procedure AddIndex(IndexDef: TMYLDBIndexDef; Cursor: TMYLDBCursor); override;
procedure DeleteIndex(IndexID: TMYLDBObjectID; Cursor: TMYLDBCursor); override;
function InsertRecord(var Cursor: TMYLDBCursor): Boolean; override;
function DeleteRecord(Cursor: TMYLDBCursor): Boolean; override;
function UpdateRecord(Cursor: TMYLDBCursor): Boolean; override;
function InternalGetRecordCount(Cursor: TMYLDBCursor): TMYLDBRecordNo; override;
// move cursor to specified position and set current record id in cursor
procedure InternalSetRecNo(Cursor: TMYLDBCursor; RecNo: TMYLDBRecordNo); override;
// get current record position from cursor
function InternalGetRecNo(Cursor: TMYLDBCursor): TMYLDBRecordNo; override;
//---------------------------------------------------------------------------
// BLOB methods
//---------------------------------------------------------------------------
procedure WriteBLOBFieldToRecordBuffer(
Cursor: TMYLDBCursor;
FieldNo: Integer;
BLOBStream: TMYLDBStream
); override;
function InternalCreateBlobStream(
Cursor: TMYLDBCursor;
ToInsert: Boolean;
FieldNo: Integer;
OpenMode: TMYLDBBLOBOpenMode
): TMYLDBStream; override;
procedure GetDirectBlobData(
Cursor: TMYLDBCursor;
FieldNo: Integer;
RecordBuffer: TMYLDBRecordBuffer;
var BLOBDescriptor: TMYLDBPartialTemporaryBLOBDescriptor;
var pBlobData: PChar); override;
procedure SetDirectBlobData(
Cursor: TMYLDBCursor;
FieldNo: Integer;
RecordBuffer: TMYLDBRecordBuffer;
var BLOBDescriptor: TMYLDBPartialTemporaryBLOBDescriptor;
var pBlobData: PChar); override;
procedure FreeDirectBlobData(
Cursor: TMYLDBCursor;
FieldNo: Integer;
RecordBuffer: TMYLDBRecordBuffer;
var BLOBDescriptor: TMYLDBPartialTemporaryBLOBDescriptor;
var pBlobData: PChar); override;
end; // TMYLDBTemporaryTableData
implementation
uses
// MYLDBoluteDatabase units
MYLDBLocalEngine,
MYLDBMemEngine;
////////////////////////////////////////////////////////////////////////////////
//
// TMYLDBTemporaryRecordManager
//
////////////////////////////////////////////////////////////////////////////////
//------------------------------------------------------------------------------
// save temporary page
//------------------------------------------------------------------------------
procedure TMYLDBTemporaryRecordManager.SaveTempPage;
var WriteBytes,WriteSize: Integer;
OldPos,NewPos: Int64;
begin
if (FTempPageRecordCount > 0) then
begin
if (FTempPageRecordCount > FRecordsPerPage) then
raise EMYLDBException.Create(10126,ErrorLInvalidRecordCount,
[FTempPageRecordCount,FRecordsPerPage]);
OldPos := FTempPageFile.Position;
NewPos := Int64(FRecordCount - FMaxCachedRecordCount - FTempPageRecordCount) *
Int64(FRecordBufferSize);
FTempPageFile.Position := NewPos;
if (FTempPageFile.Position <> NewPos) then
raise EMYLDBException.Create(10128,ErrorLCannotSetPosition,
[NewPos,OldPos,FTempPageFile.Size]);
OldPos := FTempPageFile.Position;
WriteSize := FTempPageRecordCount * FRecordBufferSize;
WriteBytes := FTempPageFile.Write(FTempPage^,WriteSize);
if (WriteBytes <> WriteSize) then
raise EMYLDBException.Create(10125,ErrorLWriteToStream,
[OldPos,FTempPageFile.Size,WriteSize,WriteBytes]);
FTempPageRecordCount := 0;
end;
end; // SaveTempPage
//------------------------------------------------------------------------------
// read record
//------------------------------------------------------------------------------
function TMYLDBTemporaryRecordManager.ReadRecord(
var RecordBuffer: TMYLDBRecordBuffer;
RecordID: TMYLDBRecordNo
): Boolean;
var ReadBytes: Integer;
OldPos,NewPos: Int64;
begin
if (FDisableTempFiles or (RecordID < FMaxCachedRecordCount)) then
begin
try
Move((FCache + RecordID * FRecordBufferSize)^,RecordBuffer^,
FRecordBufferSize);
except
raise EMYLDBException.Create(10127,ErrorLRetreivingRecord);
end;
Result := True;
end
else
begin
SaveTempPage;
OldPos := FTempPageFile.Position;
NewPos := Int64(RecordID - FMaxCachedRecordCount) *
Int64(FRecordBufferSize);
FTempPageFile.Position := NewPos;
if (FTempPageFile.Position <> NewPos) then
raise EMYLDBException.Create(10129,ErrorLCannotSetPosition,
[NewPos,OldPos,FTempPageFile.Size]);
OldPos := FTempPageFile.Position;
ReadBytes := FTempPageFile.Read(RecordBuffer^,FRecordBufferSize);
if (ReadBytes <> FRecordBufferSize) then
raise EMYLDBException.Create(10130,ErrorLCannotReadFromStream,
[OldPos,FTempPageFile.Size,FRecordBufferSize,ReadBytes]);
Result := True;
end;
end; // ReadRecord
//------------------------------------------------------------------------------
// return result for attempt of getting record relatively to first position
// and set RecordID to new record ID
//------------------------------------------------------------------------------
function TMYLDBTemporaryRecordManager.GetRecordFromFirstPosition(
GetRecordMode: TMYLDBGetRecordMode;
var RecordID: TMYLDBRecordNo
): TMYLDBGetRecordResult;
begin
Result := grrError;
case GetRecordMode of
grmPrior:
begin
Result := grrBOF;
end;
grmCurrent:
begin
Result := grrError;
end;
grmNext:
begin
RecordID := 0;
Result := grrOK;
end;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -