00001 //# SetupNewTab.h: Create a new table - define shapes, data managers, etc. 00002 //# Copyright (C) 1994,1995,1996,1999,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_SETUPNEWTAB_H 00029 #define TABLES_SETUPNEWTAB_H 00030 00031 00032 //# Includes 00033 #include <casacore/casa/aips.h> 00034 #include <casacore/tables/Tables/Table.h> 00035 #include <casacore/tables/Tables/StorageOption.h> 00036 #include <casacore/casa/Containers/SimOrdMap.h> 00037 #include <casacore/casa/BasicSL/String.h> 00038 00039 namespace casacore { //# NAMESPACE CASACORE - BEGIN 00040 00041 //# Forward Declarations 00042 class TableDesc; 00043 class ColumnSet; 00044 class VirtualColumnEngine; 00045 class DataManager; 00046 class IPosition; 00047 00048 00049 // <summary> 00050 // Representation for handle class SetupNewTable 00051 // </summary> 00052 00053 // <use visibility=local> 00054 00055 // <reviewed reviewer="bglenden" date="12AUG94" tests="None"> 00056 // </reviewed> 00057 00058 // <prerequisite> 00059 // <li> TableDesc and related classes like ArrayColumnDesc 00060 // <li> DataManager 00061 // <li> Table 00062 // </prerequisite> 00063 00064 // <etymology> 00065 // SetupNewTableRep is the representation of class SetupNewTable. 00066 // </etymology> 00067 00068 // <synopsis> 00069 // SetupNewTableRep is the representation of class 00070 // <linkto class="SetupNewTable:description">SetupNewTable</linkto>. 00071 // Its functionality is described there. 00072 // </synopsis> 00073 00074 // <motivation> 00075 // Copying a SetupNewTable object as such is very difficult, if not 00076 // impossible. However, being able to use a SetupNewTable copy constructor 00077 // was required to be able to have (static) functions constructing a 00078 // SetupNewTable object and return it by value (as done for example 00079 // by <src>ForwardColumn::setupNewTable</src>). 00080 // Therefore SetupNewTable is implemented using the handle idiom. 00081 // SetupNewTable is the interface (i.e. the handle) for the user, 00082 // while underneath SetupNewTableRep is doing all the work. 00083 // The SetupNewTable copy constructor can simply copy yhe pointer 00084 // to the underlying SetupNewTableRep object. 00085 // </motivation> 00086 00087 // <todo asof="$DATE:$"> 00088 //# A List of bugs, limitations, extensions or planned refinements. 00089 // <li> full implementation of tiling 00090 // </todo> 00091 00092 00093 class SetupNewTableRep 00094 { 00095 public: 00096 // Create a new table using the table description with the given name. 00097 // The description will be read from a file. 00098 SetupNewTableRep (const String& tableName, const String& tableDescName, 00099 Table::TableOption, const StorageOption&); 00100 00101 // Create a new table using the given table description. 00102 SetupNewTableRep (const String& tableName, const TableDesc&, 00103 Table::TableOption, const StorageOption&); 00104 00105 ~SetupNewTableRep(); 00106 00107 // Get access to the reference count. 00108 uInt& count() 00109 { return count_p; } 00110 00111 // Get the name of the table. 00112 const String& name() const 00113 { return tabName_p; } 00114 00115 // Get the table create option. 00116 int option() const 00117 { return option_p; } 00118 00119 // Get the storage option. 00120 const StorageOption& storageOption() const 00121 { return storageOpt_p; } 00122 00123 // Test if the table is marked for delete. 00124 Bool isMarkedForDelete() const 00125 { return delete_p; } 00126 00127 // Get the table description. 00128 const TableDesc& tableDesc() const 00129 { return *tdescPtr_p; } 00130 00131 // Bind a column to the given data manager. 00132 // If already bound, the binding will be overwritten. 00133 // It cannot be used anymore once the SetupNewTableRep object is used to 00134 // construct a Table object. 00135 void bindColumn (const String& columnName, const DataManager&); 00136 00137 // Bind a column to the given data manager of the other column. 00138 // If the other column is not bound, nothing will be done. 00139 // If columnName is already bound, the binding will be overwritten. 00140 // It cannot be used anymore once the SetupNewTableRep object is used to 00141 // construct a Table object. 00142 void bindColumn (const String& columnName, const String& otherColumn); 00143 00144 // Bind a group of columns to the given data manager. 00145 // The flag rebind tells if the binding of an already bound column 00146 // will be overwritten. 00147 // It cannot be used anymore once the SetupNewTableRep object is used to 00148 // construct a Table object. 00149 void bindGroup (const String& columnGroup, const DataManager&, 00150 Bool rebind=False); 00151 00152 // Bind all columns to the given data manager. 00153 // The flag rebind tells if the binding of an already bound column 00154 // will be overwritten. 00155 // It cannot be used anymore once the SetupNewTableRep object is used to 00156 // construct a Table object. 00157 void bindAll (const DataManager&, Bool rebind=False); 00158 00159 // Create data managers and bind the columns using the specifications 00160 // in the given record (which is obtained using Table::dataManagerInfo()). 00161 void bindCreate (const Record& spec); 00162 00163 // Define the shape of fixed shaped arrays in a column. 00164 // The shape of those arrays has to be known before the table 00165 // can be constructed. It has to be defined via this function, 00166 // if it was not already defined in the column description. 00167 // If only the dimensionality was defined in the column 00168 // description, the shape's dimensionality must match it. 00169 // Calling this function for an non-fixed shaped array results in 00170 // an exception. 00171 // It cannot be used anymore once the SetupNewTableRep object is used to 00172 // construct a Table object. 00173 void setShapeColumn (const String& columnName, const IPosition& shape); 00174 00175 // Test if object is already in use. 00176 Bool isUsed() const 00177 { return (colSetPtr_p == 0 ? True : False); } 00178 00179 // Get pointer to column set. 00180 // This function is used by PlainTable. 00181 ColumnSet* columnSetPtr() 00182 { return colSetPtr_p; } 00183 00184 // Get pointer to table description. 00185 // This function is used by PlainTable. 00186 TableDesc* tableDescPtr() 00187 { return tdescPtr_p; } 00188 00189 // Set object to in use by a (Plain)Table object. 00190 // This function is used by PlainTable. 00191 void setInUse() 00192 { colSetPtr_p = 0; } 00193 00194 // Make a data manager for all unbound columns. 00195 void handleUnbound(); 00196 00197 private: 00198 // Reference count. 00199 uInt count_p; 00200 // Table name. 00201 String tabName_p; 00202 // Constructor options. 00203 int option_p; 00204 StorageOption storageOpt_p; 00205 // Marked for delete? 00206 Bool delete_p; 00207 TableDesc* tdescPtr_p; 00208 ColumnSet* colSetPtr_p; //# 0 = object is already used by a Table 00209 SimpleOrderedMap<void*,void*> dataManMap_p; 00210 00211 // Copy constructor is forbidden, because copying a table requires 00212 // some more knowledge (like table name of result). 00213 // Declaring it private, makes it unusable. 00214 SetupNewTableRep (const SetupNewTableRep&); 00215 00216 // Assignment is forbidden, because copying a table requires 00217 // some more knowledge (like table name of result). 00218 // Declaring it private, makes it unusable. 00219 SetupNewTableRep& operator= (const SetupNewTableRep&); 00220 00221 // Setup the new table. 00222 // This checks various things and creates the set of columns. 00223 void setup(); 00224 00225 // Get the internal data manager object for the given data manager. 00226 // If it does not exist yet, it will be cloned and stored internally. 00227 DataManager* getDataManager (const DataManager& dataMan); 00228 }; 00229 00230 00231 00232 00233 00234 // <summary> 00235 // Create a new table - define shapes, data managers, etc. 00236 // </summary> 00237 00238 // <use visibility=export> 00239 00240 // <reviewed reviewer="bglenden" date="12AUG94" tests="None"> 00241 // </reviewed> 00242 00243 // <prerequisite> 00244 // <li> TableDesc and related classes like ArrayColumnDesc 00245 // <li> DataManager 00246 // <li> Table 00247 // </prerequisite> 00248 00249 // <etymology> 00250 // SetupNewTable is a class to setup a new table. 00251 // </etymology> 00252 00253 // <synopsis> 00254 // Constructing a new table is a two stage process. 00255 // First a SetupNewTable object has to be created. Thereafter its columns 00256 // have to be bound defining how they have to be stored or calculated. 00257 // Columns have to be bound to a data manager (e.g. a storage manager 00258 // or a virtual column engine).. 00259 // Once the required columns are bound, the actual Table object can 00260 // be created. At this stage, still unbound columns will be bound 00261 // to the default data managers. 00262 // The Table object can be used to write data, etc. 00263 // 00264 // The construct options for SetupNewTable are defined in class Table. 00265 // The possible options are: 00266 // <ul> 00267 // <li> New 00268 // creates a new table file. 00269 // The Table destructor will write the table into the file. 00270 // <li> NewNoReplace 00271 // as option New, but an exception will be thrown if the table 00272 // file already exists. 00273 // <li> Scratch 00274 // creates a temporary table. 00275 // It will be lost when the Table object gets destructed. 00276 // </ul> 00277 // More information is provided in the Tables module documentation. 00278 // </synopsis> 00279 // 00280 // <example> 00281 // <srcblock> 00282 // Table makeIt(const TableDesc &td) { // 1 00283 // SetupNewTable maker("test.table", td, Table::New); // 2 00284 // maker.setShapeColumn("SomeArray", IPosition(2,10,10)); // 3 00285 // maker.setShapeColumn("AnotherArray", IPosition(1,100)); // 4 00286 // StManAipsIO sm1; // 5 00287 // StManKarma sm2; // 6 00288 // maker.bindAll(sm1); // 7 00289 // maker.bindColumn("SomeCol", sm2); // 8 00290 // maker.bindColumn("AnotherCol", sm2); // 9 00291 // return Table(maker, 1000); // 1000 row table // 10 00292 // } // 11 00293 // </srcblock> 00294 // This code illustrates a simple function that creates a Table starting 00295 // from a Table descriptor. I 00296 // <ol> 00297 // <li> Declare the function makeIt which, given a TableDesc, returns 00298 // a table. 00299 // <li> Create the SetupNewTable object "maker". We want the new table 00300 // to be named "test.table", its rows columns and keywords come 00301 // from the TableDesc "td", and this table is to be created 00302 // unconditionally, that is, it will overwrite an existing table 00303 // of the same name. Alternative options are given in the synopsis. 00304 // <li> 00305 // <li> Give direct arrays declared in the table descriptor (but not 00306 // necessarily given a shape) a defined shape; 10x10 for the first 00307 // array, 100 long vector for the second. If all direct arrays 00308 // do not have a shape, an error will occur when the table is 00309 // actually constructed. 00310 // <li> 00311 // <li> Declare two data (storage) managers. AipsIO keeps a whole column 00312 // in memory, Karma does I/O to keep a subsection in memory at once. 00313 // A powerful feature of Casacore tables is that different columns 00314 // may be bound to different data managers, which have different 00315 // properties. 00316 // <li> Define the default data manager. AipsIO in this case. 00317 // Note that this statement and statement 5 are actually not 00318 // needed. When the Table constructor finds some unbound columns, 00319 // it will construct the default data manager for them and 00320 // bind them. A default data manager can be defined in the 00321 // column description and defaults to AipsIO. 00322 // <li> 00323 // <li> Override the default for some particular columns. 00324 // <li> Create and return a 1000 row table. With the Karma storage manager 00325 // the table size must be defined at construction since new rows 00326 // can't be added or deleted. If AipsIO was the only storage manager, 00327 // the size wouldn't need to be defined since rows can be added with 00328 // AipsIO. 00329 // </ol> 00330 // </example> 00331 00332 // <motivation> 00333 // In principle, SetupNewTab isn't necessary as what we are doing is logically 00334 // just constructing a Table, so it could be done in the Table constructor. 00335 // However such a process can be an involved one - binding multiple data 00336 // managers and filling in the shapes of direct arrays - so separating 00337 // the process makes it much clearer what is going on. 00338 // </motivation> 00339 00340 // <todo asof="$DATE:$"> 00341 //# A List of bugs, limitations, extensions or planned refinements. 00342 // <li> full implementation of tiling 00343 // </todo> 00344 00345 00346 class SetupNewTable 00347 { 00348 friend class PlainTable; 00349 friend class MemoryTable; 00350 00351 public: 00352 // Create a new table using the table description with the given name. 00353 // The description will be read from a file. 00354 SetupNewTable (const String& tableName, const String& tableDescName, 00355 Table::TableOption, const StorageOption& = StorageOption()); 00356 00357 // Create a new table using the given table description. 00358 SetupNewTable (const String& tableName, const TableDesc&, 00359 Table::TableOption, const StorageOption& = StorageOption()); 00360 00361 // Copy constructor (reference semantics). 00362 SetupNewTable (const SetupNewTable&); 00363 00364 ~SetupNewTable(); 00365 00366 // Assignment (reference semantics). 00367 SetupNewTable& operator= (const SetupNewTable&); 00368 00369 // Get the name of the table. 00370 const String& name() const 00371 { return newTable_p->name(); } 00372 00373 // Get the table create option. 00374 int option() const 00375 { return newTable_p->option(); } 00376 00377 // Get the storage option. 00378 const StorageOption& storageOption() const 00379 { return newTable_p->storageOption(); } 00380 00381 // Test if the table is marked for delete. 00382 Bool isMarkedForDelete() const 00383 { return newTable_p->isMarkedForDelete(); } 00384 00385 // Get the table description. 00386 const TableDesc& tableDesc() const 00387 { return newTable_p->tableDesc(); } 00388 00389 // Adjust the hypercolumn definitions. 00390 // It renames and/or removes columns as necessary. 00391 void adjustHypercolumns (const SimpleOrderedMap<String, String>& old2new, 00392 Bool keepUnknown) 00393 { newTable_p->tableDescPtr()->adjustHypercolumns(old2new,keepUnknown); } 00394 00395 // Bind a column to the given data manager. 00396 // If already bound, the binding will be overwritten. 00397 // It cannot be used anymore once the SetupNewTable object is used to 00398 // construct a Table object. 00399 void bindColumn (const String& columnName, const DataManager& dm) 00400 { newTable_p->bindColumn (columnName, dm); } 00401 00402 // Bind a column to the given data manager of the other column. 00403 // If the other column is not bound, nothing will be done. 00404 // If columnName is already bound, the binding will be overwritten. 00405 // It cannot be used anymore once the SetupNewTableRep object is used to 00406 // construct a Table object. 00407 void bindColumn (const String& columnName, const String& otherColumn) 00408 { newTable_p->bindColumn (columnName, otherColumn); } 00409 00410 // Bind a group of columns to the given data manager. 00411 // The flag rebind tells if the binding of an already bound column 00412 // will be overwritten. 00413 // It cannot be used anymore once the SetupNewTable object is used to 00414 // construct a Table object. 00415 void bindGroup (const String& columnGroup, const DataManager& dm, 00416 Bool rebind=False) 00417 { newTable_p->bindGroup (columnGroup, dm, rebind); } 00418 00419 // Bind all columns to the given data manager. 00420 // The flag rebind tells if the binding of an already bound column 00421 // will be overwritten. 00422 // It cannot be used anymore once the SetupNewTable object is used to 00423 // construct a Table object. 00424 void bindAll (const DataManager& dm, Bool rebind=False) 00425 { newTable_p->bindAll (dm, rebind); } 00426 00427 // Create data managers and bind the columns using the specifications 00428 // in the given record (which is obtained using Table::dataManagerInfo()). 00429 void bindCreate (const Record& spec) 00430 { newTable_p->bindCreate (spec); } 00431 00432 // Define the shape of fixed shaped arrays in a column. 00433 // The shape of those arrays has to be known before the table 00434 // can be constructed. It has to be defined via this function, 00435 // if it was not already defined in the column description. 00436 // If only the dimensionality was defined in the column 00437 // description, the shape's dimensionality must match it. 00438 // Calling this function for an non-fixed shaped array results in 00439 // an exception. 00440 // It cannot be used anymore once the SetupNewTable object is used to 00441 // construct a Table object. 00442 void setShapeColumn (const String& columnName, const IPosition& shape) 00443 { newTable_p->setShapeColumn (columnName, shape); } 00444 00445 // Test if object is already in use. 00446 Bool isUsed() const 00447 { return newTable_p->isUsed(); } 00448 00449 private: 00450 // Actual object. 00451 SetupNewTableRep* newTable_p; 00452 00453 // Get pointer to column set. 00454 // This function is used by PlainTable. 00455 ColumnSet* columnSetPtr() 00456 { return newTable_p->columnSetPtr(); } 00457 00458 // Get pointer to table description. 00459 // This function is used by PlainTable. 00460 TableDesc* tableDescPtr() 00461 { return newTable_p->tableDescPtr(); } 00462 00463 // Set object to in use by a (Plain)Table object. 00464 // This function is used by PlainTable. 00465 void setInUse() 00466 { newTable_p->setInUse(); } 00467 00468 // Make a data manager for all unbound columns. 00469 void handleUnbound() 00470 { newTable_p->handleUnbound(); } 00471 }; 00472 00473 00474 00475 } //# NAMESPACE CASACORE - END 00476 00477 #endif