00001 //# Table.h: Main interface classes to tables 00002 //# Copyright (C) 1994,1995,1996,1997,1998,1999,2000,2001,2002,2003 00003 //# Associated Universities, Inc. Washington DC, USA. 00004 //# 00005 //# This library is free software; you can redistribute it and/or modify it 00006 //# under the terms of the GNU Library General Public License as published by 00007 //# the Free Software Foundation; either version 2 of the License, or (at your 00008 //# option) any later version. 00009 //# 00010 //# This library is distributed in the hope that it will be useful, but WITHOUT 00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00012 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00013 //# License for more details. 00014 //# 00015 //# You should have receied a copy of the GNU Library General Public License 00016 //# along with this library; if not, write to the Free Software Foundation, 00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 00018 //# 00019 //# Correspondence concerning AIPS++ should be addressed as follows: 00020 //# Internet email: aips2-request@nrao.edu. 00021 //# Postal address: AIPS++ Project Office 00022 //# National Radio Astronomy Observatory 00023 //# 520 Edgemont Road 00024 //# Charlottesville, VA 22903-2475 USA 00025 //# 00026 //# $Id$ 00027 00028 #ifndef TABLES_TABLE_H 00029 #define TABLES_TABLE_H 00030 00031 00032 //# Includes 00033 #include <casa/aips.h> 00034 #include <tables/Tables/BaseTable.h> 00035 #include <tables/Tables/TableLock.h> 00036 #include <casa/Utilities/DataType.h> 00037 #include <casa/Utilities/Sort.h> 00038 #include <casa/iostream.h> 00039 00040 namespace casa { //# NAMESPACE CASA - BEGIN 00041 00042 //# Forward Declarations 00043 class SetupNewTable; 00044 class TableDesc; 00045 class ColumnDesc; 00046 class TableRecord; 00047 class Record; 00048 class TableExprNode; 00049 class DataManager; 00050 class IPosition; 00051 template<class T> class Vector; 00052 template<class T> class Block; 00053 template<class T> class PtrBlock; 00054 00055 00056 // <summary> 00057 // Main interface class to a read/write table 00058 // </summary> 00059 00060 // <use visibility=export> 00061 00062 // <reviewed reviewer="TPPR" date="08.11.94" tests="tTable.cc"> 00063 // </reviewed> 00064 00065 // <prerequisite> 00066 //# Classes you should understand before using this one. 00067 // <li> <linkto class=SetupNewTable>SetupNewTable</linkto> 00068 // <li> <linkto class=TableDesc>TableDesc</linkto> 00069 // <li> <linkto class=TableColumn>TableColumn</linkto> 00070 // <li> <linkto class=ScalarColumn>ScalarColumn</linkto> 00071 // <li> <linkto class=ArrayColumn>ArrayColum</linkto> 00072 // <li> <linkto class=TableLock>TableLock</linkto> 00073 // </prerequisite> 00074 00075 // <synopsis> 00076 // Class Table can be used to create a new table or to access an existing 00077 // table in read/write or readonly mode. 00078 // 00079 // To access the data in a Table, objects have to be created 00080 // to access the columns. These objects are TableColumn, 00081 // ScalarColumn<T> and ArrayColumn<T>, which can be created 00082 // via their constructors. 00083 // Furthermore the Table has a TableRecord object for holding keywords 00084 // which can be read or written using the appropriate functions. 00085 // 00086 // To open an existing table, a simple Table constructor can be used. 00087 // The possible construct options are: 00088 // <ul> 00089 // <li> Old readonly table (default option) 00090 // <li> Update update existing table 00091 // <li> Delete delete table 00092 // </ul> 00093 // Creating a new table requires more work, because columns have 00094 // to be bound to storage managers or virtual column engines. 00095 // Class SetupNewTable is needed for this purpose. The Tables module 00096 // documentation explains in more detail how to create a table. 00097 // When creating a table, it can be specified which endian format to use. 00098 // By default it uses the format specified in the aipsrc variable 00099 // <code>table.endianformat</code> which defaults to 00100 // <code>Table::LocalEndian</code> (thus the endian format of the 00101 // machine being used). 00102 // 00103 // Other Table objects can be created from a Table using 00104 // the select, project and sort functions. In that way a subset 00105 // of the table can be created and it can be read/written in the same 00106 // way as a normal Table. However, writing has the effect that the 00107 // underlying table gets written. 00108 // </synopsis> 00109 00110 // <example> 00111 // <srcblock> 00112 // // Open a table to be updated. 00113 // Table myTable ("theTable", Table::Update); 00114 // // Write the column containing the scalar RA. 00115 // ScalarColumn<double> raColumn(myTable, "RA"); 00116 // uInt nrrow = myTable.nrow(); 00117 // for (uInt i=0; i<nrrow; i++) { 00118 // raColumn.put (i, i+10); // Put value i+10 into row i 00119 // } 00120 // </srcblock> 00121 // </example> 00122 00123 // <motivation> 00124 // Table is the envelope for the underlying counted referenced 00125 // classes derived from BaseTable. In this way no pointers have 00126 // to be used to get polymorphism. 00127 // </motivation> 00128 00129 // <todo asof="$DATE:$"> 00130 //# A List of bugs, limitations, extensions or planned refinements. 00131 // <li> add, remove, rename columns. 00132 // <li> virtual concatenation of tables (if still necessary). 00133 // <li> maybe an isAttached function. 00134 // </todo> 00135 00136 00137 class Table 00138 { 00139 friend class ROTableColumn; 00140 friend class BaseTable; 00141 friend class PlainTable; 00142 friend class MemoryTable; 00143 friend class RefTable; 00144 friend class TableIterator; 00145 friend class RODataManAccessor; 00146 friend class TableExprNode; 00147 friend class TableExprNodeRep; 00148 00149 public: 00150 enum TableOption { 00151 // existing table 00152 Old=1, 00153 // create table 00154 New, 00155 // create table (may not exist) 00156 NewNoReplace, 00157 // new table, which gets marked for delete 00158 Scratch, 00159 // update existing table 00160 Update, 00161 // delete table 00162 Delete 00163 }; 00164 00165 enum TableType { 00166 // plain table (stored on disk) 00167 Plain, 00168 // table held in memory 00169 Memory 00170 }; 00171 00172 enum EndianFormat { 00173 // store table data in big endian (e.g. SUN) format 00174 BigEndian=1, 00175 // store table data in little endian (e.g. Intel) format 00176 LittleEndian, 00177 // store data in endian format of the machine used 00178 LocalEndian, 00179 // use endian format defined in the aipsrc variable table.endianformat 00180 AipsrcEndian 00181 }; 00182 00183 // Define the signature of the function being called when the state 00184 // of a scratch table changes (i.e. created, closed, renamed, 00185 // (un)markForDelete). 00186 // <br>- <src>isScratch=True</src> indicates that a scratch table 00187 // is created (<src>oldName</src> is empty) or renamed 00188 // (<src>oldName</src> is not empty). 00189 // <br>- <src>isScratch=False</src> indicates that a scratch table 00190 // with name <src>name</src> is not scratch anymore (because it is 00191 // closed or because its state is set to non-scratch). 00192 typedef void ScratchCallback (const String& name, Bool isScratch, 00193 const String& oldName); 00194 00195 // Set the pointer to the ScratchCallback function. 00196 // It returns the current value of the pointer. 00197 // This function is called when changing the state of a table 00198 // (i.e. create, close, rename, (un)markForDelete). 00199 static ScratchCallback* setScratchCallback (ScratchCallback*); 00200 00201 00202 // Create a null Table object (i.e. no table is attached yet). 00203 // The sole purpose of this constructor is to allow construction 00204 // of an array of Table objects. 00205 // The assignment operator can be used to make a null object 00206 // reference a column. 00207 // Note that sort functions, etc. will cause a segmentation fault 00208 // when operating on a null object. It was felt it was too expensive 00209 // to test on null over and over again. The user should use the isNull 00210 // or throwIfNull function in case of doubt. 00211 Table(); 00212 00213 // Create a table object for an existing writable table. 00214 // The only options allowed are Old, Update, and Delete. 00215 // When the name of a table description is given, it is checked 00216 // if the table has that description. 00217 // Locking options can be given (see class 00218 // <linkto class=TableLock>TableLock</linkto>. 00219 // When the table with this name was already opened in this process, 00220 // the existing and new locking options are merged using 00221 // <src>TableLock::merge</src>. 00222 // The default locking mechanism is DefaultLocking. When the table 00223 // is not open yet, it comes to AutoLocking with an inspection interval 00224 // of 5 seconds. Otherwise DefaultLocking keeps the locking options 00225 // of the already open table. 00226 // <group> 00227 explicit Table (const String& tableName, TableOption = Table::Old); 00228 Table (const String& tableName, const TableLock& lockOptions, 00229 TableOption = Table::Old); 00230 Table (const String& tableName, const String& tableDescName, 00231 TableOption = Table::Old); 00232 Table (const String& tableName, const String& tableDescName, 00233 const TableLock& lockOptions, TableOption = Table::Old); 00234 // </group> 00235 00236 // Make a new empty table (plain (scratch) or memory type). 00237 // Columns should be added to make it a real one. 00238 // Note that the endian format is only relevant for plain tables. 00239 explicit Table (TableType, EndianFormat = Table::AipsrcEndian); 00240 00241 // Make a table object for a new table, which can thereafter be used 00242 // for reading and writing. 00243 // If there are unbound columns, default storage managers an/ord virtual 00244 // column engines will be created and bound to those columns. 00245 // Create the table with the given nr of rows. If a storage manager 00246 // is used which does not allow addition of rows, the number of rows 00247 // in the table must already be given here. 00248 // Optionally the rows can be initialized with the default 00249 // values as defined in the column descriptions. 00250 // Locking options can be given (see class 00251 // <linkto class=TableLock>TableLock</linkto>. 00252 // The default locking mechanism is AutoLocking with a default 00253 // inspection interval of 5 seconds. 00254 // <br>The data will be stored in the given endian format. 00255 // <group> 00256 explicit Table (SetupNewTable&, uInt nrrow = 0, Bool initialize = False, 00257 EndianFormat = Table::AipsrcEndian); 00258 Table (SetupNewTable&, TableType, 00259 uInt nrrow = 0, Bool initialize = False, 00260 EndianFormat = Table::AipsrcEndian); 00261 Table (SetupNewTable&, TableType, const TableLock& lockOptions, 00262 uInt nrrow = 0, Bool initialize = False, 00263 EndianFormat = Table::AipsrcEndian); 00264 Table (SetupNewTable&, TableLock::LockOption, 00265 uInt nrrow = 0, Bool initialize = False, 00266 EndianFormat = Table::AipsrcEndian); 00267 Table (SetupNewTable&, const TableLock& lockOptions, 00268 uInt nrrow = 0, Bool initialize = False, 00269 EndianFormat = Table::AipsrcEndian); 00270 // </group> 00271 00272 //# Virtually concatenate some tables. 00273 //# All tables must have the same description. 00274 //#// Table (const Block<Table>&); 00275 00276 // Copy constructor (reference semantics). 00277 Table (const Table&); 00278 00279 // The destructor flushes (i.e. writes) the table if it is opened 00280 // for output and not marked for delete. 00281 // It will flush if the destructor is called due to an exception, 00282 // because the Table object may not be correct. 00283 // Of course, in that case the flush function could be called explicitly. 00284 ~Table(); 00285 00286 // Assignment (reference semantics). 00287 Table& operator= (const Table&); 00288 00289 // Is the root table of this table the same as that of the other one? 00290 Bool isSameRoot (const Table& other) const; 00291 00292 // Can the table be deleted? 00293 // If true, function deleteTable can safely be called. 00294 // If not, message contains the reason why (e.g. 'table is not writable'). 00295 // It checks if the table is writable, is not open in this process 00296 // and is not open in another process. 00297 // <br>If <src>checkSubTables</src> is set, it also checks if 00298 // a subtable is not open in another process. 00299 // <group> 00300 static Bool canDeleteTable (const String& tableName, 00301 Bool checkSubTables=False); 00302 static Bool canDeleteTable (String& message, const String& tableName, 00303 Bool checkSubTables=False); 00304 // </group> 00305 00306 // Delete the table. 00307 // An exception is thrown if the table cannot be deleted because 00308 // its is not writable or because it is still open in this or 00309 // another process. 00310 // <br>If <src>checkSubTables</src> is set, it is also checked if 00311 // a subtable is used in another process. 00312 static void deleteTable (const String& tableName, 00313 Bool checkSubTables=False); 00314 00315 // Close all open subtables. 00316 void closeSubTables() const; 00317 00318 // Try to reopen the table for read/write access. 00319 // An exception is thrown if the table is not writable. 00320 // Nothing is done if the table is already open for read/write. 00321 void reopenRW(); 00322 00323 // Get the endian format in which the table is stored. 00324 Table::EndianFormat endianFormat() const; 00325 00326 // Is the table used (i.e. open) in this process. 00327 static Bool isOpened (const String& tableName); 00328 00329 // Is the table used (i.e. open) in another process. 00330 // If <src>checkSubTables</src> is set, it is also checked if 00331 // a subtable is used in another process. 00332 Bool isMultiUsed (Bool checkSubTables=False) const; 00333 00334 // Get the locking options. 00335 const TableLock& lockOptions() const; 00336 00337 // Has this process the read or write lock, thus can the table 00338 // be read or written safely? 00339 // <group> 00340 Bool hasLock (FileLocker::LockType = FileLocker::Write) const; 00341 Bool hasLock (Bool write) const; 00342 // </group> 00343 00344 // Try to lock the table for read or write access (default is write). 00345 // The number of attempts (default = forever) can be specified when 00346 // acquiring the lock does not succeed immediately. When nattempts>1, 00347 // the system waits 1 second between each attempt, so nattempts 00348 // is more or less equal to a wait period in seconds. 00349 // The return value is false when acquiring the lock failed. 00350 // When <src>PermanentLocking</src> is in effect, a lock is already 00351 // present, so nothing will be done. 00352 // <group> 00353 Bool lock (FileLocker::LockType = FileLocker::Write, uInt nattempts = 0); 00354 Bool lock (Bool write, uInt nattempts = 0); 00355 // </group> 00356 00357 // Unlock the table. This will also synchronize the table data, 00358 // thus force the data to be written to disk. 00359 // When <src>PermanentLocking</src> is in effect, nothing will be done. 00360 void unlock(); 00361 00362 // Determine the number of locked tables opened with the AutoLock option 00363 // (Locked table means locked for read and/or write). 00364 static uInt nAutoLocks(); 00365 00366 // Unlock locked tables opened with the AutoLock option. 00367 // If <src>all=True</src> all such tables will be unlocked. 00368 // If <src>all=False</src> only tables requested by another process 00369 // will be unlocked. 00370 static void relinquishAutoLocks (Bool all = False); 00371 00372 // Determine if column or keyword table data have changed 00373 // (or is being changed) since the last time this function was called. 00374 Bool hasDataChanged(); 00375 00376 // Flush the table, i.e. write out the buffers. When <src>sync=True</src>, 00377 // it is ensured that all data are physically written to disk. 00378 // Nothing will be done if the table is not writable. 00379 // At any time a flush can be executed, even when the table is marked 00380 // for delete. 00381 // When the table is marked for delete, the destructor will remove 00382 // files written by intermediate flushes. 00383 // Note that if necessary the destructor will do an implicit flush, 00384 // unless it is executed due to an exception. 00385 // <br>If <src>fsync=True</src> the file contents are fsync-ed to disk, 00386 // thus ensured that the system buffers are actually written to disk. 00387 // <br>If <src>recursive=True</src> all subtables are flushed too. 00388 void flush (Bool fsync=False, Bool recursive=False); 00389 00390 // Resynchronize the Table object with the table file. 00391 // This function is only useful if no read-locking is used, ie. 00392 // if the table lock option is UserNoReadLocking or AutoNoReadLocking. 00393 // In that cases the table system does not acquire a read-lock, thus 00394 // does not synchronize itself automatically. 00395 void resync(); 00396 00397 // Test if the object is null, i.e. does not reference a table yet. 00398 // This is the case if the default constructor is used. 00399 Bool isNull() const 00400 { return (baseTabPtr_p == 0 ? True : baseTabPtr_p->isNull()); } 00401 00402 // Throw an exception if the object is null, i.e. 00403 // if function isNull() is True. 00404 void throwIfNull() const; 00405 00406 // Test if the given data type is native to the table system. 00407 // If not, a virtual column engine is needed to store data with that type. 00408 // With the function DataType::whatType it can be used in a templated 00409 // function like: 00410 // <srcblock> 00411 // if (Table::isNativeDataType (whatType(static_cast<T*>(0)))) { 00412 // </srcblock> 00413 static Bool isNativeDataType (DataType dtype); 00414 00415 // Make the table file name. 00416 static String fileName (const String& tableName); 00417 00418 // Test if a table with the given name exists and is readable. 00419 static Bool isReadable (const String& tableName); 00420 00421 // Return the layout of a table (i.e. description and #rows). 00422 // This function has the advantage that only the minimal amount of 00423 // information required is read from the table, thus it is much 00424 // faster than a normal table open. 00425 // <br> The number of rows is returned. The description of the table 00426 // is stored in desc (its contents will be overwritten). 00427 // <br> An exception is thrown if the table does not exist. 00428 static uInt getLayout (TableDesc& desc, const String& tableName); 00429 00430 // Get the table info of the table with the given name. 00431 // An empty object is returned when the table is unknown. 00432 static TableInfo tableInfo (const String& tableName); 00433 00434 // Test if a table with the given name exists and is writable. 00435 static Bool isWritable (const String& tableName); 00436 00437 // Find the non-writable files in a table. 00438 static Vector<String> nonWritableFiles (const String& tableName); 00439 00440 // Test if this table is the root table (ie. if it is not the subset 00441 // of another table). 00442 Bool isRootTable() const; 00443 00444 // Test if this table is opened as writable. 00445 Bool isWritable() const; 00446 00447 // Test if the given column is writable. 00448 // <group> 00449 Bool isColumnWritable (const String& columnName) const; 00450 Bool isColumnWritable (uInt columnIndex) const; 00451 // </group> 00452 00453 // Test if the given column is stored (otherwise it is virtual). 00454 // <group> 00455 Bool isColumnStored (const String& columnName) const; 00456 Bool isColumnStored (uInt columnIndex) const; 00457 // </group> 00458 00459 // Get readonly access to the table keyword set. 00460 // When UserLocking is used, it will automatically acquire 00461 // and release a read lock when the table is not locked. 00462 const TableRecord& keywordSet() const; 00463 00464 // Get read/write access to the table keyword set. 00465 // This requires that the table is locked (or it gets locked 00466 // when using AutoLocking mode). 00467 TableRecord& rwKeywordSet(); 00468 00469 // Get access to the TableInfo object. 00470 // <group> 00471 const TableInfo& tableInfo() const; 00472 TableInfo& tableInfo(); 00473 // </group> 00474 00475 // Write the TableInfo object. 00476 // Usually this is not necessary, because it is done automatically 00477 // when the table gets written (by table destructor or flush function). 00478 // This function is only useful when the table info has to be written 00479 // before the table gets written (e.g. when another process reads 00480 // the table while it gets filled). 00481 void flushTableInfo() const; 00482 00483 // Get the table description. 00484 // This can be used to get nr of columns, etc.. 00485 // <src>tableDesc()</src> gives the table description used when 00486 // constructing the table, while <src>actualTableDesc()</src> gives the 00487 // actual description, thus with the actual data managers used. 00488 // <group> 00489 const TableDesc& tableDesc() const; 00490 TableDesc actualTableDesc() const; 00491 // </group> 00492 00493 // Return all data managers used and the columns served by them. 00494 // The info is returned in a record. It contains a subrecord per 00495 // data manager. Each subrecord contains the following fields: 00496 // <dl> 00497 // <dt> TYPE 00498 // <dd> a string giving the type of the data manager. 00499 // <dt> NAME 00500 // <dd> a string giving the name of the data manager. 00501 // <dt> COLUMNS 00502 // <dd> a vector of strings giving the columns served by the data manager. 00503 // </dl> 00504 // Data managers may return some additional fields (e.g. BUCKETSIZE). 00505 Record dataManagerInfo() const; 00506 00507 // Get the table name. 00508 const String& tableName() const; 00509 00510 // Rename the table and all its subtables. 00511 // The following options can be given: 00512 // <dl> 00513 // <dt> Table::Update 00514 // <dd> A table with this name must already exists, which will be 00515 // overwritten. When succesfully renamed, the table is unmarked 00516 // for delete (if necessary). 00517 // <dt> Table::New 00518 // <dd> When a table with this name exists, it will be overwritten. 00519 // When succesfully renamed, the table is unmarked 00520 // for delete (if necessary). 00521 // <dt> Table::NewNoReplace 00522 // <dd> When a table with this name already exists, an exception 00523 // is thrown. When succesfully renamed, the table 00524 // is unmarked for delete (if necessary). 00525 // <dt> Table::Scratch 00526 // <dd> Same as Table::New, but followed by markForDelete(). 00527 // </dl> 00528 // The scratchCallback function is called when needed. 00529 void rename (const String& newName, TableOption); 00530 00531 // Copy the table and all its subtables. 00532 // Especially for RefTables <src>copy</src> and <src>deepCopy</src> behave 00533 // differently. <src>copy</src> makes a bitwise copy of the table, thus 00534 // the result is still a RefTable. On the other hand <src>deepCopy</src> 00535 // makes a physical copy of all referenced table rows and columns, thus 00536 // the result is a PlainTable. 00537 // <br>For PlainTables <src>deepCopy</src> is the same as <src>copy</src> 00538 // unless <src>valueCopy==True</src> is given. In that case the values 00539 // are copied which takes longer, but reorganizes the data files to get 00540 // rid of gaps in the data. Also if specific DataManager info is given 00541 // or if no rows have to be copied, a deep copy is made. 00542 // <br>The following options can be given: 00543 // <dl> 00544 // <dt> Table::New 00545 // <dd> When a table with this name exists, it will be overwritten. 00546 // <dt> Table::NewNoReplace 00547 // <dd> When a table with this name already exists, an exception 00548 // is thrown. 00549 // <dt> Table::Scratch 00550 // <dd> Same as Table::New, but followed by markForDelete(). 00551 // </dl> 00552 // The new table gets the given endian format. Note that the endian option 00553 // is only used if a true deep copy of a table is made. 00554 // <br>When making a deep copy, it is possible to specify the data managers 00555 // using the <src>dataManagerInfo</src> argument. 00556 // See <src>getDataManagerInfo</src> for more info about that record. 00557 // <br>If <src>noRows=True</src> no rows are copied. Also no rows are 00558 // copied in all subtables. It is useful if one wants to make a copy 00559 // of only the Table structure. 00560 // <group> 00561 void copy (const String& newName, TableOption, Bool noRows=False) const; 00562 void deepCopy (const String& newName, 00563 TableOption, Bool valueCopy=False, 00564 EndianFormat=AipsrcEndian, 00565 Bool noRows=False) const; 00566 void deepCopy (const String& newName, const Record& dataManagerInfo, 00567 TableOption, Bool valueCopy=False, 00568 EndianFormat=AipsrcEndian, 00569 Bool noRows=False) const; 00570 // </group> 00571 00572 // Make a copy of a table to a MemoryTable object. 00573 // Use the given name for the memory table. 00574 Table copyToMemoryTable (const String& name, Bool noRows=False) const; 00575 00576 // Get the table type. 00577 TableType tableType() const; 00578 00579 // Get the table option. 00580 int tableOption() const; 00581 00582 // Mark the table for delete. 00583 // This means that the underlying table gets deleted when it is 00584 // actually destructed. 00585 // The scratchCallback function is called when needed. 00586 void markForDelete(); 00587 00588 // Unmark the table for delete. 00589 // This means the underlying table does not get deleted when destructed. 00590 // The scratchCallback function is called when needed. 00591 void unmarkForDelete(); 00592 00593 // Test if the table is marked for delete. 00594 Bool isMarkedForDelete() const; 00595 00596 // Get the number of rows. 00597 // It is unsynchronized meaning that it will not check if another 00598 // process updated the table, thus possible increased the number of rows. 00599 // If one wants to take that into account, he should acquire a 00600 // read-lock (using the lock function) before using nrow(). 00601 uInt nrow() const; 00602 00603 // Test if it is possible to add a row to this table. 00604 // It is possible if all storage managers used for the table 00605 // support it. 00606 Bool canAddRow() const; 00607 00608 // Add one or more rows at the end of the table. 00609 // This will fail for tables not supporting addition of rows. 00610 // Optionally the rows can be initialized with the default 00611 // values as defined in the column descriptions. 00612 void addRow (uInt nrrow = 1, Bool initialize = False); 00613 00614 // Test if it is possible to remove a row from this table. 00615 // It is possible if all storage managers used for the table 00616 // support it. 00617 Bool canRemoveRow() const; 00618 00619 // Remove the given row(s). 00620 // The latter form can be useful with the select and rowNumbers functions 00621 // to remove some selected rows from the table. 00622 // <br>It will fail for tables not supporting removal of rows. 00623 // <note role=warning> 00624 // The following code fragments do NOT have the same result: 00625 // <srcblock> 00626 // tab.removeRow (10); // remove row 10 00627 // tab.removeRow (20); // remove row 20, which was 21 00628 // Vector<uInt> vec(2); 00629 // vec(0) = 10; 00630 // vec(1) = 20; 00631 // tab.removeRow (vec); // remove row 10 and 20 00632 // </srcblock> 00633 // because in the first fragment removing row 10 turns the former 00634 // row 21 into row 20. 00635 // </note> 00636 // <group> 00637 void removeRow (uInt rownr); 00638 void removeRow (const Vector<uInt>& rownrs); 00639 // </group> 00640 00641 // Create a TableExprNode object for a column or for a keyword 00642 // in the table keyword set. 00643 // This can be used in selecting rows from a table using 00644 // <src>operator()</src> described below. 00645 // <br>The functions taking the fieldNames vector are meant for 00646 // the cases where the keyword or column contains records. 00647 // The fieldNames indicate which field to take from that record 00648 // (which can be a record again, etc.). 00649 // <group name=keycol> 00650 TableExprNode key (const String& keywordName) const; 00651 TableExprNode key (const Vector<String>& fieldNames) const; 00652 TableExprNode col (const String& columnName) const; 00653 TableExprNode col (const String& columnName, 00654 const Vector<String>& fieldNames) const; 00655 TableExprNode keyCol (const String& name, 00656 const Vector<String>& fieldNames) const; 00657 // </group> 00658 00659 // Create a TableExprNode object for the rownumber function. 00660 // 'origin' Indicates which rownumber is the first. 00661 // C++ uses origin = 0 (default) 00662 // Glish and TaQL both use origin = 1 00663 TableExprNode nodeRownr (uInt origin=0) const; 00664 00665 // Create a TableExprNode object for the rand function. 00666 TableExprNode nodeRandom () const; 00667 00668 // Select rows from a table using an select expression consisting 00669 // of TableExprNode objects. 00670 // Basic TableExprNode objects can be created with the functions 00671 // <linkto file="Table.h#keycol">key</linkto> and especially 00672 // <linkto file="Table.h#keycol">col</linkto>. 00673 // Composite TableExprNode objects, representing an expression, 00674 // can be created by applying operations (like == and +) 00675 // to the basic ones. This is described in class 00676 // <linkto class="TableExprNode:description">TableExprNode</linkto>. 00677 // For example: 00678 // <srcblock> 00679 // Table result = tab(tab.col("columnName") > 10); 00680 // </srcblock> 00681 // All rows for which the expression is true, will be selected and 00682 // "stored" in the result. 00683 // You need to include ExprNode.h for this purpose. 00684 // <br>If <src>maxRow>0</src>, the selection process will stop 00685 // when <src>maxRow</src> matching rows are found. 00686 Table operator() (const TableExprNode&, uInt maxRow=0) const; 00687 00688 // Select rows using a vector of row numbers. 00689 // This can, for instance, be used to select the same rows as 00690 // were selected in another table (using the rowNumbers function). 00691 // <srcblock> 00692 // Table result = thisTable (otherTable.rowNumbers()); 00693 // </srcblock> 00694 Table operator() (const Vector<uInt>& rownrs) const; 00695 00696 // Select rows using a mask block. 00697 // The length of the block must match the number of rows in the table. 00698 // If an element in the mask is True, the corresponding row will be 00699 // selected. 00700 Table operator() (const Block<Bool>& mask) const; 00701 00702 // Project the given columns (i.e. select the columns). 00703 Table project (const Block<String>& columnNames) const; 00704 00705 //# Virtually concatenate all tables in this column. 00706 //# The column cells must contain tables with the same description. 00707 //#// Table concatenate (const String& columnName) const; 00708 00709 // Do logical operations on a table. 00710 // It can be used for row-selected or projected (i.e. column-selected) 00711 // tables. The tables involved must come from the same root table or 00712 // be the root table themselves. 00713 // Intersection with another table. 00714 // <group> 00715 Table operator& (const Table&) const; 00716 // Union with another table. 00717 Table operator| (const Table&) const; 00718 // Subtract another table. 00719 Table operator- (const Table&) const; 00720 // Xor with another table. 00721 Table operator^ (const Table&) const; 00722 // Take complement. 00723 Table operator! () const; 00724 // </group> 00725 00726 // Sort a table on one or more columns of scalars. 00727 // Per column a compare function can be provided. By default 00728 // the standard compare function defined in Compare.h will be used. 00729 // Default sort order is ascending. 00730 // Default sorting algorithm is the heapsort. 00731 // Sort on one column. 00732 // <group> 00733 Table sort (const String& columnName, 00734 int = Sort::Ascending, 00735 int = Sort::HeapSort) const; 00736 // Sort on multiple columns. The principal column has to be the 00737 // first element in the Block of column names. 00738 Table sort (const Block<String>& columnNames, 00739 int = Sort::Ascending, 00740 int = Sort::HeapSort) const; 00741 // Sort on multiple columns. The principal column has to be the 00742 // first element in the Block of column names. 00743 // The order can be given per column. 00744 Table sort (const Block<String>& columnNames, 00745 const Block<Int>& sortOrders, 00746 int = Sort::HeapSort) const; 00747 // Sort on multiple columns. The principal column has to be the 00748 // first element in the Block of column names. 00749 // The order can be given per column. 00750 // Provide some special compare functions via a function pointer. 00751 // A zero function pointer means using the standard compare function 00752 // from class <linkto class="ObjCompare:description">ObjCompare</linkto>. 00753 Table sort (const Block<String>& columnNames, 00754 const PtrBlock<ObjCompareFunc*>& compareFunctionPointers, 00755 const Block<Int>& sortOrders, 00756 int = Sort::HeapSort) const; 00757 // </group> 00758 00759 // Get a vector of row numbers in the root table of rows in this table. 00760 // In case the table is a subset of the root table, this tells which 00761 // rows of the root table are part of the subset. 00762 // In case the table is the root table itself, the result is a vector 00763 // containing the row numbers 0 .. #rows-1. 00764 // <br>Note that in general it is better to use the next 00765 // <src>rowNumbers(Table)</src> function. 00766 Vector<uInt> rowNumbers() const; 00767 00768 // Get a vector of row numbers in that table of rows in this table. 00769 // In case the table is a subset of that table, this tells which 00770 // rows of that table are part of the subset. 00771 // In case the table is that table itself, the result is a vector 00772 // containing the row numbers 0 .. #rows-1. 00773 // <note role=caution>This function is in principle meant for cases 00774 // where this table is a subset of that table. However, it can be used 00775 // for any table. In that case the returned vector contains a very high 00776 // number for rows in this table which are not part of that table. 00777 // In that way they are invalid if used elsewhere. 00778 // </note> 00779 // <srcblock> 00780 // Table tab("somename"); 00781 // Table subset = tab(some_select_expression); 00782 // Vector<uInt> rownrs = subset.rowNumbers(tab); 00783 // </srcblock> 00784 // Note that one cannot be sure that table "somename" is the root 00785 // (i.e. original) table. It may also be a subset of another table. 00786 // In the latter case doing 00787 // <br> <src> Vector<uInt> rownrs = subset.rowNumbers()</src> 00788 // does not give the row numbers in <src>tab</src>, but in the root table 00789 // (which is probably not what you want). 00790 Vector<uInt> rowNumbers (const Table& that) const; 00791 00792 // Add a column to the table. 00793 // The data manager used for the column depend on the function used. 00794 // Exceptions are thrown when the column already exist or when the 00795 // table is not writable. 00796 // Use the first appropriate existing storage manager. 00797 // When there is none, a data manager is created using the default 00798 // data manager in the column description. 00799 // <group> 00800 void addColumn (const ColumnDesc& columnDesc); 00801 // Use an existing data manager with the given name or type. 00802 // When the flag byName is True, a name is given, otherwise a type. 00803 // When a name is given, an exception is thrown if the data manager is 00804 // unknown or does not allow addition of columns. 00805 // When a type is given, a storage manager of the given type will be 00806 // created when there is no such data manager allowing addition of rows. 00807 void addColumn (const ColumnDesc& columnDesc, 00808 const String& dataManager, Bool byName); 00809 // Use the given data manager (which is a new one). 00810 void addColumn (const ColumnDesc& columnDesc, 00811 const DataManager& dataManager); 00812 // </group> 00813 00814 // Add a bunch of columns using the given new data manager. 00815 // All columns and possible hypercolumn definitions in the given table 00816 // description will be copied and added to the table. 00817 // This can be used in case of specific data managers which need to 00818 // be created with more than one column (e.g. the tiled hypercube 00819 // storage managers). 00820 // The data manager can be given directly or by means of a record 00821 // describing the data manager in the standard way with the fields 00822 // TYPE, NAME, and SPEC. The record can contain those fields itself 00823 // or it can contain a single subrecord with those fields. 00824 // <group> 00825 void addColumn (const TableDesc& tableDesc, 00826 const DataManager& dataManager); 00827 void addColumn (const TableDesc& tableDesc, 00828 const Record& dataManagerInfo); 00829 // </group> 00830 00831 // Test if columns can be removed. 00832 // It can if the columns exist and if the data manager it is using 00833 // supports removal of columns or if all columns from a data manager 00834 // would be removed.. 00835 // <br>You can always remove columns from a reference table. 00836 // <group> 00837 Bool canRemoveColumn (const String& columnName) const; 00838 Bool canRemoveColumn (const Vector<String>& columnNames) const; 00839 // </group> 00840 00841 // Remove columns. 00842 // <br>When removing columns from a reference table, the columns 00843 // are NOT removed from the underlying table. 00844 // <group> 00845 void removeColumn (const String& columnName); 00846 void removeColumn (const Vector<String>& columnName); 00847 // </group> 00848 00849 // Test if a column can be renamed. 00850 Bool canRenameColumn (const String& columnName) const; 00851 00852 // Rename a column. 00853 // An exception is thrown if the old name does not exist or 00854 // if the name already exists. 00855 // <note role=caution> 00856 // Renaming a column should be done with care, because other 00857 // columns may be referring this column. Also a hypercolumn definition 00858 // might be using the old name. 00859 // Finally if may also invalidate persistent selections of a table, 00860 // because the reference table cannot find the column anymore. 00861 // </note> 00862 void renameColumn (const String& newName, const String& oldName); 00863 00864 // Write a table to AipsIO (for <src>TypedKeywords<Table></src>). 00865 // This will only write the table name. 00866 friend AipsIO& operator<< (AipsIO&, const Table&); 00867 00868 // Read a table from AipsIO (for <src>TypedKeywords<Table></src>). 00869 // This will read the table name and open the table as writable 00870 // if the table file is writable, otherwise as readonly. 00871 friend AipsIO& operator>> (AipsIO&, Table&); 00872 00873 // Read a table from AipsIO (for <src>TableKeywords</src>). 00874 // This will read the table name and open the table as writable 00875 // if the switch is set and if the table file is writable. 00876 // otherwise it is opened as readonly. 00877 void getTableKeyword (AipsIO&, Bool openWritable); 00878 00879 // Write a table to ostream (for <src>TypedKeywords<Table></src>). 00880 // This only shows its name and number of columns and rows. 00881 friend ostream& operator<< (ostream&, const Table&); 00882 00883 protected: 00884 BaseTable* baseTabPtr_p; //# ptr to table representation 00885 //# The isCounted_p flag is normally true. 00886 //# Only for internally used Table objects (i.e. in the DataManager) 00887 //# this flag is False, otherwise a mutual dependency would exist. 00888 //# The DataManager has a Table object, which gets deleted by the 00889 //# DataManager destructor. The DataManager gets deleted by the 00890 //# PlainTable destructor, which gets called when the last Table 00891 //# object gets destructed. That would never be the case if this 00892 //# internally used Table object was counted. 00893 Bool isCounted_p; 00894 //# Counter of last call to hasDataChanged. 00895 uInt lastModCounter_p; 00896 //# Pointer to the ScratchCallback function. 00897 static ScratchCallback* scratchCallback_p; 00898 00899 00900 // Construct a Table object from a BaseTable*. 00901 // By default the object gets counted. 00902 Table (BaseTable*, Bool countIt = True); 00903 00904 // Open an existing table. 00905 void open (const String& name, const String& type, int tableOption, 00906 const TableLock& lockOptions); 00907 00908 00909 private: 00910 // Construct a BaseTable object from the table file. 00911 static BaseTable* makeBaseTable (const String& name, const String& type, 00912 int tableOption, 00913 const TableLock& lockOptions, 00914 Bool addToCache, uInt locknr); 00915 00916 00917 // Get the pointer to the underlying BaseTable. 00918 // This is needed for some friend classes. 00919 BaseTable* baseTablePtr() const; 00920 00921 // Look in the cache if the table is already open. 00922 // If so, check if table option matches. 00923 // If needed reopen the table for read/write and merge the lock options. 00924 BaseTable* lookCache (const String& name, int tableOption, 00925 const TableLock& tableInfo); 00926 00927 // Find the data manager with the given name. 00928 DataManager* findDataManager (const String& datamanagerName) const; 00929 }; 00930 00931 00932 00933 inline Bool Table::isSameRoot (const Table& other) const 00934 { return baseTabPtr_p->root() == other.baseTabPtr_p->root(); } 00935 00936 inline void Table::reopenRW() 00937 { baseTabPtr_p->reopenRW(); } 00938 inline void Table::flush (Bool fsync, Bool recursive) 00939 { baseTabPtr_p->flush (fsync, recursive);} 00940 inline void Table::resync() 00941 { baseTabPtr_p->resync(); } 00942 00943 inline Bool Table::isMultiUsed(Bool checkSubTables) const 00944 { return baseTabPtr_p->isMultiUsed(checkSubTables); } 00945 inline const TableLock& Table::lockOptions() const 00946 { return baseTabPtr_p->lockOptions(); } 00947 inline Bool Table::lock (FileLocker::LockType type, uInt nattempts) 00948 { return baseTabPtr_p->lock (type, nattempts); } 00949 inline Bool Table::lock (Bool write, uInt nattempts) 00950 { 00951 return baseTabPtr_p->lock (write ? FileLocker::Write : FileLocker::Read, 00952 nattempts); 00953 } 00954 inline void Table::unlock() 00955 { baseTabPtr_p->unlock(); } 00956 inline Bool Table::hasLock (FileLocker::LockType type) const 00957 { return baseTabPtr_p->hasLock (type); } 00958 inline Bool Table::hasLock (Bool write) const 00959 { 00960 return baseTabPtr_p->hasLock (write ? FileLocker::Write : FileLocker::Read); 00961 } 00962 00963 inline Bool Table::isRootTable() const 00964 { return baseTabPtr_p == baseTabPtr_p->root(); } 00965 00966 inline Bool Table::isWritable() const 00967 { return baseTabPtr_p->isWritable(); } 00968 inline Bool Table::isColumnWritable (const String& columnName) const 00969 { return baseTabPtr_p->isColumnWritable (columnName); } 00970 inline Bool Table::isColumnWritable (uInt columnIndex) const 00971 { return baseTabPtr_p->isColumnWritable (columnIndex); } 00972 00973 inline Bool Table::isColumnStored (const String& columnName) const 00974 { return baseTabPtr_p->isColumnStored (columnName); } 00975 inline Bool Table::isColumnStored (uInt columnIndex) const 00976 { return baseTabPtr_p->isColumnStored (columnIndex); } 00977 00978 inline void Table::rename (const String& newName, TableOption option) 00979 { baseTabPtr_p->rename (newName, option); } 00980 inline void Table::deepCopy (const String& newName, 00981 const Record& dataManagerInfo, 00982 TableOption option, 00983 Bool valueCopy, 00984 EndianFormat endianFormat, 00985 Bool noRows) const 00986 { baseTabPtr_p->deepCopy (newName, dataManagerInfo, option, valueCopy, 00987 endianFormat, noRows); } 00988 inline void Table::markForDelete() 00989 { baseTabPtr_p->markForDelete (True, ""); } 00990 inline void Table::unmarkForDelete() 00991 { baseTabPtr_p->unmarkForDelete(True, ""); } 00992 inline Bool Table::isMarkedForDelete() const 00993 { return baseTabPtr_p->isMarkedForDelete(); } 00994 00995 inline uInt Table::nrow() const 00996 { return baseTabPtr_p->nrow(); } 00997 inline BaseTable* Table::baseTablePtr() const 00998 { return baseTabPtr_p; } 00999 inline const TableDesc& Table::tableDesc() const 01000 { return baseTabPtr_p->tableDesc(); } 01001 inline const TableRecord& Table::keywordSet() const 01002 { return baseTabPtr_p->keywordSet(); } 01003 01004 inline TableInfo Table::tableInfo (const String& tableName) 01005 { return BaseTable::tableInfo (tableName); } 01006 inline const TableInfo& Table::tableInfo() const 01007 { return baseTabPtr_p->tableInfo(); } 01008 inline TableInfo& Table::tableInfo() 01009 { return baseTabPtr_p->tableInfo(); } 01010 inline void Table::flushTableInfo() const 01011 { baseTabPtr_p->flushTableInfo(); } 01012 01013 inline const String& Table::tableName() const 01014 { return baseTabPtr_p->tableName(); } 01015 inline Table::TableType Table::tableType() const 01016 { return TableType(baseTabPtr_p->tableType()); } 01017 inline int Table::tableOption() const 01018 { return baseTabPtr_p->tableOption(); } 01019 01020 inline Bool Table::canAddRow() const 01021 { return baseTabPtr_p->canAddRow(); } 01022 inline Bool Table::canRemoveRow() const 01023 { return baseTabPtr_p->canRemoveRow(); } 01024 inline Bool Table::canRemoveColumn (const Vector<String>& columnNames) const 01025 { return baseTabPtr_p->canRemoveColumn (columnNames); } 01026 inline Bool Table::canRenameColumn (const String& columnName) const 01027 { return baseTabPtr_p->canRenameColumn (columnName); } 01028 01029 inline void Table::addRow (uInt nrrow, Bool initialize) 01030 { baseTabPtr_p->addRow (nrrow, initialize); } 01031 inline void Table::removeRow (uInt rownr) 01032 { baseTabPtr_p->removeRow (rownr); } 01033 inline void Table::removeRow (const Vector<uInt>& rownrs) 01034 { baseTabPtr_p->removeRow (rownrs); } 01035 inline void Table::addColumn (const ColumnDesc& columnDesc) 01036 { baseTabPtr_p->addColumn (columnDesc); } 01037 inline void Table::addColumn (const ColumnDesc& columnDesc, 01038 const String& dataManager, Bool byName) 01039 { baseTabPtr_p->addColumn (columnDesc, dataManager, byName); } 01040 inline void Table::addColumn (const ColumnDesc& columnDesc, 01041 const DataManager& dataManager) 01042 { baseTabPtr_p->addColumn (columnDesc, dataManager); } 01043 inline void Table::addColumn (const TableDesc& tableDesc, 01044 const DataManager& dataManager) 01045 { baseTabPtr_p->addColumn (tableDesc, dataManager); } 01046 inline void Table::addColumn (const TableDesc& tableDesc, 01047 const Record& dataManagerInfo) 01048 { baseTabPtr_p->addColumns (tableDesc, dataManagerInfo); } 01049 inline void Table::removeColumn (const Vector<String>& columnNames) 01050 { baseTabPtr_p->removeColumn (columnNames); } 01051 inline void Table::renameColumn (const String& newName, const String& oldName) 01052 { baseTabPtr_p->renameColumn (newName, oldName); } 01053 01054 inline DataManager* Table::findDataManager (const String& name) const 01055 { 01056 return baseTabPtr_p->findDataManager (name); 01057 } 01058 01059 01060 01061 } //# NAMESPACE CASA - END 01062 01063 #endif
1.5.1