Inserting and Updating Records
Most of the time, inserting and updating records is a simple process: you use the Insert operation (2) or the Update operation (3) and pass in the record using the Data Buffer. This section discusses some special cases involving inserts and updates.
Ensuring Reliability in Mission-Critical Inserts and Updates
While the MicroKernel is an extremely reliable data management engine, it cannot prevent system failures. System failures are more common in client/server applications, because network failures can occur. You can ensure reliability by taking advantage of these MicroKernel features:
Consider “wrapping” individual mission-critical insert and update operations inside Begin Transaction and End Transaction operations and using the MicroKernel’s Transaction Durability configuration option. For more information about the Begin Transaction and End Transaction operations, refer to the Btrieve API Guide. For more information about transaction durability, refer to Transaction Durability.
*Note: When you open a file in Accelerated mode, the MicroKernel does not perform transaction logging on the file. That is, operations performed on a file opened in Accelerated mode are not transaction durable.
If you set both the Operation Bundle Limit and Initiation Time Limit to 1, the MicroKernel commits each operation as a separate system transaction. Doing so decreases performance, so this method is useful only for applications that can accept a performance decrease. One way to determine this is to measure the CPU utilization while your application runs. Applications that utilize 50 to 100 percent of the CPU are not good candidates for this approach.
Inserting Non-Duplicatable Keys
If you are inserting a record with a key value that may already exist and for which you do not allow duplicates, you can proceed in one of two ways:
If your Insert operation stands alone and does not depend on logical currency in the file, executing a Get Equal prior to each Insert is an additional overhead. However, for a group of inserts, the Get Equal operation facilitates any subsequent Insert operations by fetching into memory the index pages that point to the key location.
Inserting and Updating Variable-Length Records
When designing a variable-length data file, you must decide the maximum size of the variable-length portion of the record your application will support. You should set up a record structure that accommodates the fixed-length portion plus the maximum size of the variable portion. Use this structure as the Data Buffer when reading, inserting, and updating your variable-length records.
When inserting or updating a variable-length record, you use the Data Buffer Length parameter to tell the MicroKernel how much data to write. Set this parameter to the size of the fixed-length portion plus the amount of real data in the variable portion. Do not set the Data Buffer Length to the fixed length plus the maximum size your application allows for the variable field; if you do, the MicroKernel will always write the maximum size.
For example, suppose you want to insert the following record.
Following are examples of Insert operations. Note that the Data Buffer Length is computed as the fixed-length portion plus the amount of data in the Comments field (8 bytes), not the maximum size of the Comments field (1,000 bytes).
Insert Operation
#define MAX_COMMENT 1000 /* Largest variable comment size */
typedef struct
{ char owner[30];
int number;
int balance;
} FixedData;
typedef struct
{ FixedData fix;
char variable[MAX_COMMENT];
} DataBuffer;
 
DataBuffer account;
BTI_ULONG dataBufLen;
BTI_SINT status;
strcpy(account.fix.owner, "John Q. Smith");
account.fix.number = 263512477;
account.fix.balance = 102438;
strcpy (account.variable, “Comments”);
dataBufLen = sizeof(FixedData) + strlen(account.variable) +1;
/* the +1 accommodates the null character after the data */
status = BTRV(B_INSERT, PosBlock, &account, &dataBufLen,
keyBuffer, 0);
 
Reading and Updating Fixed-length Portions
It is possible to read only the fixed-length portion of a record by setting the data buffer size to that fixed length. The MicroKernel returns only the fixed-length portion and Status Code 22. However, if you then use the Update operation and pass in only the fixed-length portion, the variable-length portion is lost. Instead, use the Update Chunk operation (53), which updates any part of a record, based on a byte offset and length. Set the byte offset to 0 and the length to the length of the fixed-length portion. This operation updates the fixed-length portion and retains the variable-length portion.
Updating Non-Modifiable Keys
If you attempt to update a key value that is defined as not modifiable, the MicroKernel returns Status Code 10. If you want to update the key value anyway, you must first Delete (4) the record and then Insert (2) it.
No-Currency-Change (NCC) Operations
You can perform a variation on the standard Insert or Update, called a no-currency-change (NCC) operation, by passing in a -1 (0xFF) for the Key Number parameter. NCC operations are useful when an application must save its original logical position in a file in order to perform another operation, such as a Get Next operation (6).
To achieve the same effect without an NCC Insert operation, you would have to execute these steps:
1
2
3
The NCC Insert operation has the same effect as a standard Insert in terms of logical currency, but can have a different effect in terms of physical currency. For example, executing a Get Next (6) operation after either procedure produces the same result, but executing a Step Next (24) might return different records.
To maintain original positioning without an NCC Update operation, you would have to execute these steps:
1
2
3
4
5
6
7
8
Get Direct/Record (23)—Establish the currencies to the record that preceded or followed the record updated in Step 7 If your application is to continue searching forward, you would pass to the Get Direct/Record operation the address saved in Step 2. If the application is to continue searching backward, you would pass the address saved in Step 5.