TableRow.h

Classes

ROTableRow -- Readonly access to a table row (full description)
TableRow -- Read/write access to a table row (full description)

class ROTableRow

Interface

Public Members
ROTableRow()
explicit ROTableRow (const Table& table, Bool storedColumnsOnly = True)
ROTableRow (const Table& table, const Vector<String>& columnNames, Bool exclude = False)
ROTableRow (const ROTableRow&)
~ROTableRow()
ROTableRow& operator= (const ROTableRow&)
Bool isAttached() const
const Table& table() const
const TableRecord& record() const
Int rowNumber() const
Vector<String> columnNames() const
const TableRecord& get (uInt rownr, Bool alwaysRead = False) const
Protected Members
void copy (const ROTableRow& that, Bool writable)
void create (const Table& table, Bool storedColumnsOnly, Bool writable)
void create (const Table& table, const Vector<String>& columnNames, Bool exclude, Bool writable)
void putRecord (uInt rownr)
void putField (uInt rownr, const TableRecord& record, Int whichColumn, Int whichField)
void setReread (uInt rownr)
Private Members
void init()
void makeDescExclude (RecordDesc& description, const Vector<String>& columnNames, Bool writable)
void addColumnToDesc (RecordDesc& description, const ROTableColumn& column, Bool skipOther)
void makeObjects (const RecordDesc& description, Bool writable)
void deleteObjects()

Description

Review Status

Reviewed By:
Paul Shannon
Date Reviewed:
1996/05/10
Programs:
Tests:

Prerequisite

Synopsis

This class provides easy access to the contents of a table, one row at a time. 'Normal' access to a table is by columns, each of which contains values of the same type. A table row, by contrast, will be a collection of heterogeneous data, similar to a C struct. For this reason, the TableRow classes (ROTableRow and TableRow) are built around and provide access to the class TableRecord . The TableRow delegates much of its behaviour to the TableRecord class. For example:
   Table table ("some.table");
   ROTableRow row (table);                 // construct TableRow object
   cout << row.record().description();     // show its description
   // Get the values in row 17.
   const TableRecord& record = row.get (17);
   // column name is "Title", and automatically becomes the record
   // key for this field of the record:
   String row17title = record.asString ("Title");  
   Int    row17count = record.asInt ("Count");
The simplest constructor will include all columns in the TableRow object (although columns with a non-standard data type will be excluded, because they cannot be represented in a TableRecord). However, it is possible to be more selective and to include only some columns in the TableRow object. The various constructors show how this can be done.

It is possible to have multiple TableRow objects for the same table. They can contain different columns or they can share columns.

On construction an internal TableRecord object is created containing the required fields. The contents of this record will be changed with each get call, but the structure of it is fixed. This means that RORecordFieldPtr objects can be constructed once and used many times. This results in potentially faster access to the record, because it avoids unnecessary name lookups.

Example

    // Open the table as readonly and define a row object containing
    // the given columns.
    // Note that the function stringToVector is a very convenient
    // way to construct a Vector<String>.
    // Show the description of the fields in the row.
    Table table("Some.table");
    ROTableRow row (table, stringToVector("col1,col2,col3"));
    cout << row.record().description();
    // Loop through all rows and get their values.
    for (uInt i=0; i<table.nrow(); i++) {
        const TableRecord& values = row.get (i);
        someString = values.asString ("col1");
        somedouble = values.asdouble ("col2");
        someArrayInt = values.asArrayInt ("col3");
    }
    
    // Provided the structure of the record is known, the RecordFieldPtr
    // objects could be used as follows.
    // This is faster than the previous method, because it avoids a name
    // lookup for each iteration.
    RORecordFieldPtr<String> col1(row.record(), "col1");
    RORecordFieldPtr<double> col2(row.record(), "col2");
    RORecordFieldPtr<Array<Int> > col3(row.record(), "col3");
    for (uInt i=0; i<table.nrow(); i++) {
        row.get (i);
        someString = *col1;
        somedouble = *col2;
        someArrayInt = *col3;
    }
    
Please note that the TableRecord& returned by the get() function is the same as returned by the record() function. Therefore the RORecordField objects can be created in advance.

Member Description

ROTableRow()

Create a detached ROTableRow object. This means that no Table, etc. is contained in it. Function isAttached will return False for it.
This constructor should normally not be used, because it does not result in a valid object. It should only be used when really needed (e.g. when an array of objects has to be used).

explicit ROTableRow (const Table& table, Bool storedColumnsOnly = True)

