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

📄 abstempengine.pas

📁 Absolute Database 是来替代BDE[Borland数据库引擎]的用于Delphi 和 C++ Builder 开发用的数据库引擎. 它小巧, 高速, 健壮, 易于使用. 它能直接编译进
💻 PAS
📖 第 1 页 / 共 4 页
字号:
unit ABSTempEngine;

{$I ABSVer.inc}

interface

uses SysUtils, Classes,

// AbsoluteDatabase units

{$IFNDEF D5H}
     ABSD4Routines,
{$ENDIF}
{$IFDEF DEBUG_LOG}
     ABSDebug,
{$ENDIF}
     ABSExcept,
     ABSBase,
     ABSPage,
     ABSBaseEngine,
     ABSMemory,
     ABSCompression,
     ABSSecurity,
     ABSTypes,
     ABSConst;

type
   TABSTemporaryTableData = class;


////////////////////////////////////////////////////////////////////////////////
//
// TABSTemporaryRecordManager
//
////////////////////////////////////////////////////////////////////////////////


  TABSTemporaryRecordManager = class (TABSBaseRecordManager)
   private
    FRecordsPerPage:        Integer;
    FPageSize:              Integer;
    FCachedRecordCount:     Integer;
    FCache:                 PChar;
    FAllocatedRecordCount:  Integer;
    FTempPage:              PChar;
    FTempPageRecordCount:   Integer;
    FTempPageFile:          TABSFileStream;
    FMaxCachedRecordCount:  Integer;
    FAllocRecordsBy:        Integer;
    FDisableTempFiles:      Boolean;

    procedure SaveTempPage;
    function ReadRecord(
                        var RecordBuffer: TABSRecordBuffer;
                        RecordID: TABSRecordNo
                       ): Boolean;
    // return result for attempt of getting record relatively to first position
    // and set RecordID to new record ID
    function GetRecordFromFirstPosition(
            GetRecordMode: TABSGetRecordMode;
            var RecordID:  TABSRecordNo
                                       ): TABSGetRecordResult;
    // return result for attempt of getting record relatively to last position
    // and set RecordID to new record ID
    function GetRecordFromLastPosition(
            GetRecordMode: TABSGetRecordMode;
            var RecordID:  TABSRecordNo
                                      ): TABSGetRecordResult;
    // return result for attempt of getting record relatively any position
    // and set RecordID to new record ID
    function GetRecordFromAnyPosition(
            GetRecordMode: TABSGetRecordMode;
            var RecordID:  TABSRecordNo
                                      ): TABSGetRecordResult;
   public
    constructor Create(
                        RecordBufferSize:     Integer;
                        RecordsPerPage:       Integer;
                        AllocRecordsBy:       Integer;
                        DisableTempFiles:     Boolean
                      );
    destructor Destroy; override;

    procedure Empty(SessionID: TABSSessionID); override;

    // add record and return its number
    function AddRecord(
                        SessionID: TABSSessionID;
                        RecordBuffer: TABSRecordBuffer;
                        var RecordID: TABSRecordID
                       ): Boolean; override;
    // update record, return true if record was updated, false if record was deleted
    function UpdateRecord(SessionID: TABSSessionID; RecordBuffer: TABSRecordBuffer; RecordID: TABSRecordID): Boolean; override;
    // delete record, return true if record was deleted, false if record was deleted earlier
    function DeleteRecord(SessionID: TABSSessionID; var RecordID: TABSRecordID): Boolean; override;
    procedure GetRecordBuffer(SessionID: TABSSessionID; var NavigationInfo: TABSNavigationInfo); override;
    // return 0,1, or -1 if (1 = 2), (1 > 2) or (1 < 2)
    function CompareRecordID(RecordID1: TABSRecordID; RecordID2: TABSRecordID): Integer; override;
    // return record no
    function GetApproximateRecNo(SessionID: TABSSessionID; RecordID: TABSRecordID): TABSRecordNo; override;
  end; // TABSTemporaryRecordManager


