Introduction to Btrieve APIs
The Zen MicroKernel Engine is designed for high-performance data handling and improved programming productivity. The MicroKernel Engine operations allow your application to retrieve, insert, update, or delete records either by key value, or by sequential or random access methods.
The Btrieve API provides compatibility with the following programming languages and development environments:
• Embarcadero C/C++
• Embarcadero Delphi
• GNU C/C++
• Micro Focus COBOL
• Microsoft Visual Basic
• Microsoft Visual C++
• Watcom C/C++
The following topics cover the API functionality:
Btrieve API Functions
The Btrieve API is single-function in that most program actions are determined by an operation code parameter rather than a function name. You should choose the API for your application based on whether you are most interested in cross-platform portability of code or the best possible performance on a particular platform.
Your Btrieve application should never perform any standard I/O against a data file. Your application should perform all file I/O using a Btrieve API function.
The following table lists Btrieve API functions provided for use with the operation codes.
To find the language-specific syntax for calling Btrieve API functions, see
Btrieve API Programming in
Zen Programmer’s Guide.
BTRV
BTRV allows an application to make calls to the MicroKernel Engine. All the language interface modules provided with the Programming Interfaces installation option support the BTRV function. In some cases, the BTRV function actually calls the BTRCALL function. However, BTRV is the preferred function because of the platform independence it provides.
BTRVID
BTRVID allows an application to make a single MicroKernel Engine call that contains a clientID parameter, which the application can control. An application can use BTRVID to assign itself more than one client identity to the MicroKernel Engine and to execute operations for one client without affecting the state of the other clients. For more information, see
Client ID.
BTRCALL
For Windows, Linux, and macOS, BTRCALL is equivalent to the BTRV function. You should use the BTRV function instead of BTRCALL unless you cannot afford the slight performance decrease that occurs with BTRV.
BTRCALLID
Use the BTRCALLID function if you need client-level control and your application operates in Windows, Linux, macOS, or Raspbian.
This function is similar to the BTRVID function, except that it does not call an intermediate function.
Note: The legacy BTRCALLID32 function is aliased to the BTRCALLID function.
BTRVEX
The potentially large size of 13.0 format files and the use of larger data buffers requires run-time values larger than what older Btrieve interfaces have provided. The newer entry points BTRVEX and BTRVEXID meet these requirements. They are similar to BTRCALL and BTRCALLID, except that some of the function arguments use wider types, and some of the data buffers are laid out differently. The declarations are in btrvexid.h and the implementations are in the same files as BTRCALL.
For a Btrieve operation that uses a BTRVEX entry point, some values passed in data buffers are wider, such as 8-byte record addresses and record counts. Please note that the 8-byte behavior is due to the BTRVEX entry points and does not depend on the format version of the file being accessed. To use BTRVEX, the following operations require changed data buffer layouts:
• Create (14), Create Index (31)
• Stat (15)
• Get Position (22)
• Get Direct (23)
• Get Next Extended (36), Get Previous Extended (37)
• Step Next Extended (38), Step Previous Extended (39)
• Insert Extended (40)
• Find Percentage (45)
• Stat Extended (65) subfunctions 3 and 8
• Unlock (27)
The choice of entry point does not affect record data.
As noted above, the data buffer size argument for BTRVEX is a pointer to a 32-bit integer, where BTRCALL uses a 16-bit integer. Thus, data buffers can be larger than 64 KB.
If you are migrating to the new file format, keep in mind that the position block and client ID values can be used with both BTRCALL and BTRVEX, so it is not necessary to convert all code to BTRVEX at once.
The key number argument for BTRVEX is a 32-bit integer, where BTRCALL uses an 8-bit signed integer. To make it easier to convert existing code to BTRVEX, the BTRVEX entry point remaps key values 128 through 255 to –128 through –1. This accommodates constants that were specified as unsigned bytes (e.g., 0xFE) instead of as signed bytes (e.g., –2).
BTRVEXID
Like BTRVID and BTRCALLID, BTRVEXID allows client ID control in addition to the benefits of BTRVEX.
Obsolete Functions
The following historical functions are supported to maintain compatibility with applications written for previous Btrieve API releases:
• BTRCALLBACK
• BTRVINIT
• BTRVSTOP
• RQSHELLINIT
• WBRQSHELLINIT
• WBTRVINIT
• WBTRVSTOP
• BRQSHELLINIT
While these functions are now obsolete, older applications that call these functions will still run with 6.15 and later MicroKernel versions.
Btrieve API Function Parameters
Every function call must provide all parameters. This holds true even though the MicroKernel Engine does not use every parameter on every operation and in some cases may ignore a parameter value. In general, different parameters can be sent and returned for each operation. See
Btrieve API Operations for details of the parameters for each Btrieve API operation.
Note: C developers: See the file btitypes.h for information about the platform-independent data types and pointers used in the C language interface.
Btrieve API functions use the following parameters:
• Client ID (BTRVID, BTRCALLID, and BTRVEXID functions only)
• Key Length (BTRCALL, BTRCALLID, BTRVEX, and BTRVEXID functions only)
Operation Code
The operation code parameter determines the action of the Btrieve API function. For example, the operation may read, write, delete, or update one or more records. Your application must specify an operation code in every Btrieve API call. The MicroKernel Engine never changes the code. Operation codes are described under
Btrieve API Operations.
Note: C developers: The data type of the variable you specify must be either BTI_WORD, an unsigned short integer, or BTI_INT, a signed 32-bit integer used only with BTRVEX and BTRVEXID. In both cases, the variable is passed by value.
Status Code
In BASIC and COBOL applications, the MicroKernel Engine returns status codes, which are signed integers. In most programming environments, the status code is the return value of the Btrieve API function call. However, some BASIC and COBOL language interfaces require a Status Code parameter, which contains a coded value to indicate whether errors occurred during the operation. After a Btrieve API call, the application must always check the value of the status variable to determine success.
Zen components return status codes from calls to their APIs. When you write to these APIs, you should provide handling for three conditions:
• API success
• Anticipated API failure
• Unanticipated API failure
Here is a C code example that handles all three conditions:
status = BTRVID(B_VERSION, posBlock1, &versionBuffer, &dataLen, keyBuf1, keyNum, (BTI_BUFFER_PTR) &clientID);
if (status == B_NO_ERROR)
{
/* continue normal operation */
status = BTRVID(...);
}
else if (status == B_RECORD_MANAGER_INACTIVE)
{
/* handle known error */
printf("Btrieve Get Version() returned B_RECORD_MANAGER_INACTIVE\n");
}
else
{
/* unanticipated error */
printf("Btrieve Get Version() returned %d\n", status);
} /* end if-else */
By following this method of status code handling, you can help ensure your application's future stability.
Note: In the older BTRV functions, status codes are 2-byte integers, while the newer BTRVEX and BTRVEXID return 4-byte integers.
Position Block
The position block parameter is the address of a 128byte array that the MicroKernel Engine uses to store file I/O structures and the positioning information associated with an Open (0) operation. Each time your application opens a file, it must allocate a unique position block. The MicroKernel WEngineEitializes the position block when your application performs the Open operation, then references and updates it during file operations. Therefore, your application must specify the same position block on all subsequent Btrieve API operations for the file.
Note: Do not write to the position block. Doing so could result in a lost position error, other errors, or damage to the file.
When you open more than one file at a time, the MicroKernel Engine uses the position block to determine which file a particular call is for. Similarly, when you open the same file more than once, the engine uses a different position block for each Open operation. Likewise, the engine uses a different position block for each separate client that opens the same file. Clients cannot share position blocks.
Note: The position block is not bound to an entry point. It is possible to open a data file using BTRV, read data using BTRVEX, and close the file using BTRCALL.
Data Buffer
Your application transfers data to and from a file using the data buffer. The information passed to or from the MicroKernel Engine in the data buffer depends on which Btrieve API operation is being performed. Frequently, the data buffer contains one or more records that your application is transferring to or from a file. However, depending on the Btrieve API operation, the data buffer can contain other information, such as file or key specifications, MicroKernel Engine version information, and so on.
Be sure to allocate a large enough data buffer to accommodate the longest record in your file. If your data buffer length parameter specifies a value larger than the allocated size of your data buffer, MicroKernel Engine modification operations may destroy data following the data buffer.
Note: The same operations use different layouts depending on the entry point. BTRV, BTRVID, BTRCALL, and BTRCALLID use the legacy layout. BTRVEX and BTRVEXID use a newer, slightly different layout. The different layouts do not affect user data records.
Data Buffer Length
For any operation that requires a data buffer, your application must pass a variable that indicates the size (in bytes) of the data buffer, which should be large enough to contain data that the operation returns.
Note: BASIC developers: Applications must pass the data buffer length parameter ByRef as a Long integer.
C, COBOL, and Pascal developers: Applications must pass the data buffer length parameter as a pointer to a 2-byte integer for older BTRV functions, while the newer BTRVEX and BTRVEXID functions use a 4-byte integer.
When you are inserting records into or updating a file with variable-length records, the data buffer length should equal the record length specified when you first created the file, plus the number of characters included beyond the fixed-length portion. When you are retrieving variable-length records, the data buffer length should be large enough to accommodate the longest record in the file. If a record is longer than the maximum data buffer size, you must use a chunk operation to operate on a portion of the record.
The MicroKernel Engine uses the data buffer length parameter to determine how much space is available in the data buffer. If you pass a data buffer length that is longer than the data buffer you have allocated, you may cause the MicroKernel Engine to overwrite memory. The data buffer length should always represent the size of the allocated data buffer.
Note: The data buffer length is 2 bytes for the older BTRV functions and 4 bytes for the newer BTRVEX and BTRVEXID. For the older functions, the maximum data buffer size is 64 KB, while for the two newer ones it is 252 KB.
Key Buffer
Your application must pass the key buffer parameter on every Btrieve API operation, even if that operation does not use a key buffer. Depending on the operation, your application may set the data in the key buffer, or the Btrieve API function may return it.
Note: BASIC developers: Your application must pass the key buffer as a string. If the key value is an integer, your application should convert it to a string using the MKI$ statement before calling the Btrieve API function. If a key consists of two or more segments, you must concatenate them into a single string variable and pass the variable as the key buffer.
The MicroKernel Engine returns an error if the string variable passed as the key buffer is shorter than the defined key length. If your first application call does not require initialization of the key buffer, then assign the string variable the value SPACE$(x), where x represents the defined length of the key. Until your application assigns a value in BASIC to the string variable, its length is 0.
C developers: Your application must pass the key buffer as the address of a variable containing the key value. The file btitypes.h defines the key buffer as a VOID pointer (BTI_VOID_PTR). Your application can then define the key buffer type as needed.
COBOL developers: Your application must pass the key buffer as a record variable. If the key consists of two or more segments, list them in the correct order as individual fields under an 01 level record. Then you can pass the entire record as the key buffer.
Pascal developers: Your application must pass the key buffer as a variable containing a key value. If a key consists of two or more segments, use a record structure to define the individual fields in the key.
In most environments, the MicroKernel Engine cannot determine the key buffer length when an application makes a Btrieve API call. You must ensure that the buffer is at least as long as the key length you chose when you created the key. Otherwise, Btrieve operations may destroy data stored in memory following the key buffer. It is best to have a 255-byte key buffer, because 255 is the maximum key length.
Key Number
The information passed in the key number parameter depends on which operation is being performed. Most often, the key number contains a value that indicates which of up to 119 key (access) paths to follow for a particular operation. In all functions, the key number has a value range of 0 through 118.
The key number size varies:
• For BTRV and BTRVID, this parameter is a 2-byte integer.
• For BTRCALL, BTRCALLID, BTRCALL32, and BTRCALLID32, it is a 1-byte signed character (BTI_CHAR).
• For BTRVEX and BTRVEXID, it is a 4-byte integer. As a convenience for code migrating to BTRVEX, the key values 128–255 are mapped to key values –128 to –1. This simulates the conversion of a large unsigned byte value (e.g., 0xFF) to the signed byte argument of BTRCALL.
Btrieve API functions never alter the key number parameter.
Other information can be sent or returned in the key number parameter, such as a value indicating the mode for opening the file.
Client ID
The Client ID parameter is used only in the BTRVID, BTRCALLID, and BTRVEXID functions. The Client ID parameter is the address of a 16-byte structure that allows the MicroKernel Engine to differentiate among the clients on a computer. Use the following structure for the Client ID.
Key Length
The Key Length parameter is used only for BTRCALL, BTRCALLID, BTRVEX, and BTRVEXID.
The key length value is used as follows:
• For BTRCALL and BTRCALLID, pass the key length as an unsigned char of type BTI_BYTE, with a value of the allocated length of your key buffer. The maximum length you can specify is 255, the maximum length of any key.
• For BTRVEX and BTRVEXID, pass the key length as an unsigned char of type BTI_INT, with the same maximum length of 255.
Consider the following when you access the key buffer:
• For all four functions, the bytes of the key buffer up to the specified key length must be readable or writable, depending on the operation code.
• BTRV and BTRVID assume a key length of 255, so you should supply a key buffer at least that large.
• For BTRCALL and BTRCALLID, Zen client components may attempt to determine the actual key length and in some instances may read or write a smaller portion of the key buffer.
• BTRVEX and BTRVEXID take the specified key length at face value.
Summary of Btrieve API Operations
The Btrieve API provides over 40 operations to call from your application program. This topic summarize these operations. See
Btrieve API Operations for complete descriptions. See
Quick Reference of Btrieve Operations for brief summaries ordered by operation code.
Session-Specific Operations
The following operations allow you to set or retrieve the current directory, shut down a workstation MicroKernel Engine, retrieve the MicroKernel Engine version number, terminate a client connection with the server MicroKernel Engine, and begin, end, or abort a transaction. In applications that handle multiple clients, these operations are specific to the calling client.
File-Specific Operations
The following operations deal with a specific file, and therefore use the position block parameter to identify the file on which to operate. The file-specific operations are of three types:
File Access and Information
The following table lists access and information operations to create a file, open and close it, retrieve its statistics, set and clear its owner name, start or stop its continuous operation mode, unlock it, and create and drop its indexes.
Data Retrieval
The following table lists data retrieval operations to retrieve a single record or a set of records given specified criteria. The Btrieve API supports data retrieval either by logical location in an index path or by physical location. For more about accessing records, see Zen Programmer’s Guide.
In addition, you can apply biases to the operation codes to control file and record locking in multiclient situations. For more about supporting multiple clients, see Zen Programmer’s Guide.
Operation | Code | Description |
---|
Index-Based (Logical) Data Retrieval |
Get Equal | 5 | Returns the first record in the specified index path whose key value matches the specified key value. |
Get Next | 6 | Returns the record following the current record in the index path. |
Get Previous | 7 | Returns the record preceding the current record in the index path. |
Get Greater Than | 8 | Returns the first record in the specified index path whose key value is greater than the specified key value. |
Get Greater Than or Equal | 9 | Returns the first record in the specified index path whose key value is equal to or greater than the specified key value. |
Get Less Than | 10 | Returns the first record in the specified index path whose key value is less than the specified key value. |
Get Less Than or Equal | 11 | Returns the first record in the specified index path whose key value is equal to or less than the specified key value. |
Get First | 12 | Returns the first record in the specified index path. |
Get Last | 13 | Returns the last record in the specified index path. |
Get Next Extended | 36 | Returns one or more records that follow the current record in the index path. Filtering conditions can be applied. |
Get Previous Extended | 37 | Returns one or more records that precede the current record in the index path. Filtering conditions can be applied. |
Get Key | +50 | Detects the presence of a key value in a file, without returning an actual record. |
Get By Percentage | 44 | Returns the record located approximately at a position derived from the specified percentage value. |
Find Percentage | 45 | Returns a percentage figure based on the position of the current record in the file. |
Non-Index-Based (Physical) Retrieval |
Get Position | 22 | Returns the position of the current record. |
Get Direct/Chunk | 23 | Returns data from the specified portions (chunks) of a record at a specified position. |
Get Direct/Record | 23 | Returns the record at a specified position. |
Step Next | 24 | Returns the record from the physical location following the current record. |
Step First | 33 | Returns the record in the first physical location in the file. |
Step Last | 34 | Returns the record in the last physical location in the file. |
Step Previous | 35 | Returns the record in the physical location preceding the current record. |
Step Next Extended | 38 | Returns one or more successive records from the location physically following the current record. Filtering conditions can be applied. |
Step Previous Extended | 39 | Returns one or more preceding records from the location physically preceding the current record. Filtering conditions can be applied. |
Get By Percentage | 44 | Returns the record located approximately at a position derived from the specified percentage value. |
Find Percentage | 45 | Returns a percentage figure based on the position of the current record in the file. |
Concurrency Control Biases (Add to the Appropriate Operation Code) |
Single-record wait read lock | +100 | Locks only one record at a time. If the record is already locked, the client retries the operation. |
Single-record no-wait read lock | +200 | Locks only one record at a time. If the record is already locked, the MicroKernel Engine returns an error status code. |
Multiple-record wait read lock | +300 | Locks several records concurrently in the same file. If the record is already locked, the client retries the operation. |
Multiple-record no-wait read lock | +400 | Locks several records concurrently in the same file. If the record is already locked, the MicroKernel Engine returns an error status code. |
No-wait page write lock | +500 | In a concurrent transaction, tells the MicroKernel Engine not to wait if the page to be changed has already been changed by another active concurrent transaction. This bias can be combined with any of the record locking read biases (+100, +200, +300, or +400). |
Data Manipulation
The following table lists operations to insert, update, or delete data.
Unsupported Operations
When looking at MicroKernel Engine traces or SDK header files, you may see operations that are not listed in the reference for Btrieve API operations. These are for the internal use of Zen and you should not use them in your applications. The following operations are not supported.
Sequence of Events in Performing a Btrieve API Operation
To perform a Btrieve API operation, your application must complete the following tasks
1. Satisfy any prerequisites the operation requires. For example, before your application can perform any file I/O operations, it must make the file available by performing an Open (0) operation on that file.
2. Initialize the parameters that the Btrieve API operation requires. The parameters are program variables or data structures that correspond in type and size to the particular values that the MicroKernel Engine expects for an operation.
For future compatibility, initialize all parameters, whether or not they are used. For parameters of type INTEGER, set the value to binary 0. For character arrays, pass a pointer to a buffer. Initialize the first byte of the buffer to binary 0.
4. Evaluate the results of the function call. Every Btrieve API operation returns a status code. Your application must check the status code and take the appropriate action. The operation also returns data or other information to the individual parameters based on the purpose of the operation.