CMS 3D CMS Logo

SequenceManager.cc

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

Generated on Tue Jun 9 17:26:06 2009 for CMSSW by  doxygen 1.5.4