////////////////////////////////////////////////////////////////////////////////
//
// TABSTemporaryPageManager
//
////////////////////////////////////////////////////////////////////////////////


  TABSTemporaryPageManager = class (TABSPageManager)
   protected
     FAllocatedPageMap:    TABSBitsArray;
     FAllocatedPageCount:  TABSPageNo;
     FTempPageFile:        TABSFileStream;
     FMaxMemoryPageCount:  TABSPageNo;
     FMemoryPageManager:   TABSPageManager;
     FDisableTempFiles:    Boolean;

   public
     procedure InternalAddPage(aPage: TABSPage); override;
     procedure InternalRemovePage(PageNo: TABSPageNo); override;
     function InternalReadPage(aPage: TABSPage): Boolean; override;
     procedure InternalWritePage(aPage: TABSPage); override;

     constructor Create(DisableTempFiles: Boolean);
     destructor Destroy; override;
  end; // TABSMemoryPageManager



////////////////////////////////////////////////////////////////////////////////
//
// TABSTemporaryDatabaseData
//
////////////////////////////////////////////////////////////////////////////////


  TABSTemporaryDatabaseData = class (TABSDatabaseData)
   private
    FLastObjectID: TABSLastObjectID;
   public
    constructor Create;
    destructor Destroy; override;
    // create table data
    function CreateTableData(Cursor: TABSCursor): TABSTableData; override;
    function GetNewObjectId: TABSObjectID; override;
  end; // TABSTemporaryDatabaseData


////////////////////////////////////////////////////////////////////////////////
//
// TABSTemporaryTableData
//
////////////////////////////////////////////////////////////////////////////////


  TABSTemporaryTableData = class (TABSTableData)
   private
    FBLOBFile:          TABSStream;
    FRecordsPerPage:    Integer;
    FAllocRecordsBy:    Integer;

   protected
    procedure CreateRecordManager; override;
    procedure CreateFieldManager(FieldDefs: TABSFieldDefs); override;
    procedure CreateIndexManager(IndexDefs: TABSIndexDefs); override;
    procedure CreateConstraintManager(ConstraintDefs: TABSConstraintDefs); override;
    procedure CreateBLOBFile;
    procedure DeleteBLOBFile;
    // return filter bitmap rec count
    function GetBitmapRecordCount(SessionID: TABSSessionID): TABSRecordNo; override;
    // return filter bitmap rec no by record id
    function GetBitmapRecNoByRecordID(RecordID: TABSRecordID): TABSRecordNo; override;
    // return filter bitmap rec no by record id
    function GetRecordIDByBitmapRecNo(RecordNo: TABSRecordNo): TABSRecordID; override;
   public
    constructor Create(
                        aDatabaseData:  TABSDatabaseData;
                        RecordsPerPage: Integer = 10;
                        AllocRecordsBy: Integer = 1000
                      );
    destructor Destroy; override;

    procedure CreateTable(
                          Cursor: TABSCursor;
                          FieldDefs: TABSFieldDefs;
                          IndexDefs: TABSIndexDefs;
                          ConstraintDefs: TABSConstraintDefs
                         ); override;
    procedure DeleteTable(Cursor: TABSCursor; DesignMode: Boolean = False); override;
    procedure EmptyTable(Cursor: TABSCursor); override;
    procedure OpenTable(Cursor: TABSCursor); override;
    procedure CloseTable(Cursor: TABSCursor); override;

    procedure AddIndex(IndexDef: TABSIndexDef; Cursor: TABSCursor); override;
    procedure DeleteIndex(IndexID: TABSObjectID; Cursor: TABSCursor); override;

    function InsertRecord(var Cursor: TABSCursor): Boolean; override;
    function DeleteRecord(Cursor: TABSCursor): Boolean; override;
    function UpdateRecord(Cursor: TABSCursor): Boolean; override;

    function InternalGetRecordCount(Cursor: TABSCursor): TABSRecordNo; override;
    // move cursor to specified position and set current record id in cursor
    procedure InternalSetRecNo(Cursor: TABSCursor; RecNo: TABSRecordNo); override;
    // get current record position from cursor
    function InternalGetRecNo(Cursor: TABSCursor): TABSRecordNo; override;

    //---------------------------------------------------------------------------
    // BLOB methods
    //---------------------------------------------------------------------------
    procedure WriteBLOBFieldToRecordBuffer(
              Cursor:     TABSCursor;
              FieldNo:    Integer;
              BLOBStream: TABSStream
              ); override;

    function InternalCreateBlobStream(
              Cursor:   TABSCursor;
              ToInsert: Boolean;
              FieldNo:  Integer;
              OpenMode: TABSBLOBOpenMode
              ): TABSStream; override;

    procedure GetDirectBlobData(
              Cursor:     TABSCursor;
              FieldNo:    Integer;
              RecordBuffer: TABSRecordBuffer;
              var BLOBDescriptor: TABSPartialTemporaryBLOBDescriptor;
              var pBlobData: PChar); override;

    procedure SetDirectBlobData(
              Cursor:     TABSCursor;
              FieldNo:    Integer;
              RecordBuffer: TABSRecordBuffer;
              var BLOBDescriptor: TABSPartialTemporaryBLOBDescriptor;
              var pBlobData: PChar); override;

    procedure FreeDirectBlobData(
              Cursor:     TABSCursor;
              FieldNo:    Integer;
              RecordBuffer: TABSRecordBuffer;
              var BLOBDescriptor: TABSPartialTemporaryBLOBDescriptor;
              var pBlobData: PChar); override;

  end; // TABSTemporaryTableData


