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

📄 myldbtempengine.pas

📁 一个本地database引擎,支持中文T_Sql查询,兼容DELPHI标准数据库控件
💻 PAS
📖 第 1 页 / 共 4 页
字号:
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
    FBLOBFile:          TMYLDBStream;
    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 + -