11.6.1.4.4. RowChangeData Objects

RowChangeData is information that has been written into the THL in row format, and therefore consists of rows of individual data divided into the individual columns that make up each row-based change. Processing of these individual changes must be performed one row at a time using the list of OneRowChange objects provided.

The following methods are supported for the RowChangeData object:

Method Description
appendOneRowChange(rowChange) Appends a single row change to the event, using the supplied OneRowChange object.
getRowChanges() Returns an array list of all the changes as OneRowChange objects.
setRowChanges(rowChanges) Sets the row changes within the event using the supplied list of OneRowChange objects.

For example, a typical row-based process will operate as follows:

if (d != null && d instanceof com.continuent.tungsten.replicator.dbms.RowChangeData)
 {
   rowChanges = d.getRowChanges();

   for(j = 0; j < rowChanges.size(); j++)
   {
     oneRowChange = rowChanges.get(j);
     // Do row filter

The OneRowChange object contains the changes for just one row within the event. The class contains the information about the tables, field names and field values. The following methods are supported:

Method Description
getAction() Returns the row action type, i.e. whether the row change is an INSERT, UPDATE or DELETE
getColumnSpec() Returns the specification of each column within the row change
getColumnValues() Returns the value of each column within the row change
getSchemaName() Gets the schema name of the row change
getTableName() Gets the table name of the row change
setColumnSpec() Sets the column specification using an array of column specifications
setColumnValues() Sets the column values
setSchemaName() Sets the schema name
setTableName() Sets the table name

Changing Schema or Table Names

The schema, table and column names are exposed at different levels within the OneRowChange object. Updating the schema name can be achieved by getting and setting the name through the getSchemaName() and setSchemaName() methods. For example, to add a prefix to a schema name:

rowchange.setSchemaName('prefix_' + rowchange.getSchemaName());

To update a table name, the getTableName() and setTableName() can be used in the same manner:

oneRowChange.setTableName('prefix_' + oneRowChange.getTableName());

Getting Action Types

Row operations are categorised according to the action of the row change, i.e. whether the change was an insert, update or delete operation. This information can be extracted from each row change by using the getAction() method:

action = oneRowChange.getAction();

The action information is returned as a string, i.e. INSERT, UPDATE, or DELETE. This enables information to be filtered according to the changes; for example by selectively modifying or altering events.

For example, DELETE events could be removed from the list of row changes:

for(j=0;j<rowChanges.size();j++)
{
  oneRowChange = rowChanges.get(j);
  if (oneRowChange.actionType == 'DELETE')
  {
    rowChanges.remove(j);
    j--;
  }
}

The j-- is required because as each row change is removed, the size of the array changes and our current index within the array needs to be explicitly modified.

Extracting Column Definitions

To extract the row data, the getColumnValues() method returns the an array containing the value of each column in the row change. Obtaining the column specification information using getColumnSpec() returns a corresponding specification of each corresponding column. The column data can be used to obtain the column type information

To change column names or values, first the column information should be identified. The column information in each row change should be retrieved and/or updated. The getColumnSpec() returns the column specification of the row change. The information is returned as an array of the individual columns and their specification:

columns = oneRowChange.getColumnSpec();

For each column specification a ColumnSpec object is returned, which supports the following methods:

Method Description
getIndex() Gets the index of the column within the row change
getLength() Gets the length of the column
getName() Returns the column name if available
getType() Gets the type number of the column
getTypeDescription()  
isBlob() Returns true if the column is a blob
isNotNull() Returns true if the column is configured as NOT NULL
isUnsigned() Returns true if the column is unsigned.
setBlob() Set the column blob specification
setIndex() Set the column index order
setLength() Returns the column length
setName() Set the column name
setNotNull() Set whether the column is configured as NOT NULL
setSigned() Set whether the column data is signed
setType() Set the column type
setTypeDescription() Set the column type description

To identify the column type, use the getType() method which returns an integer matching the underlying data type. There are no predefined types, but common values include:

Type Value Notes
INT 4  
CHAR or VARCHAR 12  
TEXT or BLOB 2004 Use isBlob() to identify if the column is a blob or not
TIME 92  
DATE 91  
DATETIME or TIMESTAMP 92  
DOUBLE 8  

Other information about the column, such as the length, and value types (unsigned, null, etc.) can be determined using the other functions against the column specification.

Extracting Row Data

The getColumnValues() method returns an array that corresponds to the information returned by the getColumnSpec() method. That is, the method returns a complementary array of the row change values, one element for each row, where each row is itself a further array of each column:

values = oneRowChange.getColumnValues();

This means that index 0 of the array from getColumnSpec() refers to the same column as index 0 of the array for a single row from getColumnValues().

getColumnSpec() msgid message msgdate
getColumnValues()    
[0] 1 Hello New York! Thursday, June 13, 2013
[1] 2 Hello San Francisco! Thursday, June 13, 2013
[2] 3 Hello Chicago! Thursday, June 13, 2013

This enables the script to identify the column type by the index, and then the corresponding value update using the same index. In the above example, the message field will always be index 1 within the corresponding values.

Each value object supports the following methods:

Method Description
getValue() Get the current column value
setValue() Set the column value to the supplied value
setValueNull() Set the column value to NULL

For example, within the zerodate2null sample, dates with a zero value are set to NULL using the following code:

columns = oneRowChange.getColumnSpec();
columnValues = oneRowChange.getColumnValues();
for (c = 0; c < columns.size(); c++)
{
  columnSpec = columns.get(c);
  type = columnSpec.getType();

  if (type == TypesDATE || type == TypesTIMESTAMP)
  {
    for (row = 0; row < columnValues.size(); row++)
    {
      values = columnValues.get(row);
      value = values.get(c);

      if (value.getValue() == 0)
      {
        value.setValueNull()
      }
    }
  }
}

In the above example, the column specification is retrieved to determine which columns are date types. Then the list of embedded row values is extracted, and iterates over each row, setting the value for a date that is zero (0) to be NULL using the setValueNull() method.

An alternative would be to update to an explicit value using the setValue() method.