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