Step Eleven Clean up after yourself

Any time memory is manually allocated in a program, good programming practice states that you must deallocate it. All of the structures and buffers that you have manually allocated in the previous steps must be removed from memory

Free(pRecordBuf) DbiCloseCursor(hCur) DbiCloseDatabase( hDb


free record buffer close the cursor } close the database close the BDE }

Upon closer review of the steps involved, you might reconsider the amount of effort involved against the eventual payoff. Listing 9.1 is a template program, provided by Borland, that has been converted from

Chapter 9—The Borland Database Engine API ■ 283

C to Object Pascal. It demonstrates each of the steps described above. Because it was n°t meant to be a finished application, you will notice that the error handling is limited to describing the error message and returning to the code. You should plan on improving the VerifyDBI procedure before putting this to use in a critical application.

unit BDETmplt;

BDE API Template Copyright 1998 Borland Corporation

Converted to Delphi - Warren Rachele - }

interface uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

StdCtrls, BDE;


TForml = class(TForm) Button1: TButton; Label 1: TLabel;

procedure ButtonlClick(Sender: TObject); private

  • Private declarations } public
  • Public declarations ) end;

Forml: TForml; implementation

procedure VerifyDBI( inResultCode : DBIResuit); var

ErrorMsg : DBIMsg;

284 ■ Part lll-The Weil-Rounded Application begin if not (i nResul tCode = DBIERR_NONE) then begin

DbiGetErrorString( inResultCode, ErrorMsg ); ShowMessage('Error + IntToStr( inResultCode ) + ': ' + StrPas( ErrorMsg));

procedure TForm l .Button lC lick (Sender: var hDb : hDBIDb;

hCur : hDBICur;

CursorProps : curProps;

buffer pFieldVal : string; i sBlank : bool;



  • handle to the database
  • handle to the cursor
  • cursor properties
  • pointer to the record
  • variable for field data
  • is the field blank
  • init the database / cursor handles -hDb := nil; hCur := nil;

I - Step one . initialize the engine ) SnowMessage (' Step 1: Initialize Engine'); VerifyDBI(DbiInit(ni1));

  • Step two Open a database object -ShowMessage (' Step 2: Opening database') Veri fyDBI(Dbi OpenDatabase('DBDEMOS1,

dbi OPENSHARED, nil, 0, nil, database name } database type } mode for opening the database } open as shared or exclusive j { password if needed } { number of optional parameters } { field deSC for optional parameters }

nil, { values for opt parameters']

hDb)); { database handle }

  • Step three - set the table directory - } ShowMessage ('Step 3: Setting Table dir.'); {Db iSetD irectory ( database handle, table directory)} VerifyDBI( DbiSetD irectory ( hDb,'C:\Program Files\Common Files\Borland Shared\Data'));
  • Step four - set the temp directory - } ShowMessage ('Step 4: Setting temp dir'); VerifyDBI( DbiSetPrivateDir(1C:\Windows\Temp'));
  • Step five - Open table/establish cursor -ShowMessage ('Step 5: Open table'); VerifyDB I ( Db iOpenTab le (hDb ,
  • customer.db nil, nil, nil, 0, dbi READWRITE, I dbiOPENSHARED, X11 FI ELD, false, nil,
  • handle to database j { table name (ext optional ) } { driver type * not needed if ext used } { index name } { index tag } { index identi fier j open mode } { shared or exclusive use } { translation mode almost always xlt FI ELD } { determines if cursor is unidirectional } { optional parameter } I handle to the cursor )
  • Step six - get the cursor properties - } ShowMessage(' Step 6: Get Cursor Properties'); VerifyDBI( DbiGetCursorProps( hCur, CursorProps));
  • Step Seven - allocate memory for record buffer - } ShowMessage (' Step 7: Alloc memory for Record Buffer'); GetMem( pRecordBuf, CursorProps . iRecBufSize * SizeOf(BYTE))

if pRecordBuf = nil then { - Not enough memory - } ShowMessage('Record buffer allocation else begin failure ')

- Step Eight • if buffer good, set record pointer — }

ShowMessage('Step 8: Set Crack'); Veri fyDBI( ObiSetToBegin(hCur));

ShowMessage('Step 9: Goto Record');

VerifyDBI( DbiGetNextRecord( hCur, { cursor to get record from }

dbiNOLOCK, { lock type } pRecordBuf,{ record buffer } nil)); { record properties ■


{ -. Step Ten - get the desired fields from the record - }

ShowMessage('Step 10: Get field data');

VerifyDBI( DbiGetField( hCur, { cursor handle }

1 { ordinal value of field }

pReCOrdBuf, { record buffer } @CuStNum, { variable to receive data }

label 1.Caption := F1oatToStr(CustNum);


ShowMessage('Step 11: shut it all down') if pRecordBuf <> nil then if hCur <> nil then VerifyDBI( Obi CIoseCursor( hCur ));

VerifyDBI( Obi CIoseDatabase( hDb ));



Listing 9.1 Template program

Rather than using the API directly to build your database applications, the more likely scenario is one in which you will combine the ease of development that comes with the visual components and the depth available through the API. Using the API to perform selective tasks allows you to accomplish some items that cannot be performed throu; gh the visual components. The first of these is packing a dBASE table.

Was this article helpful?

0 0

Post a comment