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