PreviousTutorials and Guide to Samples (9.1 revision 1) Next

Lesson 2: Btrieve API Tutorials with Delphi

Show this topic in Library frames

This section discusses using Delphi and the Btrieve API. The tasks are as follows:

Performing Basic File Operations

Opening a File

To open a Btrieve file, call BTRV with the Open (0) operation, and the following additional information:

    1. the Position Block for the file
    2. the file name
    3. and the Owner Name for the file.

The file name is placed in the Key Buffer and the Owner Name is placed in the Data Buffer for the BTRV call. Both parameters must be "null-terminated". The DataLength parameter must contain the length of the Data Buffer.

Note that the Position Block should be declared at a scope that ensures its validity as long as the file is to be kept open. Btrieve uses the Position Block to store currency and other information between calls, so the variable must be extant and visible for any Btrieve call involving the file.

Example

var 
  Status:     smallint; 
  PosBlock:   array[1..128] of byte; 
  DataBuffer: array[0..8] of char; 
  KeyBuffer:  array[0..254] of char; 
  DataLength: word; 
  KeyNumber:  byte; 
[. . .] 
  // Set the owner name, if any, in the DataBuffer, and 
set the length 
  fillchar(DataBuffer, sizeof(DataBuffer), #0); 
  DataBuffer := ''; // no owner name for this file 
  DataLength := length(DataBuffer); 
  // Place the file name in the KeyBuffer 
  fillchar(KeyBuffer, sizeof(KeyBuffer), #0); 
  KeyBuffer := 'g:\pvsw\sdk\pviddb\data\customer.mkd'; 
  // Set the KeyNumber to 0 
  KeyNumber := 0; 
  // Call Btrieve with the parameters 
  Status := BTRV( B_OPEN, 
                  PosBlock, 
                  DataBuffer, 
                  DataLength, 
                  KeyBuffer, 
                  KeyNumber); 
  // Check the status returned 
  ShowMessage('Open returned ' + intToStr(Status)); 
  [. . .] 

Closing a File

To close a Btrieve file, simply call BTRV with the Close (1) operation and pass the open file's Position Block. The status returned then can be used to determine success or failure.

Example

[. . .] 
Status := BTRV( B_CLOSE, 
                PosBlock, 
                DataBuffer, 
                DataLength, 
                KeyBuffer, 
                KeyNumber); 
ShowMessage('Close returned ' + intToStr(Status)); 
[. . .] 

Creating a File

To create a file, you need to create a structure that contains the necessary information required to build a new Btrieve file. This is most easily done by constructing several smaller structures which are aggregated before the BTRV call is made. See the Programmer's documentation for more information on the structures passed to the Create (14) call.

Example 
{****************************************************** 
  Record type definitions for Stat and Create operations 
******************************************************} 
type 
// File Specifications - one structure per file 
FILE_SPECS = packed record 
  recLength   : smallint; 
  pageSize    : smallint; 
  indexCount  : smallint; 
  reserved    : array[0..3] of char; 
  flags       : smallint; 
  dupPointers : byte; 
  notUsed     : byte; 
  allocations : smallint; 
end; 
// Key Specifications - one structure per key segment in 
the file 
KEY_SPECS = packed record 
  position        : smallint; 
  length          : smallint; 
  flags           : smallint; 
  reserved        : array [0..3] of char; 
  keyType         : char; 
  nullChar        : char; 
  notUsed         : array[0..1] of char; 
  manualKeyNumber : byte; 
  acsNumber       : byte; 
end; 
// The aggregated buffer contains one FILE_SPECS and as 
many 
//  KEY_SPECS structures are there will be key segments 
FILE_CREATE_BUF = packed record 
  fileSpecs : FILE_SPECS; 
  // array used here for flexibility 
  keySpecs  : array[1..1] of KEY_SPECS; // one key 
segment 
end; 
{****************************************************** 
  Create and Fill the File Specification Structure 
******************************************************} 
var 
  NewFileSpec:  FILE_CREATE_BUF; 
  DataLength;   smallint; 
  KeyBuffer:    array[0..254] of char; 
  KeyNumber:    byte; 
  PosBlock:     array[1..128] of byte; 
[. . .] 
fillchar(NewFileSpec, sizeof(NewfileSpec), #0); 
With NewFileSpec.fileSpecs do begin 
  recLength   := 100; 
  pageSize    := 4096; 
  indexCount  := 3;  // number of indexes, not key 
segments 
  reserved    := 0; 
  flags       := 0; 
  dupPointers := 0; 
  notUsed     := 0; 
  allocations := 0; 
end; 
	 
With NewFileSpec.keySpecs[1] do begin 
  position        := 0; 
  length          := 4; 
  flags           := 0; 
  // reserved               // not needed - NULLed by 
fillchar() 
  keyType         := 1; 
  nullChar        := 0; 
  // notUsed                // not needed - NULLed by 
fillchar() 
  manualKeyNumber := 0; 
  acsNumber       := 0; 
end; 
{****************************************************** 
  Specify a file path and name 
******************************************************} 
fillchar(KeyBuffer, sizeof(KeyBuffer), #0); 
KeyBuffer := 'c:\test.mkd'; 
{****************************************************** 
  Set Key Number to 0 to overwrite without warning, -1 
to err if file exists 
******************************************************} 
KeyNumber := 0; 
{****************************************************** 
  Call Btrieve Create operation and check status returned 
******************************************************} 
Status := BTRV( B_CREATE, 
                PosBlock, 
                NewFileSpec, 
                DataLength, 
                KeyBuffer, 
                KeyNumber); 
ShowMessage('Create returned ' + intToStr(Status)); 

Modifying Data

Inserting Records

  1. Place the Btrieve record to be inserted in the Data Buffer.
  2. Call Btrieve Insert function and check status returned.

Example

Status := BTRV( B_INSERT, 
                PosBlock, 
                DataBuffer, 
                DataLength, 
                KeyBuffer, 
                KeyNumber); 
ShowMessage('Insert returned ' + intToStr(Status)); 

Updating Records

  1. Use a Get or Step operation to establish currency and load the record.
  2. Modify the Data Buffer as desired.
  3. Call the Btrieve Update function.

Example

Status := BTRV( B_UPDATE, 
                PosBlock, 
                DataBuffer, 
                DataLength, 
                KeyBuffer, 
                KeyNumber); 
ShowMessage('Update returned ' + intToStr(Status)); 

Deleting Records

  1. Use a Get or Step operation to establish currency and load the record.
  2. Call the Btrieve Delete function.
Example 
Status := BTRV( B_DELETE, 
                PosBlock, 
                DataBuffer, 
                DataLength, 
                KeyBuffer, 
                KeyNumber); 
ShowMessage('Delete returned ' + intToStr(Status)); 

Retrieving Data

Performing Step Operations

The Step operations return a record without using an index.

  1. Call Step operation.
Status := BTRV( B_STEP_FIRST, 
                PosBlock, 
                DataBuffer, 
                DataLength, 
                KeyBuffer, 
                KeyNumber); 
  1. Verify status.
ShowMessage('Update returned ' + intToStr(Status)); 
  1. Use or manipulate the Data Buffer as desired.

Performing Get Operations

The Get operations return a record using an index.

  1. (For Get Equal, Get Greater or Equal, etc.) Set the Key Buffer parameter to the value sought.
// The following code would set the Key Buffer 
// appropriately for 
// an index with two segments, both 10-character strings.  
// Unlike ZStrings, these fields are blank-padded and 
// not NULL-terminated. 
KeyBuffer := 'Adams     George    '; 
  1. Set the Key Number parameter to the desired index.
KeyNumber := 1; 
  1. Call Step operation.
Status := BTRV( B_GET_EQUAL, 
                PosBlock, 
                DataBuffer, 
                DataLength, 
                KeyBuffer, 
                KeyNumber); 
  1. Verify status.
ShowMessage('Update returned ' + intToStr(Status)); 
  1. Use or manipulate the Data Buffer as desired.

Working with Segmented Indexes

Segmented indexes are used in the same way as non-segmented indexes, but care must be taken to fill the Key Buffer correctly in these cases.

The Key Buffer must contain the values in the same form as the key. For integer and other binary fields, the Key Buffer information must be in binary form. For the different string types, the data must appear in the Key Buffer exactly as it appears in the Btrieve file.

It is convenient to define Key Buffer records as Variant Records (or, in "C" terminology, "unions." The following key buffer type could be used for several different segmented and non-segmented key types:

Example

type 
  KEY_BUFFER_TYPE = packed record 
    case integer of 1:  ( 
          IDNumber:   integer; 
          Filler1:    array[1..255 - sizeof(integer)] of 
char; 
        ); 
    2:  ( 
          LastName:   array[0..23] of char; 
          FirstName:  array[0..23] of char; 
          Filler2:    array[1..255 - 24 - 24] of char; 
        ); 
    3:  ( 
          ZipCode:    array[0..9] of char; 
          Filler3:    array[1..255 - 10] of char 
        ) 
  end; 
[. . .] 
var 
  KeyBuffer:  KEY_BUFFER_TYPE; 
[. . .] 
fillchar(KeyBuffer, sizeof(KeyNumber), #0); 
KeyBuffer.IDNumber := 1047; 
Status := BTRV( B_GET_EQUAL, 
                PosBlock, 
                DataBuffer, 
                DataLength, 
                KeyBuffer, 
                KeyNumber); 

Locating Data

To locate data, you use a key to locate a row in a database.

To find a key in a file without actually retrieving a row (assuming one exists), add +50 (KEY_BIAS in btrconst.pas) to the operation number for GetEqual, GetNext, GetFirst, or GetLast.

Example

// Get Key only -- does not get record 
Status := BTRV( B_GET_EQUAL + KEY_BIAS, 
                PosBlock, 
                DataBuffer, 
                DataLength, 
                KeyBuffer, 
                KeyNumber); 

To locate data, you use a key to locate a row in a database.

To find a key in a file without actually retrieving a row (assuming one exists), add +50 (KEY_BIAS in btrconst.pas) to the operation number for GetEqual, GetNext, GetFirst, or GetLast.

Example

// Get Key only -- does not get record 
Status := BTRV( B_GET_EQUAL + KEY_BIAS, 
                PosBlock, 
                DataBuffer, 
                DataLength, 
                KeyBuffer, 
                KeyNumber); 

Chapter contents
Publication contents

Prev topic: Lesson 1: ActiveX Tutorials with Delphi
Next topic: Lesson 3: ODBC Tutorials with Delphi