CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_2_9_HLT1_bphpatch4/src/CondCore/DBCommon/src/SequenceManager.cc

Go to the documentation of this file.
00001 #include "CondCore/DBCommon/interface/SequenceManager.h"
00002 #include "CondCore/DBCommon/interface/Exception.h"
00003 #include "RelationalAccess/ISchema.h"
00004 #include "RelationalAccess/TableDescription.h"
00005 #include "RelationalAccess/ITable.h"
00006 #include "RelationalAccess/ITableDataEditor.h"
00007 #include "RelationalAccess/ITablePrivilegeManager.h"
00008 #include "RelationalAccess/IQuery.h"
00009 #include "RelationalAccess/ICursor.h"
00010 #include "CoralBase/Attribute.h"
00011 #include "CoralBase/AttributeList.h"
00012 #include "CoralBase/AttributeSpecification.h"
00013 #include "RelationalAccess/SchemaException.h"
00014 #include <memory>
00015 //#include <iostream>
00016 cond::SequenceManager::SequenceManager(cond::DbSession& coraldb,
00017                                        const std::string& sequenceTableName):
00018   m_coraldb(coraldb),
00019   m_sequenceTableName( sequenceTableName ),
00020   m_tableToId(),
00021   m_sequenceTableExists( false ),
00022   m_whereClause( std::string("REFTABLE_NAME")+" =:"+std::string("REFTABLE_NAME")), 
00023   m_whereData( 0 ),
00024   m_setClause( std::string("IDVALUE")+" = "+std::string("IDVALUE")+" + 1"),
00025   m_started( false )
00026 {
00027   m_whereData = new coral::AttributeList; 
00028   m_whereData->extend<std::string>(std::string("REFTABLE_NAME"));
00029   init();
00030 }
00031 void
00032 cond::SequenceManager::init(){ 
00033   m_sequenceTableExists=m_coraldb.nominalSchema().existsTable(m_sequenceTableName) ;
00034   m_started=true;
00035 }
00036 cond::SequenceManager::~SequenceManager()
00037 {  
00038   delete m_whereData;
00039 }
00040 unsigned long long
00041 cond::SequenceManager::incrementId( const std::string& tableName ){
00042   std::map< std::string, unsigned long long >::iterator iSequence = m_tableToId.find( tableName );
00043   coral::ISchema& schema=m_coraldb.nominalSchema();
00044   if ( iSequence == m_tableToId.end() ) {
00045     // Make sure that the sequence table exists.
00046     if ( ! m_sequenceTableExists ) {
00047       throw cond::Exception("SequenceManager::incrementId");
00048     }
00049     // Lock the entry in the table.
00050     unsigned long long lastIdUsed = 0;
00051     if ( ! ( this->lockEntry( schema, tableName, lastIdUsed ) ) ) {
00052       // Create the entry in the table if it does not exist.
00053       coral::AttributeList rowData;
00054       rowData.extend<std::string>("REFTABLE_NAME");
00055       rowData.extend<unsigned long long>("IDVALUE");
00056       coral::AttributeList::iterator iAttribute = rowData.begin();
00057       iAttribute->data< std::string >() = tableName;
00058       ++iAttribute;
00059       unsigned long long startingIdValue = lastIdUsed;
00060       iAttribute->data< unsigned long long >() = startingIdValue;
00061       try{
00062         schema.tableHandle( m_sequenceTableName ).dataEditor().insertRow( rowData );
00063         m_tableToId.insert( std::make_pair( tableName, startingIdValue ) );
00064         return startingIdValue;
00065       }catch(const coral::DataEditorException& er){
00066         //std::cout<<"cannot insert, probably already created by others, try lock again"<<std::endl;
00067         this->lockEntry( schema, tableName, lastIdUsed );
00068         ++lastIdUsed;
00069         iSequence = m_tableToId.insert( std::make_pair( tableName, lastIdUsed ) ).first;
00070         m_whereData->begin()->data<std::string>() = tableName;
00071         schema.tableHandle(m_sequenceTableName).dataEditor().updateRows(m_setClause,m_whereClause,*m_whereData );
00072         return lastIdUsed;
00073         //startingIdValue = lastIdUsed+1;
00074         //m_tableToId.insert( std::make_pair( tableName, startingIdValue ) );
00075       }catch(std::exception& er){
00076         //std::cout<<"real error "<<er.what()<<std::endl;
00077         throw cond::Exception(er.what());
00078       }
00079 
00080     }
00081     // Add the entry into the map.
00082     iSequence = m_tableToId.insert( std::make_pair( tableName, lastIdUsed ) ).first;
00083   }
00084   // Increment the oid transiently
00085   unsigned long long& oid = iSequence->second;
00086   this->lockEntry( schema, tableName, oid );
00087   ++oid;
00088   // Increment the oid in the database as well
00089   
00090   m_whereData->begin()->data<std::string>() = tableName;
00091   schema.tableHandle(m_sequenceTableName).dataEditor().updateRows(m_setClause,m_whereClause,*m_whereData );
00092   
00093   return oid;
00094 }
00095 /*
00096 void
00097 cond::SequenceManager::updateId( const std::string& tableName, 
00098                                  unsigned long long lastId ){
00099   // Make sure that the sequence table exists.
00100   if ( ! m_sequenceTableExists ) {
00101     throw;
00102   }
00103   bool update = false;
00104   coral::IQuery* query = m_coraldb.nominalSchema().tableHandle( m_sequenceTableName ).newQuery();
00105   query->limitReturnedRows( 1, 0 );
00106   query->addToOutputList( std::string("IDVALUE") );
00107   query->defineOutputType( std::string("IDVALUE"),coral::AttributeSpecification::typeNameForType<unsigned long long>() );
00108   m_whereData->begin()->data< std::string >() = tableName;
00109   query->setCondition( m_whereClause, *m_whereData );
00110   coral::ICursor& cursor = query->execute();
00111   if ( cursor.next() ) {
00112     update = true;
00113   }
00114   delete query;
00115 
00116   coral::AttributeList rowData;
00117   rowData.extend<unsigned long long>( std::string("IDVALUE") );
00118   rowData.extend<std::string>(  std::string("REFTABLE_NAME") );
00119   coral::AttributeList::iterator iAttribute = rowData.begin();
00120   iAttribute->data< unsigned long long >() = lastId;
00121   ++iAttribute;
00122   iAttribute->data< std::string >() = tableName;
00123   coral::ISchema& schema= m_coraldb.nominalSchema();
00124   if ( update ) {
00125     // Update the entry in the table
00126     std::string setClause(std::string("IDVALUE")+" =: "+std::string("IDVALUE"));
00127     schema.tableHandle( m_sequenceTableName ).dataEditor().updateRows( setClause,m_whereClause,rowData );
00128     m_tableToId.erase( tableName );
00129   } else {
00130     schema.tableHandle( m_sequenceTableName ).dataEditor().insertRow( rowData );
00131   }
00132   m_tableToId.insert( std::make_pair( tableName, lastId ) );
00133 }
00134 */
00135 void
00136 cond::SequenceManager::clear()
00137 {
00138   m_tableToId.clear();
00139 }
00140 bool
00141 cond::SequenceManager::existSequencesTable(){
00142   return m_sequenceTableExists;
00143 }
00144 void
00145 cond::SequenceManager::createSequencesTable()
00146 {
00147   coral::ISchema& schema= m_coraldb.nominalSchema();
00148   coral::TableDescription description( "CONDSEQ" );
00149   description.setName(m_sequenceTableName);
00150   description.insertColumn(std::string("REFTABLE_NAME"),
00151                            coral::AttributeSpecification::typeNameForType<std::string>() );
00152   description.setNotNullConstraint(std::string("REFTABLE_NAME"));
00153   description.insertColumn(std::string("IDVALUE"),
00154                            coral::AttributeSpecification::typeNameForType<unsigned long long>() );
00155   description.setNotNullConstraint(std::string("IDVALUE"));
00156   description.setPrimaryKey( std::vector< std::string >( 1, std::string("REFTABLE_NAME")));
00157   schema.createTable( description ).privilegeManager().grantToPublic( coral::ITablePrivilegeManager::Select );
00158   m_sequenceTableExists=true;
00159 }
00160 
00161 bool
00162 cond::SequenceManager::lockEntry( coral::ISchema& schema,
00163                                   const std::string& sequenceName,
00164                                   unsigned long long& lastId ){
00165   std::auto_ptr< coral::IQuery > query( schema.tableHandle(m_sequenceTableName).newQuery());
00166   query->limitReturnedRows( 1, 0 );
00167   query->addToOutputList( std::string("IDVALUE") );
00168   query->defineOutputType( std::string("IDVALUE"), coral::AttributeSpecification::typeNameForType<unsigned long long>() );
00169   query->setForUpdate();
00170   m_whereData->begin()->data< std::string >() = sequenceName;
00171   query->setCondition( m_whereClause, *m_whereData );
00172   coral::ICursor& cursor = query->execute();
00173   if ( cursor.next() ) {
00174     lastId = cursor.currentRow().begin()->data< unsigned long long >();
00175     //std::cout<<"sequence table lastId "<<lastId<<std::endl;
00176     //cursor.close();
00177     //std::cout<<"SequenceManager::lockEntry return true"<<std::endl;
00178     return true;
00179   }else {
00180     cursor.close();
00181     //std::cout<<"SequenceManager::lockEntry return false"<<std::endl;
00182     return false;
00183   }
00184 }