Mega Code Archive

 
Categories / Delphi / ADO Database
 

Create You Own Custom Dataset!

Title: Create You Own Custom Dataset! Question: How to create a custom DataSet Answer: Create you own Custom DataSet! by William Anthony Have you ever needed/wanted to create your own personal Database, well this is the place for you! [HybridSPOT] is proud to present a multi-part series on just that, starting with the TDataSet Component we will create a new and powerful OPEN-SOURCE Database Engine. This tutorial will teach you about the basics of Developing a TDataSet, and trust me it isn't such a simple task. -_- the TDataSet Structure The Naked Truth TNAKEDDataSet = class(TDataSet) protected function AllocRecordBuffer: PChar; override; function GetBookmarkFlag(Buffer: PChar): TBookmarkFlag; override; function GetCanModify: Boolean; override; function GetRecord(Buffer: PChar; GetMode: TGetMode; DoCheck: Boolean): TGetResult; override; function IsCursorOpen: Boolean; override; { THESE THREE WE CAN LEAVE OUT } function GetRecNo: Integer; override; function GetRecordCount: Integer; override; function GetRecordSize: Word; override; procedure FreeRecordBuffer(var Buffer: PChar); override; procedure GetBookmarkData(Buffer: PChar; Data: Pointer); override; procedure InternalAddRecord(Buffer: Pointer; Append: Boolean); override; procedure InternalClose; 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; procedure SetBookmarkData(Buffer: PChar; Data: Pointer); override; procedure SetBookmarkFlag(Buffer: PChar; Value: TBookmarkFlag); override; procedure SetFieldData(Field: TField; Buffer: Pointer; NativeFormat: Boolean); override; public property BufferCount; property Buffers; property Fields; property FieldValues; function GetFieldData(Field: TField; Buffer: Pointer; NativeFormat: Boolean): Boolean; override; published property Active; property AfterCancel; property AfterClose; property AfterDelete; property AfterEdit; property AfterInsert; property AfterOpen; property AfterPost; property AfterRefresh; property AfterScroll; property BeforeCancel; property BeforeClose; property BeforeDelete; property BeforeEdit; property BeforeInsert; property BeforeOpen; property BeforePost; property BeforeRefresh; property BeforeScroll; property CanModify; property FieldDefs; property Filter; property FilterOptions; property ObjectView default False; property OnCalcFields; property OnDeleteError; property OnEditError; property OnNewRecord; property OnPostError; property RecNo; property RecordCount; property RecordSize; property State; end; Well it looks a bit BULKY but that's what it needs in the REAL WORLD the Abstract Functions In earlier versions of Delphi this class had LOTS of abstract procedures, now it contains but a few: InternalOpen Type Abstract Use Generate Fields Bind Fields Open the Source of Data (File - Memory - Other) InternalClose Type Abstract Use Un-Bind Fields Close the Source of Data (File - Memory - Other) IsCursorOpen Type Abstract Function Use Return DataSet Active Status (is dataset open) InternalHandleException Type Abstract Use Respond to any exception that is generated GetRecord Type Abstract Function Use Get record data, There record position has to be updated within the procedure VIA the GETMODE param. the resulting value must be updated aswell, for example if the file goes off the EOF or BOF. the BookMark System You might be asking yourself as i once did: "WELL I DONT NEED BOOKMARKS FOR THIS SIMPLE DATASET!" Well guess what YOU DO.It seems that the Bookmark is not really a Bookmark more of a ID for each one of the Temporary Buffer. in standard it keeps about 3 records in memory Prior - Current - Next. Each containing there WHERE and WHO: WHERE is the BookmarkFlag (Prior, Current, Next) for orientation WHO is the BookmarkData (Record No) for ID and Placement. So in turn we must make a record for this data, beeing that it is fixed width we can place it infront of the main data, but in the case of this sample i fused them both together. the BookMark procedures SetBookmarkData Type Procedure Use Set RecordNo to Active Buffer No thinker ^_^ SetBookmarkFlag Type Procedure Use Set BookmarkFlag to Active Buffer No thinker ^_^ aswell GetBookmarkData Type Procedure Use Get RecordNo from Active Buffer No thinker ^_^ x 3 GetBookmarkFlag Type Function Use Get BookmarkFlag from Active Buffer No thinker ^_^ exp 4 InternalSetToRecord Type Procedure Use Get RecordNo from Active Buffer and set it as current record No thinker o_O InternalGotoBookmark Type Procedure Use Get RecordNo from DATA and set it as current record No thinker O_o EASY AS "3.1415..." (Pi) the Navegation Now that we see that the last part isn't that hard we move to the navegation, if you have used a DataSet before this shuld be easy. InternalFirst Type Procedure Use We set our Current Position to -1 (in some cases) BOF No thinker ^_^ InternalLast Type Procedure Use We set our Current Position to RecordCount (in some cases) EOF No thinker ^_^ the BUFFERS of Terror Now we come to the next level of the DataSet "the Buffer System" AllocRecordBuffer Type Function Use Return the new memory allocation for the buffer result := getMemory(MYRECORDSIZEWITHBOOKMARKINFO); No thinker ^_^ FreeRecordBuffer Type Procedure Use HERE IS THE CODE "FreeMem(Buffer);" No thinker ^_^ x 1000 Well that wasnt that bad was it? the Data Processing Ahh yes we are getting more work to do! InternalPost Type Procedure Use Post changes if any, We must check if the State is Edit or Insert, since this will have an effect on our process, if the state is set to Edit this meens that we must write our changes on the current record no questions asked, else we must go to the end and add a new record, then we write. NOT EVEN A MICRO-Thinker o_O InternalAddRecord Type Procedure Use Add current buffered record to file, same as the last but this time we just add it no questions asked. NOT EVEN A MICRO-Thinker O_O x 2 the Field System Yes the work is yet to come! SetFieldData Type Procedure Use Convert and Pass the data from the Active Buffer to the Field Buffer the param contains the FieldClass and the Field Buffer. the active buffer is given by the ActiveBuffer function. Semi-Thinker ^_^ depends on the Table Format GetFieldData Type Function Use Convert and Pass the data from the Field Buffer to the Active Buffer the param contains the FieldClass and the Field Buffer. the active buffer is given by the ActiveBuffer function. Result Value is boolean, it the data was passed OK then it returns TRUE Semi-Thinker ^_^ depends on the Table Format again the Usefull yet Not Needed I still use them do, even if they to make a mess if not used properly GetRecNo Type Function Use Return the current Record No GetRecordCount Type Function Use Return the Record Count GetRecordSize Type Function Use Return the Record Size w/o Bookmark Info SetRecNo Type Procedure Use Set the current Record No These procedures are used by some controls like TDBGrid and such. the Holy-Grail It is time to learn! All these procedures have been detailed for you to figure out, the code is WAY SIMPLE and WELL COMMENTATED so you shuldnt be lost for long. This is a sample of a TINY User Database complete with: User Name 20 Characters Password 10 Characters AccessLevel 4 Bytes [Integer] now in two days we will learn to make a DBF file reader! yes you wont have to use that bulky DBE anymore! and you will learn how different file formats work O_o Download NOW I hope this tutorial (instruction manual) has gotten some of you to try and build your skill up, remember that some if not all of knowledge comes from practice, so... repeat and repeat, make your own DataSet's until you get it working just fine! -William Anthony HybridGRAF Interactive Solutions