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{
137public:
138 // Create a detached ROTableRow object.
139 // This means that no Table, etc. is contained in it.
140 // Function isAttached will return False for it.
141 // <br>
142 // This constructor should normally not be used, because it does not
143 // result in a valid object. It should only be used when really needed
144 // (e.g. when an array of objects has to be used).
146
147 // Create a ROTableRow object for the given Table.
148 // Its TableRecord will contain all columns except columns with
149 // datatype TpOther (i.e. non-standard data types).
150 // <br>
151 // If the flag <src>storedColumnsOnly</src> is True, only the
152 // columns actually stored by a storage manager will be selected.
153 // This is useful when the contents of an entire row have to be copied.
154 // Virtual columns are calculated on-the-fly (often using stored columns),
155 // thus it makes no sense to copy their data.
156 // <note role=caution>
157 // If the table contains columns with large arrays, it may
158 // be better not to use this constructor. Each get will read in
159 // all data in the row, thus also the large data array(s).
160 // In that case it is better to use the constructor which
161 // includes selected columns only.
162 // </note>
163 explicit ROTableRow (const Table& table, Bool storedColumnsOnly = True);
164
165 // Create a ROTableRow object for the given Table.
166 // Its TableRecord will contain all columns given in the Vector.
167 // An exception is thrown if an unknown column name is given.
168 // <br>
169 // When exclude=True, all columns except the given columns are taken.
170 // In that case an unknown name does not result in an exception.
172 Bool exclude = False);
173
174 // Copy constructor (copy semantics).
176
178
179 // Assignment (copy semantics).
181
182 // Test if a Table is attached to this object.
183 Bool isAttached() const;
184
185 // Get the Table used for this object.
186 const Table& table() const;
187
188 // Get the record containing all fields.
189 const TableRecord& record() const;
190
191 // Get the number of the last row read.
192 // -1 is returned when no Table is attached or no row has been read yet.
193 Int64 rowNumber() const;
194
195 // Get a vector consisting of all columns names.
196 // This can, for instance, be used to construct a TableRow object
197 // with the same columns in another table.
199
200 // Get the values of all columns used from the given row.
201 // When the given row number equals the current one, nothing
202 // will be read unless the alwaysRead flag is set to True.
203 // <br>The TableRecord& returned is the same one as returned by the
204 // record() function. So one can ignore the return value of get().
205 const TableRecord& get (rownr_t rownr, Bool alwaysRead = False) const;
206
207 // Get the block telling for each column if its value in the row
208 // was indefined in the table.
209 // Note that array values might be undefined in the table, but in
210 // the record they will be represented as empty arrays.
211 const Block<Bool>& getDefined() const;
212
213protected:
214 // Copy that object to this object.
215 // The writable flag determines if writable or readonly
216 // TableColumn objects will be created.
217 void copy (const ROTableRow& that);
218
219 // Create the record, column, and field objects
220 // for all columns in the table.
221 // The writable flag determines if writable or readonly
222 // TableColumn objects will be created.
223 void create (const Table& table, Bool storedColumnsOnly, Bool writable);
224
225 // Create the record, column, and field objects for the given columns.
226 // The writable flag determines if writable or readonly
227 // TableColumn objects will be created.
229 Bool exclude, Bool writable);
230
231 // Put the values found in the internal TableRecord at the given row.
232 // This is a helper function for class TableRow.
233 void putRecord (rownr_t rownr);
234
235 // Put a value in the given field in the TableRecord into the
236 // given row and column.
237 // This is a helper function for class TableRow.
238 void putField (rownr_t rownr, const TableRecord& record,
239 Int whichColumn, Int whichField);
240
241 // Set the switch to reread when the current row has been put.
242 void setReread (rownr_t rownr);
243
244 //# The record of all fields.
246 //# The table used.
248 //# The following block is actually a Block<TableColumn*>.
249 //# However, using void* (and appropriate casts) saves on template
250 //# instantiations.
252 //# The following block is actually a Block<Scalar/ArrayColumn<T>>.
254 //# The following block is actually a block of RecordFieldPtr<T>*.
255 //# These are used for fast access to the record.
257 //# Block to tell if the corresponding column value is defined.
259 //# A cache for itsRecord.nfields()
261 //# The last rownr read (-1 is nothing read yet).
263 //# A switch to indicate that the last row has to be reread.
264 //# This is the case when it has been put after being read.
266
267private:
268 // Initialize the object.
269 void init();
270
271 // Make a RecordDesc from the table with some excluded column names.
272 void makeDescExclude (RecordDesc& description,
274 Bool writable);
275
276 // Add a column to the record.
277 // When skipOther is True, columns with a non-standard data type
278 // will be silently skipped.
279 void addColumnToDesc (RecordDesc& description,
280 const TableColumn& column, Bool skipOther);
281
282 // Make the required objects. These are the TableRecord and for
283 // each column a TableColumn and RecordFieldPtr.
284 void makeObjects (const RecordDesc& description);
285
286 // Delete all objects.
288};
289
290
291
292
293// <summary>
294// Read/write access to a table row
295// </summary>
296
297// <use visibility=export>
298
299// <reviewed reviewer="Paul Shannon" date="1995/05/10" tests="tTableRow.cc">
300// </reviewed>
301
302// <prerequisite>
303// <li> <linkto class=ROTableRow>ROTableRow</linkto>
304// </prerequisite>
305
306// <synopsis>
307// The class TableRow is derived from ROTableRow and as an extra it
308// provides write-access to a row in a table.
309// With the put function, all values in the TableRecord object will
310// be put in the corresponding columns in the table row.
311// There is, however, an extra consideration:
312// <ul>
313// <li> Constructing a TableRow object fails if the table is not
314// writable. Non-writable columns will not be part of the object.
315// If an explicitly given column is non-writable, the construction
316// will also fail.
317// </ul>
318// There are effectively 3 ways of writing data.
319// <ol>
320// <li> The function
321// <srcblock>
322// put (rownr, tableRecord);
323// </srcblock>
324// can be used to put all values from the given TableRecord,
325// which has to be conforming (i.e. matching order and names).
326// Optionally the conformance is checked.
327// This put function is capable of data type promotion.
328// For instance, if column COL1 is float, the corresponding
329// field in the TableRecord can be Int.
330// <li> A faster way is using the functions <src>record</src>
331// and <src>put</src>. It is possible to use <linkto class=RecordFieldPtr>
332// RecordFieldPtr</linkto> objects to get direct access to the
333// fields in the record (provided the structure of the record
334// is known).
335// E.g.
336// <srcblock>
337// TableRow row (someTable, stringToVector("col1,col2,col3"));
338// RecordFieldPtr<String> col1(row.record(), "col1");
339// RecordFieldPtr<double> col2(row.record(), "col2");
340// RecordFieldPtr<Array<Int> > col3(row.record(), "col3");
341// for (rownr_t i=0; i<n; i++) {
342// *col1 = someString;
343// *col2 = somedouble;
344// *col3 = someArrayInt;
345// row.put (i);
346// }
347// </srcblock>
348// <li>
349// <li> The function
350// <srcblock>
351// putMatchingFields (rownr, tableRecord);
352// </srcblock>
353// can be used to put some fields from the given TableRecord.
354// Only fields having a corresponding name in the TableRow object
355// will be put. Similar to the first way data type promotion will
356// be applied for numeric values.
357// <br>E.g.: Suppose the TableRow object has columns A, C, and B,
358// and the given TableRecord has fields B, D, and C. Only fields B and C
359// will be put. As the example shows, the order of the fields is not
360// important.
361// <br>
362// This way is (much) slower than the other 2, because a name
363// lookup is involved for each field. It can, however, be more
364// convenient to use.
365// </ol>
366// </synopsis>
367
368// <example>
369// <srcblock>
370// // Open the new table (with 10 rows) and define a row object containing
371// // values from the given column.
372// // Note that the function stringToVector is a very convenient
373// // way to construct a Vector<String>.
374// SetupNewTable newtab(tableDesc, Table::new);
375// Table table(newtab, 10);
376// TableRow row (table, stringToVector("col1,col2,col3,col4"));
377// // Loop through all rows and get their values.
378// for (rownr_t i=0; i<table.nrow(); i++) {
379// // Some magic filler function returns a filled TableRecord
380// // (with the correct fields in the correct order).
381// TableRecord record = fillerFunction();
382// row.put (i, record);
383// }
384// </srcblock>
385// </example>
386
387class TableRow : public ROTableRow
388{
389public:
390 // Create a detached TableRow object.
391 // This means that no Table, etc. is contained in it.
392 // Function isAttached (in the base class) will return False for it.
393 // <br>
394 // This constructor should normally not be used, because it does not
395 // result in a valid object. It should only be used when really needed
396 // (e.g. when an array of objects has to be used).
398
399 // Create a TableRow object for the given Table.
400 // Its TableRecord will contain all columns except columns with
401 // datatype TpOther and columns which are not writable.
402 // <br>
403 // If the flag <src>storedColumnsOnly</src> is True, only the
404 // columns actually stored by a storage manager will be selected.
405 // This is useful when the contents of an entire row have to be copied.
406 // Virtual columns are calculated on-the-fly (often using stored columns),
407 // thus it makes no sense to copy their data.
408 // <note role=caution>
409 // If the table contains columns with large arrays, it may
410 // be better not to use this constructor. Each get will read in
411 // all data in the row, thus also the large data array(s).
412 // In that case it is better to use the next constructor which
413 // works selectively.
414 // </note>
415 explicit TableRow (const Table& table, Bool storedColumnsOnly = True);
416
417 // Create a TableRow object for the given Table.
418 // Its TableRecord will contain all columns given in the Vector.
419 // An exception is thrown if an unknown column name is given
420 // or if a column is given which is not writable.
421 // <br>
422 // When exclude=True, all columns except the given columns are taken.
423 // In that case an unknown name does not result in an exception
424 // and non-writable columns are simply skipped.
426 Bool exclude = False);
427
428 // Copy constructor (copy semantics).
430
432
433 // Assignment (copy semantics).
435
436 // Get non-const access to the TableRecord in this object.
437 // This can be used to change values in it which can thereafter
438 // be put using the function <src>put(rownr)</src>.
439 // <note> The returned TableRecord has a fixed structure, so it is
440 // not possible to add or remove fields. It is only possible
441 // to change values.
442 // </note>
444
445 // Put into the last row read.
446 // An exception is thrown if no row has been read yet.
447 // The values in the TableRecord contained in this object are put.
448 // This TableRecord can be accessed and updated using the
449 // function <src>record</src>.
450 void put();
451
452 // Put into the given row.
453 // The values in the TableRecord contained in this object are put.
454 // This TableRecord can be accessed and updated using the
455 // function <src>record</src>.
456 void put (rownr_t rownr);
457
458 // Put the values found in the TableRecord in the appropriate columns
459 // in the given row.
460 // The names and order of the fields in the TableRecord must conform
461 // those of the description of the TableRow. The data types of numeric
462 // values do not need to conform exactly; they can be promoted
463 // (e.g. an Int value in the record may correspond to a float column).
464 // If not conforming, an exception is thrown.
465 // <note> For performance reasons it is optional to check
466 // the name order conformance.
467 // </note>
468 // The <src>valuesDefined</src> block tells if the value in the
469 // corresponding field in the record is actually defined.
470 // If not, nothing will be written.
471 // It is meant for array values which might be undefined in a table.
472 // <group>
473 void put (rownr_t rownr, const TableRecord& record,
474 Bool checkConformance = True);
475 void put (rownr_t rownr, const TableRecord& record,
476 const Block<Bool>& valuesDefined,
477 Bool checkConformance = True);
478 // </group>
479
480 // Put the values found in the TableRecord. Only fields with a matching
481 // name in the TableRow object will be put.
482 // This makes it possible to put fields in a selective way.
483 // <br>E.g.: If the TableRow contains columns A and B, and the
484 // record contains fields B and C, only field B will be put.
485 // <br>In principle the data types of the matching fields must match,
486 // but data type promotion of numeric values will be applied.
488
489private:
490 // Check if the names of the given record match this row.
491 Bool namesConform (const TableRecord& that) const;
492};
493
494
496{
497 return (itsRecord != 0);
498}
499inline const Table& ROTableRow::table() const
500{
501 return itsTable;
502}
504{
505 return itsLastRow;
506}
507inline const TableRecord& ROTableRow::record() const
508{
509 return *itsRecord;
510}
512{
513 return itsDefined;
514}
516{
517 return *itsRecord;
518}
519inline void TableRow::put (rownr_t rownr)
520{
521 putRecord (rownr);
522}
523
524
525
526} //# NAMESPACE CASACORE - END
527
528#endif
simple 1-D array
Definition Block.h:198
Block< void * > itsColumns
Definition TableRow.h:253
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:256
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:258
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:511
Int64 rowNumber() const
Get the number of the last row read.
Definition TableRow.h:503
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:495
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:245
const TableRecord & record() const
Get the record containing all fields.
Definition TableRow.h:507
void init()
Initialize the object.
const Table & table() const
Get the Table used for this object.
Definition TableRow.h:499
Block< void * > itsTabCols
Definition TableRow.h:251
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:388
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:515
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:42
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