CMS 3D CMS Logo

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