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

Generated on 31 Aug 2016 for casa by  doxygen 1.6.1