Delphi Clinic C++Builder Gate Training & Consultancy Delphi Notes Weblog Dr.Bob's Webshop
Dr.Bob's Delphi Notes Dr.Bob's Delphi Clinics
 Delphi Conference 1999
See Also: Dr.Bob's Delphi Training Clinic in Eindhoven, The Netherlands

I've Grown Custom To Your DataSet
In this session we'll build our own Custom DataSet component, TBDataSet, derived from the abstract base class TDataSet (also the parent class for TBDEDataSet and TClientDataSet). We'll see that in order to write a custom dataset, we not only need to derive from TDataSet, but we need to override and implement 20+ abstract methods to make sure we get the custom dataset to work (unfortunately, it will become clear that in order to test the custom dataset, all methods must be implemented - hence quite difficult to test and debug).

Implemented as a simple flat-file of strings, we'll be spending most of the time in this session looking at a number of different implementations of the abstract methods from our derived class TBDataSet.

    TBDataSet = class(TDataSet)
      constructor Create(AOwner: TComponent); override;
      destructor Destroy; override;
    protected { abstract methods }
      function AllocRecordBuffer: PChar; override;
      procedure FreeRecordBuffer(var Buffer: PChar); override;
      procedure GetBookmarkData(Buffer: PChar; Data: Pointer); override;
      function GetBookmarkFlag(Buffer: PChar): TBookmarkFlag; override;
      function GetFieldData(Field: TField; Buffer: Pointer): Boolean; override; { overloaded }
      function GetRecord(Buffer: PChar; GetMode: TGetMode; DoCheck: Boolean): TGetResult; override;
      function GetRecordSize: Word; override;
      procedure InternalAddRecord(Buffer: Pointer; Append: Boolean); override;
      procedure InternalClose; override;
      procedure InternalDelete; override;
      procedure InternalFirst; override;
      procedure InternalGotoBookmark(Bookmark: Pointer); override;
      procedure InternalHandleException; override;
      procedure InternalInitFieldDefs; override;
      procedure InternalInitRecord(Buffer: PChar); override;
      procedure InternalLast; override;
      procedure InternalOpen; override;
      procedure InternalPost; override;
      procedure InternalSetToRecord(Buffer: PChar); override;
      function IsCursorOpen: Boolean; override;
      procedure SetBookmarkFlag(Buffer: PChar; Value: TBookmarkFlag); override;
      procedure SetBookmarkData(Buffer: PChar; Data: Pointer); override;
      procedure SetFieldData(Field: TField; Buffer: Pointer); override;
      { Published declarations }
For each of these methods, we'll see what it means and what it's supposed to do, and how we can implement it for the custom dataset we have in mind. Most code will be written "live" during the session (so it should be possible to follow the entire construction of the custom dataset from the ground up).
Apart from the above 20+ methods, we can also decide to implement the following three methods as well (and make them public) to give additional support to DBGrids, for example:
    function GetRecordCount: Integer; override;
    function GetRecNo: Integer; override;
    procedure SetRecNo(Value: Integer); override;
At the end of the session, we'll add the TBDataSet to the "Data Access" tab of the Component Palette, and see that we can hook it up - via a regular TDataSource component - to all visual Data Aware components available. Only this time, the resulting (database) application won't be needing the BDE or any other library/file since it's build with our own custom dataset.

This webpage © 2000-2015 by Bob Swart (aka Dr.Bob - All Rights Reserved.