|
This section discusses using Delphi and the Btrieve API. The tasks are as follows:
To open a Btrieve file, call BTRV with the Open (0) operation, and the following additional information:
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)); [. . .]
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)); [. . .]
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));
Example
Status := BTRV( B_INSERT, PosBlock, DataBuffer, DataLength, KeyBuffer, KeyNumber); ShowMessage('Insert returned ' + intToStr(Status));
Example
Status := BTRV( B_UPDATE, PosBlock, DataBuffer, DataLength, KeyBuffer, KeyNumber); ShowMessage('Update returned ' + intToStr(Status));
Example Status := BTRV( B_DELETE, PosBlock, DataBuffer, DataLength, KeyBuffer, KeyNumber); ShowMessage('Delete returned ' + intToStr(Status));
The Step operations return a record without using an index.
The Get operations return a record using an index.
// 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 ';
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);
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
|
Chapter contents
Prev topic: Lesson 1: ActiveX Tutorials with Delphi
|