Creating cursors

For your operators to process an input data set and write results to an output data set, you need a mechanism for accessing the records and record fields that make up a data set. Three mechanisms work together for accessing the records and record fields of a data set: cursors, subcursors, and field accessors.

Cursors allow you to reference specific records in a data set, and field accessors let you access the individual fields in those records. You use cursors and field accessors from within your override of the APT_Operator::runLocally() function. You use subcursors only with vectors of subrecords. A subcursor allows you to identify the current element of the vector.

You use two types of cursors with data sets: input cursors and output cursors. Input cursors provide read-only access to the records of an input data set; output cursors provide read/write access to the current record of an output data set.

To process an input data set, you initialize the input cursor to point to the current input record. The cursor advances through the records until all have been processed. Once a cursor has moved beyond a record of an input data set, that record can no longer be accessed.

For the output data set, the output cursor initially points to the current output record and advances through the rest of the records. As with input data sets, once a cursor has moved beyond a record of an output data set, that record can no longer be accessed.

The following figure shows an operator with a single input and a single output data set:

Figure 1. Single input and output data setSingle input and output data set
The following classes represent cursors:
  • APT_InputCursor defines a cursor for an input data set.
  • APT_OutputCursor defines a cursor for an output data set.
When you create an input cursor, it does not reference a record. You must call APT_InputCursor::getRecord() from within runLocally() to initialize the cursor to point to a specific record. When you have finished processing that record, you again call APT_InputCursor::getRecord() to advance the cursor to the next record in the input data set, making it the current input record. When no more input records are available, APT_InputCursor::getRecord() returns false. Typically, you use a while loop to determine when APT_InputCursor::getRecord() returns false.

When you create an output cursor, it references the first record in the output data set.

The record output fields are set to the following default values:
  • Nullable fields are set to null.
  • Integers = 0.
  • Floats = 0.
  • Dates = January 1, 0001.
  • Decimals = 0.
  • Times = 00:00:00 (midnight).
  • Timestamps = 00:00:00 (midnight) on January 1, 0001.
  • The length of variable-length string and raw fields is set to 0.
  • The characters of a fixed-length string are set to null (0x00) or to the pad character, if specified.
  • The bytes of fixed-length raw fields are set to zero.
  • The tag of a tagged aggregate is set to 0 to set the data type to be that of the first field of the tagged aggregate.
  • The length of variable-length vector fields is set to 0.
After you write to that output record, you must call APT_OutputCursor::putRecord() to advance the cursor to the next record in the output data set, making it the current output record.
The following table shows an example of a while loop that processes the records of a single input data set and writes its results to a single output data set. You would place this loop, along with the code to define and initialize the cursors, within the override of the runLocally() function.
Table 1. Example of while loop
Comments Code
APT_Status AddOperator::runLocally()
{
3
	APT_InputCursor inCur;
4
	APT_OutputCursor outCur;
5
	setupInputCursor(&inCur, 0);
6
	setupOutputCursor(&outCur, 0);
7
	while (inCur.getRecord()) 
	
  
9
	{
		// body of the loop

		outCur.putRecord(); 
	} 
10
	return APT_StatusOk; 

}
3
Define inCur, an instance of APT_InputCursor, as the input cursor for the first data set input to this operator.
4
Define outCur, an instance of APT_OutputCursor, as the output cursor for the first data set output by this operator.
5
Use APT_Operator::setupInputCursor() to initialize inCur. Input data sets are numbered starting from 0.
6
Use APT_Operator::setupOutputCursor() to initialize outCur. Output data sets are numbered starting from 0.
7
Use APT_InputCursor::getRecord() to advance the input cursor to the next input record. You must call this function before attempting to process an input record because an input cursor does not initially reference a valid record. APT_InputCursor::getRecord() returns false when there are no more records in the input data set, terminating the while loop.
9
Process the record. Processing includes writing any results to the current output record. Do not call APT_OutputCursor::putRecord() until after you have written to the first output record (unless you want default values), because the output cursor initially points to the first empty record in an output data set.
10
Use APT_OutputCursor::putRecord() to update the current output record, then advance the output cursor to the next output record.

Not all operators produce an output record for each input record. Also, operators can produce more output records than there are input records. An operator can process many input records before computing a single output record. You call putRecord() only when you have completed processing an output record, regardless of the number of input records you process between calls to putRecord().