Scanning Records Using a Cursor (lkt_dbrecnext)

This function is used to retrieve all records, or a subset of records in a table.

int cursor_at_EOT(lpar_t next_pt);
int cursor_skipped_records(lpar_t next_pt);
dvkerr_t lkt_dbrecnext(lpar_t host, lpar_t dbname, lpar_t tran,
lpar_t start_pt,lpar_t params,
lpar_t *reclst, lpar_t *next_pt);

This function is useful whenever the records in a table must be scanned. This might be to perform some operation on each record, or to dump the contents of a table to another storage medium. It uses a cursor object to maintain the current position in the scan so that records can be fetched in a series of calls.

The number of records to be returned with each call can be specified. When scanning through a large number of records larger batch sizes are more efficient. You can specify that an initial number of records are to be skipped. This might be useful when resuming a partially completed scan.

The returned cursor position is valid only as long as no records are added or deleted from the table. The cursor position lpar returned in next_pt should be treated as an opaque item, the contents are subject to change.

The functions cursor_at_EOT and cursor_skipped_records are used to test for the end of the table being reached and to fetch the actual number of records that were skipped. The actual number of records skipped can be less than the requested number of records to skip if the table has fewer records than the requested skip count.

The following code example shows how to scan through all the records in a table skipping the first 300 records. A batch size of 100 records is used.

 

    lpar_t dbname = lpar_create_str(LPAR_STR_DBDESCRIPTOR, "table-name");
lpar_t params = lpar_create_lst(LPAR_LST_GENERIC);
int skip_count = 300 ;
lpar_t start_pt = LPAR_NULL ;
lpar_t reclist = LPAR_NULL ;
lpar_t next_pt = LPAR_NULL ;
dvkerr_t err ;
/* Create the initial params setting */
lpar_append_lst(params, lpar_create_int(LPAR_INT_BATCHSIZE, 100));
lpar_append_lst(params, lpar_create_int(LPAR_INT_SKIPCOUNT, skip_count));
/* Get first batch */
err = lkt_dbrecnext( LPAR_NULL, /* local process */
dbname, /* Our table name*/
LPAR_NULL, /* Transactions always NULL */
start_pt, /* start_pt is NULL for first call */
params, /* parameters with initial skip count */
&reclist, /* records returned in here */
&next_pt); /* next batch location returned in here */
if (DVKERR(err)) {
fprintf(stderr, "First call failed: %d (%s)\n",
DVKERR(err), dvkerr_get_string(err));
/* clean up and return error */
dvkerr_clear(err);
if (start_pt != LPAR_NULL) { lpar_destroy(start_pt) ; }
if (next_pt != LPAR_NULL) { lpar_destroy(next_pt) ; }
if (params != LPAR_NULL) { lpar_destroy(params) ; }
if (reclist != LPAR_NULL) { lpar_destroy(reclist) ; }
lpar_destroy(dbname) ;
/* return error here */
}
dvkerr_clear(err);
/* process initial batch of records */
process_record_list(reclist);
/* clean up the records */
if (reclist != LPAR_NULL) {
lpar_destroy(reclist) ;
reclist = LPAR_NULL ;
}
/* retrieve more records until cursor hits EOT */
while ( ! cursor_at_EOT(next_pt) ) {
/* reset skip count if we skipped records on previous batch */
if (skip_count > 0) {
skip_count -= cursor_skipped_records(next_pt);
/* recreate parameters with new skip count */
lpar_destroy(params);
params = lpar_create_lst(LPAR_LST_GENERIC);
lpar_append_lst(params,
lpar_create_int(LPAR_INT_BATCHSIZE,100));
if (skip_count > 0) {
lpar_append_list(params,
lpar_create_int(LPAR_INT_SKIPCOUNT,
skip_count));
}
}
/* Set start point to previous call's next_pt */
if (start_pt != LPAR_NULL) {
/* must destroy old start point! */
lpar_destroy(start_pt) ;
}
start_pt = next_pt ;
next_pt = LPAR_NULL ;
/* Following batches use next_pt as starting point */
err = lkt_dbrecnext(LPAR_NULL, /* local process */
dbname, /* our table name*/
LPAR_NULL, /* transactions always NULL */
start_pt, /* now the previous next point */
params, /* params with skip count updated */
&reclist, /* records returned in here */
&next_pt); /* next batch location returned here */
if (DVKERR(err)) {
fprintf(stderr, "Next call failed: %d (%s)\n",
DVKERR(err), dvkerr_get_string(err));
/* clean up and return error */
dvkerr_clear(err);
if (start_pt != LPAR_NULL) { lpar_destroy(start_pt) ; }
if (next_pt != LPAR_NULL) { lpar_destroy(next_pt) ; }
if (params != LPAR_NULL) { lpar_destroy(params) ; }
if (reclist != LPAR_NULL) { lpar_destroy(reclist) ; }
lpar_destroy(dbname) ;
/* return error here */
}
dvkerr_clear(err);
/* process the records from this batch */
process_record_list(reclist);
/* clean up the processed record list */
if (reclist != LPAR_NULL) {
lpar_destroy(reclist);
}
}
/* clean up */
if (start_pt != LPAR_NULL) { lpar_destroy(start_pt) ; }
if (next_pt != LPAR_NULL) { lpar_destroy(next_pt) ; }
if (params != LPAR_NULL) { lpar_destroy(params) ; }
if (reclist != LPAR_NULL) { lpar_destroy(reclist) ; }
lpar_destroy(dbname) ;
/* return success */

Input

host (optional)

This is used to identify the server. For more information, see Communicating with TIBCO Patterns Servers

name (required)

is the name of the database (LPAR_STR_DBDESCRIPTOR) to be scanned.

tran

this must always be LPAR_NULL. It is a place holder for potential future functionality.

start_pt

This is either LPAR_NULL, or the next_pt value returned by a previous call. Remember to clean up this value before resetting it.

params (optional)

This might be LPAR_INT_BATCHSIZE, LPAR_INT_SKIPCOUNT or a generic list containing one or both of these values.

LPAR_INT_BATCHSIZE
This specifies the number of records to be returned. The actual number of records returned might be fewer if the end of the table is reached.
Default value: 1
LPAR_INT_SKIPCOUNT
This specifies the number of records to be skipped, starting at start_pt. This effectively sets the starting cursor position to the SKIPCOUNT record position after start_pt.
Default value: 0.

Output

reclist (required)

is a generic list of records. If the cursor position was at the end of the table this is set to LPAR_NULL.

next_pt (required)

is an opaque cursor position value. It is set to the next record in the table after the last record in reclist. If there are no more records in the table, the call cursort_at_EOT(next_pt) returns true. If params contained LPAR_INT_SKIPCOUNT with a value greater than zero, this also contains the actual number of records skipped. This can be retrieved using the function: cursor_skipped_records(next_pt).

Error codes and items returned by lkt_dbrecnext

NOSYSINIT

(LPAR_NULL) Devkit was not initialized

PARAMTYPE

(dbname) invalid lpar type for dbname

NODBDESC

(LPAR_NULL) dbname value was null