Table.h

Go to the documentation of this file.
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

Generated on Mon Sep 1 22:36:26 2008 for NRAOCASA by  doxygen 1.5.1