00001 #include "CondCore/ORA/interface/Exception.h"
00002 #include "CondCore/ORA/interface/Monitoring.h"
00003 #include "DatabaseSession.h"
00004 #include "IDatabaseSchema.h"
00005 #include "Sequences.h"
00006 #include "MappingDatabase.h"
00007 #include "TransactionCache.h"
00008 #include "DatabaseContainer.h"
00009 #include "ClassUtils.h"
00010 #include "MappingRules.h"
00011 #include "DatabaseUtilitySession.h"
00012
00013 #include "RelationalAccess/IConnectionServiceConfiguration.h"
00014 #include "RelationalAccess/ISessionProxy.h"
00015 #include "RelationalAccess/ITransaction.h"
00016
00017 ora::ContainerUpdateTable::ContainerUpdateTable():
00018 m_table(){
00019 }
00020
00021 ora::ContainerUpdateTable::~ContainerUpdateTable(){
00022 }
00023
00024 void ora::ContainerUpdateTable::takeNote( int contId,
00025 unsigned int size ){
00026 std::map<int, unsigned int>::iterator iC = m_table.find( contId );
00027 if( iC == m_table.end() ){
00028 iC = m_table.insert( std::make_pair( contId, 0 ) ).first;
00029 }
00030 iC->second = size;
00031 }
00032
00033 void ora::ContainerUpdateTable::remove( int contId ){
00034 m_table.erase( contId );
00035 }
00036
00037 const std::map<int, unsigned int>& ora::ContainerUpdateTable::table(){
00038 return m_table;
00039 }
00040
00041 void ora::ContainerUpdateTable::clear(){
00042 m_table.clear();
00043 }
00044
00045 ora::DatabaseSession::DatabaseSession():
00046 m_connectionPool( new ConnectionPool ),
00047 m_dbSession(),
00048 m_connectionString( "" ),
00049 m_schema(),
00050 m_contIdSequence(),
00051 m_mappingDb(),
00052 m_transactionCache(),
00053 m_containerUpdateTable(),
00054 m_configuration(),
00055 m_monitoring(0){
00056
00057 m_connectionPool->configuration().setConnectionTimeOut(0);
00058 }
00059
00060 ora::DatabaseSession::DatabaseSession(boost::shared_ptr<ConnectionPool>& connectionPool ):
00061 m_connectionPool( connectionPool ),
00062 m_dbSession(),
00063 m_connectionString( "" ),
00064 m_schema(),
00065 m_contIdSequence(),
00066 m_mappingDb(),
00067 m_transactionCache(),
00068 m_containerUpdateTable(),
00069 m_configuration(),
00070 m_monitoring(0){
00071 }
00072
00073 ora::DatabaseSession::~DatabaseSession(){
00074 disconnect();
00075 }
00076
00077 bool ora::DatabaseSession::connect( const std::string& connectionString,
00078 bool readOnly ){
00079 m_dbSession = m_connectionPool->connect( connectionString, readOnly?coral::ReadOnly:coral::Update );
00080 if(m_dbSession.isValid()) {
00081 m_connectionString = connectionString;
00082 if( ora::Monitoring::isEnabled() ){
00083 m_monitoring = ora::Monitoring::get().startSession( connectionString );
00084 }
00085 }
00086 return isConnected();
00087 }
00088
00089 bool ora::DatabaseSession::connect( const std::string& connectionString,
00090 const std::string& asRole,
00091 bool readOnly ){
00092 m_dbSession = m_connectionPool->connect( connectionString, asRole, readOnly?coral::ReadOnly:coral::Update );
00093 if(m_dbSession.isValid()) {
00094 m_connectionString = connectionString;
00095 if( ora::Monitoring::isEnabled() ){
00096 m_monitoring = ora::Monitoring::get().startSession( connectionString );
00097 }
00098 }
00099 return isConnected();
00100 }
00101
00102 void ora::DatabaseSession::clearTransaction(){
00103 m_transactionCache.reset();
00104 m_mappingDb.reset();
00105 m_contIdSequence.reset();
00106 m_schema.reset();
00107 m_containerUpdateTable.clear();
00108 }
00109
00110 void ora::DatabaseSession::disconnect(){
00111 if( isConnected() ){
00112 if( isTransactionActive()) rollbackTransaction();
00113 }
00114 clearTransaction();
00115 m_dbSession.close();
00116 m_connectionString.clear();
00117 if(m_monitoring) m_monitoring->stop();
00118 }
00119
00120 bool ora::DatabaseSession::isConnected(){
00121 return m_dbSession.isValid();
00122 }
00123
00124 const std::string& ora::DatabaseSession::connectionString(){
00125 return m_connectionString;
00126 }
00127
00128 void ora::DatabaseSession::startTransaction( bool readOnly ){
00129 if( !m_transactionCache.get() ){
00130 m_dbSession.get().transaction().start( readOnly );
00131 m_schema.reset( IDatabaseSchema::createSchemaHandle( m_dbSession.get().nominalSchema() ));
00132 m_contIdSequence.reset( new NamedSequence( MappingRules::sequenceNameForContainerId(), *m_schema ));
00133 m_mappingDb.reset( new MappingDatabase( *m_schema ));
00134 m_transactionCache.reset( new TransactionCache );
00135 if(m_monitoring) {
00136 m_monitoring->newTransaction();
00137 }
00138 }
00139 }
00140
00141 void ora::DatabaseSession::commitTransaction(){
00142 if( m_transactionCache.get() ){
00143 m_schema->containerHeaderTable().updateNumberOfObjects( m_containerUpdateTable.table() );
00144 m_dbSession.get().transaction().commit();
00145 clearTransaction();
00146 if(m_monitoring) {
00147 m_monitoring->stopTransaction();
00148 }
00149 }
00150 }
00151
00152 void ora::DatabaseSession::rollbackTransaction(){
00153 if( m_transactionCache.get() ){
00154 m_dbSession.get().transaction().rollback();
00155 clearTransaction();
00156 if(m_monitoring) {
00157 m_monitoring->stopTransaction(false);
00158 }
00159 }
00160 }
00161
00162 bool ora::DatabaseSession::isTransactionActive( bool checkIfReadOnly ){
00163 bool ret = false;
00164 if( m_dbSession.get().transaction().isActive() ){
00165 if( checkIfReadOnly ){
00166 if( m_dbSession.get().transaction().isReadOnly() ) ret = true;
00167 } else {
00168 ret = true;
00169 }
00170 }
00171 return ret;
00172 }
00173
00174 bool ora::DatabaseSession::exists(){
00175 if(!m_transactionCache->dbExistsLoaded()){
00176 m_transactionCache->setDbExists( m_schema->exists() );
00177 }
00178 return m_transactionCache->dbExists();
00179 }
00180
00181 void ora::DatabaseSession::create( const std::string& userSchemaVersion ){
00182 m_schema->create( userSchemaVersion );
00183 m_contIdSequence->create();
00184 m_mappingDb->setUp();
00185 m_transactionCache->setDbExists( true );
00186 }
00187
00188 void ora::DatabaseSession::drop(){
00189 if(!testDropPermission()){
00190 throwException("Drop permission has been denied for the current user.",
00191 "DatabaseSession::drop");
00192 }
00193 m_schema->drop();
00194 m_transactionCache->dropDatabase();
00195 }
00196
00197 void ora::DatabaseSession::setAccessPermission( const std::string& principal,
00198 bool forWrite ){
00199 m_schema->setAccessPermission( principal, forWrite );
00200 }
00201
00202 bool ora::DatabaseSession::testDropPermission(){
00203 if(!m_transactionCache->dropPermissionLoaded()){
00204 m_transactionCache->setDropPermission( m_schema->testDropPermission() );
00205 }
00206 return m_transactionCache->dropPermission();
00207 }
00208
00209 void ora::DatabaseSession::open(){
00210 if(!m_transactionCache->isLoaded()){
00211 std::map<std::string, ContainerHeaderData> containersData;
00212 m_schema->containerHeaderTable().getContainerData( containersData );
00213 for(std::map<std::string, ContainerHeaderData>::iterator iC = containersData.begin();
00214 iC != containersData.end(); ++iC){
00215 Handle<DatabaseContainer> container( new DatabaseContainer( iC->second.id, iC->first,
00216 iC->second.className,
00217 iC->second.numberOfObjects, *this ) );
00218 m_transactionCache->addContainer( iC->second.id, iC->first, container );
00219 }
00220 m_schema->mainTable().getParameters( m_transactionCache->dbParams() );
00221 m_transactionCache->setLoaded();
00222 }
00223 }
00224
00225 std::string ora::DatabaseSession::schemaVersion( bool userSchema ){
00226 std::map<std::string,std::string>& params = m_transactionCache->dbParams();
00227 std::string version("");
00228 std::string paramName = IMainTable::versionParameterName();
00229 if(userSchema ) paramName = IMainTable::userSchemaVersionParameterName();
00230 std::map<std::string,std::string>::const_iterator iPar = params.find( paramName );
00231 if( iPar != params.end() ){
00232 version = iPar->second;
00233 }
00234 return version;
00235 }
00236
00237 ora::Handle<ora::DatabaseContainer> ora::DatabaseSession::addContainer( const std::string& containerName,
00238 const std::string& className ){
00239 int newContId = m_contIdSequence->getNextId( true );
00240 m_schema->containerHeaderTable().addContainer( newContId, containerName, className );
00241 Handle<DatabaseContainer> container( new DatabaseContainer( newContId, containerName,
00242 className, 0, *this ) );
00243 m_transactionCache->addContainer( newContId, containerName, container );
00244 return container;
00245 }
00246
00247
00248 ora::Handle<ora::DatabaseContainer> ora::DatabaseSession::createContainer( const std::string& containerName,
00249 const Reflex::Type& type ){
00250
00251 int newContId = m_contIdSequence->getNextId( true );
00252 Handle<DatabaseContainer> newCont ( new DatabaseContainer( newContId, containerName, type, *this ) );
00253 m_transactionCache->addContainer( newContId, containerName, newCont );
00254 newCont->create();
00255 return newCont;
00256 }
00257
00258 void ora::DatabaseSession::dropContainer( const std::string& name ){
00259 Handle<DatabaseContainer> cont = m_transactionCache->getContainer( name );
00260 m_transactionCache->eraseContainer( cont->id(), name );
00261 cont->drop();
00262 }
00263
00264 ora::Handle<ora::DatabaseContainer> ora::DatabaseSession::containerHandle( const std::string& name ){
00265 return m_transactionCache->getContainer( name );
00266 }
00267
00268 ora::Handle<ora::DatabaseContainer> ora::DatabaseSession::containerHandle( int contId ){
00269 return m_transactionCache->getContainer( contId );
00270 }
00271
00272 const std::map<int, ora::Handle<ora::DatabaseContainer> >& ora::DatabaseSession::containers(){
00273 return m_transactionCache->containers();
00274 }
00275
00276 void ora::DatabaseSession::setObjectName( const std::string& name,
00277 int containerId,
00278 int itemId ){
00279 m_schema->namingServiceTable().setObjectName( name, containerId, itemId );
00280 }
00281
00282 bool ora::DatabaseSession::eraseObjectName( const std::string& name ){
00283 return m_schema->namingServiceTable().eraseObjectName( name );
00284 }
00285
00286 bool ora::DatabaseSession::eraseAllNames(){
00287 return m_schema->namingServiceTable().eraseAllNames();
00288 }
00289
00290 ora::Object ora::DatabaseSession::fetchObjectByName( const std::string& name ){
00291 ora::Object ret;
00292 std::pair<int,int> oid;
00293 if( m_schema->namingServiceTable().getObjectByName( name, oid ) ){
00294 ora::Handle<ora::DatabaseContainer> cont = containerHandle( oid.first );
00295 if( cont ) ret = Object( cont->fetchItem( oid.second ), cont->type() );
00296 }
00297 return ret;
00298 }
00299
00300 bool ora::DatabaseSession::getItemId( const std::string& name, ora::OId& destination ){
00301 std::pair<int,int> oidData;
00302 if( m_schema->namingServiceTable().getObjectByName( name, oidData ) ){
00303 destination = OId( oidData.first, oidData.second );
00304 return true;
00305 }
00306 return false;
00307 }
00308
00309 boost::shared_ptr<void> ora::DatabaseSession::fetchTypedObjectByName( const std::string& name,
00310 const Reflex::Type& asType ){
00311 boost::shared_ptr<void> ret = m_transactionCache->getNamedReference( name );
00312 if( !ret.get() ){
00313 std::pair<int,int> oid;
00314 if( m_schema->namingServiceTable().getObjectByName( name, oid ) ){
00315 ora::Handle<ora::DatabaseContainer> cont = containerHandle( oid.first );
00316 void* ptr = 0;
00317 if( cont ) {
00318 ptr = cont->fetchItemAsType( oid.second, asType );
00319 if( ptr) ret = boost::shared_ptr<void>( ptr, RflxDeleter( cont->type() ) );
00320 }
00321 }
00322 if( ret.get() ) m_transactionCache->setNamedReference( name, ret );
00323 }
00324 return ret;
00325 }
00326
00327 bool ora::DatabaseSession::getNamesForContainer( int containerId,
00328 std::vector<std::string>& destination ){
00329 return m_schema->namingServiceTable().getNamesForContainer( containerId, destination );
00330 }
00331
00332 bool ora::DatabaseSession::getNamesForObject( int containerId,
00333 int itemId,
00334 std::vector<std::string>& destination ){
00335 return m_schema->namingServiceTable().getNamesForObject( containerId, itemId, destination );
00336 }
00337
00338 bool ora::DatabaseSession::listObjectNames( std::vector<std::string>& destination ){
00339
00340 return m_schema->namingServiceTable().getAllNames( destination );
00341 }
00342
00343 ora::Handle<ora::DatabaseUtilitySession> ora::DatabaseSession::utility(){
00344 if( !m_transactionCache->utility() ){
00345 Handle<DatabaseUtilitySession> util ( new DatabaseUtilitySession( *this ) );
00346 m_transactionCache->setUtility( util );
00347 }
00348 return m_transactionCache->utility();
00349 }
00350
00351 ora::IDatabaseSchema& ora::DatabaseSession::schema(){
00352 return *m_schema;
00353 }
00354
00355 ora::NamedSequence& ora::DatabaseSession::containerIdSequence(){
00356 return *m_contIdSequence;
00357 }
00358
00359 ora::MappingDatabase& ora::DatabaseSession::mappingDatabase(){
00360 return *m_mappingDb;
00361 }
00362
00363 ora::Configuration& ora::DatabaseSession::configuration(){
00364 return m_configuration;
00365 }
00366
00367 ora::SharedSession& ora::DatabaseSession::storageAccessSession(){
00368 return m_dbSession;
00369 }
00370
00371 boost::shared_ptr<ora::ConnectionPool>& ora::DatabaseSession::connectionPool(){
00372 return m_connectionPool;
00373 }
00374
00375 ora::ContainerUpdateTable& ora::DatabaseSession::containerUpdateTable(){
00376 return m_containerUpdateTable;
00377 }