CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_0/src/CondCore/ORA/src/MappingToSchema.cc

Go to the documentation of this file.
00001 #include "CondCore/ORA/interface/Exception.h"
00002 #include "MappingToSchema.h"
00003 #include "MappingTree.h"
00004 #include "MappingRules.h"
00005 //
00006 // externals
00007 #include "CoralBase/Blob.h"
00008 #include "CoralBase/AttributeSpecification.h"
00009 #include "RelationalAccess/IColumn.h"
00010 #include "RelationalAccess/ISchema.h"
00011 #include "RelationalAccess/ITable.h"
00012 #include "RelationalAccess/ITablePrivilegeManager.h"
00013 #include "RelationalAccess/SchemaException.h"
00014 #include "RelationalAccess/TableDescription.h"
00015 
00016 ora::MappingToSchema::MappingToSchema( coral::ISchema& schema ):
00017   m_schema( schema ){
00018 }
00019 
00020 ora::MappingToSchema::~MappingToSchema(){
00021 }
00022 
00023 void ora::MappingToSchema::createTable( const TableInfo& tableInfo ){
00024   coral::TableDescription description("ORA");
00025   description.setName(tableInfo.m_tableName);
00026   std::vector<std::string> columnsForIndex;
00027   std::vector<std::string> columnsForFk;
00028   size_t i=0;
00029   size_t cols = tableInfo.m_idColumns.size();
00030   for( std::vector<std::string>::const_iterator iCol = tableInfo.m_idColumns.begin();
00031        iCol != tableInfo.m_idColumns.end(); ++iCol ){
00032     description.insertColumn( *iCol, coral::AttributeSpecification::typeNameForId( typeid(int) ) );
00033     description.setNotNullConstraint( *iCol );
00034     if( !tableInfo.m_dependency ) {
00035       columnsForIndex.push_back( *iCol );
00036       if( i< cols-1 ) columnsForFk.push_back( *iCol );
00037     } else {
00038       if( i>0 ) columnsForIndex.push_back( *iCol );
00039       if( i>0 && i< cols-1 ) columnsForFk.push_back( *iCol );
00040     }
00041     ++i;
00042   }
00043   for( std::map<std::string,std::string>::const_iterator iDataCol = tableInfo.m_dataColumns.begin();
00044        iDataCol != tableInfo.m_dataColumns.end(); ++iDataCol ){
00045     description.insertColumn( iDataCol->first, iDataCol->second );
00046     // workaround (temporary?) for Blob. The metadata column has to be relaxed in the NOT NULL constraint (previous versions are not filling this column)
00047     std::set<std::string>::const_iterator iNullable = tableInfo.m_nullableColumns.find( iDataCol->first );
00048     if( iNullable == tableInfo.m_nullableColumns.end()){
00049       description.setNotNullConstraint( iDataCol->first );
00050     }
00051   }
00052   description.setPrimaryKey( columnsForIndex );
00053   if( !tableInfo.m_parentTableName.empty() ){
00054     std::string fkName = MappingRules::fkNameForIdentity( tableInfo.m_tableName );
00055     
00056     if( !tableInfo.m_dependency ) {
00057       description.createForeignKey( fkName, columnsForFk, tableInfo.m_parentTableName, tableInfo.m_refColumns );
00058     } else {
00059       std::vector<std::string> refCols;
00060       for(size_t i=1;i<tableInfo.m_refColumns.size();i++) refCols.push_back( tableInfo.m_refColumns[i] );
00061       if( !refCols.empty() ) description.createForeignKey( fkName, columnsForFk, tableInfo.m_parentTableName, refCols );
00062     }
00063   }
00064   m_schema.createTable( description );
00065   //.privilegeManager().grantToPublic( coral::ITablePrivilegeManager::Select );
00066   
00067 }
00068 
00069 void ora::MappingToSchema::create( const MappingTree& mapping ){
00070   std::vector<TableInfo> tableList = mapping.tables();
00071   for( std::vector<TableInfo>::iterator iT = tableList.begin();
00072        iT != tableList.end(); ++iT ){
00073     createTable( *iT );
00074   }
00075   
00076 }
00077 
00078 void ora::MappingToSchema::alter( const MappingTree& mapping ){
00079   std::vector<TableInfo> tableList = mapping.tables();
00080   for( std::vector<TableInfo>::iterator iT = tableList.begin();
00081        iT != tableList.end(); ++iT ){
00082     if( m_schema.existsTable( iT->m_tableName ) ){
00083       std::set<std::string> allCols;
00084       coral::ITable& table = m_schema.tableHandle( iT->m_tableName );
00085       // check all of the columns
00086       for( std::vector<std::string>::const_iterator iCol = iT->m_idColumns.begin();
00087            iCol != iT->m_idColumns.end(); ++iCol ){
00088         try {
00089           table.description().columnDescription( *iCol );
00090         } catch ( const coral::InvalidColumnNameException&){
00091           // not recoverable: id columns cannot be added.
00092           throwException("ID Column \""+*iCol+"\" has not been found in table \""+iT->m_tableName+"\" as required in the mapping.",
00093                          "MappingToSchema::alter");
00094         }
00095         allCols.insert( *iCol );
00096       }
00097       for( std::map<std::string,std::string>::const_iterator iDataCol = iT->m_dataColumns.begin();
00098            iDataCol != iT->m_dataColumns.end(); ++iDataCol ){
00099         try {
00100           const coral::IColumn& colDescr = table.description().columnDescription( iDataCol->first );
00101           // check the type
00102           if( colDescr.type() != iDataCol->second ){
00103             // not recoverable: column type cannot be changed.
00104             throwException("ID Column \""+iDataCol->first+"\" in table \""+iT->m_tableName+"\" is type \""+colDescr.type()+
00105                            "\" while is required of type \""+iDataCol->second+"\" in the mapping.",
00106                            "MappingToSchema::alter");
00107           }
00108           
00109         } catch ( const coral::InvalidColumnNameException&){
00110           table.schemaEditor().insertColumn( iDataCol->first, iDataCol->second );
00111           table.schemaEditor().setNotNullConstraint( iDataCol->first );
00112         }        
00113         allCols.insert( iDataCol->first );
00114       }
00115       // then check the unused columns for not null constraint
00116       int ncols = table.description().numberOfColumns();
00117       for( int i=0;i<ncols;i++ ){
00118         const coral::IColumn& colDescr = table.description().columnDescription( i );
00119         std::set<std::string>::const_iterator iC = allCols.find( colDescr.name() );
00120         if( iC == allCols.end() ){
00121           table.schemaEditor().setNotNullConstraint( colDescr.name(), false );
00122         }
00123       }
00124     } else {
00125       createTable( *iT );
00126     }
00127   }
00128 }
00129 
00130 bool ora::MappingToSchema::check( const MappingTree& mapping ){
00131   bool ok = true;
00132   std::vector<TableInfo> tableList = mapping.tables();
00133   for( std::vector<TableInfo>::iterator iT = tableList.begin();
00134        iT != tableList.end(); ++iT ){
00135     if( m_schema.existsTable( iT->m_tableName ) ){
00136       ok = false;
00137     }
00138   }
00139   return ok;
00140 }
00141 
00142 
00143