casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
TableDesc.h
Go to the documentation of this file.
00001 //# TableDesc.h:  specify structure of aips++ tables
00002 //# Copyright (C) 1994,1995,1996,1997,1999,2000,2001,2002
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: TableDesc.h 20739 2009-09-29 01:15:15Z Malte.Marquarding $
00027 
00028 #ifndef TABLES_TABLEDESC_H
00029 #define TABLES_TABLEDESC_H
00030 
00031 
00032 //# Includes
00033 #include <casa/aips.h>
00034 #include <tables/Tables/ColDescSet.h>
00035 #include <casa/IO/AipsIO.h>
00036 #include <casa/iosfwd.h>
00037 
00038 namespace casa { //# NAMESPACE CASA - BEGIN
00039 
00040 //# Forward Declarations
00041 class TableRecord;
00042 class TableAttr;
00043 class TabPath;
00044 template<class T> class Vector;
00045 
00046 // <summary>
00047 // Define the structure of an AIPS++ table
00048 // </summary>
00049 
00050 // <use visibility=export>
00051 
00052 // <reviewed reviewer="Paul Shannon" date="1994/08/11" tests="none">
00053 // </reviewed>
00054 
00055 // <prerequisite>
00056 //   <li> column description classes
00057 //   <li> TableRecord
00058 // </prerequisite>
00059 
00060 // <synopsis> 
00061 // A TableDesc object contains the description, or structure, of a table.
00062 // This description is required for the creation of a new table.  
00063 // Descriptions are subsequently associated with every table and
00064 // embedded in them.
00065 //
00066 // A table description consists of the following items:
00067 // <ul>
00068 //  <li> Name, which cannot be blank if the description is saved in a file.
00069 //         The file name will be this name followed by .tabdsc.
00070 //  <li> Version, which defaults to a blank string.
00071 //         It serves merely as information for the user.
00072 //  <li> Comment, which defaults to an empty string.
00073 //         This serves purely as an informational string for the user.
00074 //  <li> A set of column descriptions which has to be added to the
00075 //         table description. A column description can be created using
00076 //         the classes ScalarColumnDesc, etc..
00077 //         At table creation it is determined by the user if a column
00078 //         has to be stored using a storage manager or calculated
00079 //         on-the-fly using a so-called virtual column engine.
00080 //  <li> A keyword set, which is by default empty.
00081 //         When a table is created from the description, it gets
00082 //         a copy of this keyword set as its initial keyword set.
00083 // </ul>
00084 //
00085 // A TableDesc object can be constructed with one of the following
00086 // options:
00087 // <ul>
00088 //  <li> Old
00089 //    Open an existing table description file as readonly.
00090 //  <li> Update
00091 //    Open an existing table description file as read/write
00092 //    The TableDesc destructor will rewrite the possibly changed
00093 //    description.
00094 //  <li> New
00095 //    Create a new table description file.
00096 //    The TableDesc destructor will write the table description into the file.
00097 //  <li> NewNoReplace
00098 //    As option New, but an exception will be thrown if the table
00099 //    description file already exists.
00100 //  <li> Scratch
00101 //    Create a temporary table description. The table description will
00102 //    be lost when the TableDesc object is destructed.
00103 //    This is useful to create a Table object without storing the
00104 //    description separately.
00105 //    Note that the Table object maintains its own description (i.e. it
00106 //    copies the description when being constructed).
00107 //  <li> Delete
00108 //    Delete the table description file. This gets done by the destructor.
00109 // </ul>
00110 //
00111 // More information is provided in the Tables module documentation.
00112 // </synopsis>
00113  
00114 // <example>
00115 // <srcblock>
00116 //     // First build the new description of a subtable.
00117 //     // Define columns ra and dec (double).
00118 //     TableDesc subTableDesc("tTableDesc_sub", "1", TableDesc::New);
00119 //     subTableDesc.addColumn (ScalarColumnDesc<double>("ra"));
00120 //     subTableDesc.addColumn (ScalarColumnDesc<double>("dec"));
00121 //
00122 //     // Now create a new table description
00123 //     // Define a comment for the table description.
00124 //     // Define a double keyword.
00125 //     ColumnDesc colDesc1, colDesc2;
00126 //     TableDesc td("tTableDesc", "1", TableDesc::New);
00127 //     td.comment() = "A test of class TableDesc";
00128 //     td.rwKeywordSet().define ("equinox", 1950.0);
00129 //
00130 //     // Define an integer column ab using the TableDesc::addColumn
00131 //     // function which creates a scalar column description.
00132 //     td.addColumn (ScalarColumnDesc<Int>("ab", "Comment for column ab"));
00133 //
00134 //     // Add a scalar integer column ac, define keywords for it
00135 //     // and define a default value 0.
00136 //     // Overwrite the value of keyword unit.
00137 //     ScalarColumnDesc<Int> acColumn("ac");
00138 //     acColumn.rwKeywordSet().define ("scale", Complex(0.0f));
00139 //     acColumn.rwKeywordSet().define ("unit", "");
00140 //     acColumn.setDefault (0);
00141 //     td.addColumn (acColumn);
00142 //     td["ac"].rwKeywordSet().define ("unit", "DEG");
00143 //
00144 //     // Add a scalar string column ad and define its comment string.
00145 //     td.addColumn (ScalarColumnDesc<String>("ad","comment for ad"));
00146 //
00147 //     // Now define array columns.
00148 //     // This one is indirect and has no dimensionality mentioned yet.
00149 //     td.addColumn (ArrayColumnDesc<Complex>("Arr1","comment for Arr1"));
00150 //     // This one is indirect and has 3-dim arrays.
00151 //     td.addColumn (ArrayColumnDesc<Int>("A2r1","comment for Arr1",3));
00152 //     // This one is direct and has 2-dim arrays with axes length 4 and 7.
00153 //     td.addColumn (ArrayColumnDesc<uInt>("Arr3","comment for Arr1",
00154 //                                         IPosition(2,4,7),
00155 //                                         ColumnDesc::Direct));
00156 //
00157 //     // Add a columns containing tables.
00158 //     td.addColumn (SubTableDesc("sub1", "subtable by name",
00159 //                                "tTableDesc_sub"));
00160 //
00161 //     // Define hypercolumn "dataCube".
00162 //     td.addColumn (ArrayColumnDesc<Complex>("data",2));
00163 //     td.addColumn (ArrayColumnDesc<Int>("pol",1));
00164 //     td.addColumn (ArrayColumnDesc<float>("freq",1));
00165 //     td.addColumn (ScalarColumnDesc<float>("time"));
00166 //     td.addColumn (ScalarColumnDesc<float>("baseline"));
00167 //     td.defineHypercolumn ("dataCube", 4,
00168 //                           stringToVector ("data"),
00169 //                           stringToVector ("pol,freq,time,baseline"));
00170 // }
00171 // </srcblock>
00172 // </example>
00173 
00174 // <motivation>
00175 // A table description specifies the structure, but not the contents,
00176 // of an aips++ table.  Since many tables will have identical structure
00177 // and different content, it makes good sense to separate structure 
00178 // ("description") from content.
00179 // </motivation>
00180 
00181 //# <todo asof="$DATE:$">
00182 //# A List of bugs, limitations, extensions or planned refinements.
00183 //# </todo>
00184 
00185 
00186 class TableDesc
00187 {
00188 public:
00189 
00190     //# Enumerate the possible options for TableDesc.
00191     enum TDOption {Old=1, New, NewNoReplace, Scratch, Update, Delete};
00192 
00193     // The default constructor creates a table description with
00194     // option = Scratch and a blank name.
00195     TableDesc();
00196 
00197     // Create a table description object with the given name.
00198     // This name can be seen as the table type in the same way as a
00199     // class name is the data type of an object.
00200     // The name can only be blank when option=Scratch.
00201     // The default table description path is used for the description file.
00202     TableDesc (const String& type, TDOption = Old);
00203 
00204     // Create a table description object with the given name (i.e. table type)
00205     // and version.
00206     // The name can only be blank when option=Scratch.
00207     // The default table description path is used for the description file.
00208     TableDesc (const String& type, const String& version, TDOption = Old);
00209 
00210     // Create a table description object.
00211     // The given table description path is used for the description file.
00212     // The name can only be blank with option=Scratch.
00213     TableDesc (const String& type, const String& version,
00214                const TabPath&, TDOption = Old);
00215 
00216     // Create a table description object with the given name (i.e. table type)
00217     // and version by copying the input table description.
00218     // If the given name or version is blank, it will be copied from
00219     // the input table description.
00220     // The default table description path is used for the description file.
00221     // The only options allowed are New, NewNoReplace and Scratch.
00222     TableDesc (const TableDesc&, const String& type, const String& version,
00223                TDOption, Bool copyColumns=True);
00224 
00225     // Create a table description object with the given name (i.e. table type)
00226     // and version by copying the input table description.
00227     // If the given name or version is blank, it will be copied from
00228     // the input table description.
00229     // The given table description path is used for the description file.
00230     // The only options allowed are New, NewNoReplace and Scratch.
00231     TableDesc (const TableDesc&, const String& type, const String& version,
00232                const TabPath&, TDOption, Bool copyColumns=True);
00233 
00234     // This copy constructor makes a copy of the table description
00235     // maintaining its name and version. By default a Scratch copy is made.
00236     // It serves as a shorthand for the constructor:
00237     // <br><src> TableDesc (const TableDesc&, "", "", TDOption); </src>
00238     TableDesc (const TableDesc&, TDOption = Scratch);
00239 
00240     // The destructor writes the table description if changed.
00241     ~TableDesc();
00242 
00243     // Test if a description file exists (i.e. isReadable).
00244     static Bool isReadable (const String& tableDescName);
00245 
00246     // Get access to the set of column descriptions.
00247     // In this way const <linkto class=ColumnDescSet>ColumnDescSet</linkto>
00248     // functions (e.g. isDisjoint) can be used.
00249     const ColumnDescSet& columnDescSet() const;
00250 
00251     // Add another table description to this table description.
00252     // It merges the column descriptions, the special keywordSet
00253     // (containing hypercolumn definitions) and the user keywordSet
00254     // (this last one is not added if the flag is False).
00255     // The two table descriptions have to be disjoint, i.e. no column
00256     // nor keyword should already exist. Otherwise an TableInvOper
00257     // exception is thrown and nothing gets added.
00258     void add (const TableDesc& other, Bool addKeywordSet = True);
00259 
00260     // Get access to the keyword set.
00261     // <group>
00262     TableRecord& rwKeywordSet();
00263     const TableRecord& keywordSet() const;
00264     // </group>
00265 
00266     // Get readonly access to the private set of keywords.
00267     const TableRecord& privateKeywordSet() const;
00268 
00269     // Add a column to the table description.
00270     // An exception is thrown if a keyword or column with this name
00271     // already exists.
00272     // Although this function has a <src>ColumnDesc</src> as argument,
00273     // it is usually needed to construct a more specialized object like
00274     // <src>ArrayColumnDesc<float></src>. A <src>ColumnDesc</src>
00275     // constructor converts that automatically to a <src>ColumnDesc</src>
00276     // object.
00277     // <srcblock>
00278     //   tableDesc.addColumn (ArrayColumnDesc<float> ("NAME"));
00279     // </srcblock>
00280     // On the other hand this function can also be used to add a
00281     // column description from another table as in:
00282     // <srcblock>
00283     //   tableDesc.addColumn (otherTableDesc.columnDesc("NAME"));
00284     // </srcblock>
00285     ColumnDesc& addColumn (const ColumnDesc&);
00286 
00287     // Add a column to the table description and give it another name.
00288     // This may be useful to use a description of another column.
00289     ColumnDesc& addColumn (const ColumnDesc&, const String& newname);
00290 
00291     // Remove a column.
00292     // An exception is thrown if the column does not exist.
00293     void removeColumn (const String& name);
00294 
00295     // Rename a column.
00296     // An exception is thrown if the old name does not exist or
00297     // if the name already exists.
00298     // <note role=caution>
00299     // Renaming a column should be done with care, because other
00300     // columns may be referring this column. Also a hypercolumn definition
00301     // might be using the old name.
00302     // </note>
00303     void renameColumn (const String& newname, const String& oldname);
00304 
00305     // Get number of columns.
00306     uInt ncolumn() const;
00307 
00308     // Test if a column with this name exists.
00309     Bool isColumn (const String& name) const;
00310 
00311     // Get a vector containing all column names.
00312     Vector<String> columnNames() const;
00313 
00314     // Get the column description by name or by index.
00315     // An exception is thrown if the column does not exist.
00316     // Function isColumn should be used to test if a column exists.
00317     // <group>
00318     const ColumnDesc& columnDesc (const String& name) const;
00319     const ColumnDesc& operator[] (const String& name) const;
00320     const ColumnDesc& columnDesc (uInt index) const;
00321     const ColumnDesc& operator[] (uInt index) const;
00322     ColumnDesc& rwColumnDesc (const String& name);
00323     ColumnDesc& rwColumnDesc (uInt index);
00324     // </group>
00325 
00326     // Get comment string.
00327     const String& comment() const;
00328 
00329     // Get comment string (allowing it to be changed).
00330     String& comment();
00331 
00332     // Show the table description on cout.
00333     void show() const;
00334 
00335     // Show the table description.
00336     void show (ostream& os) const;
00337 
00338     // Get the table type (i.e. name of table description).
00339     const String& getType() const;
00340 
00341     // Get the table description version.
00342     const String& version() const;
00343 
00344     // Define a hypercolumn.
00345     // A hypercolumn is a group of one or more data columns of which
00346     // the data is treated as one or more (regular) hypercubes.
00347     // The hypercolumn has coordinate axes (e.g. time, frequency)
00348     // which are columns in the table.
00349     // When the entire hypercolumn consists of multiple hypercubes,
00350     // ID-columns can be defined, which uniquely determine the
00351     // hypercube to be used.
00352     //  Note that only <linkto class=TiledDataStMan>TiledDataStMan</linkto>
00353     // requires the use of ID-columns.
00354     // A hypercolumn definition is needed to be able to use a Tiled
00355     // Storage Manager.
00356     //
00357     // The following has to be specified:
00358     // <dl>
00359     //  <dt> Hypercolumn name
00360     //  <dd> which is the name used to refer to the hypercolumn.
00361     //  <dt> ndim
00362     //  <dd> defining the dimensionality of the hypercolumn (and
00363     //       of its hypercube(s)).
00364     //  <dt> Data column names
00365     //  <dd> which are the columns containing the hypercube data.
00366     //       When multiple columns are used, the shapes of the data
00367     //       in their cells must be the same in the same row.
00368     //       All data columns must contain numeric or Bool scalars or arrays.
00369     //       <dl>
00370     //        <dt> array:
00371     //        <dd> Its dimensionality has to be less than or equal to the
00372     //             dimensionality of the hypercolumn. If equal, the
00373     //             array itself already forms the hypercube. That would
00374     //             mean that each row is a hypercube.
00375     //             If less, the arrays from multiple rows form a hypercube,
00376     //             adding one or more dimensions to the array dimensionality.
00377     //        <dt> scalar:
00378     //        <dd> The data from multiple rows form a hypercube.
00379     //             Not all tiled storage managers support scalars.
00380     //       </dl>
00381     //  <dt> Coordinate column names (optional)
00382     //  <dd> which are the columns containing the coordinates of the
00383     //       hypercubes. They must be (u)Int, float, double or (D)Complex.
00384     //       When given, the number of coordinate columns must match the
00385     //       dimensionality of the hypercolumn.
00386     //       <br>
00387     //       When the data column cells contain arrays, the first N coordinate
00388     //       columns must contain vector values, where N is the dimensionality
00389     //       of the data arrays.
00390     //       The remaining coordinate columns must contain scalar values.
00391     //  <dt> Id column names (optional)
00392     //  <dd> have to be given when a hypercolumn can consist of multiple
00393     //       hypercubes. They define the column(s) determining which
00394     //       hypercube has to be used for a data array.
00395     //       The id columns must contain scalar values ((u)Int, float,
00396     //       double, (D)Complex, String and/or Bool).
00397     // </dl>
00398     // It will be checked if the given columns exists and have
00399     // an appropriate type.
00400     // <br>
00401     // The default data manager type of the columns involved will be set
00402     // to TiledColumnStMan if all data columns have a fixed shape.
00403     // Otherwise they are set to TiledShapeStMan.
00404     // The storage manager group of all columns involved will be set to
00405     // the hypercolumn name. In that way binding columns to storage managers
00406     // during the table creation process is easier because a simple
00407     // <code>bindGroup</code> can be used.
00408     // <p>
00409     // For example:<br>
00410     // A table contains data matrices with axes pol and freq.
00411     // Those axes are defined in columns pol and freq containing
00412     // vectors with the same length as the corresponding axis.
00413     // The table also contains scalar columns time and baseline, which
00414     // superimpose dimensions upon the data. So the data will be stored
00415     // in a 4-d hypercube with axes pol,freq,time,baseline.
00416     // It would be defined as follows:
00417     // <srcblock>
00418     //     tableDesc.defineHypercolumn ("dataCube", 4,
00419     //                            stringToVector ("data"),
00420     //                            stringToVector ("pol,freq,time,baseline"));
00421     // </srcblock>
00422     // Note that the function <linkto group="ArrayUtil.h#stringToVector">
00423     // stringToVector</linkto> is very convenient for creating a vector
00424     // of Strings.
00425     // <group name=defineHypercolumn>
00426     void defineHypercolumn (const String& hypercolumnName,
00427                             uInt ndim,
00428                             const Vector<String>& dataColumnNames);
00429     void defineHypercolumn (const String& hypercolumnName,
00430                             uInt ndim,
00431                             const Vector<String>& dataColumnNames,
00432                             const Vector<String>& coordColumnNames);
00433     void defineHypercolumn (const String& hypercolumnName,
00434                             uInt ndim,
00435                             const Vector<String>& dataColumnNames,
00436                             const Vector<String>& coordColumnNames,
00437                             const Vector<String>& idColumnNames);
00438     // </group>
00439 
00440     // Test if the given hypercolumn exists.
00441     Bool isHypercolumn (const String& hypercolumnName) const;
00442 
00443     // Get the names of all hypercolumns.
00444     Vector<String> hypercolumnNames() const;
00445 
00446     // Get the columns involved in a hypercolumn.
00447     // It returns the dimensionality of the hypercolumn.
00448     // An exception is thrown if the hypercolumn does not exist.
00449     uInt hypercolumnDesc (const String& hypercolumnName,
00450                           Vector<String>& dataColumnNames,
00451                           Vector<String>& coordColumnNames,
00452                           Vector<String>& idColumnNames) const;
00453 
00454     // Adjust the hypercolumn definitions (for a RefTable).
00455     // It removes and/or renames columns as necessary.
00456     // Column names which are not part of the map are removed if
00457     // <src>keepUnknown==False</src>.
00458     // If all data columns of a hypercolumn are removed, the entire
00459     // hypercolumn is removed.
00460     void adjustHypercolumns (const SimpleOrderedMap<String,String>& old2new,
00461                              Bool keepUnknownData = False,
00462                              Bool keepUnknownCoord = False,
00463                              Bool keppUnknownId = False);
00464 
00465     // Remove ID-columns from the given hypercolumn definitions
00466     // and set their default data manager type to IncrementalStMan
00467     // and group to ISM_TSM.
00468     void removeIDhypercolumns (const Vector<String>& hcNames);
00469 
00470     // Remove given hypercolumn definition.
00471     // An exception is thrown if it is not a hypercolumn.
00472     void removeHypercolumnDesc (const String& hypercolumnName);
00473 
00474     // Check recursively if the descriptions of all subtables are known.
00475     void checkSubTableDesc() const;
00476 
00477     void renameHypercolumn (const String& newHypercolumnName,
00478                             const String& hypercolumnName);
00479 
00480 
00481 private:
00482     String             name_p;          //# name of table description
00483     String             vers_p;          //# version of table description
00484     String             dir_p;           //# directory
00485     String             comm_p;          //# comment
00486     TableRecord*       key_p;           //# user set of keywords
00487     TableRecord*       privKey_p;       //# Private set of keywords
00488     ColumnDescSet      col_p;           //# set of column names + indices
00489     Bool               swwrite_p;       //# True = description can be written
00490     TDOption           option_p;        //# Table desc. open option
00491     AipsIO             iofil_p;         //# File
00492 
00493     // Assignment is not supported, because it is impossible to define
00494     // its semantics. Does the data need to be written into a file
00495     // before being overwritten?
00496     // Declaring it private, makes it unusable.
00497     TableDesc& operator= (const TableDesc&);
00498 
00499     // Initialize the table description.
00500     void init (const TabPath&);
00501 
00502     // Initialize and copy a table description.
00503     void copy (const TableDesc&, const TabPath&, Bool copyColumns);
00504 
00505     // Throw an invalid hypercolumn exception.
00506     void throwHypercolumn (const String& hyperColumnName,
00507                            const String& message);
00508 
00509 
00510 public:
00511     // Put the table description into the file.
00512     // The name can be used to write the TableDesc from a Table and
00513     // is used to set the names of subtables correctly.
00514     void putFile (AipsIO&, const TableAttr&) const;
00515 
00516     // Get the table description from the file.
00517     void getFile (AipsIO&, const TableAttr&);
00518 };
00519 
00520 
00521 //# Get number of columns.
00522 inline uInt TableDesc::ncolumn () const
00523     { return col_p.ncolumn(); }
00524 
00525 //# Test if column exists.
00526 inline Bool TableDesc::isColumn (const String& name) const
00527     { return col_p.isDefined(name); }
00528 
00529 //# Get a column description.
00530 inline const ColumnDesc& TableDesc::columnDesc (const String& name) const
00531     { return col_p[name]; }
00532 inline const ColumnDesc& TableDesc::operator[] (const String& name) const
00533     { return col_p[name]; }
00534 inline const ColumnDesc& TableDesc::columnDesc (uInt index) const
00535     { return col_p[index]; }
00536 inline const ColumnDesc& TableDesc::operator[] (uInt index) const
00537     { return col_p[index]; }
00538 inline ColumnDesc& TableDesc::rwColumnDesc (const String& name)
00539     { return col_p[name]; }
00540 inline ColumnDesc& TableDesc::rwColumnDesc (uInt index)
00541     { return col_p[index]; }
00542 
00543 
00544 //# Return the name (ie. type) of the table description.
00545 inline const String& TableDesc::getType () const
00546     { return name_p; }
00547 
00548 //# Return the version of the table description.
00549 inline const String& TableDesc::version () const
00550     { return vers_p; }
00551 
00552 //# Get access to the sets of keywords.
00553 inline TableRecord& TableDesc::rwKeywordSet ()
00554     { return *key_p; }
00555 inline const TableRecord& TableDesc::keywordSet () const
00556     { return *key_p; }
00557 inline const TableRecord& TableDesc::privateKeywordSet () const
00558     { return *privKey_p; }
00559 
00560 //# Get the set of columns.
00561 inline const ColumnDescSet& TableDesc::columnDescSet() const
00562     { return col_p; }
00563 
00564 //# Add a column.
00565 inline ColumnDesc& TableDesc::addColumn (const ColumnDesc& column)
00566     { return col_p.addColumn (column); }
00567 
00568 inline ColumnDesc& TableDesc::addColumn (const ColumnDesc& column,
00569                                          const String& newname)
00570     { return col_p.addColumn (column, newname); }
00571 
00572 //# Remove a column.
00573 inline void TableDesc::removeColumn (const String& name)
00574     { col_p.remove (name); }
00575 
00576 //# Access the comment.
00577 inline const String& TableDesc::comment () const
00578     { return comm_p; }
00579 
00580 inline String& TableDesc::comment ()
00581     { return comm_p; }
00582 
00583 inline void TableDesc::checkSubTableDesc () const
00584    { col_p.checkSubTableDesc(); }
00585 
00586 
00587 
00588 
00589 } //# NAMESPACE CASA - END
00590 
00591 #endif
00592