There are situations where a record fetch, a record insert, or a record delete operation has to be applied to a group of related records. For example, if an invoice record is being displayed, it may be necessary to retrieve all invoice items for that invoice as well. The following code fragment shows a typical c-treeDB API C function to extract all items of an invoice, given the invoice number.
c-treeDB API C API Example
void GetInvoiceItems(CTHANDLE hRecord, NINT Invoice)
{
NINT count = 0;
TEXT target[32];
VRLEN len = sizeof(target);
/* find the first record that match the Invoice */
ctdbClearRecord(hRecord);
ctdbSetFieldAsSigned(hRecord, 0, Invoice);
if (ctdbFindRecord(hRecord, CTFIND_GE) == CTDBRET_OK)
{
LONG val;
/* make sure all record invoice numbers match */
ctdbGetFieldAsSigned(hRecord, 0, &val);
while (val == (LONG)Invoice)
{
val = -1;
count++;
if (ctdbNextRecord(hRecord) == CTDBRET)OK)
ctdbGetFieldAsSigned(hRecord, 0, &val);
}
}
printf("%d records found\n", count);
}
The code fragment above shows how easy it is to use c-treeDB API functionality to retrieve a number of related records from a table. A close inspection of the code reveals that while it is simple to implement, it does have a hidden issue that may affect the overall performance of the system, specially when running in client/server mode: for every record that is fetched, the client must place a request to the server, which must travel the network, the c-tree Server must interpret the client request, perform the record retrieval operation and return the record to the client, again traveling across the network.
It is obvious the operation described above would be more efficient if we could, in just one call, request the c-tree Server to perform a given operation on a group of related records, and return all the resulting records, or as many records as possible, in one client request.
The ability of perform record retrievals, insert or delete operations on a group of related records is implemented under c-treeDB API as record batch operations. The same code fragment above implemented with c-treeDB API C API batch record facility would look as follows:
c-treeDB API C API Batch Example
void GetInvoiceItems(CTHANDLE hRecord, NINT Invoice)
{
NINT count = 0;
/* set the partial target key */
ctdbClearRecord(hRecord);
ctdbSetFieldAsSigned(hRecord, 0, Invoice);
/* set the batch operation */
if (ctdbSetBatch(hRecord, CTBATCH_GET, sizeof(Invoice), 0) == CTDBRET_OK)
{
/* retrieve records */
while (ctdbNextBatch(hRecord) == CTDBRET_OK)
count++;
/* terminate batch operations */
ctdbEndBatch(hRecord);
}
printf("%d records found\n", count);
}
The code fragment above is even simpler than the initial example, and it also performs far fewer c-tree Server calls to perform the operations. c-treeDB API batch record functionality is implemented on top of c-tree ISAM batch operations.