casacore
Loading...
Searching...
No Matches
TableRow.h
Go to the documentation of this file.
1// # TableRow.h: Access to a table row
2// # Copyright (C) 1996,1999,2001
3// # Associated Universities, Inc. Washington DC, USA.
4// #
5// # This library is free software; you can redistribute it and/or modify it
6// # under the terms of the GNU Library General Public License as published by
7// # the Free Software Foundation; either version 2 of the License, or (at your
8// # option) any later version.
9// #
10// # This library is distributed in the hope that it will be useful, but WITHOUT
11// # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12// # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13// # License for more details.
14// #
15// # You should have received a copy of the GNU Library General Public License
16// # along with this library; if not, write to the Free Software Foundation,
17// # Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18// #
19// # Correspondence concerning AIPS++ should be addressed as follows:
20// # Internet email: casa-feedback@nrao.edu.
21// # Postal address: AIPS++ Project Office
22// # National Radio Astronomy Observatory
23// # 520 Edgemont Road
24// # Charlottesville, VA 22903-2475 USA
25
26#ifndef TABLES_TABLEROW_H
27#define TABLES_TABLEROW_H
28
29// # Includes
30#include <casacore/casa/aips.h>
31#include <casacore/tables/Tables/Table.h>
32#include <casacore/tables/Tables/TableRecord.h>
33#include <casacore/casa/Containers/Block.h>
34#include <casacore/casa/BasicSL/String.h>
35#include <casacore/casa/Arrays/ArrayFwd.h>
36
37namespace casacore { // # NAMESPACE CASACORE - BEGIN
38
39// # Forward Declarations
40class TableColumn;
41
42// <summary>
43// Readonly access to a table row
44// </summary>
45
46// <use visibility=export>
47
48// <reviewed reviewer="Paul Shannon" date="1996/05/10" tests="tTableRow.cc">
49// </reviewed>
50
51// <prerequisite>
52// <li> <linkto class=Table>Table</linkto>
53// <li> <linkto class=TableRecord>TableRecord</linkto>
54// </prerequisite>
55
56// <synopsis>
57// This class provides easy access to the contents of a table,
58// one row at a time. 'Normal' access to a table is by columns, each of
59// which contains values of the same type.
60// A table row, by contrast, will be a collection
61// of heterogeneous data, similar to a C struct. For
62// this reason, the TableRow classes (ROTableRow and TableRow) are built
63// around and provide access to the class
64// <linkto class=TableRecord> TableRecord </linkto>.
65// The TableRow delegates much of its behaviour to the TableRecord class.
66// For example:
67// <srcblock>
68// Table table ("some.table");
69// ROTableRow row (table); // construct TableRow object
70// cout << row.record().description(); // show its description
71// // Get the values in row 17.
72// const TableRecord& record = row.get (17);
73// // column name is "Title", and automatically becomes the record
74// // key for this field of the record:
75// String row17title = record.asString ("Title");
76// Int row17count = record.asInt ("Count");
77// </srcblock>
78// The simplest constructor will include all columns in the TableRow object
79// (although columns with a non-standard data type will be excluded,
80// because they cannot be represented in a TableRecord).
81// However, it is possible to be more selective and to include only
82// some columns in the TableRow object. The various constructors show
83// how this can be done.
84// <p>
85// It is possible to have multiple TableRow objects for the same table.
86// They can contain different columns or they can share columns.
87//
88// <p>
89// On construction an internal <linkto class=TableRecord>TableRecord</linkto>
90// object is created containing the required fields. The contents of this
91// record will be changed with each get call, but the structure of it is
92// fixed. This means that <linkto class=RORecordFieldPtr>RORecordFieldPtr
93// </linkto> objects can be constructed once and used many times.
94// This results in potentially faster access to the record, because it avoids
95// unnecessary name lookups.
96// </synopsis>
97
98// <example>
99// <srcblock>
100// // Open the table as readonly and define a row object containing
101// // the given columns.
102// // Note that the function stringToVector is a very convenient
103// // way to construct a Vector<String>.
104// // Show the description of the fields in the row.
105// Table table("Some.table");
106// ROTableRow row (table, stringToVector("col1,col2,col3"));
107// cout << row.record().description();
108// // Loop through all rows and get their values.
109// for (rownr_t i=0; i<table.nrow(); i++) {
110// const TableRecord& values = row.get (i);
111// someString = values.asString ("col1");
112// somedouble = values.asdouble ("col2");
113// someArrayInt = values.asArrayInt ("col3");
114// }
115//
116// // Provided the structure of the record is known, the RecordFieldPtr
117// // objects could be used as follows.
118// // This is faster than the previous method, because it avoids a name
119// // lookup for each iteration.
120// RORecordFieldPtr<String> col1(row.record(), "col1");
121// RORecordFieldPtr<double> col2(row.record(), "col2");
122// RORecordFieldPtr<Array<Int> > col3(row.record(), "col3");
123// for (rownr_t i=0; i<table.nrow(); i++) {
124// row.get (i);
125// someString = *col1;
126// somedouble = *col2;
127// someArrayInt = *col3;
128// }
129// </srcblock>
130// Please note that the TableRecord& returned by the get() function is the
131// same as returned by the record() function. Therefore the RORecordField
132// objects can be created in advance.
133// </example>
134
136 public:
137 // Create a detached ROTableRow object.
138 // This means that no Table, etc. is contained in it.
139 // Function isAttached will return False for it.
140 // <br>
141 // This constructor should normally not be used, because it does not
142 // result in a valid object. It should only be used when really needed
143 // (e.g. when an array of objects has to be used).
145
146 // Create a ROTableRow object for the given Table.
147 // Its TableRecord will contain all columns except columns with
148 // datatype TpOther (i.e. non-standard data types).
149 // <br>
150 // If the flag <src>storedColumnsOnly</src> is True, only the
151 // columns actually stored by a storage manager will be selected.
152 // This is useful when the contents of an entire row have to be copied.
153 // Virtual columns are calculated on-the-fly (often using stored columns),
154 // thus it makes no sense to copy their data.
155 // <note role=caution>
156 // If the table contains columns with large arrays, it may
157 // be better not to use this constructor. Each get will read in
158 // all data in the row, thus also the large data array(s).
159 // In that case it is better to use the constructor which
160 // includes selected columns only.
161 // </note>
162 explicit ROTableRow(const Table& table, Bool storedColumnsOnly = True);
163
164 // Create a ROTableRow object for the given Table.
165 // Its TableRecord will contain all columns given in the Vector.
166 // An exception is thrown if an unknown column name is given.
167 // <br>
168 // When exclude=True, all columns except the given columns are taken.
169 // In that case an unknown name does not result in an exception.
171
172 // Copy constructor (copy semantics).
174
176
177 // Assignment (copy semantics).
179
180 // Test if a Table is attached to this object.
181 Bool isAttached() const;
182
183 // Get the Table used for this object.
184 const Table& table() const;
185
186 // Get the record containing all fields.
187 const TableRecord& record() const;
188
189 // Get the number of the last row read.
190 // -1 is returned when no Table is attached or no row has been read yet.
191 Int64 rowNumber() const;
192
193 // Get a vector consisting of all columns names.
194 // This can, for instance, be used to construct a TableRow object
195 // with the same columns in another table.
197
198 // Get the values of all columns used from the given row.
199 // When the given row number equals the current one, nothing
200 // will be read unless the alwaysRead flag is set to True.
201 // <br>The TableRecord& returned is the same one as returned by the
202 // record() function. So one can ignore the return value of get().
203 const TableRecord& get(rownr_t rownr, Bool alwaysRead = False) const;
204
205 // Get the block telling for each column if its value in the row
206 // was indefined in the table.
207 // Note that array values might be undefined in the table, but in
208 // the record they will be represented as empty arrays.
209 const Block<Bool>& getDefined() const;
210
211 protected:
212 // Copy that object to this object.
213 // The writable flag determines if writable or readonly
214 // TableColumn objects will be created.
215 void copy(const ROTableRow& that);
216
217 // Create the record, column, and field objects
218 // for all columns in the table.
219 // The writable flag determines if writable or readonly
220 // TableColumn objects will be created.
221 void create(const Table& table, Bool storedColumnsOnly, Bool writable);
222
223 // Create the record, column, and field objects for the given columns.
224 // The writable flag determines if writable or readonly
225 // TableColumn objects will be created.
226 void create(const Table& table, const Vector<String>& columnNames, Bool exclude, Bool writable);
227
228 // Put the values found in the internal TableRecord at the given row.
229 // This is a helper function for class TableRow.
230 void putRecord(rownr_t rownr);
231
232 // Put a value in the given field in the TableRecord into the
233 // given row and column.
234 // This is a helper function for class TableRow.
235 void putField(rownr_t rownr, const TableRecord& record, Int whichColumn, Int whichField);
236
237 // Set the switch to reread when the current row has been put.
238 void setReread(rownr_t rownr);
239
240 // # The record of all fields.
242 // # The table used.
244 // # The following block is actually a Block<TableColumn*>.
245 // # However, using void* (and appropriate casts) saves on template
246 // # instantiations.
248 // # The following block is actually a Block<Scalar/ArrayColumn<T>>.
250 // # The following block is actually a block of RecordFieldPtr<T>*.
251 // # These are used for fast access to the record.
253 // # Block to tell if the corresponding column value is defined.
255 // # A cache for itsRecord.nfields()
257 // # The last rownr read (-1 is nothing read yet).
259 // # A switch to indicate that the last row has to be reread.
260 // # This is the case when it has been put after being read.
262
263 private:
264 // Initialize the object.
265 void init();
266
267 // Make a RecordDesc from the table with some excluded column names.
269
270 // Add a column to the record.
271 // When skipOther is True, columns with a non-standard data type
272 // will be silently skipped.
273 void addColumnToDesc(RecordDesc& description, const TableColumn& column, Bool skipOther);
274
275 // Make the required objects. These are the TableRecord and for
276 // each column a TableColumn and RecordFieldPtr.
278
279 // Delete all objects.
281};
282
283// <summary>
284// Read/write access to a table row
285// </summary>
286
287// <use visibility=export>
288
289// <reviewed reviewer="Paul Shannon" date="1995/05/10" tests="tTableRow.cc">
290// </reviewed>
291
292// <prerequisite>
293// <li> <linkto class=ROTableRow>ROTableRow</linkto>
294// </prerequisite>
295
296// <synopsis>
297// The class TableRow is derived from ROTableRow and as an extra it
298// provides write-access to a row in a table.
299// With the put function, all values in the TableRecord object will
300// be put in the corresponding columns in the table row.
301// There is, however, an extra consideration:
302// <ul>
303// <li> Constructing a TableRow object fails if the table is not
304// writable. Non-writable columns will not be part of the object.
305// If an explicitly given column is non-writable, the construction
306// will also fail.
307// </ul>
308// There are effectively 3 ways of writing data.
309// <ol>
310// <li> The function
311// <srcblock>
312// put (rownr, tableRecord);
313// </srcblock>
314// can be used to put all values from the given TableRecord,
315// which has to be conforming (i.e. matching order and names).
316// Optionally the conformance is checked.
317// This put function is capable of data type promotion.
318// For instance, if column COL1 is float, the corresponding
319// field in the TableRecord can be Int.
320// <li> A faster way is using the functions <src>record</src>
321// and <src>put</src>. It is possible to use <linkto class=RecordFieldPtr>
322// RecordFieldPtr</linkto> objects to get direct access to the
323// fields in the record (provided the structure of the record
324// is known).
325// E.g.
326// <srcblock>
327// TableRow row (someTable, stringToVector("col1,col2,col3"));
328// RecordFieldPtr<String> col1(row.record(), "col1");
329// RecordFieldPtr<double> col2(row.record(), "col2");
330// RecordFieldPtr<Array<Int> > col3(row.record(), "col3");
331// for (rownr_t i=0; i<n; i++) {
332// *col1 = someString;
333// *col2 = somedouble;
334// *col3 = someArrayInt;
335// row.put (i);
336// }
337// </srcblock>
338// <li>
339// <li> The function
340// <srcblock>
341// putMatchingFields (rownr, tableRecord);
342// </srcblock>
343// can be used to put some fields from the given TableRecord.
344// Only fields having a corresponding name in the TableRow object
345// will be put. Similar to the first way data type promotion will
346// be applied for numeric values.
347// <br>E.g.: Suppose the TableRow object has columns A, C, and B,
348// and the given TableRecord has fields B, D, and C. Only fields B and C
349// will be put. As the example shows, the order of the fields is not
350// important.
351// <br>
352// This way is (much) slower than the other 2, because a name
353// lookup is involved for each field. It can, however, be more
354// convenient to use.
355// </ol>
356// </synopsis>
357
358// <example>
359// <srcblock>
360// // Open the new table (with 10 rows) and define a row object containing
361// // values from the given column.
362// // Note that the function stringToVector is a very convenient
363// // way to construct a Vector<String>.
364// SetupNewTable newtab(tableDesc, Table::new);
365// Table table(newtab, 10);
366// TableRow row (table, stringToVector("col1,col2,col3,col4"));
367// // Loop through all rows and get their values.
368// for (rownr_t i=0; i<table.nrow(); i++) {
369// // Some magic filler function returns a filled TableRecord
370// // (with the correct fields in the correct order).
371// TableRecord record = fillerFunction();
372// row.put (i, record);
373// }
374// </srcblock>
375// </example>
376
377class TableRow : public ROTableRow {
378 public:
379 // Create a detached TableRow object.
380 // This means that no Table, etc. is contained in it.
381 // Function isAttached (in the base class) will return False for it.
382 // <br>
383 // This constructor should normally not be used, because it does not
384 // result in a valid object. It should only be used when really needed
385 // (e.g. when an array of objects has to be used).
387
388 // Create a TableRow object for the given Table.
389 // Its TableRecord will contain all columns except columns with
390 // datatype TpOther and columns which are not writable.
391 // <br>
392 // If the flag <src>storedColumnsOnly</src> is True, only the
393 // columns actually stored by a storage manager will be selected.
394 // This is useful when the contents of an entire row have to be copied.
395 // Virtual columns are calculated on-the-fly (often using stored columns),
396 // thus it makes no sense to copy their data.
397 // <note role=caution>
398 // If the table contains columns with large arrays, it may
399 // be better not to use this constructor. Each get will read in
400 // all data in the row, thus also the large data array(s).
401 // In that case it is better to use the next constructor which
402 // works selectively.
403 // </note>
404 explicit TableRow(const Table& table, Bool storedColumnsOnly = True);
405
406 // Create a TableRow object for the given Table.
407 // Its TableRecord will contain all columns given in the Vector.
408 // An exception is thrown if an unknown column name is given
409 // or if a column is given which is not writable.
410 // <br>
411 // When exclude=True, all columns except the given columns are taken.
412 // In that case an unknown name does not result in an exception
413 // and non-writable columns are simply skipped.
415
416 // Copy constructor (copy semantics).
418
420
421 // Assignment (copy semantics).
423
424 // Get non-const access to the TableRecord in this object.
425 // This can be used to change values in it which can thereafter
426 // be put using the function <src>put(rownr)</src>.
427 // <note> The returned TableRecord has a fixed structure, so it is
428 // not possible to add or remove fields. It is only possible
429 // to change values.
430 // </note>
432
433 // Put into the last row read.
434 // An exception is thrown if no row has been read yet.
435 // The values in the TableRecord contained in this object are put.
436 // This TableRecord can be accessed and updated using the
437 // function <src>record</src>.
438 void put();
439
440 // Put into the given row.
441 // The values in the TableRecord contained in this object are put.
442 // This TableRecord can be accessed and updated using the
443 // function <src>record</src>.
444 void put(rownr_t rownr);
445
446 // Put the values found in the TableRecord in the appropriate columns
447 // in the given row.
448 // The names and order of the fields in the TableRecord must conform
449 // those of the description of the TableRow. The data types of numeric
450 // values do not need to conform exactly; they can be promoted
451 // (e.g. an Int value in the record may correspond to a float column).
452 // If not conforming, an exception is thrown.
453 // <note> For performance reasons it is optional to check
454 // the name order conformance.
455 // </note>
456 // The <src>valuesDefined</src> block tells if the value in the
457 // corresponding field in the record is actually defined.
458 // If not, nothing will be written.
459 // It is meant for array values which might be undefined in a table.
460 // <group>
461 void put(rownr_t rownr, const TableRecord& record, Bool checkConformance = True);
462 void put(rownr_t rownr, const TableRecord& record, const Block<Bool>& valuesDefined,
463 Bool checkConformance = True);
464 // </group>
465
466 // Put the values found in the TableRecord. Only fields with a matching
467 // name in the TableRow object will be put.
468 // This makes it possible to put fields in a selective way.
469 // <br>E.g.: If the TableRow contains columns A and B, and the
470 // record contains fields B and C, only field B will be put.
471 // <br>In principle the data types of the matching fields must match,
472 // but data type promotion of numeric values will be applied.
474
475 private:
476 // Check if the names of the given record match this row.
477 Bool namesConform(const TableRecord& that) const;
478};
479
480inline Bool ROTableRow::isAttached() const { return (itsRecord != 0); }
481inline const Table& ROTableRow::table() const { return itsTable; }
482inline Int64 ROTableRow::rowNumber() const { return itsLastRow; }
483inline const TableRecord& ROTableRow::record() const { return *itsRecord; }
484inline const Block<Bool>& ROTableRow::getDefined() const { return itsDefined; }
486inline void TableRow::put(rownr_t rownr) { putRecord(rownr); }
487
488} // namespace casacore
489
490#endif
Block< void * > itsColumns
Definition TableRow.h:249
ROTableRow(const ROTableRow &)
Copy constructor (copy semantics).
void copy(const ROTableRow &that)
Copy that object to this object.
void putRecord(rownr_t rownr)
Put the values found in the internal TableRecord at the given row.
Vector< String > columnNames() const
Get a vector consisting of all columns names.
ROTableRow & operator=(const ROTableRow &)
Assignment (copy semantics).
void deleteObjects()
Delete all objects.
void addColumnToDesc(RecordDesc &description, const TableColumn &column, Bool skipOther)
Add a column to the record.
Block< void * > itsFields
Definition TableRow.h:252
void makeObjects(const RecordDesc &description)
Make the required objects.
ROTableRow(const Table &table, Bool storedColumnsOnly=True)
Create a ROTableRow object for the given Table.
Block< Bool > itsDefined
Definition TableRow.h:254
ROTableRow(const Table &table, const Vector< String > &columnNames, Bool exclude=False)
Create a ROTableRow object for the given Table.
void setReread(rownr_t rownr)
Set the switch to reread when the current row has been put.
void putField(rownr_t rownr, const TableRecord &record, Int whichColumn, Int whichField)
Put a value in the given field in the TableRecord into the given row and column.
const Block< Bool > & getDefined() const
Get the block telling for each column if its value in the row was indefined in the table.
Definition TableRow.h:484
Int64 rowNumber() const
Get the number of the last row read.
Definition TableRow.h:482
void makeDescExclude(RecordDesc &description, const Vector< String > &columnNames, Bool writable)
Make a RecordDesc from the table with some excluded column names.
Bool isAttached() const
Test if a Table is attached to this object.
Definition TableRow.h:480
void create(const Table &table, const Vector< String > &columnNames, Bool exclude, Bool writable)
Create the record, column, and field objects for the given columns.
TableRecord * itsRecord
Definition TableRow.h:241
const TableRecord & record() const
Get the record containing all fields.
Definition TableRow.h:483
void init()
Initialize the object.
const Table & table() const
Get the Table used for this object.
Definition TableRow.h:481
Block< void * > itsTabCols
Definition TableRow.h:247
void create(const Table &table, Bool storedColumnsOnly, Bool writable)
Create the record, column, and field objects for all columns in the table.
const TableRecord & get(rownr_t rownr, Bool alwaysRead=False) const
Get the values of all columns used from the given row.
ROTableRow()
Create a detached ROTableRow object.
TableRow(const Table &table, const Vector< String > &columnNames, Bool exclude=False)
Create a TableRow object for the given Table.
Bool namesConform(const TableRecord &that) const
Check if the names of the given record match this row.
void put(rownr_t rownr, const TableRecord &record, const Block< Bool > &valuesDefined, Bool checkConformance=True)
void put(rownr_t rownr, const TableRecord &record, Bool checkConformance=True)
Put the values found in the TableRecord in the appropriate columns in the given row.
TableRow(const TableRow &)
Copy constructor (copy semantics).
TableRow(const Table &table, Bool storedColumnsOnly=True)
Create a TableRow object for the given Table.
void put()
Put into the last row read.
TableRecord & record()
Get non-const access to the TableRecord in this object.
Definition TableRow.h:485
TableRow & operator=(const TableRow &)
Assignment (copy semantics).
void putMatchingFields(rownr_t rownr, const TableRecord &record)
Put the values found in the TableRecord.
TableRow()
Create a detached TableRow object.
For temporary backward namespace compatibility, use casa as alias for casacore.
Definition mainpage.dox:28
const Bool False
Definition aipstype.h:42
const RecordDesc & description() const
Describes the current structure of this Record.
unsigned int uInt
Definition aipstype.h:49
long long Int64
Define the extra non-standard types used by Casacore (like proposed uSize, Size).
Definition aipsxtype.h:36
int Int
Definition aipstype.h:48
bool Bool
Define the standard types used by Casacore.
Definition aipstype.h:40
const Bool True
Definition aipstype.h:41
uInt64 rownr_t
Define the type of a row number in a table.
Definition aipsxtype.h:44