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