Create a ROTableRow object for the given Table. Its TableRecord will contain all columns except columns with datatype TpOther (i.e. non-standard data types).
When the flag storedColumnsOnly is True, only the columns actually stored by a storage manager will be selected. This is useful when the contents of an entire row has to be copied. Virtual columns are calculated on-the-fly (often using stored columns), thus it makes no sense to copy their data.

Caution When the table contains columns with large arrays, it may be better not to use this constructor. Each get will read in all data in the row, thus also the large data array(s). In that case it is better to use the constructor which includes selected columns only.

ROTableRow (const Table& table, const Vector<String>& columnNames, Bool exclude = False)

Create a ROTableRow object for the given Table. Its TableRecord will contain all columns given in the Vector. An exception is thrown if an unknown column name is given.
When exclude=True, all columns except the given columns are taken. In that case an unknown name does not result in an exception.

ROTableRow (const ROTableRow&)

Copy constructor (copy semantics).

~ROTableRow()

ROTableRow& operator= (const ROTableRow&)

Assignment (copy semantics).

Bool isAttached() const

Test if a Table is attached to this object.

const Table& table() const

Get the Table used for this object.

const TableRecord& record() const

Get the record containing all fields.

Int rowNumber() const

Get the number of the last row read. -1 is returned when no Table is attached or no row has been read yet.

Vector<String> columnNames() const

Get a vector consisting of all columns names. This can, for instance, be used to construct a TableRow object with the same columns in another table.

const TableRecord& get (uInt rownr, Bool alwaysRead = False) const

Get the values of all columns used from the given row. When the given row number equals the current one, nothing will be read unless the alwaysRead flag is set to True.
The TableRecord& returned is the same one as returned by the record() function. So one can ignore the return value of get().

void copy (const ROTableRow& that, Bool writable)

Copy that object to this object. The writable flag determines if writable or readonly TableColumn objects will be created.

void create (const Table& table, Bool storedColumnsOnly, Bool writable)

Create the record, column, and field objects for all columns in the table. The writable flag determines if writable or readonly TableColumn objects will be created.

void create (const Table& table, const Vector<String>& columnNames, Bool exclude, Bool writable)

Create the record, column, and field objects for the given columns. The writable flag determines if writable or readonly TableColumn objects will be created.

void putRecord (uInt rownr)

Put the values found in the internal TableRecord at the given row. This is a helper function for class TableRow.

void putField (uInt rownr, const TableRecord& record, Int whichColumn, Int whichField)

Put a value in the given field in the TableRecord into the given row and column. This is a helper function for class TableRow.

void setReread (uInt rownr)

Set the switch to reread when the current row has been put.

void init()

Initialize the object.

void makeDescExclude (RecordDesc& description, const Vector<String>& columnNames, Bool writable)

Make a RecordDesc from the table with some excluded column names.

void addColumnToDesc (RecordDesc& description, const ROTableColumn& column, Bool skipOther)

Add a column to the record. When skipOther is True, columns with a non-standard data type will be silently skipped.

void makeObjects (const RecordDesc& description, Bool writable)

Make the required objects. These are the TableRecord and for each column a TableColumn and RecordFieldPtr.

void deleteObjects()

Delete all objects.


class TableRow : public ROTableRow

Interface

Public Members
TableRow()
explicit TableRow (const Table& table, Bool storedColumnsOnly = True)
TableRow (const Table& table, const Vector<String>& columnNames, Bool exclude = False)
TableRow (const TableRow&)
~TableRow()
TableRow& operator= (const TableRow&)
TableRecord& record()
void put()
void put (uInt rownr)
void put (uInt rownr, const TableRecord& record, Bool checkConformance = True)
void putMatchingFields (uInt rownr, const TableRecord& record)
Private Members
Bool namesConform (const TableRecord& that) const

Description

Review Status

Reviewed By:
Paul Shannon
Date Reviewed:
1995/05/10
Programs:
Tests:
  • tTableRow.cc

Prerequisite

Synopsis

