Introduction to Btrieve APIs
 
Introduction to Btrieve APIs
The PSQL 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
Btrieve API Function Parameters
Summary of Btrieve API Operations
Sequence of Events in Performing a Btrieve API Operation
You can also go directly to a list of Btrieve API Operations or the Quick Reference of Btrieve Operations.
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.
Table 1 Btrieve API Functions
Function
Operating Systems
Description
BTRV
BTRVID
All
Use for complete code portability between operating systems. For most developers, this advantage offsets a very slight performance decrease. Uses older data buffer layout.
BTRCALL
BTRCALLID
All
Use when you want to specify the key length argument. Uses older data buffer layout.
BTRVEX
BTRVEXID
All
Use when you need longer data buffers, or when you want the new data buffer layout. May be intermixed with BTRV type entry points so long as you interpret the data buffers correctly.
To find the language-specific syntax for calling Btrieve API functions, see Btrieve API Programming in PSQL 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 very 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. 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:
Operation Code
Status Code (BASIC and COBOL only)
Position Block
Data Buffer
Data Buffer Length
Key Buffer
Key Number
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 variable you specify must be of one of the following data types:
BTI_WORD, an unsigned short integer
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.
PSQL 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 EngineWnitializes 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 APIWperations 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 key’s defined length. If your application’s first call does not require initialization of the key buffer, assign the string variable the value SPACE$(x), where x represents the key’s defined length. Until your application assigns some value in BASIC to the string variable, it has a length of 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. Therefore, you must ensure that the buffer is at least as long as the key length you specified when you first created the key. Otherwise, Btrieve API operations may destroy data stored in memory following the key buffer. It is best to always have a 255-byte key buffer, because 255 is the maximum length for a key.
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.
Note Other information can be sent or returned in the key number parameter, such as a value indicating in what mode a file is to be opened.
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.
Table 2 Client ID Structure 
Element
Length (bytes)
Description
Filler
12
Initialize to 0.
Service Agent ID
2
Identifies each instance of your application to the MicroKernel Engine. This is a 2-character ASCII value. The value of this identifier must be greater than or equal to the ASCII value AA (0x41 0x41). The MicroKernel Engine assumes special meaning for the following values:
 
 
0x4140 (@A)
Used internally.
 
 
0xFFFF
Used internally.
 
 
0x4952 (RI)
Used internally.
 
 
0x5244 (DR)
Used internally.
 
 
0x4553 (SE)
0x4353 (SC)
0x4344 (DC)
0x4544 (DE)
0x5544 (DU)
Used to identify clients originated by Scalable SQL.
 
 
0x5257 (WR)
Used by Btrieve Requesters.
Client Identifier
2
Establishes a client’s identity within the current instance of your application. The MicroKernel Engine uses this unique identifier for concurrency and transaction-processing purposes.
Key Length
The Key Length parameter is used only in BTRCALL, BTRCALLID, BTRVEX, and BTRVEXID.
When using the two older functions, you must pass this parameter 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.
When using the newer BTRVEX and BTRVEXID, you must pass this parameter as an unsigned char of type BTI_INT. The maximum key length in PSQL v13 remains 255.
Summary of Btrieve API Operations
The Btrieve API provides over 40 operations that you can call from your application program. The following tables 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.
Table 3 Session-Specific Operations 
Operation
Code
Description
Stop
25
Terminates the workstation MicroKernel Engine (not available for server-based MicroKernel Engine).
Version
26
Returns the version number of the MicroKernel Engine.
Reset
28
Releases all resources held by a client.
Set Directory
17
Sets the current directory to a specified path name.
Get Directory
18
Returns the current directory for a specified logical disk drive.
Begin Transaction
19
1019
Marks the beginning of a set of logically related operations. Operation 19 begins an exclusive transaction. Operation 1019 begins a concurrent transaction.
End Transaction
20
Marks the end of a set of logically related operations.
Abort Transaction
21
Removes operations performed during an incomplete transaction.
Continuous Operation
42
Allows you to perform system backups without closing active MicroKernel Engine files.
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. These operations allow you to create a file, open and close a file, retrieve file statistics, set and clear the file owner name, start or stop continuous operation mode on a file, unlock a file, and create and drop indexes on a file.
Data retrieval. These operations allow you 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 information, read about accessing records in PSQL Programmer's Guide.
In addition, you can apply biases to the operation codes to control file and record locking in multi-client situations. For more information, read about supporting multiple clients in PSQL Programmer's Guide.
Data manipulation. These operations allow you to insert, update, or delete data.
 
Table 4 File Access and Information Operations 
Operation
Code
Description
Open
0
Makes a file available for access.
Close
1
Releases a file from availability.
Create
14
Creates a file with the specified characteristics.
Stat
15
Returns file and index characteristics, and number of records.
Continuous Operation
42
Allows you to perform system backups without closing active MicroKernel Engine files.
Stat Extended
65
Returns file names and paths of an extended file’s components and reports whether a file is using a system-defined log key.
Set Owner
29
Assigns an owner name to a file.
Clear Owner
30
Removes an owner name from a file.
Unlock
27
Unlocks a record or records.
Create Index
31
Creates an index.
Drop Index
32
Removes an index.
 
Table 5 Data Retrieval Operations 
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 current record’s position 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 current record’s position 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).
 
Table 6 Data Manipulation Operations 
Operation
Code
Description
Insert
2
Inserts a new record into a file.
Update
3
Updates the current record.
Delete
4
Removes the current record from the file.
Insert Extended
40
Inserts one or more records into a file.
Update Chunk
53
Updates specified portions (chunks) of the current record. This operation can also append data to a record or truncate a record.
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 PSQL and you should not use them in your applications. The following operations are not supported.
 
Table 7 Unsupported Operations 
Operation
Code
Description
B_MISC_DATA
41
Reserved for use by MicroKernel Engine
B_EXTEND
16
Reserved for use by SQL engine
Begin Transaction (nested) via Btrieve
2019
Reserved for use by MicroKernel Engine
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.
3 Call the appropriate Btrieve API function. (Refer to Btrieve API Functions.)
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.