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
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
00046 if ( ! m_sequenceTableExists ) {
00047 throw cond::Exception("SequenceManager::incrementId");
00048 }
00049
00050 unsigned long long lastIdUsed = 0;
00051 if ( ! ( this->lockEntry( schema, tableName, lastIdUsed ) ) ) {
00052
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
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
00074
00075 }catch(std::exception& er){
00076
00077 throw cond::Exception(er.what());
00078 }
00079
00080 }
00081
00082 iSequence = m_tableToId.insert( std::make_pair( tableName, lastIdUsed ) ).first;
00083 }
00084
00085 unsigned long long& oid = iSequence->second;
00086 this->lockEntry( schema, tableName, oid );
00087 ++oid;
00088
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
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
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
00176
00177
00178 return true;
00179 }else {
00180 cursor.close();
00181
00182 return false;
00183 }
00184 }