Go to the documentation of this file.00001
00002 #include "CondCore/DBCommon/interface/DbSession.h"
00003 #include "CondCore/DBCommon/interface/DbConnection.h"
00004 #include "CondCore/DBCommon/interface/DbTransaction.h"
00005 #include "CondCore/DBCommon/interface/Exception.h"
00006 #include "CondCore/DBCommon/interface/BlobStreamerPluginFactory.h"
00007 #include "CondCore/DBCommon/interface/Auth.h"
00008
00009 #include "FWCore/PluginManager/interface/PluginFactory.h"
00010 #include "CondCore/DBCommon/interface/TechnologyProxyFactory.h"
00011 #include "CondCore/ORA/interface/ConnectionPool.h"
00012
00013 #include "RelationalAccess/ISessionProxy.h"
00014
00015 namespace cond {
00016
00017 inline std::auto_ptr<cond::TechnologyProxy> buildTechnologyProxy(const std::string&userconnect,
00018 const DbConnection& connection){
00019 std::string protocol;
00020 std::size_t pos=userconnect.find_first_of(':');
00021 if( pos!=std::string::npos ){
00022 protocol=userconnect.substr(0,pos);
00023 std::size_t p=protocol.find_first_of('_');
00024 if(p!=std::string::npos){
00025 protocol=protocol.substr(0,p);
00026 }
00027 }else{
00028 throw cond::Exception(userconnect +":connection string format error");
00029 }
00030 std::auto_ptr<cond::TechnologyProxy> ptr(cond::TechnologyProxyFactory::get()->create(protocol));
00031 (*ptr).initialize(connection);
00032 return ptr;
00033 }
00034
00035 class SessionImpl {
00036 public:
00037 SessionImpl():
00038 connection(),
00039 blobStreamingService( "COND/Services/BlobStreamingService" ),
00040 database(),
00041 transaction(),
00042 isOpen(false){
00043 }
00044
00045 explicit SessionImpl( const DbConnection& connection ):
00046 connection(new DbConnection(connection)),
00047 blobStreamingService( "COND/Services/BlobStreamingService" ),
00048 database(),
00049 transaction(),
00050 isOpen(false){
00051 }
00052
00053
00054 virtual ~SessionImpl(){
00055 close();
00056 }
00057
00058 void open( const std::string& connectionString,
00059 const std::string& role,
00060 bool readOnly ){
00061 close();
00062 if( connection.get() ){
00063 if(!connection->isOpen()){
00064 throw cond::Exception("DbSession::open: cannot open session. Underlying connection is closed.");
00065 }
00066 boost::shared_ptr<ora::ConnectionPool> connPool = connection->connectionPool();
00067 database.reset( new ora::Database( connPool ) );
00068
00069 ora::IBlobStreamingService* blobStreamer = cond::BlobStreamerPluginFactory::get()->create( blobStreamingService );
00070 if(!blobStreamer) throw cond::Exception("DbSession::open: cannot find required plugin. No instance of ora::IBlobStreamingService has been loaded..");
00071 database->configuration().setBlobStreamingService( blobStreamer );
00072
00073 database->configuration().properties().setFlag( ora::Configuration::automaticContainerCreation() );
00074
00075 technologyProxy = buildTechnologyProxy(connectionString, *connection);
00076 std::string connStr = (*technologyProxy).getRealConnectString( connectionString );
00077 database->connect( connStr, role, readOnly );
00078 transaction.reset( new cond::DbTransaction( database->transaction() ) );
00079 isOpen = true;
00080 }
00081 }
00082
00083 void openReadOnly( const std::string& connectionString,
00084 const std::string& transactionId ){
00085 close();
00086 if( connection.get() ){
00087 if(!connection->isOpen()){
00088 throw cond::Exception("DbSession::open: cannot open session. Underlying connection is closed.");
00089 }
00090 boost::shared_ptr<ora::ConnectionPool> connPool = connection->connectionPool();
00091 database.reset( new ora::Database( connPool ) );
00092
00093 ora::IBlobStreamingService* blobStreamer = cond::BlobStreamerPluginFactory::get()->create( blobStreamingService );
00094 if(!blobStreamer) throw cond::Exception("DbSession::open: cannot find required plugin. No instance of ora::IBlobStreamingService has been loaded..");
00095 database->configuration().setBlobStreamingService( blobStreamer );
00096
00097 technologyProxy = buildTechnologyProxy(connectionString, *connection);
00098 std::string connStr = (*technologyProxy).getRealConnectString(connectionString, transactionId);
00099 database->connect( connStr, Auth::COND_READER_ROLE, true );
00100 transaction.reset( new cond::DbTransaction( database->transaction() ) );
00101 isOpen = true;
00102 }
00103 }
00104
00105 void close(){
00106 transaction.reset();
00107 database.reset();
00108 isOpen = false;
00109 }
00110
00111 std::auto_ptr<DbConnection> connection;
00112 std::auto_ptr<cond::TechnologyProxy> technologyProxy;
00113 std::string const blobStreamingService;
00114 std::auto_ptr<ora::Database> database;
00115 std::auto_ptr<DbTransaction> transaction;
00116 bool isOpen;
00117 };
00118
00119 }
00120
00121 const char* cond::DbSession::COND_SCHEMA_VERSION = "2.0.0";
00122 const char* cond::DbSession::CHANGE_SCHEMA_VERSION = "2.0.0";
00123
00124 cond::DbSession::DbSession():
00125 m_implementation( new SessionImpl ){
00126 }
00127
00128 cond::DbSession::DbSession( const DbConnection& connection ):
00129 m_implementation( new SessionImpl ( connection ) ){
00130 }
00131
00132 cond::DbSession::DbSession( const DbSession& rhs ):
00133 m_implementation( rhs.m_implementation ){
00134 }
00135
00136 cond::DbSession::~DbSession(){
00137 }
00138
00139 cond::DbSession& cond::DbSession::operator=( const cond::DbSession& rhs ){
00140 if(this!=&rhs) m_implementation = rhs.m_implementation;
00141 return *this;
00142 }
00143
00144 void cond::DbSession::open( const std::string& connectionString, bool readOnly )
00145 {
00146 std::string emptyRole("");
00147 m_implementation->open( connectionString, emptyRole, readOnly );
00148 }
00149
00150 void cond::DbSession::open( const std::string& connectionString, const std::string& asRole, bool readOnly )
00151 {
00152 m_implementation->open( connectionString, asRole, readOnly );
00153 }
00154
00155 void cond::DbSession::openReadOnly( const std::string& connectionString, const std::string& id )
00156 {
00157 m_implementation->openReadOnly( connectionString, id );
00158 }
00159
00160 void cond::DbSession::close()
00161 {
00162 m_implementation->close();
00163 }
00164
00165 bool cond::DbSession::isOpen() const {
00166 return m_implementation->isOpen;
00167 }
00168
00169 const std::string& cond::DbSession::connectionString() const {
00170 if(!m_implementation->database.get())
00171 throw cond::Exception("DbSession::connectionString: cannot get connection string. Session has not been open.");
00172 return m_implementation->database->connectionString();
00173 }
00174
00175 cond::DbConnection const & cond::DbSession::connection() const {
00176 return *(m_implementation->connection);
00177 }
00178
00179
00180 bool cond::DbSession::isTransactional() const {
00181 return m_implementation->technologyProxy->isTransactional();
00182 }
00183
00184 const std::string& cond::DbSession::blobStreamingService() const
00185 {
00186 return m_implementation->blobStreamingService;
00187 }
00188
00189 cond::DbTransaction& cond::DbSession::transaction()
00190 {
00191 if(!m_implementation->connection.get() || !m_implementation->connection->isOpen())
00192 throw cond::Exception("DbSession::transaction: cannot open transaction. Underlying connection is closed.");
00193 if(!m_implementation->transaction.get())
00194 throw cond::Exception("DbSession::transaction: cannot get transaction. Session has not been open.");
00195 return *m_implementation->transaction;
00196 }
00197
00198 ora::Database& cond::DbSession::storage(){
00199 if(!m_implementation->connection.get() || !m_implementation->connection->isOpen())
00200 throw cond::Exception("DbSession::storage: cannot access the storage. Underlying connection is closed.");
00201 if(!m_implementation->database.get())
00202 throw cond::Exception("DbSession::storage: cannot access the database. Session has not been open.");
00203 return *m_implementation->database;
00204 }
00205
00206 bool cond::DbSession::createDatabase(){
00207 bool created = false;
00208 if ( !storage().exists() ){
00209 created = true;
00210 storage().create( std::string(COND_SCHEMA_VERSION) );
00211 }
00212 return created;
00213 }
00214
00215 bool cond::DbSession::isOldSchema()
00216 {
00217 ora::Version dbVer = storage().schemaVersion();
00218 if (dbVer == ora::Version::poolSchemaVersion()) return true;
00219 dbVer = storage().schemaVersion( true );
00220 return dbVer < ora::Version::fromString( std::string( CHANGE_SCHEMA_VERSION ) );
00221 }
00222
00223 coral::ISchema& cond::DbSession::schema( const std::string& schemaName )
00224 {
00225 return storage().storageAccessSession().get().schema( schemaName );
00226 }
00227
00228 coral::ISchema& cond::DbSession::nominalSchema()
00229 {
00230 return storage().storageAccessSession().get().nominalSchema();
00231 }
00232
00233 bool cond::DbSession::deleteMapping( const std::string& mappingVersion ){
00234 ora::DatabaseUtility utility = storage().utility();
00235 utility.eraseMapping( mappingVersion );
00236 return true;
00237 }
00238
00239 bool cond::DbSession::importMapping( const std::string& sourceConnectionString,
00240 const std::string& contName ){
00241 ora::DatabaseUtility utility = storage().utility();
00242 std::auto_ptr<cond::TechnologyProxy> technologyProxy = buildTechnologyProxy(sourceConnectionString, *(m_implementation->connection));
00243 utility.importContainerSchema( (*technologyProxy).getRealConnectString( sourceConnectionString ), contName );
00244 return true;
00245 }
00246
00247 std::string cond::DbSession::storeObject( const ora::Object& object, const std::string& containerName ){
00248 ora::OId oid = storage().insertItem( containerName, object );
00249 storage().flush();
00250 return oid.toString();
00251 }
00252
00253 ora::Object cond::DbSession::getObject( const std::string& objectId ){
00254 ora::OId oid;
00255 oid.fromString( objectId );
00256 return storage().fetchItem( oid );
00257 }
00258
00259 bool cond::DbSession::deleteObject( const std::string& objectId ){
00260 ora::OId oid;
00261 oid.fromString( objectId );
00262 storage().erase( oid );
00263 storage().flush();
00264 return true;
00265 }
00266
00267 std::string cond::DbSession::importObject( cond::DbSession& fromDatabase, const std::string& objectId ){
00268 ora::OId oid;
00269 oid.fromString( objectId );
00270 ora::Object data = fromDatabase.getObject( objectId );
00271 ora::Container cont = fromDatabase.storage().containerHandle( oid.containerId() );
00272 std::string ret = storeObject( data, cont.name() );
00273 data.destruct();
00274 return ret;
00275 }
00276
00277 std::string cond::DbSession::classNameForItem( const std::string& objectId ){
00278 ora::OId oid;
00279 oid.fromString( objectId );
00280 std::string ret("");
00281 if( !oid.isInvalid() ){
00282 ora::Container cont = storage().containerHandle( oid.containerId() );
00283 ret = cont.className();
00284 }
00285 return ret;
00286 }
00287
00288 void cond::DbSession::flush(){
00289 storage().flush();
00290 }
00291
00292 cond::PoolTokenParser::PoolTokenParser( ora::Database& db ):
00293 m_db( db ){
00294 }
00295
00296 ora::OId cond::PoolTokenParser::parse( const std::string& poolToken ){
00297 std::pair<std::string,int> oidData = parseToken( poolToken );
00298 if( oidData.first.empty() ){
00299 throwException("Could not resolve Container name from token=\""+poolToken+"\".","PoolTokenParser::parse");
00300 }
00301 ora::Container cont = m_db.containerHandle( oidData.first );
00302 return ora::OId( cont.id(), oidData.second );
00303 }
00304
00305 std::string cond::PoolTokenParser::className( const std::string& oraToken ){
00306 ora::OId oid;
00307 oid.fromString( oraToken );
00308 ora::Container cont = m_db.containerHandle( oid.containerId() );
00309 return cont.className();
00310 }
00311
00312 cond::PoolTokenWriter::PoolTokenWriter( ora::Database& db ):
00313 m_db( db ){
00314 }
00315
00316 std::string cond::PoolTokenWriter::write( const ora::OId& oid ){
00317 ora::Container cont = m_db.containerHandle( oid.containerId() );
00318 return writeToken( cont.name(), oid.containerId(), oid.itemId(), cont.className() );
00319 }