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