casa
$Rev:20696$
|
00001 //# BaseTable.h: Abstract base class for tables 00002 //# Copyright (C) 1994,1995,1996,1997,1998,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 received 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: BaseTable.h 21025 2011-03-03 15:09:00Z gervandiepen $ 00027 00028 #ifndef TABLES_BASETABLE_H 00029 #define TABLES_BASETABLE_H 00030 00031 00032 //# Includes 00033 #include <casa/aips.h> 00034 #include <tables/Tables/TableInfo.h> 00035 #include <tables/Tables/TableDesc.h> 00036 #include <casa/Utilities/Compare.h> 00037 #include <casa/Utilities/CountedPtr.h> 00038 #include <casa/BasicSL/String.h> 00039 #include <casa/IO/FileLocker.h> 00040 00041 namespace casa { //# NAMESPACE CASA - BEGIN 00042 00043 //# Forward Declarations 00044 class RefTable; 00045 // class TableDesc; !Forward declaration not recognized SGI compiler 00046 class TableLock; 00047 class BaseColumn; 00048 class ColumnDesc; 00049 class TableRecord; 00050 class Record; 00051 class TableExprNode; 00052 class BaseTableIterator; 00053 class DataManager; 00054 class IPosition; 00055 template<class T> class Vector; 00056 template<class T> class Block; 00057 template<class T> class PtrBlock; 00058 class AipsIO; 00059 00060 00061 // <summary> 00062 // Abstract base class for tables 00063 // </summary> 00064 00065 // <use visibility=local> 00066 00067 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests=""> 00068 // </reviewed> 00069 00070 // <prerequisite> 00071 //# Classes you should understand before using this one. 00072 // <li> Table 00073 // <li> Sort 00074 // <li> TableExprNode 00075 // </prerequisite> 00076 00077 // <etymology> 00078 // BaseTable is the (abstract) base class for different kind of tables. 00079 // </etymology> 00080 00081 // <synopsis> 00082 // BaseTables defines many virtual functions, which are actually 00083 // implemented in the underlying table classes like PlainTable and 00084 // RefTable. Other functions like sort and select are implemented 00085 // in BaseTable itself. 00086 // 00087 // The functions in BaseTable and its derived classes can only be 00088 // used by the table system classes. All user access is via the 00089 // envelope class Table, which references (counted) BaseTable. 00090 // </synopsis> 00091 00092 // <todo asof="$DATE:$"> 00093 //# A List of bugs, limitations, extensions or planned refinements. 00094 // <li> Implement function renameColumn, removeColumn. 00095 // </todo> 00096 00097 00098 class BaseTable 00099 { 00100 public: 00101 00102 // Initialize the object. 00103 BaseTable (const String& tableName, int tableOption, uInt nrrow); 00104 00105 virtual ~BaseTable(); 00106 00107 // Link to this BaseTable object (i.e. increase reference count). 00108 void link(); 00109 00110 // Unlink from a BaseTable. 00111 // Delete it if no more references. 00112 static void unlink (BaseTable*); 00113 00114 // Is the table a null table? 00115 // By default it is not. 00116 virtual Bool isNull() const; 00117 00118 // Reopen the table for read/write. 00119 virtual void reopenRW() = 0; 00120 00121 // Is the table stored in big or little endian format? 00122 virtual Bool asBigEndian() const = 0; 00123 00124 // Is the table in use (i.e. open) in another process? 00125 // If <src>checkSubTables</src> is set, it is also checked if 00126 // a subtable is used in another process. 00127 virtual Bool isMultiUsed(Bool checkSubTables) const = 0; 00128 00129 // Get the locking info. 00130 virtual const TableLock& lockOptions() const = 0; 00131 00132 // Merge the given lock info with the existing one. 00133 virtual void mergeLock (const TableLock& lockOptions) = 0; 00134 00135 // Has this process the read or write lock, thus can the table 00136 // be read or written safely? 00137 virtual Bool hasLock (FileLocker::LockType) const = 0; 00138 00139 // Try to lock the table for read or write access. 00140 virtual Bool lock (FileLocker::LockType, uInt nattempts) = 0; 00141 00142 // Unlock the table. This will also synchronize the table data, 00143 // thus force the data to be written to disk. 00144 virtual void unlock() = 0; 00145 00146 // Flush the table, i.e. write it to disk. 00147 virtual void flush (Bool fsync, Bool recursive) = 0; 00148 00149 // Resync the Table object with the table file. 00150 virtual void resync() = 0; 00151 00152 // Get the modify counter. 00153 virtual uInt getModifyCounter() const = 0; 00154 00155 // Set the table to being changed. By default it does nothing. 00156 virtual void setTableChanged(); 00157 00158 // Do not write the table (used in in case of exceptions). 00159 void doNotWrite() 00160 { noWrite_p = True; } 00161 00162 // Test if this table is writable. 00163 // This tells if values can be put into a column. 00164 virtual Bool isWritable() const = 0; 00165 00166 // Test if the given column is writable. 00167 // <group> 00168 Bool isColumnWritable (const String& columnName) const; 00169 Bool isColumnWritable (uInt columnIndex) const; 00170 // </group> 00171 00172 // Test if the given column is stored (otherwise it is virtual). 00173 // <group> 00174 Bool isColumnStored (const String& columnName) const; 00175 Bool isColumnStored (uInt columnIndex) const; 00176 // </group> 00177 00178 // Get the table name. 00179 const String& tableName() const 00180 { return name_p; } 00181 00182 // Get the names of the tables this table consists of. 00183 // The default implementation adds the name of this table to the block. 00184 virtual void getPartNames (Block<String>& names, Bool recursive) const; 00185 00186 // Rename the table. 00187 // The following options can be given: 00188 // <dl> 00189 // <dt> Table::Update 00190 // <dd> A table with this name must already exists, which will be 00191 // overwritten. When succesfully renamed, the table is unmarked 00192 // for delete (if necessary). 00193 // <dt> Table::New 00194 // <dd> When a table with this name exists, it will be overwritten. 00195 // When succesfully renamed, the table is unmarked 00196 // for delete (if necessary). 00197 // <dt> Table::NewNoReplace 00198 // <dd> When a table with this name already exists, an exception 00199 // is thrown. When succesfully renamed, the table 00200 // is unmarked for delete (if necessary). 00201 // <dt> Table::Scratch 00202 // <dd> Same as Table::New, but followed by markForDelete(). 00203 // </dl> 00204 // The rename function in this base class renames the table file. 00205 // In a derived class (e.g. PlainTable) the function should also 00206 // be implemented to rename subtables in its keywords. 00207 virtual void rename (const String& newName, int tableOption); 00208 00209 // Copy the table and all its subtables. 00210 // The default implementation of deepCopy is to call copy. 00211 // The following options can be given: 00212 // <dl> 00213 // <dt> Table::New 00214 // <dd> When a table with this name exists, it will be overwritten. 00215 // <dt> Table::NewNoReplace 00216 // <dd> When a table with this name already exists, an exception 00217 // is thrown. 00218 // <dt> Table::Scratch 00219 // <dd> Same as Table::New, but followed by markForDelete(). 00220 // </dl> 00221 // <group> 00222 virtual void copy (const String& newName, int tableOption) const; 00223 virtual void deepCopy (const String& newName, 00224 const Record& dataManagerInfo, 00225 int tableOption, 00226 Bool valueCopy, 00227 int endianFormat, 00228 Bool noRows) const; 00229 // </group> 00230 00231 // Get the table type. 00232 // By default it returns Table::Plain. 00233 virtual int tableType() const; 00234 00235 // Get the table option. 00236 int tableOption() const 00237 { return option_p; } 00238 00239 // Mark the table for delete. 00240 // This means that the underlying table gets deleted when it is 00241 // actually destructed. 00242 // The scratchCallback function is called when needed. 00243 void markForDelete (Bool callback, const String& oldName); 00244 00245 // Unmark the table for delete. 00246 // This means the underlying table does not get deleted when destructed. 00247 // The scratchCallback function is called when needed. 00248 void unmarkForDelete (Bool callback, const String& oldName); 00249 00250 // Test if the table is marked for delete. 00251 Bool isMarkedForDelete() const 00252 { return delete_p; } 00253 00254 // Get the table description. 00255 const TableDesc& tableDesc() const 00256 { return (tdescPtr_p == 0 ? makeTableDesc() : *tdescPtr_p); } 00257 00258 // Get the actual table description. 00259 virtual TableDesc actualTableDesc() const = 0; 00260 00261 // Get the data manager info. 00262 virtual Record dataManagerInfo() const = 0; 00263 00264 // Show the table structure (implementation of Table::showStructure). 00265 void showStructure (std::ostream&, 00266 Bool showDataMan, 00267 Bool showColumns, 00268 Bool showSubTables, 00269 Bool sortColumns); 00270 00271 // Get readonly access to the table keyword set. 00272 virtual TableRecord& keywordSet() = 0; 00273 00274 // Get read/write access to the table keyword set. 00275 // This requires that the table is locked (or it gets locked 00276 // when using AutoLocking mode). 00277 virtual TableRecord& rwKeywordSet() = 0; 00278 00279 // Get access to the TableInfo object. 00280 TableInfo& tableInfo() 00281 { return info_p; } 00282 00283 // Get the table info of the table with the given name. 00284 // An empty object is returned when the table is unknown. 00285 static TableInfo tableInfo (const String& tableName); 00286 00287 // Write the TableInfo object. 00288 virtual void flushTableInfo(); 00289 00290 // Get number of rows. 00291 uInt nrow() const 00292 { return nrrow_p; } 00293 00294 // Get a column object using its index. 00295 virtual BaseColumn* getColumn (uInt columnIndex) const = 0; 00296 00297 // Get a column object using its name. 00298 virtual BaseColumn* getColumn (const String& columnName) const = 0; 00299 00300 // Test if it is possible to add a row to this table. 00301 virtual Bool canAddRow() const; 00302 00303 // Add one or more rows and possibly initialize them. 00304 // This will fail for tables not supporting addition of rows. 00305 virtual void addRow (uInt nrrow = 1, Bool initialize = True); 00306 00307 // Test if it is possible to remove a row from this table. 00308 virtual Bool canRemoveRow() const; 00309 00310 // Remove rows. 00311 // This will fail for tables not supporting removal of rows. 00312 // <note role=tip> 00313 // The following code fragments do NOT have the same result: 00314 // <srcblock> 00315 // tab.removeRow (10); // remove row 10 00316 // tab.removeRow (20); // remove row 20, which was 21 00317 // 00318 // Vector<uInt> vec(2); 00319 // vec(0) = 10; 00320 // vec(1) = 20; 00321 // tab.removeRow (vec); // remove row 10 and 20 00322 // </srcblock> 00323 // because in the first fragment removing row 10 turns the former 00324 // row 21 into row 20. 00325 // </note> 00326 // <group> 00327 virtual void removeRow (uInt rownr); 00328 void removeRow (const Vector<uInt>& rownrs); 00329 // </group> 00330 00331 // Find the data manager with the given name or for the given column. 00332 virtual DataManager* findDataManager (const String& name, 00333 Bool byColumn) const = 0; 00334 00335 // Select rows using the given expression. 00336 BaseTable* select (const TableExprNode&, uInt maxRow); 00337 00338 // Select maxRow rows. maxRow=0 means all. 00339 BaseTable* select (uInt maxRow); 00340 00341 // Select rows using a vector of row numbers. 00342 BaseTable* select (const Vector<uInt>& rownrs); 00343 00344 // Select rows using a mask block. 00345 // The length of the block must match the number of rows in the table. 00346 // If True, the corresponding row will be selected. 00347 BaseTable* select (const Block<Bool>& mask); 00348 00349 // Project the given columns (i.e. select the columns). 00350 BaseTable* project (const Block<String>& columnNames); 00351 00352 //# Virtually concatenate all tables in this column. 00353 //# The column cells must contain tables with the same description. 00354 //#// BaseTable* concatenate (const String& columnName); 00355 00356 // Do logical operations on a table. 00357 // <group> 00358 // intersection with another table 00359 BaseTable* tabAnd (BaseTable*); 00360 // union with another table 00361 BaseTable* tabOr (BaseTable*); 00362 // subtract another table 00363 BaseTable* tabSub (BaseTable*); 00364 // xor with another table 00365 BaseTable* tabXor (BaseTable*); 00366 // take complement 00367 BaseTable* tabNot (); 00368 // </group> 00369 00370 // Sort a table on one or more columns of scalars. 00371 BaseTable* sort (const Block<String>& columnNames, 00372 const Block<CountedPtr<BaseCompare> >& compareObjects, 00373 const Block<Int>& sortOrder, int sortOption); 00374 00375 // Create an iterator. 00376 BaseTableIterator* makeIterator (const Block<String>& columnNames, 00377 const Block<CountedPtr<BaseCompare> >&, 00378 const Block<Int>& orders, int option); 00379 00380 // Add one or more columns to the table. 00381 // The default implementation throws an "invalid operation" exception. 00382 // <group> 00383 virtual void addColumn (const ColumnDesc& columnDesc, Bool addToParent); 00384 virtual void addColumn (const ColumnDesc& columnDesc, 00385 const String& dataManager, Bool byName, 00386 Bool addToParent); 00387 virtual void addColumn (const ColumnDesc& columnDesc, 00388 const DataManager& dataManager, Bool addToParent); 00389 virtual void addColumn (const TableDesc& tableDesc, 00390 const DataManager& dataManager, Bool addToParent); 00391 // </group> 00392 00393 // Add one or more columns to the table. 00394 // The data manager to use is described in the record. 00395 void addColumns (const TableDesc& tableDesc, const Record& dmInfo, 00396 Bool addToParent); 00397 00398 // Test if columns can be removed. 00399 virtual Bool canRemoveColumn (const Vector<String>& columnNames) const = 0; 00400 00401 // Remove columns. 00402 virtual void removeColumn (const Vector<String>& columnNames) = 0; 00403 00404 // Check if the set of columns can be removed. 00405 // It checks if columns have not been specified twice and it 00406 // checks if they exist. 00407 // If the flag is set an exception is thrown if errors are found. 00408 Bool checkRemoveColumn (const Vector<String>& columnNames, 00409 Bool throwException) const; 00410 00411 // Test if a column can be renamed. 00412 virtual Bool canRenameColumn (const String& columnName) const = 0; 00413 00414 // Rename a column. 00415 virtual void renameColumn (const String& newName, 00416 const String& oldName) = 0; 00417 00418 // Rename a hypercolumn. 00419 virtual void renameHypercolumn (const String& newName, 00420 const String& oldName) = 0; 00421 00422 // Get a vector of row numbers. 00423 // By default it returns the row numbers 0..nrrow()-1. 00424 // It needs to be implemented for RefTable only. 00425 virtual Vector<uInt> rowNumbers() const; 00426 00427 // Get pointer to root table (i.e. parent of a RefTable). 00428 // Default it is this table. 00429 // It is meant for the reference tables after a select or sort which 00430 // can then still name their parent as the root. 00431 virtual BaseTable* root(); 00432 00433 // Tell if the table is in row order. 00434 // By default it is, since normally a table is always in row order. 00435 // It is meant for RefTable-s, where the rows can be in 00436 // another (sorted) order. 00437 virtual Bool rowOrder() const; 00438 00439 // By the default the table cannot return the storage of rownrs. 00440 // That can only be done by a RefTable, where it is implemented. 00441 virtual Vector<uInt>* rowStorage(); 00442 00443 // Adjust the row numbers to be the actual row numbers in the 00444 // root table. This is, for instance, used when a RefTable is sorted. 00445 // Optionally it also determines if the resulting rows are in order. 00446 virtual Bool adjustRownrs (uInt nrrow, Vector<uInt>& rownrs, 00447 Bool determineOrder) const; 00448 00449 // Do the actual sort. 00450 // The default implementation is suitable for almost all cases. 00451 // Only in RefTable a smarter implementation is provided. 00452 virtual BaseTable* doSort (PtrBlock<BaseColumn*>&, 00453 const Block<CountedPtr<BaseCompare> >&, 00454 const Block<Int>& sortOrder, 00455 int sortOption); 00456 00457 // Create a RefTable object. 00458 RefTable* makeRefTable (Bool rowOrder, uInt initialNrrow); 00459 00460 // Check if the row number is valid. 00461 // It throws an exception if out of range. 00462 void checkRowNumber (uInt rownr) const 00463 { if (rownr >= nrrow_p + nrrowToAdd_p) checkRowNumberThrow (rownr); } 00464 00465 00466 protected: 00467 uInt nrlink_p; //# #references to this table 00468 uInt nrrow_p; //# #rows in this table 00469 uInt nrrowToAdd_p; //# #rows to be added 00470 TableDesc* tdescPtr_p; //# Pointer to table description 00471 String name_p; //# table name 00472 int option_p; //# Table constructor option 00473 Bool noWrite_p; //# False = do not write the table 00474 Bool delete_p; //# True = delete when destructed 00475 TableInfo info_p; //# Table information (type, etc.) 00476 Bool madeDir_p; //# True = table dir has been created 00477 00478 00479 // Do the callback for scratch tables (if callback is set). 00480 void scratchCallback (Bool isScratch, const String& oldName) const; 00481 00482 // Create the table directory when needed (and possible). 00483 // When the file already exists, check if it is a directory. 00484 // It returns True when it actually created the directory. 00485 Bool makeTableDir(); 00486 00487 // Make a true deep copy of the table. 00488 void trueDeepCopy (const String& newName, 00489 const Record& dataManagerInfo, 00490 int tableOption, 00491 int endianFormat, 00492 Bool noRows) const; 00493 00494 // Prepare for copying or renaming a table. 00495 // It checks if the target table already exists and removes it 00496 // when necessary. 00497 void prepareCopyRename (const String& newName, int tableOption) const; 00498 00499 // Rename the subtables (used by rename function). 00500 virtual void renameSubTables (const String& newName, 00501 const String& oldName); 00502 00503 // Check if the table already exists. 00504 // Throw an exception if so. 00505 void throwIfTableExists(); 00506 00507 // Test if the table is opened for write. 00508 Bool openedForWrite() const; 00509 00510 // Start writing a table. It does a putstart and writes <src>nrrow_p</src>. 00511 // It should be ended by calling <src>writeEnd</src>. 00512 void writeStart (AipsIO&, Bool bigEndian); 00513 00514 // End writing a table. 00515 void writeEnd (AipsIO&); 00516 00517 // Should the table be written. 00518 // This flag is False if an exception was thrown. 00519 Bool shouldNotWrite() const 00520 { return noWrite_p; } 00521 00522 // Read the TableInfo object. 00523 void getTableInfo(); 00524 00525 private: 00526 // Copy constructor is forbidden, because copying a table requires 00527 // some more knowledge (like table name of result). 00528 // Declaring it private, makes it unusable. 00529 BaseTable (const BaseTable&); 00530 00531 // Assignment is forbidden, because copying a table requires 00532 // some more knowledge (like table name of result). 00533 // Declaring it private, makes it unusable. 00534 BaseTable& operator= (const BaseTable&); 00535 00536 // Show a possible extra table structure header. 00537 // It is used by e.g. RefTable to show which table is referenced. 00538 virtual void showStructureExtra (std::ostream&) const; 00539 00540 // Show the info of the given columns. 00541 // Sort the columns if needed. 00542 void showColumnInfo (ostream& os, const TableDesc&, uInt maxNameLength, 00543 const Array<String>& columnNames, Bool sort) const; 00544 00545 // Throw an exception for checkRowNumber. 00546 void checkRowNumberThrow (uInt rownr) const; 00547 00548 // Check if the tables combined in a logical operation have the 00549 // same root. 00550 void logicCheck (BaseTable* that); 00551 00552 // Get the rownrs of the table in ascending order to be 00553 // used in the logical operation on the table. 00554 uInt logicRows (uInt*& rownrs, Bool& allocated); 00555 00556 // Make an empty table description. 00557 // This is used if one asks for the description of a NullTable. 00558 // Creating an empty TableDesc in the NullTable takes too much time. 00559 // Furthermore it causes static initialization order problems. 00560 const TableDesc& makeTableDesc() const; 00561 }; 00562 00563 00564 00565 00566 } //# NAMESPACE CASA - END 00567 00568 #endif