implementation


uses

// AbsoluteDatabase units

  ABSLocalEngine,
  ABSMemEngine;


////////////////////////////////////////////////////////////////////////////////
//
// TABSTemporaryRecordManager
//
////////////////////////////////////////////////////////////////////////////////


//------------------------------------------------------------------------------
// save temporary page
//------------------------------------------------------------------------------
procedure TABSTemporaryRecordManager.SaveTempPage;
var WriteBytes,WriteSize:   Integer;
    OldPos,NewPos:          Int64;
begin
 if (FTempPageRecordCount > 0) then
  begin
   if (FTempPageRecordCount > FRecordsPerPage) then
    raise EABSException.Create(10126,ErrorLInvalidRecordCount,
      [FTempPageRecordCount,FRecordsPerPage]);
   OldPos := FTempPageFile.Position;
   NewPos := Int64(FRecordCount - FMaxCachedRecordCount - FTempPageRecordCount) *
             Int64(FRecordBufferSize);
   FTempPageFile.Position := NewPos;
   if (FTempPageFile.Position <> NewPos) then
    raise EABSException.Create(10128,ErrorLCannotSetPosition,
      [NewPos,OldPos,FTempPageFile.Size]);
   OldPos := FTempPageFile.Position;
   WriteSize := FTempPageRecordCount * FRecordBufferSize;
   WriteBytes := FTempPageFile.Write(FTempPage^,WriteSize);
   if (WriteBytes <> WriteSize) then
    raise EABSException.Create(10125,ErrorLWriteToStream,
      [OldPos,FTempPageFile.Size,WriteSize,WriteBytes]);
   FTempPageRecordCount := 0;
  end;
end; // SaveTempPage


//------------------------------------------------------------------------------
// read record
//------------------------------------------------------------------------------
function TABSTemporaryRecordManager.ReadRecord(
                        var RecordBuffer: TABSRecordBuffer;
                        RecordID: TABSRecordNo
                       ): Boolean;
var ReadBytes:          Integer;
    OldPos,NewPos:      Int64;
begin
 if (FDisableTempFiles or (RecordID < FMaxCachedRecordCount)) then
  begin
   try
     Move((FCache + RecordID * FRecordBufferSize)^,RecordBuffer^,
      FRecordBufferSize);
   except
     raise EABSException.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 EABSException.Create(10129,ErrorLCannotSetPosition,
      [NewPos,OldPos,FTempPageFile.Size]);
   OldPos := FTempPageFile.Position;
   ReadBytes := FTempPageFile.Read(RecordBuffer^,FRecordBufferSize);
   if (ReadBytes <> FRecordBufferSize) then
    raise EABSException.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 TABSTemporaryRecordManager.GetRecordFromFirstPosition(
        GetRecordMode: TABSGetRecordMode;
        var RecordID:  TABSRecordNo
                                   ): TABSGetRecordResult;
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 + -