Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

CdbEnvironmentImpl.cc

Go to the documentation of this file.
00001 // File and Version Information:
00002 //      $Id: CdbEnvironmentImpl.cc,v 1.16 2005/11/03 02:49:26 gapon Exp $
00003 
00004 /// The implementation of the CdbEnvironmentImplImpl singleton.
00005 /**
00006   * @see CdbEnvironmentImpl
00007   */
00008 
00009 #include "BaBar/BaBar.hh"
00010 
00011 #include "CdbBase/CdbEnvironmentImpl.hh"
00012 #include "CdbBase/Cdb.hh"
00013 #include "CdbBase/CdbDebugStream.hh"
00014 
00015 #include <stdio.h>
00016 #include <string.h>    // strcmp()
00017 #include <assert.h>
00018 
00019 #include "ErrLogger/ErrLog.hh"
00020 using std::endl;
00021 
00022 CdbEnvironmentImpl::CdbEnvironmentImpl( ) :
00023     _truncateTime(BdbTime::plusInfinity),
00024     _defaultTechnologyName("")
00025 { }
00026 
00027 CdbEnvironmentImpl::CdbEnvironmentImpl( const CdbEnvironmentImpl& theOther ) :
00028     _truncateTime         (theOther._truncateTime),
00029     _technologies         (theOther._technologies),
00030     _defaultTechnologyName(theOther._defaultTechnologyName)
00031 { }
00032 
00033 CdbEnvironmentImpl::~CdbEnvironmentImpl( )
00034 { }
00035 
00036 CdbEnvironmentImpl&
00037 CdbEnvironmentImpl::operator=( const CdbEnvironmentImpl& theOther )
00038 {
00039     if( this != &theOther ) {
00040         _truncateTime          = theOther._truncateTime;
00041         _technologies          = theOther._technologies;
00042         _defaultTechnologyName = theOther._defaultTechnologyName;
00043     }
00044     return *this;
00045 }
00046 
00047 BdbTime
00048 CdbEnvironmentImpl::getTruncateTime( )
00049 {
00050     return _truncateTime;
00051 }
00052 
00053 BdbTime
00054 CdbEnvironmentImpl::setTruncateTime( const BdbTime& theNewTruncateTime )
00055 {
00056     if( BdbTime::minusInfinity == theNewTruncateTime )
00057         ErrMsg(fatal) << "Incorrect value passed to the procedure. The current application" << endl
00058                       << "may be misconfigured. A memory corruption may also take place." << endmsg;
00059 
00060     BdbTime previous = _truncateTime;
00061     _truncateTime = theNewTruncateTime;
00062 
00063     CDB_DEBUG_STREAM << "Condition/DB API truncate time set to " << _truncateTime << endl;
00064 
00065     return _truncateTime;
00066 }
00067 
00068 CdbStatus
00069 CdbEnvironmentImpl::getDefaultTechnology( std::string& theTechnologyName )
00070 {
00071   // Make sure the underlying implementations of CDB API registered
00072   // in the dictionary are properly initialized.
00073 
00074     initialize( );
00075 
00076   // Check if there is the one
00077 
00078     if( 0 == _technologies.size( )) return CdbStatus::NotFound;
00079 
00080     assert( "" != _defaultTechnologyName ); // Inconsistent state of the internal data structures of
00081                                             // the current class.
00082 
00083   // Done
00084 
00085     theTechnologyName = _defaultTechnologyName;
00086 
00087     return CdbStatus::Success;
00088 }
00089 
00090 CdbStatus
00091 CdbEnvironmentImpl::getDefaultImplementation( std::string& theImplementationName,
00092                                               const char*  theTechnologyName )
00093 {
00094   // Make sure the underlying implementations of CDB API registered
00095   // in the dictionary are properly initialized.
00096 
00097     initialize( );
00098 
00099   // Make adjustment to the technology.
00100 
00101     std::string technologyName;
00102     {
00103         CdbStatus status = translateAndVerify( technologyName,
00104                                                theTechnologyName );
00105         if     ( CdbStatus::Success  == status ) ;
00106         else if( CdbStatus::NotFound == status ) return status;
00107         else {
00108             ErrMsg(error) << "Failed to translate the parameters of CDB API passed to the procedure." << endl
00109                           << "The current application may be misconfigured." << endmsg;
00110             return CdbStatus::Error;
00111         }
00112     }
00113 
00114   // Now try to get the default implementation in the scope of found
00115   // technology object.
00116 
00117     CdbPtr implementationPtr;
00118     if( !(_technologies[technologyName].getDefault( implementationPtr ))) return CdbStatus::NotFound;
00119 
00120     assert( !implementationPtr.isNull( ));  // Inconsistent state of the internal data structures of
00121                                             // the current class.
00122 
00123   // Done
00124 
00125     theImplementationName = implementationPtr->implementationName( );
00126 
00127     return CdbStatus::Success;
00128 }
00129 
00130 CdbStatus
00131 CdbEnvironmentImpl::getDefaultDatabase( std::string& theDatabaseName,
00132                                         const char*  theImplementationName,
00133                                         const char*  theTechnologyName )
00134 {
00135   // Make sure the underlying implementations of CDB API registered
00136   // in the dictionary are properly initialized.
00137 
00138     initialize( );
00139 
00140   // Make adjustment to the technology.& implementation
00141 
00142     std::string technologyName;
00143     std::string implementationName;
00144     CdbPtr      implementationPtr;
00145     {
00146         CdbStatus status = translateAndVerify( technologyName,
00147                                                implementationName,
00148                                                implementationPtr,
00149                                                theTechnologyName,
00150                                                theImplementationName );
00151         if     ( CdbStatus::Success  == status ) ;
00152         else if( CdbStatus::NotFound == status ) return status;
00153         else {
00154             ErrMsg(error) << "Failed to translate the parameters of CDB API passed to the procedure." << endl
00155                           << "The current application may be misconfigured." << endmsg;
00156             return CdbStatus::Error;
00157         }
00158     }
00159 
00160   // Finish
00161 
00162     return implementationPtr->getDefaultDatabase( theDatabaseName );
00163 }
00164 
00165 CdbStatus
00166 CdbEnvironmentImpl::getDefaultView( std::string& theViewName,
00167                                     const char*  theDatabaseName,
00168                                     const char*  theImplementationName,
00169                                     const char*  theTechnologyName )
00170 {
00171   // Make sure the underlying implementations of CDB API registered
00172   // in the dictionary are properly initialized.
00173 
00174     initialize( );
00175 
00176   // Make adjustment to the technology.& implementation
00177 
00178     std::string technologyName;
00179     std::string implementationName;
00180     CdbPtr      implementationPtr;
00181     {
00182         CdbStatus status = translateAndVerify( technologyName,
00183                                                implementationName,
00184                                                implementationPtr,
00185                                                theTechnologyName,
00186                                                theImplementationName );
00187         if     ( CdbStatus::Success  == status ) ;
00188         else if( CdbStatus::NotFound == status ) return status;
00189         else {
00190             ErrMsg(error) << "Failed to translate the parameters of CDB API passed to the procedure." << endl
00191                           << "The current application may be misconfigured." << endmsg;
00192             return CdbStatus::Error;
00193         }
00194     }
00195 
00196   // Make adjustments to the database if 0 pointer was passed
00197 
00198     std::string databaseName;
00199     if( CdbStatus::Success != implementationPtr->getDefaultDatabase( databaseName )) {
00200 
00201         ErrMsg(fatal) << "Failed to obtain the default database from the following implementation" << endl
00202                       << "    TECHNOLOGY     : \"" << technologyName << "\"" << endl
00203                       << "    IMPLEMENTATION : \"" << implementationName << "\"" << endl
00204                       << "The problem can be caused either by a misconfigured application or" << endl
00205                       << "by a bug in the corresponding CDB API implementation module." << endmsg;
00206     }
00207 
00208     if( 0 != theDatabaseName ) databaseName = theDatabaseName;
00209     if( "" == databaseName ) return CdbStatus::IllegalParameters;
00210 
00211   // Finish
00212 
00213     return implementationPtr->getDefaultView( theViewName,
00214                                               databaseName.c_str( ));
00215 }
00216 
00217 CdbStatus
00218 CdbEnvironmentImpl::getDefaultPath( std::string& theViewName,
00219                                     std::string& theDatabaseName,
00220                                     std::string& theImplementationName,
00221                                     std::string& theTechnologyName )
00222 {
00223   // Make sure the underlying implementations of CDB API registered
00224   // in the dictionary are properly initialized.
00225 
00226     initialize( );
00227 
00228   // Get the components of the pass one-by-one
00229 
00230     std::string technologyName;
00231     {
00232         CdbStatus status = getDefaultTechnology( technologyName );
00233         if     ( CdbStatus::Success  == status ) ;
00234         else if( CdbStatus::NotFound == status ) return status;
00235         else {
00236             ErrMsg(error) << "Failed to obtain the default 'technology' of CDB API." << endl
00237                           << "The current application may be misconfigured." << endmsg;
00238             return CdbStatus::Error;
00239         }
00240     }
00241 
00242     std::string implementationName;
00243     {
00244         CdbStatus status = getDefaultImplementation( implementationName,
00245                                                      technologyName.c_str( ));
00246         if     ( CdbStatus::Success  == status ) ;
00247         else if( CdbStatus::NotFound == status ) return status;
00248         else {
00249             ErrMsg(error) << "Failed to obtain the default 'implementation' of CDB API." << endl
00250                           << "The current application may be misconfigured." << endmsg;
00251             return CdbStatus::Error;
00252         }
00253     }
00254 
00255     std::string databaseName;
00256     {
00257         CdbStatus status = getDefaultDatabase( databaseName,
00258                                                implementationName.c_str( ),
00259                                                technologyName.c_str( ) );
00260         if     ( CdbStatus::Success  == status ) ;
00261         else if( CdbStatus::NotFound == status ) return status;
00262         else {
00263             ErrMsg(error) << "Failed to obtain the default 'database' of CDB API." << endl
00264                           << "The current application may be misconfigured." << endmsg;
00265             return CdbStatus::Error;
00266         }
00267     }
00268     std::string viewName;
00269     {
00270         CdbStatus status = getDefaultView( viewName,
00271                                            databaseName.c_str( ),
00272                                            implementationName.c_str( ),
00273                                            technologyName.c_str( ) );
00274         if     ( CdbStatus::Success  == status ) ;
00275         else if( CdbStatus::NotFound == status ) return status;
00276         else {
00277             ErrMsg(error) << "Failed to obtain the default 'view' of CDB API." << endl
00278                           << "The current application may be misconfigured." << endmsg;
00279             return CdbStatus::Error;
00280         }
00281     }
00282 
00283   // Done
00284 
00285     theTechnologyName     = technologyName;
00286     theImplementationName = implementationName;
00287     theDatabaseName       = databaseName;
00288     theViewName           = viewName;
00289 
00290     return CdbStatus::Success;
00291 }
00292 
00293 CdbStatus
00294 CdbEnvironmentImpl::setDefaultTechnology( const char* theTechnologyName )
00295 {
00296     return CdbStatus::NotImplemented;
00297 }
00298 
00299 CdbStatus
00300 CdbEnvironmentImpl::setDefaultImplementation( const char* theImplementationName,
00301                                               const char* theTechnologyName )
00302 {
00303     return CdbStatus::NotImplemented;
00304 }
00305 
00306 CdbStatus
00307 CdbEnvironmentImpl::setDefaultDatabase( const char* theDatabaseName,
00308                                         const char* theImplementationName,
00309                                         const char* theTechnologyName )
00310 {
00311     return CdbStatus::NotImplemented;
00312 }
00313 
00314 CdbStatus
00315 CdbEnvironmentImpl::setDefaultView( const char* theViewName,
00316                                     const char* theDatabaseName,
00317                                     const char* theImplementationName,
00318                                     const char* theTechnologyName )
00319 {
00320     return CdbStatus::NotImplemented;
00321 }
00322 
00323 CdbStatus
00324 CdbEnvironmentImpl::setDefaultPath( const char* theViewName,
00325                                     const char* theDatabaseName,
00326                                     const char* theImplementationName,
00327                                     const char* theTechnologyName )
00328 {
00329   // Make sure the underlying implementations of CDB API registered
00330   // in the dictionary are properly initialized.
00331 
00332     initialize( );
00333 
00334   // DESIGN NOTE: The algorithm below assumes that specified 'technology' and
00335   //              'implementation' are already registered in the dictionary
00336   //              and that the corresponding object implementing CDB API
00337   //              will respect both of specified database and view names.
00338 
00339     CdbStatus result = CdbStatus::Error;
00340     do {
00341 
00342       // Verify parameters
00343 
00344         if(( 0 == theTechnologyName ) ||
00345            ( 0 == strcmp( "", theTechnologyName )) ||
00346            ( 0 == theImplementationName ) ||
00347            ( 0 == strcmp( "", theImplementationName ))) return CdbStatus::IllegalParameters;
00348 
00349       // Find the technology
00350 
00351         std::string technologyName = theTechnologyName;
00352         if( _technologies.find( technologyName ) == _technologies.end( )) {
00353 
00354             ErrMsg(error) << "Specified 'technology' is unknown." << endl
00355                           << "    TECHNOLOGY : \"" << technologyName << "\"" << endmsg;
00356             break;
00357         }
00358 
00359       // Find the implementation
00360 
00361         CdbPtr implementationPtr;
00362 
00363         std::string implementationName = theImplementationName;
00364         if( !_technologies[technologyName].find( implementationPtr,
00365                                                  implementationName )) {
00366 
00367             ErrMsg(error) << "Specified 'implementation' is unknown." << endl
00368                           << "    TECHNOLOGY     : \"" << technologyName << "\"" << endl
00369                           << "    IMPLEMENTATION : \"" << implementationName << "\"" << endmsg;
00370             break;
00371         }
00372 
00373       // Propagate request down to the found implementation to set up default
00374       // database and the view.
00375 
00376         if( CdbStatus::Success != implementationPtr->setDefaultDatabase( theDatabaseName )) {
00377 
00378             ErrMsg(error) << "Failed to set default database." << endl
00379                           << "    TECHNOLOGY     : \"" << technologyName << "\"" << endl
00380                           << "    IMPLEMENTATION : \"" << implementationName << "\"" << endl
00381                           << "    DATABASE       : \"" << theDatabaseName << "\"" << endmsg;
00382             break;
00383         }
00384         if( CdbStatus::Success != implementationPtr->setDefaultView( theViewName, theDatabaseName )) {
00385 
00386             ErrMsg(error) << "Failed to set default view." << endl
00387                  << "    TECHNOLOGY     : \"" << technologyName << "\"" << endl
00388                  << "    IMPLEMENTATION : \"" << implementationName << "\"" << endl
00389                  << "    DATABASE       : \"" << theDatabaseName << "\"" << endl
00390                  << "    VIEW           : \"" << theViewName << "\"" << endmsg;
00391             break;
00392         }
00393 
00394       // Remember new defaults
00395 
00396         if( !_technologies[technologyName].setDefault( implementationName )) {
00397 
00398             ErrMsg(error) << "Failed to set specified 'implementation' as the default one." << endl
00399                  << "    TECHNOLOGY     : \"" << technologyName << "\"" << endl
00400                  << "    IMPLEMENTATION : \"" << implementationName << "\"" << endmsg;
00401             break;
00402         }
00403         _defaultTechnologyName = technologyName;
00404 
00405       // Done
00406 
00407         CDB_DEBUG_STREAM << "Condition/DB API defaults set to "
00408                          << " TECHNOLOGY=\"" << theTechnologyName << "\""
00409                          << " IMPLEMENTATION=\"" << theImplementationName << "\""
00410                          << " DATABASE=\"" << theDatabaseName << "\""
00411                          << " VIEW=\"" << theViewName << "\"" << endl;
00412  
00413         result = CdbStatus::Success;
00414 
00415     } while( false );
00416 
00417     return result;
00418 }
00419 
00420 CdbStatus
00421 CdbEnvironmentImpl::set( CdbPtr& thePtr )
00422 {
00423   // IMPORTANT NOTE: This method does NOT initialize implementations to avoid any actual
00424   //                 interructions with persistent store(s) before they are going to be used.
00425 
00426 //    initialize( );
00427 
00428     CdbStatus result = CdbStatus::Error;
00429     do {
00430 
00431       // Verify parameters
00432 
00433         if( thePtr.isNull( )) {
00434             result = CdbStatus::IllegalParameters;
00435             break;
00436         }
00437         std::string technologyName     = thePtr->technologyName( );
00438         std::string implementationName = thePtr->implementationName( );
00439 
00440       // Find the technology first. Create it if it does not exist.
00441       //
00442       // NOTE: If thsi is going to be the very first technology then it will automatically
00443       //       become the default one.
00444 
00445         if( 0 == _technologies.size( )) {
00446 
00447             _technologies[technologyName] = Technology( );
00448             _defaultTechnologyName        = technologyName;
00449 
00450         } else {
00451 
00452             std::map<std::string, Technology>::iterator technologyItr = _technologies.find( technologyName );
00453             if( technologyItr == _technologies.end( )) _technologies[technologyName] = Technology( );
00454         }
00455 
00456       // Insert the implementation into found technology the implementation.
00457       //
00458       // NOTE: There should not be any other implementation under the same name.
00459       //       Report a problem back to the caller if there is one.
00460 
00461         if( !(_technologies[technologyName].insert( thePtr ))) {
00462 
00463             ErrMsg(error) << "The CDB API implementation with specified parameters has already been registered." << endl
00464                           << "    TECHNOLOGY     : \"" << technologyName << "\"" << endl
00465                           << "    IMPLEMENTATION : \"" << implementationName << "\"" << endmsg;
00466 
00467             break;
00468         }
00469 
00470       // Done
00471 
00472         result = CdbStatus::Success;
00473 
00474     } while( false );
00475 
00476     return result;
00477 }
00478 
00479 CdbStatus
00480 CdbEnvironmentImpl::get( CdbPtr&     thePtr,
00481                          const char* theTechnologyName,
00482                          const char* theImplementationName )
00483 {
00484   // Make sure the underlying implementations of CDB API registered
00485   // in the dictionary are properly initialized.
00486 
00487     initialize( );
00488 
00489     CdbStatus result = CdbStatus::Error;
00490     do {
00491 
00492       // Verify parameters
00493 
00494         if(( 0 == theTechnologyName ) ||
00495            ( 0 == strcmp( "", theTechnologyName )) ||
00496            ( 0 == theImplementationName ) ||
00497            ( 0 == strcmp( "", theImplementationName ))) {
00498 
00499             result = CdbStatus::IllegalParameters;
00500             break;
00501         }
00502 
00503       // Find the technology first
00504 
00505         std::map<std::string, Technology>::iterator technologyItr = _technologies.find( std::string( theTechnologyName ));
00506         if( technologyItr == _technologies.end( )) {
00507             result = CdbStatus::NotFound;
00508             break;
00509         }
00510 
00511       // Find the implementation
00512 
00513         CdbPtr implementationPtr;
00514         if( !technologyItr->second.find( implementationPtr,
00515                                          std::string( theImplementationName ))) {
00516             result = CdbStatus::NotFound;
00517             break;
00518         }
00519 
00520       // Done
00521 
00522         thePtr = implementationPtr;
00523 
00524         result = CdbStatus::Success;
00525 
00526     } while(false);
00527 
00528     return result;
00529 }
00530 
00531 CdbAnyTypeDict<std::string>&
00532 CdbEnvironmentImpl::extra( )
00533 {
00534     return _extra;
00535 }
00536 
00537 void
00538 CdbEnvironmentImpl::initialize( )
00539 {
00540   // Walk through each CDB API implementation and check for those which are
00541   // not initialized yet.
00542 
00543     for( std::map<std::string, Technology>::iterator technologyItr = _technologies.begin( );
00544          technologyItr != _technologies.end( );
00545          ++technologyItr ) {
00546 
00547         for( std::map<std::string, CdbPtr>::iterator implementationItr = technologyItr->second._implementations.begin( );
00548              implementationItr != technologyItr->second._implementations.end( );
00549              ++implementationItr ) {
00550 
00551             CdbPtr ptr = (*implementationItr).second;
00552 
00553             if( !ptr->isInitialized( )) ptr->initialize( );
00554         }
00555     }
00556 }
00557 
00558 CdbStatus
00559 CdbEnvironmentImpl::translateAndVerify( std::string& theOutTechnologyName,
00560                                         const char*  theInTechnologyName )
00561 {
00562   // Make adjustment to the technology if 0 pointer was passed.
00563 
00564     std::string technologyName;
00565     if( CdbStatus::Success != getDefaultTechnology( technologyName )) {
00566 
00567         ErrMsg(error) << "Failed to obtain the default CDB API 'technology'." << endl
00568                       << "The current application may be misconfigured." << endmsg;
00569         return CdbStatus::Error;
00570     }
00571 
00572     if( 0 != theInTechnologyName ) technologyName = theInTechnologyName;
00573     if( "" == technologyName ) return CdbStatus::IllegalParameters;
00574 
00575   // Find the technology
00576   //
00577   // NOTE: If this operation will fail then depending on which source of information
00578   //       we used we produce different return status. If the default value was used
00579   //       we have internally inconsistent data structure.
00580 
00581     std::map<std::string, Technology>::iterator technologyItr = _technologies.find( technologyName );
00582     if( technologyItr == _technologies.end( )) return CdbStatus::NotFound;
00583 
00584   // Done
00585 
00586     theOutTechnologyName  = technologyName;
00587 
00588     return CdbStatus::Success;
00589 }
00590 
00591 CdbStatus
00592 CdbEnvironmentImpl::translateAndVerify( std::string& theOutTechnologyName,
00593                                         std::string& theOutImplementationName,
00594                                         CdbPtr&      thePtr,
00595                                         const char*  theInTechnologyName,
00596                                         const char*  theInImplementationName )
00597 {
00598   // Make adjustment to the technology.
00599 
00600     std::string technologyName;
00601     {
00602         CdbStatus result = translateAndVerify( technologyName, theInTechnologyName );
00603         if( CdbStatus::Success != result ) return result;
00604     }
00605 
00606   // Make adjustment to the implementation if 0 pointer was passed.
00607 
00608     std::string implementationName;
00609     if( CdbStatus::Success != getDefaultImplementation( implementationName,
00610                                                         technologyName.c_str( ))) {
00611 
00612         ErrMsg(error) << "Failed to obtain the default CDB API 'implementation'." << endl
00613                       << "The current application may be misconfigured." << endmsg;
00614         return CdbStatus::Error;
00615     }
00616 
00617     if( 0 != theInImplementationName ) implementationName = theInImplementationName;
00618     if( "" == technologyName ) return CdbStatus::IllegalParameters;
00619 
00620   // Find the implementation
00621   //
00622   // NOTE: If this operation will fail then depending on which source of information
00623   //       we used we produce different return status. If the default value was used
00624   //       we have internally inconsistent data structure.
00625 
00626     CdbPtr implementationPtr;
00627     if( !(_technologies[technologyName].find( implementationPtr,
00628                                               implementationName.c_str( )))) return CdbStatus::NotFound;
00629 
00630   // Done
00631 
00632     theOutTechnologyName     = technologyName;
00633     theOutImplementationName = implementationName;
00634     thePtr                   = implementationPtr;
00635 
00636     return CdbStatus::Success;
00637 }
00638 
00639 /////////////////
00640 // End Of File //
00641 /////////////////

Generated on Mon Dec 5 18:22:05 2005 for CDB by doxygen1.3-rc3