casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
BaseTable.h
Go to the documentation of this file.
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