//# ConcatTable.cc: Class to view a concatenation of tables as a single table //# Copyright (C) 2008 //# Associated Universities, Inc. Washington DC, USA. //# //# This library is free software; you can redistribute it and/or modify it //# under the terms of the GNU Library General Public License as published by //# the Free Software Foundation; either version 2 of the License, or (at your //# option) any later version. //# //# This library is distributed in the hope that it will be useful, but WITHOUT //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public //# License for more details. //# //# You should have received a copy of the GNU Library General Public License //# along with this library; if not, write to the Free Software Foundation, //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. //# //# Correspondence concerning AIPS++ should be addressed as follows: //# Internet email: aips2-request@nrao.edu. //# Postal address: AIPS++ Project Office //# National Radio Astronomy Observatory //# 520 Edgemont Road //# Charlottesville, VA 22903-2475 USA //# //# $Id$ #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace casacore { //# NAMESPACE CASACORE - BEGIN ConcatTable::ConcatTable (AipsIO& ios, const String& name, rownr_t nrrow, int option, const TableLock& lockOptions, const TSMOption& tsmOption) : BaseTable (name, option, nrrow), changed_p (False) { //# Read the file in. // Set initially to no write in destructor. // At the end it is reset. In this way nothing is written if // an exception is thrown during initialization. noWrite_p = True; getConcat (ios, option, lockOptions, tsmOption); noWrite_p = False; } ConcatTable::ConcatTable (const Block& tables, const Block& subTables, const String& subDirName) : BaseTable ("", Table::Scratch, 0), subTableNames_p (subTables), subDirName_p (subDirName), tables_p (tables), changed_p (True) { ///cout<<"cctab1="<& tableNames, const Block& subTables, const String& subDirName, int option, const TableLock& lockOptions, const TSMOption& tsmOption) : BaseTable ("", Table::Scratch, 0), subTableNames_p (subTables), subDirName_p (subDirName), changed_p (True) { ///cout<<"cctab1="<& names, Bool recursive) const { if (recursive) { for (uInt i=0; igetPartNames (names, recursive); } } else { uInt inx = names.size(); names.resize (inx + tables_p.nelements()); for (uInt i=0; iasBigEndian(); } const StorageOption& ConcatTable::storageOption() const { return tables_p[0].storageOption(); } Bool ConcatTable::isMultiUsed (Bool) const { return False; } const TableLock& ConcatTable::lockOptions() const { return tables_p[0].lockOptions(); } void ConcatTable::mergeLock (const TableLock& lockOptions) { for (uInt i=0; imergeLock (lockOptions); } } Bool ConcatTable::hasLock (FileLocker::LockType type) const { for (uInt i=0; igetModifyCounter(); } //# Write a concatenate table into a file. void ConcatTable::writeConcatTable (Bool) { //# Write name and type of root and write object data. //# Do this only when something has changed. if (changed_p) { AipsIO ios; writeStart (ios, True); // writeStart has made the table directory. // Create the subDir directory if given. String sdName; if (! subDirName_p.empty()) { sdName = tableName() + '/' + subDirName_p + '/'; Directory dir(sdName); dir.create(); } ios << "ConcatTable"; ios.putstart ("ConcatTable", 0); // Make the name of the base tables relative to this table. // First move a table if subDirName_p is set. ios << uInt(tables_p.nelements()); for (uInt i=0; i rootNames; Int version = ios.getstart ("ConcatTable"); AlwaysAssert (version==0, AipsError); ios >> nrtab; rootNames.resize(nrtab); for (uInt i=0; i> rootNames[i]; rootNames[i] = Path::addDirectory (rootNames[i], tableName()); } ios >> subTableNames_p; ios.getend(); openTables (rootNames, option, lockOptions, tsmOption); initialize(); //# Read the TableInfo object. getTableInfo(); } void ConcatTable::openTables (const Block& tableNames, int option, const TableLock& lockOptions, const TSMOption& tsmOption) { //# Open the tables referenced to. tables_p.resize (tableNames.nelements()); rows_p.reserve (tableNames.nelements() + 1); for (uInt i=0; i > actualDesc(tables_p.nelements());; Bool equalDataTypes; for (uInt i=0; i (new TableDesc (tables_p[i].actualTableDesc())); if (actualDesc[i]->columnDescSet().isEqual (actualDesc[0]->columnDescSet(), equalDataTypes)) { if (equalDataTypes) { continue; } } throw TableError("All tables in ConCatTable must have same description"); } // For fixed shaped arrays check if all tables have the same shape. // If not, clear dimensionality and options. for (uInt i=0; incolumn(); ++i) { ColumnDesc& colDesc = actualDesc[0]->rwColumnDesc(i); if (colDesc.isArray() && (colDesc.options() & ColumnDesc::FixedShape) != 0) { Bool sameShape = true; for (uInt j=1; jcolumnDesc(i); if ((cd.options() & ColumnDesc::FixedShape) == 0 || ! colDesc.shape().isEqual (cd.shape())) { sameShape = False; break; } } if (!sameShape) { colDesc.setNdim (0); colDesc.setOptions (0); } } } //# Use the table description. tdescPtr_p = new TableDesc (*(actualDesc[0]), TableDesc::Scratch); keywordSet_p = tables_p[0].keywordSet(); // Handle the possible concatenated subtables. handleSubTables(); // Create the concatColumns. // Do this last, to avoid leaks in case of exceptions above. makeConcatCol(); } void ConcatTable::handleSubTables() { // Check for each subtable if it exists in all tables. // If fine, create a ConcatTable for each subtable. Block
subtables(tables_p.nelements()); for (uInt i=0; i rootNames, subNames; Int version = ios.getstart ("ConcatTable"); AlwaysAssert (version==0, AipsError); ios >> nrtab; rootNames.resize(nrtab); for (uInt i=0; i> rootNames[i]; } ios >> subNames; ios.getend(); TableUtil::getLayout (desc, rootNames[0]); } //# Create a ConcatColumn object for all columns in the description. //# Insert it with the name in the column map. void ConcatTable::makeConcatCol() { for (uInt i=0; incolumn(); i++) { const ColumnDesc& cd = tdescPtr_p->columnDesc(i); colMap_p.insert (std::make_pair(cd.name(), cd.makeConcatColumn (this))); } } Block ConcatTable::getRefColumns (const String& columnName) { Block cols(tables_p.nelements()); for (uInt i=0; igetColumn (columnName); } return cols; } //# Test if the table is writable. Bool ConcatTable::isWritable() const { for (uInt i=0; icolumnDesc(columnName); // check if column exists return colMap_p.at(columnName); } BaseColumn* ConcatTable::getColumn (uInt columnIndex) const { const String& name = tdescPtr_p->columnDesc(columnIndex).name(); return colMap_p.at(name); } void ConcatTable::addConcatCol (const ColumnDesc& columnDesc) { ColumnDesc& cd = tdescPtr_p->addColumn(columnDesc); colMap_p.insert (std::make_pair(cd.name(), cd.makeConcatColumn(this))); changed_p = True; } void ConcatTable::addConcatCol (const TableDesc& tdesc) { for (uInt i=0; iisColumn(name)) { throw TableInvOper ("Table::addColumn; column " + name + " already exists"); } if (!addToParent) { throw TableInvOper ("ConcatTable::addColumn; column " + name + " does not exist in parent table, but must not be added" " (addToParent=False)"); } } void ConcatTable::addColumn (const ColumnDesc& columnDesc, Bool addToParent) { checkAddColumn (columnDesc.name(), addToParent); for (uInt i=0; i&) const { return False; } Bool ConcatTable::canRenameColumn (const String&) const { return False; } void ConcatTable::removeRow (rownr_t) { throw TableInvOper("ConcatTable cannot remove rows"); } void ConcatTable::removeColumn (const Vector&) { throw TableInvOper("ConcatTable cannot remove columns"); } void ConcatTable::renameColumn (const String&, const String&) { throw TableInvOper("ConcatTable cannot rename columns"); } void ConcatTable::renameHypercolumn (const String&, const String&) { throw TableInvOper("ConcatTable cannot rename hypercolumns"); } DataManager* ConcatTable::findDataManager (const String& name, Bool byColumn) const { return tables_p[0].findDataManager (name, byColumn); } void ConcatTable::showStructureExtra (std::ostream& os) const { for (uInt i=0; i