The class TableRow is derived from ROTableRow and as an extra it provides write-access to a row in a table. With the put function, all values in the TableRecord object will be put in the corresponding columns in the table row. There is, however, an extra consideration: There are effectively 3 ways of writing data.
  1. The function
              put (rownr, tableRecord);
    
    can be used to put all values from the given TableRecord, which has to be conforming (i.e. matching order and names). Optionally the conformance is checked. This put function is capable of data type promotion. For instance, if column COL1 is float, the corresponding field in the TableRecord can be Int.
  2. A faster way is using the functions record and put. It is possible to use RecordFieldPtr objects to get direct access to the fields in the record (provided the structure of the record is known). E.g.
             TableRow row (someTable, stringToVector("col1,col2,col3"));
             RecordFieldPtr<String> col1(row.record(), "col1");
             RecordFieldPtr<double> col2(row.record(), "col2");
             RecordFieldPtr<Array<Int> > col3(row.record(), "col3");
             for (uInt i=0; i<n; i++) {
                 *col1 = someString;
                 *col2 = somedouble;
                 *col3 = someArrayInt;
                 row.put (i);
             }
    
  3. The function
              putMatchingFields (rownr, tableRecord);
    
    can be used to put some fields from the given TableRecord. Only fields having a corresponding name in the TableRow object will be put. Similar to the first way data type promotion will be applied for numeric scalars.
    E.g.: Suppose the TableRow object has columns A, C, and B, and the given TableRecord has fields B, D, and C. Only fields B and C will be put. As the example shows, the order of the fields is not important.
    This way is (much) slower than the other 2, because a name lookup is involved for each field. It can, however, be more convenient to use.

Example

    // Open the new table (with 10 rows) and define a row object containing
    // values from the given column.
    // Note that the function stringToVector is a very convenient
    // way to construct a Vector<String>.
    SetupNewTable newtab(tableDesc, Table::new);
    Table table(newtab, 10);
    TableRow row (table, stringToVector("col1,col2,col3,col4"));
    // Loop through all rows and get their values.
    for (uInt i=0; i<table.nrow(); i++) {
        // Some magic filler function returns a filled TableRecord
        // (with the correct fields in the correct order).
        TableRecord record = fillerFunction();
        row.put (i, record);
    }
    

Member Description

TableRow()

Create a detached TableRow object. This means that no Table, etc. is contained in it. Function isAttached (in the base class) will return False for it.
This constructor should normally not be used, because it does not result in a valid object. It should only be used when really needed (e.g. when an array of objects has to be used).

explicit TableRow (const Table& table, Bool storedColumnsOnly = True)

Create a TableRow object for the given Table. Its TableRecord will contain all columns except columns with datatype TpOther and columns which are not writable.
When the flag storedColumnsOnly is True, only the columns actually stored by a storage manager will be selected. This is useful when the contents of an entire row has to be copied. Virtual columns are calculated on-the-fly (often using stored columns), thus it makes no sense to copy their data.

Caution When the table contains columns with large arrays, it may be better not to use this constructor. Each get will read in all data in the row, thus also the large data array(s). In that case it is better to use the next constructor which works selectively.

TableRow (const Table& table, const Vector<String>& columnNames, Bool exclude = False)

Create a TableRow object for the given Table. Its TableRecord will contain all columns given in the Vector. An exception is thrown if an unknown column name is given or if a column is given which is not writable.
When exclude=True, all columns except the given columns are taken. In that case an unknown name does not result in an exception and non-writable columns are simply skipped.

TableRow (const TableRow&)

Copy constructor (copy semantics).

~TableRow()

TableRow& operator= (const TableRow&)

Assignment (copy semantics).

TableRecord& record()

Get non-const access to the TableRecord in this object. This can be used to change values in it which can thereafter be put using the function put(rownr). The returned TableRecord has a fixed structure, so it is not possible to add or remove fields. It is only possible to change values.

void put()

Put into the last row read. An exception is thrown if no row has been read yet. The values in the TableRecord contained in this object are put. This TableRecord can be accessed and updated using the function record.

void put (uInt rownr)

Put into the given row. The values in the TableRecord contained in this object are put. This TableRecord can be accessed and updated using the function record.

void put (uInt rownr, const TableRecord& record, Bool checkConformance = True)

Put the values found in the TableRecord in the appropriate columns in the given row. The names and order of the fields in the TableRecord must conform those of the description of the TableRow. The data types of numeric scalars do not need to conform exactly; they can be promoted (e.g. an Int value in the record may correspond to a float column). If not conforming, an exception is thrown. For performance reasons it is optional to check the name order conformance.

void putMatchingFields (uInt rownr, const TableRecord& record)

Put the values found in the TableRecord. Only fields with a matching name in the TableRow object will be put. This makes it possible to put fields in a selective way.
E.g.: If the TableRow contains columns A and B, and the record contains fields B and C, only field B will be put.
In principle the data types of the matching fields must match, but data type promotion of numeric scalars will be applied.

Bool namesConform (const TableRecord& that) const

Check if the names of the given record match this row.