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
00045 if ( ! m_sequenceTableExists ) {
00046 throw cond::Exception("SequenceManager::incrementId");
00047 }
00048
00049 unsigned long long lastIdUsed = 0;
00050 if ( ! ( this->lockEntry( schema, tableName, lastIdUsed ) ) ) {
00051
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
00072
00073 }catch(std::exception& er){
00074 throw cond::Exception(er.what());
00075 }
00076
00077 }
00078
00079 iSequence = m_tableToId.insert( std::make_pair( tableName, lastIdUsed ) ).first;
00080 }
00081
00082 unsigned long long& oid = iSequence->second;
00083 this->lockEntry( schema, tableName, oid );
00084 ++oid;
00085
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
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 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 }