Bdb packages | Design docs | Source docs | Guidelines | Recent releases

Search | Site Map .

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

/BdbCond/BdbCondDebug.cc

Go to the documentation of this file.
00001 //-----------------------------------------------------------------------------
00002 //
00003 // File and Version Information:
00004 //      $Id: BdbCondDebug.cc,v 1.5 2002/08/07 21:45:26 gapon Exp $
00005 //
00006 // Description:
00007 //      Class BdbCondDebug. 
00008 //      This is a low level debugger class to manipulating with
00009 //      meta data within a scope of specified cindition.
00010 //
00011 //      All these operations are protected through the BDB Authorization
00012 //      system.
00013 //
00014 // Environment:
00015 //      Software developed for the BaBar Detector at the SLAC B-Factory.
00016 //
00017 // Author List:
00018 //      Igor A. Gaponenko       Original Author
00019 //
00020 // Copyright Information:
00021 //      Copyright (C) 2001      Lawrence Berkeley Laboratory
00022 //
00023 //-----------------------------------------------------------------------------
00024 
00025 // -------------------------
00026 // -- This Class's Header --
00027 // -------------------------
00028 
00029 #include "BdbCond/BdbCondDebug.hh"
00030 
00031 // ---------------
00032 // -- C Headers --
00033 // ---------------
00034 
00035 extern "C" {
00036 #include <assert.h>
00037 #include <ctype.h>
00038 #include <stddef.h>
00039 #include <stdio.h>
00040 #include <stdlib.h>
00041 #include <string.h>
00042 }
00043 
00044 // -----------------
00045 // -- C++ Headers --
00046 // -----------------
00047 
00048 #include <iostream.h>
00049 #include <string>
00050 using std::string;
00051 
00052 // ---------------------------------
00053 // -- Collaborating Class Headers --
00054 // ---------------------------------
00055 
00056 #include "BdbAccess/BdbAuth.hh"
00057 #include "BdbCond/BdbIntervalR.hh"
00058 #include "BdbCond/BdbIntervalGene.hh"
00059 #include "BdbCond/BdbCondRevision.hh"
00060 #include "BdbCond/BdbCondContainerLink.hh"
00061 #include "BdbTime/BdbTime.hh"
00062 #include "ErrLogger/ErrLog.hh"
00063 
00064 // -------------------------
00065 // -- Objectivity Headers --
00066 // -------------------------
00067 
00068 #include <ooIndex.h>
00069 
00070 // --------------------------------------------------------------------------
00071 // -- Local Macros, Typedefs, Structures, Unions, and Forward Declarations --
00072 // --------------------------------------------------------------------------
00073 
00074 static const char  rcsid[] = "$Id: BdbCondDebug.cc,v 1.5 2002/08/07 21:45:26 gapon Exp $";
00075 
00076 // ------------------
00077 // -- Constructors --
00078 // ------------------
00079 
00080 BdbCondDebug::BdbCondDebug( const char* theDetectorName,
00081                             const char* theContName ) :
00082     _isInitialized(false),
00083     _detectorName(""),
00084     _containerName(""),
00085     _databasePtr(0)
00086 {
00087     assert( 0 != theDetectorName );
00088     assert( 0 != theContName );
00089 
00090     if ( 0 != theDetectorName ) _detectorName  = theDetectorName;
00091     if ( 0 != theContName )     _containerName = theContName;
00092 }
00093 
00094 // ----------------
00095 // -- Destructor --
00096 // ----------------
00097 
00098 BdbCondDebug::~BdbCondDebug( )
00099 {
00100     if ( 0 != _databasePtr ) delete _databasePtr;
00101 }
00102 
00103 // --------------------------------------------
00104 // -- Deferred initialization of the context --
00105 // --------------------------------------------
00106 
00107 bool
00108 BdbCondDebug::initialize( )
00109 {
00110     const char* errorString = "BdbCondDebug::initialize() -- error.";
00111 
00112     if( ! _isInitialized ) {
00113 
00114       // Do initialization in the exception-like loop.
00115 
00116         do {
00117 
00118           // Initialization means opening specified container and providing
00119           // that the cache of BdbObsoleteDatabase object is loaded with all the nessesary
00120           // handles.
00121 
00122             _databasePtr = new BdbObsoleteDatabase( _detectorName.c_str() );
00123 
00124             BdbStatus              status;
00125             BdbHandle(BdbInterval) theFirstIntervalH;
00126 
00127             status = _databasePtr->firstInterval( theFirstIntervalH, _containerName.c_str() );
00128             if(( BdbcSuccess != status ) || BdbIsNull(theFirstIntervalH)) {
00129 
00130                 ErrMsg(error) << errorString << endl
00131                               << "    Failed to initialize the proper context since the VERY FIRST interval" << endl
00132                               << "    in this container can't be found." << endl
00133                               << "        DETECTOR:  " << _detectorName  << endl
00134                               << "        CONTAINER: " << _containerName << endmsg;
00135 
00136                 delete _databasePtr;
00137                 _databasePtr = 0;
00138 
00139                 break;
00140             }
00141 
00142           // Check for the proper index and authorization as well.
00143           //
00144           // NOTE: Here we're assuming that we may call the following methods
00145           //       in the context of BdbObsoleteDatabase class.
00146 
00147             if( ! _databasePtr->verifyIndexMode( ) || ! _databasePtr->setAuthLevel( _containerName.c_str() )) {
00148 
00149                 delete _databasePtr;
00150                 _databasePtr = 0;
00151 
00152                 break;
00153             }
00154 
00155           // Success.
00156 
00157             _isInitialized = true;
00158 
00159         } while( false );
00160     }
00161 
00162     return _isInitialized;
00163 }
00164 
00165 // --------------
00166 // -- Accessor --
00167 // --------------
00168 
00169 bool
00170 BdbCondDebug::isInitialized( )
00171 {
00172     return initialize( );
00173 }
00174 
00175 string
00176 BdbCondDebug::getDetectorName( )
00177 {
00178     if( initialize( )) {
00179         return _detectorName;
00180     }
00181     return "";
00182 }
00183 
00184 string
00185 BdbCondDebug::getContainerName( )
00186 {
00187     if( initialize( )) {
00188         return _containerName;
00189     }
00190     return "";
00191 }
00192 
00193 string
00194 BdbCondDebug::getOriginName( )
00195 {
00196     if( initialize( )) {
00197 
00198         BdbCondContainerLink theLink;
00199         _databasePtr->getContainerLink( theLink );
00200  
00201         return theLink.getOrigin( );
00202     }
00203     return "";
00204 }
00205 
00206 // ----------------
00207 // -- Operations --
00208 // ----------------
00209 
00210 BdbStatus
00211 BdbCondDebug::removeIndex( )
00212 {
00213     const char* errorString = "BdbCondDebug::removeIndex() -- error.";
00214 
00215     BdbStatus status = BdbcError;
00216 
00217   // Do the rest in an exception alike loop.
00218 
00219     do {
00220 
00221       // Some safety checks.
00222 
00223         if( ! initialize( )) break;
00224 
00225       // We use the cached container handle to find out old indexes.
00226 
00227         BdbHandle(BdbContObj) theContH;
00228         _databasePtr->getIntervalContH( theContH );
00229 
00230       // Find out the "Key Description" and remove it if found.
00231 
00232         BdbHandle(ooKeyDesc) theKeyDescH;
00233         theKeyDescH = 0;
00234 
00235         BdbItr(BdbPersObj) theItr;
00236 
00237         status = theItr.scan( theContH, oocNoOpen );
00238         if ( BdbcSuccess != status ) {
00239             ErrMsg(error) << errorString << endl
00240                           << "    Failed to prepare an iterator." << endmsg;
00241             break;
00242         }
00243         while ( theItr.next( )) {
00244             if (theItr.typeN( ) == ooTypeN(ooKeyDesc)) {
00245                 theKeyDescH = (const BdbHandle(ooKeyDesc)&) theItr;
00246                 break;
00247             }
00248         }
00249         if( BdbIsNull(theKeyDescH)) {
00250             ErrMsg(error) << errorString << endl
00251                           << "    The old Key Description object is not found." << endmsg;
00252             break;
00253         }
00254         theKeyDescH->dropIndex( theContH );
00255         BdbDelete( theKeyDescH );
00256 
00257       // Success.
00258 
00259         status = BdbcSuccess;
00260 
00261     } while( false );
00262 
00263     return status;
00264 }
00265 
00266 BdbStatus
00267 BdbCondDebug::createIndex( )
00268 {
00269     const char* errorString = "BdbCondDebug::createIndex() -- error.";
00270 
00271     BdbStatus status = BdbcError;
00272 
00273   // Do the rest in an exception alike loop.
00274 
00275     do {
00276 
00277       // Some safety checks.
00278 
00279         if( ! initialize( )) break;
00280 
00281       // We use the cached container handle to keep indexes.
00282 
00283         BdbHandle(BdbContObj) theContH;
00284         _databasePtr->getIntervalContH( theContH );
00285 
00286       // Create the index (assuming that there is not other index)
00287 
00288         BdbHandle(ooKeyDesc)  theKeyDescH;
00289         BdbHandle(ooKeyField) theKeyFieldH;
00290 
00291         d_Boolean uniqueKeys = d_False;
00292 
00293         theKeyDescH  = new( theContH ) ooKeyDesc( ooTypeN(BdbInterval), uniqueKeys );
00294 
00295         theKeyFieldH = new( theKeyDescH ) ooKeyField( ooTypeN(BdbInterval), "_beginTime._gmtSec" );
00296         theKeyDescH->addField( theKeyFieldH );
00297           
00298         theKeyFieldH = new( theKeyDescH ) ooKeyField( ooTypeN(BdbInterval), "_endTime._gmtSec" );
00299         theKeyDescH->addField( theKeyFieldH );
00300 
00301         theKeyDescH->createIndex( theContH );
00302 
00303       // Success.
00304 
00305         status = BdbcSuccess;
00306 
00307     } while( false );
00308 
00309     return status;
00310 }
00311 
00312 BdbStatus
00313 BdbCondDebug::removeSubTree( BdbHandle(BdbIntervalR)& theIntervalH,
00314                              BdbHandle(BdbIntervalR)& thePrevBaselineIntervalH,
00315                              BdbHandle(BdbIntervalR)& theNextBaselineIntervalH,
00316                              BdbHandle(BdbIntervalR)& thePrevTopmostIntervalH,
00317                              BdbHandle(BdbIntervalR)& theNextTopmostIntervalH )
00318 {
00319     const char* errorString = "BdbCondDebug::createInterval() -- error.";
00320 
00321     BdbStatus status = BdbcError;
00322 
00323     thePrevBaselineIntervalH = 0;
00324     theNextBaselineIntervalH = 0;
00325     thePrevTopmostIntervalH  = 0;
00326     theNextTopmostIntervalH  = 0;
00327 
00328   // Do the rest in an exception alike loop.
00329 
00330     BdbHandle(BdbIntervalR) theNullIntervalH;
00331     theNullIntervalH = 0;
00332 
00333     do {
00334 
00335       // Some safety checks.
00336 
00337         if( ! initialize( )) break;
00338         if( ! isInValidContext( theIntervalH )) {
00339 
00340             ErrMsg(error) << errorString << endl
00341                           << "    Specified interval " << theIntervalH.sprint( ) << " does not belong" << endl
00342                           << "    to the current context, which is:" << endl
00343                           << "        DETECTOR:  " << _detectorName  << endl
00344                           << "        CONTAINER: " << _containerName << endmsg;
00345 
00346             break;
00347         }
00348 
00349       // Determine the characteristics of the interval.
00350 
00351         bool isBaseline  = itIsBaseline ( theIntervalH );
00352         bool isTopmost   = itIsTopmost  ( theIntervalH );
00353         bool isVersioned = itIsVersioned( theIntervalH );
00354 
00355       // Find and modify BASELINE neigbors if the removed interval is a BASELINE one.
00356 
00357         if( isBaseline ) {
00358 
00359           // Reset links to this interval from its topmost neigbors
00360           // if this interval is not the FIRST or the LAST one.
00361 
00362             theIntervalH->getBaselinePrevious( thePrevBaselineIntervalH );
00363             if( ! BdbIsNull(thePrevBaselineIntervalH)) {
00364                 thePrevBaselineIntervalH->setBaselineNext( theNullIntervalH );
00365             }
00366 
00367             theIntervalH->getBaselineNext( theNextBaselineIntervalH );
00368             if( ! BdbIsNull(theNextBaselineIntervalH)) {
00369                 theNextBaselineIntervalH->setBaselinePrevious( theNullIntervalH );
00370             }
00371         }
00372 
00373       // Find and modify TOPMOST neighbors.
00374 
00375         if( isTopmost ) {
00376             theIntervalH->getTopPrevious( thePrevTopmostIntervalH );
00377             theIntervalH->getTopNext    ( theNextTopmostIntervalH );
00378         } else {
00379 
00380             bool ambiguousResult = false;
00381 
00382             findTopmostNeighborsInSubTree( theIntervalH->beginTime( ),
00383                                            theIntervalH->endTime( ),
00384                                            theIntervalH,
00385                                            thePrevTopmostIntervalH,
00386                                            theNextTopmostIntervalH,
00387                                            ambiguousResult );
00388             if( ambiguousResult ) {
00389 
00390                 ErrMsg(error) << errorString << endl
00391                               << "    The operation is inpossible for interval " << theIntervalH.sprint( ) << " due to" << endl
00392                               << "    incorrect internal structure of the genealogy sub-tree above this interval." << endl
00393                               << "    The current context is:" << endl
00394                               << "        DETECTOR:  " << _detectorName  << endl
00395                               << "        CONTAINER: " << _containerName << endmsg;
00396 
00397                 break;
00398             }
00399         }
00400 
00401         if( ! BdbIsNull(thePrevTopmostIntervalH)) {
00402             thePrevTopmostIntervalH->setTopNext( theNullIntervalH );
00403         }
00404 
00405         if( ! BdbIsNull(theNextTopmostIntervalH)) {
00406             theNextTopmostIntervalH->setTopPrevious( theNullIntervalH );
00407         }
00408 
00409       // Remove the Genealogy object if we're going to delete the whole cluster
00410       // growing from a baseline interval.
00411 
00412         if( isBaseline && isVersioned ) {
00413             BdbHandle(BdbIntervalGene) theGeneH;
00414             theGeneH = (const BdbHandle(BdbIntervalGene)&) theIntervalH->geneObj( );
00415             BdbDelete(theGeneH);
00416         }
00417 
00418       // Remove the cluster of intervals starting from this one.
00419       //
00420       // NOTE: A reason why we're doing this recursivly is that the deletion
00421       //       procedure does not propagate along the genealogy.
00422 
00423         deleteIntervalsInSubTree( theIntervalH );
00424 
00425       // Success.
00426 
00427         status = BdbcSuccess;
00428 
00429     } while( false );
00430 
00431     return status;
00432 }
00433 
00434 BdbStatus
00435 BdbCondDebug::createInterval( BdbHandle(BdbIntervalR)& theIntervalH,
00436                               const BdbRef(BdbObject)& theObjectRef,
00437                               const BdbTime&           theBeginTime,
00438                               const BdbTime&           theEndTime,
00439                               d_ULong                  theTag )
00440 {
00441     const char* errorString = "BdbCondDebug::createInterval() -- error.";
00442 
00443     BdbStatus status = BdbcError;
00444 
00445     theIntervalH = 0;
00446 
00447   // Do the rest in an exception alike loop.
00448 
00449     do {
00450 
00451       // Some safety checks.
00452 
00453         if( ! initialize( )) break;
00454 
00455       // We use the cached container handle as a clustering hint
00456       // for new interval.
00457 
00458         BdbHandle(BdbContObj) theContH;
00459         _databasePtr->getIntervalContH( theContH );
00460 
00461         theIntervalH = new( theContH ) BdbIntervalR( theObjectRef,
00462                                                      theBeginTime,
00463                                                      theEndTime,
00464                                                      theTag );
00465 
00466       // Success.
00467 
00468         status = BdbcSuccess;
00469 
00470     } while( false );
00471 
00472     return status;
00473 }
00474 
00475 BdbStatus
00476 BdbCondDebug::createBaselineInterval( BdbHandle(BdbIntervalR)& theIntervalH,
00477                                       const BdbRef(BdbObject)& theObjectRef,
00478                                       BdbHandle(BdbIntervalR)& thePrevBaselineIntervalH,
00479                                       BdbHandle(BdbIntervalR)& theNextBaselineIntervalH,
00480                                       BdbHandle(BdbIntervalR)& thePrevTopmostIntervalH,
00481                                       BdbHandle(BdbIntervalR)& theNextTopmostIntervalH,
00482                                       const BdbTime&           theVersionTime,
00483                                       d_ULong                  theTag )
00484 {
00485     const char* errorString = "BdbCondDebug::createBaselineInterval() -- error.";
00486 
00487     BdbStatus status = BdbcError;
00488 
00489     theIntervalH = 0;
00490 
00491   // Do the rest in an exception alike loop.
00492 
00493     do {
00494 
00495       // Some safety checks.
00496 
00497         if( ! initialize( )) break;
00498 
00499       // Check if border intervals belong to the current context.
00500 
00501         if( ! BdbIsNull(thePrevBaselineIntervalH) &&
00502             ! isInValidContext( thePrevBaselineIntervalH )) {
00503 
00504             ErrMsg(error) << errorString << endl
00505                           << "    Specified interval " << thePrevBaselineIntervalH.sprint( ) << " does not belong" << endl
00506                           << "    to the current context, which is:" << endl
00507                           << "        DETECTOR:  " << _detectorName  << endl
00508                           << "        CONTAINER: " << _containerName << endmsg;
00509 
00510             break;
00511         }
00512         if( ! BdbIsNull(theNextBaselineIntervalH) &&
00513             ! isInValidContext( theNextBaselineIntervalH )) {
00514 
00515             ErrMsg(error) << errorString << endl
00516                           << "    Specified interval " << theNextBaselineIntervalH.sprint( ) << " does not belong" << endl
00517                           << "    to the current context, which is:" << endl
00518                           << "        DETECTOR:  " << _detectorName  << endl
00519                           << "        CONTAINER: " << _containerName << endmsg;
00520 
00521             break;
00522         }
00523         if( ! BdbIsNull(thePrevTopmostIntervalH) &&
00524             ! isInValidContext( thePrevTopmostIntervalH )) {
00525 
00526             ErrMsg(error) << errorString << endl
00527                           << "    Specified interval " << thePrevTopmostIntervalH.sprint( ) << " does not belong" << endl
00528                           << "    to the current context, which is:" << endl
00529                           << "        DETECTOR:  " << _detectorName  << endl
00530                           << "        CONTAINER: " << _containerName << endmsg;
00531 
00532             break;
00533         }
00534         if( ! BdbIsNull(theNextTopmostIntervalH) &&
00535             ! isInValidContext( theNextTopmostIntervalH )) {
00536 
00537             ErrMsg(error) << errorString << endl
00538                           << "    Specified interval " << theNextTopmostIntervalH.sprint( ) << " does not belong" << endl
00539                           << "    to the current context, which is:" << endl
00540                           << "        DETECTOR:  " << _detectorName  << endl
00541                           << "        CONTAINER: " << _containerName << endmsg;
00542 
00543             break;
00544         }
00545 
00546       // Check for consistent presense of the border intervals.
00547       //
00548       // RULE 1: Both intervals in each "vertical" pair of PREVIOUS or NEXT
00549       //         group must be present/abswnt together.
00550       //
00551       // RULE 2: At least one "vertical" pair must be specified, otherwise
00552       //         the newely created interval will be the only one in a container.
00553 
00554         if( BdbIsNull(thePrevBaselineIntervalH) ^ BdbIsNull(thePrevTopmostIntervalH)) {
00555             ErrMsg(error) << errorString << endl
00556                           << "    Invalid input parameters. Specified PREVIOUS intervals" << endl
00557                           << "    must be absent or present together." << endmsg;
00558             break;
00559         }
00560         if( BdbIsNull(theNextBaselineIntervalH) ^ BdbIsNull(theNextTopmostIntervalH)) {
00561             ErrMsg(error) << errorString << endl
00562                           << "    Invalid input parameters. Specified NEXT intervals" << endl
00563                           << "    must be absent or present together." << endmsg;
00564             break;
00565         }
00566         if( BdbIsNull(thePrevBaselineIntervalH) && BdbIsNull(theNextBaselineIntervalH)) {
00567             ErrMsg(error) << errorString << endl
00568                           << "    Invalid input parameters. At least one pair of border intervals" << endl
00569                           << "    from either side must be specified. Otherwise the newly created" << endl
00570                           << "    interval would be the only one in the container." << endmsg;
00571             break;
00572         }
00573 
00574       // Check if the border intervals are properly aligned in time and if all is OK
00575       // then calculate the validity limits of the new interval.
00576 
00577         BdbTime theBeginTime = BdbTime::minusInfinity;
00578         BdbTime theEndTime   = BdbTime::plusInfinity;
00579 
00580         if( ! BdbIsNull(thePrevBaselineIntervalH)) {
00581             if( thePrevBaselineIntervalH->endTime( ) != thePrevTopmostIntervalH->endTime( )) {
00582                 ErrMsg(error) << errorString << endl
00583                               << "    Invalid input parameters. The END times of PREVIOUS intervals" << endl
00584                               << "    are not equal." << endl
00585                               << "        TOPMOST:  " << thePrevTopmostIntervalH->endTime( ) << endl
00586                               << "        BASELINE: " << thePrevBaselineIntervalH->endTime( ) << endmsg;
00587                 break;
00588             }
00589             theBeginTime = thePrevBaselineIntervalH->endTime( );
00590         }
00591         if( ! BdbIsNull(theNextBaselineIntervalH)) {
00592             if( theNextBaselineIntervalH->beginTime( ) != theNextTopmostIntervalH->beginTime( )) {
00593                 ErrMsg(error) << errorString << endl
00594                               << "    Invalid input parameters. The BEGIN times of NEXT intervals" << endl
00595                               << "    are not equal." << endl
00596                               << "        TOPMOST:  " << theNextTopmostIntervalH->beginTime( ) << endl
00597                               << "        BASELINE: " << theNextBaselineIntervalH->beginTime( ) << endmsg;
00598                 break;
00599             }
00600             theEndTime = theNextBaselineIntervalH->beginTime( );
00601         }
00602 
00603       // We use the cached container handle as a clustering hint
00604       // for new interval.
00605 
00606         BdbHandle(BdbContObj) theContH;
00607         _databasePtr->getIntervalContH( theContH );
00608 
00609         theIntervalH = new( theContH ) BdbIntervalR( theObjectRef,
00610                                                      theBeginTime,
00611                                                      theEndTime,
00612                                                      theTag );
00613 
00614       // Now we're going to connect this interval with its borders.
00615 
00616         if( ! BdbIsNull(thePrevBaselineIntervalH)) {
00617 
00618             theIntervalH->setBaselinePrevious( thePrevBaselineIntervalH );
00619             theIntervalH->setTopPrevious     ( thePrevTopmostIntervalH );
00620 
00621             thePrevBaselineIntervalH->setBaselineNext( theIntervalH );
00622             thePrevTopmostIntervalH->setTopNext      ( theIntervalH);
00623         }
00624         if( ! BdbIsNull(theNextBaselineIntervalH)) {
00625 
00626             theIntervalH->setBaselineNext( theNextBaselineIntervalH );
00627             theIntervalH->setTopNext     ( theNextTopmostIntervalH );
00628 
00629             theNextBaselineIntervalH->setBaselinePrevious( theIntervalH );
00630             theNextTopmostIntervalH->setTopPrevious      ( theIntervalH );
00631         }
00632 
00633       // And its BASELINE revision.
00634 
00635         BdbHandle(BdbCondRevision) theRevisionH;
00636         _databasePtr->getBaselineRevisionH( theRevisionH );
00637 
00638         theIntervalH->setRevision( theRevisionH );
00639 
00640       // Set the version time if required.
00641 
00642         if( BdbTime::minusInfinity != theVersionTime ) {
00643             theIntervalH->setVersionTime( theVersionTime );
00644         }
00645 
00646       // Name interval if it's going to be either the FIRST one or the LAST one.
00647 
00648         if(      BdbIsNull(thePrevBaselineIntervalH)) theIntervalH.nameObj( theContH, "FirstInterval" );
00649         else if( BdbIsNull(theNextBaselineIntervalH)) theIntervalH.nameObj( theContH, "LastInterval"  );
00650 
00651       // Success.
00652 
00653         status = BdbcSuccess;
00654 
00655     } while( false );
00656 
00657     return status;
00658 }
00659 
00660 BdbStatus
00661 BdbCondDebug::setObject( BdbHandle(BdbIntervalR)& theIntervalH,
00662                          const BdbRef(BdbObject)& theObjectRef,
00663                          BdbRef(BdbObject)&       theOldObjectRef )
00664 {
00665     const char* errorString = "BdbCondDebug::setObject() -- error.";
00666 
00667     BdbStatus status = BdbcError;
00668 
00669   // Do the rest in an exception alike loop.
00670 
00671     do {
00672 
00673       // Some safety checks.
00674 
00675         if( ! initialize( )) break;
00676         if( ! isInValidContext( theIntervalH )) {
00677 
00678             ErrMsg(error) << errorString << endl
00679                           << "    Specified interval " << theIntervalH.sprint( ) << " does not belong" << endl
00680                           << "    to the current context, which is:" << endl
00681                           << "        DETECTOR:  " << _detectorName  << endl
00682                           << "        CONTAINER: " << _containerName << endmsg;
00683 
00684             break;
00685         }
00686 
00687       // Do it.
00688 
00689         theIntervalH->getObject( theOldObjectRef );
00690         theIntervalH->setObject( theObjectRef );
00691 
00692       // Success.
00693 
00694         status = BdbcSuccess;
00695 
00696     } while( false );
00697 
00698     return status;
00699 }
00700 
00701 BdbStatus
00702 BdbCondDebug::setBeginTime( BdbHandle(BdbIntervalR)& theIntervalH,
00703                             const BdbTime&           theTime,
00704                             BdbTime&                 theOldTime )
00705 {
00706     const char* errorString = "BdbCondDebug::setBeginTime() -- error.";
00707 
00708     BdbStatus status = BdbcError;
00709 
00710   // Do the rest in an exception alike loop.
00711 
00712     do {
00713 
00714       // Some safety checks.
00715 
00716         if( ! initialize( )) break;
00717         if( ! isInValidContext( theIntervalH )) {
00718 
00719             ErrMsg(error) << errorString << endl
00720                           << "    Specified interval " << theIntervalH.sprint( ) << " does not belong" << endl
00721                           << "    to the current context, which is:" << endl
00722                           << "        DETECTOR:  " << _detectorName  << endl
00723                           << "        CONTAINER: " << _containerName << endmsg;
00724 
00725             break;
00726         }
00727 
00728       // Modify interval in en explicit "update" mode.
00729       //
00730       // NOTE: A reason why we're doing this is that we're calling a method
00731       //       from a transient base class BdbIntervalBase.
00732 
00733         theOldTime = theIntervalH->beginTime( );
00734         theIntervalH.update( );
00735         theIntervalH->setBeginTime( theTime );
00736 
00737       // Success.
00738 
00739         status = BdbcSuccess;
00740 
00741     } while( false );
00742 
00743     return status;
00744 }
00745 
00746 BdbStatus
00747 BdbCondDebug::setEndTime( BdbHandle(BdbIntervalR)& theIntervalH,
00748                           const BdbTime&           theTime,
00749                           BdbTime&                 theOldTime )
00750 {
00751     const char* errorString = "BdbCondDebug::setEndTime() -- error.";
00752 
00753     BdbStatus status = BdbcError;
00754 
00755   // Do the rest in an exception alike loop.
00756 
00757     do {
00758 
00759       // Some safety checks.
00760 
00761         if( ! initialize( )) break;
00762         if( ! isInValidContext( theIntervalH )) {
00763 
00764             ErrMsg(error) << errorString << endl
00765                           << "    Specified interval " << theIntervalH.sprint( ) << " does not belong" << endl
00766                           << "    to the current context, which is:" << endl
00767                           << "        DETECTOR:  " << _detectorName  << endl
00768                           << "        CONTAINER: " << _containerName << endmsg;
00769 
00770             break;
00771         }
00772 
00773       // Modify interval in en explicit "update" mode.
00774       //
00775       // NOTE: A reason why we're doing this is that we're calling a method
00776       //       from a transient base class BdbIntervalBase.
00777 
00778         theOldTime = theIntervalH->endTime( );
00779         theIntervalH.update( );
00780         theIntervalH->setEndTime( theTime );
00781 
00782       // Success.
00783 
00784         status = BdbcSuccess;
00785 
00786     } while( false );
00787 
00788     return status;
00789 }
00790 
00791 BdbStatus
00792 BdbCondDebug::setVersionTime( BdbHandle(BdbIntervalR)& theIntervalH,
00793                               const BdbTime&           theTime,
00794                               BdbTime&                 theOldTime )
00795 {
00796     const char* errorString = "BdbCondDebug::setVersionTime() -- error.";
00797 
00798     BdbStatus status = BdbcError;
00799 
00800   // Do the rest in an exception alike loop.
00801 
00802     do {
00803 
00804       // Some safety checks.
00805 
00806         if( ! initialize( )) break;
00807         if( ! isInValidContext( theIntervalH )) {
00808 
00809             ErrMsg(error) << errorString << endl
00810                           << "    Specified interval " << theIntervalH.sprint( ) << " does not belong" << endl
00811                           << "    to the current context, which is:" << endl
00812                           << "        DETECTOR:  " << _detectorName  << endl
00813                           << "        CONTAINER: " << _containerName << endmsg;
00814 
00815             break;
00816         }
00817 
00818       // Modify interval.
00819 
00820         theOldTime = theIntervalH->getVersionTime( );
00821         theIntervalH->setVersionTime( theTime );
00822 
00823       // Success.
00824 
00825         status = BdbcSuccess;
00826 
00827     } while( false );
00828 
00829     return status;
00830 }
00831 
00832 BdbStatus
00833 BdbCondDebug::setTag( BdbHandle(BdbIntervalR)& theIntervalH,
00834                       d_ULong                  theTag,
00835                       d_ULong&                 theOldTag )
00836 {
00837     const char* errorString = "BdbCondDebug::setTag() -- error.";
00838 
00839     BdbStatus status = BdbcError;
00840 
00841   // Do the rest in an exception alike loop.
00842 
00843     do {
00844 
00845       // Some safety checks.
00846 
00847         if( ! initialize( )) break;
00848         if( ! isInValidContext( theIntervalH )) {
00849 
00850             ErrMsg(error) << errorString << endl
00851                           << "    Specified interval " << theIntervalH.sprint( ) << " does not belong" << endl
00852                           << "    to the current context, which is:" << endl
00853                           << "        DETECTOR:  " << _detectorName  << endl
00854                           << "        CONTAINER: " << _containerName << endmsg;
00855 
00856             break;
00857         }
00858 
00859       // Modify interval.
00860 
00861         theOldTag = theIntervalH->getTag( );
00862         theIntervalH->setTag( theTag );
00863 
00864       // Success.
00865 
00866         status = BdbcSuccess;
00867 
00868     } while( false );
00869 
00870     return status;
00871 }
00872 
00873 BdbStatus
00874 BdbCondDebug::setBaseInterval( BdbHandle(BdbIntervalR)& theIntervalH,
00875                                BdbHandle(BdbIntervalR)& theBaseIntervalH,
00876                                BdbHandle(BdbIntervalR)& theOldBaseIntervalH )
00877 {
00878     const char* errorString = "BdbCondDebug::setBaseInterval() -- error.";
00879 
00880     BdbStatus status = BdbcError;
00881 
00882   // Do the rest in an exception alike loop.
00883 
00884     do {
00885 
00886       // Some safety checks.
00887 
00888         if( ! initialize( )) break;
00889         if( ! isInValidContext( theIntervalH )) {
00890 
00891             ErrMsg(error) << errorString << endl
00892                           << "    Specified interval " << theIntervalH.sprint( ) << " does not belong" << endl
00893                           << "    to the current context, which is:" << endl
00894                           << "        DETECTOR:  " << _detectorName  << endl
00895                           << "        CONTAINER: " << _containerName << endmsg;
00896 
00897             break;
00898         }
00899         if( ! isInValidContext( theBaseIntervalH )) {
00900 
00901             ErrMsg(error) << errorString << endl
00902                           << "    Specified interval " << theBaseIntervalH.sprint( ) << " does not belong" << endl
00903                           << "    to the current context, which is:" << endl
00904                           << "        DETECTOR:  " << _detectorName  << endl
00905                           << "        CONTAINER: " << _containerName << endmsg;
00906 
00907             break;
00908         }
00909 
00910       // Check if both intervals belong to the same genealogy tree.
00911       //
00912       // NOTE: This restriction will be removed later to allow "whild"
00913       //       intervals to be created and inserted into existing tree.
00914 
00915         BdbHandle(BdbIntervalGene) theGeneH;
00916         theGeneH = 0;
00917         if ( theIntervalH->exist_geneObj( )) {
00918             theGeneH = (const BdbHandle(BdbIntervalGene)&) theIntervalH->geneObj( );
00919         }
00920 
00921         BdbHandle(BdbIntervalGene) theBaseGeneH;
00922         theBaseGeneH = 0;
00923         if ( theBaseIntervalH->exist_geneObj( )) {
00924             theBaseGeneH = (const BdbHandle(BdbIntervalGene)&) theBaseIntervalH->geneObj( );
00925         }
00926 
00927         if( theGeneH != theBaseGeneH ) {
00928 
00929             ErrMsg(error) << errorString << endl
00930                           << "    Specified intervals:" << endl
00931                           << "        " << theIntervalH.sprint( ) << endl
00932                           << "        " << theBaseIntervalH.sprint( ) << endl
00933                           << "    have different genealogy objects:" << endl
00934                           << "        " << theGeneH.sprint( ) << endl
00935                           << "        " << theBaseGeneH.sprint( ) << endl
00936                           << "    respectively, in the context of:" << endl
00937                           << "        DETECTOR:  " << _detectorName  << endl
00938                           << "        CONTAINER: " << _containerName << endmsg;
00939 
00940             break;
00941         }
00942 
00943       // Get the current base interval. We'll need to modify it's versioning
00944       // status later when the interval will be disconnected from it.
00945 
00946         theIntervalH->prevVers( theOldBaseIntervalH );
00947 
00948       // Modify specified interval. Its new base will automatically be updated
00949       // to accomodate a new version. The old base will automatically updated
00950       // to "forget" about the old version.
00951 
00952         theIntervalH->del_prevVers( );
00953         theIntervalH->set_prevVers( theBaseIntervalH );
00954 
00955       // Update the versioning status of the both old and new base interval.
00956 
00957         int numVersions;
00958 
00959         if( ! BdbIsNull(theOldBaseIntervalH)) {
00960             numVersions = 0;
00961             {
00962                 BdbItr(BdbPersObj) theItr;
00963 
00964                 theOldBaseIntervalH->nextVers( theItr );
00965                 while( theItr.next( )) {
00966                     numVersions++;
00967                     if( numVersions > 1 ) break;    // That's enough choices {0,1,n}
00968                 }
00969             }
00970             if(      0 == numVersions ) theOldBaseIntervalH.setVersStatus( oocNoVers );
00971             else if( 1 == numVersions ) theOldBaseIntervalH.setVersStatus( oocLinearVers );
00972             else                        theOldBaseIntervalH.setVersStatus( oocBranchVers );
00973         }
00974         if( ! BdbIsNull(theBaseIntervalH)) {
00975             numVersions = 0;
00976             {
00977                 BdbItr(BdbPersObj) theItr;
00978 
00979                 theBaseIntervalH->nextVers( theItr );
00980                 while( theItr.next( )) {
00981                     numVersions++;
00982                     if( numVersions > 1 ) break;    // That's enough choices {0,1,n}
00983                 }
00984             }
00985             if(      0 == numVersions ) theBaseIntervalH.setVersStatus( oocNoVers );
00986             else if( 1 == numVersions ) theBaseIntervalH.setVersStatus( oocLinearVers );
00987             else                        theBaseIntervalH.setVersStatus( oocBranchVers );
00988         }
00989 
00990       // Success.
00991 
00992         status = BdbcSuccess;
00993 
00994     } while( false );
00995 
00996     return status;
00997 }
00998 
00999 BdbStatus
01000 BdbCondDebug::setPrevBaselineInterval( BdbHandle(BdbIntervalR)& theIntervalH,
01001                                        BdbHandle(BdbIntervalR)& thePrevBaselineIntervalH,
01002                                        BdbHandle(BdbIntervalR)& theOldPrevBaselineIntervalH )
01003 {
01004     const char* errorString = "BdbCondDebug::setPrevBaselineInterval() -- error.";
01005 
01006     BdbStatus status = BdbcError;
01007 
01008   // Do the rest in an exception alike loop.
01009 
01010     do {
01011 
01012       // Some safety checks.
01013 
01014         if( ! initialize( )) break;
01015         if( ! isInValidContext( theIntervalH )) {
01016 
01017             ErrMsg(error) << errorString << endl
01018                           << "    Specified interval " << theIntervalH.sprint( ) << " does not belong" << endl
01019                           << "    to the current context, which is:" << endl
01020                           << "        DETECTOR:  " << _detectorName  << endl
01021                           << "        CONTAINER: " << _containerName << endmsg;
01022 
01023             break;
01024         }
01025         if( ! BdbIsNull(thePrevBaselineIntervalH) &&
01026             ! isInValidContext( thePrevBaselineIntervalH )) {
01027 
01028             ErrMsg(error) << errorString << endl
01029                           << "    Specified interval " << thePrevBaselineIntervalH.sprint( ) << " does not belong" << endl
01030                           << "    to the current context, which is:" << endl
01031                           << "        DETECTOR:  " << _detectorName  << endl
01032                           << "        CONTAINER: " << _containerName << endmsg;
01033 
01034             break;
01035         }
01036 
01037       // Get (if any) and modify (if found) the old interval.
01038 
01039         theIntervalH->getBaselinePrevious( theOldPrevBaselineIntervalH );
01040         if( ! BdbIsNull(theOldPrevBaselineIntervalH)) {
01041             BdbHandle(BdbIntervalR) theNullIntervalH;
01042             theNullIntervalH = 0;
01043             theOldPrevBaselineIntervalH->setBaselineNext( theNullIntervalH );
01044         }
01045 
01046       // Modify both intervals (if applied).
01047 
01048         theIntervalH->setBaselinePrevious( thePrevBaselineIntervalH );
01049         if( ! BdbIsNull(thePrevBaselineIntervalH)) {
01050             thePrevBaselineIntervalH->setBaselineNext( theIntervalH );
01051         }
01052 
01053       // Success.
01054 
01055         status = BdbcSuccess;
01056 
01057     } while( false );
01058 
01059     return status;
01060 }
01061 
01062 BdbStatus
01063 BdbCondDebug::setNextBaselineInterval( BdbHandle(BdbIntervalR)& theIntervalH,
01064                                        BdbHandle(BdbIntervalR)& theNextBaselineIntervalH,
01065                                        BdbHandle(BdbIntervalR)& theOldNextBaselineIntervalH )
01066 {
01067     const char* errorString = "BdbCondDebug::setNextBaselineInterval() -- error.";
01068 
01069     BdbStatus status = BdbcError;
01070 
01071   // Do the rest in an exception alike loop.
01072 
01073     do {
01074 
01075       // Some safety checks.
01076 
01077         if( ! initialize( )) break;
01078         if( ! isInValidContext( theIntervalH )) {
01079 
01080             ErrMsg(error) << errorString << endl
01081                           << "    Specified interval " << theIntervalH.sprint( ) << " does not belong" << endl
01082                           << "    to the current context, which is:" << endl
01083                           << "        DETECTOR:  " << _detectorName  << endl
01084                           << "        CONTAINER: " << _containerName << endmsg;
01085 
01086             break;
01087         }
01088         if( ! BdbIsNull(theNextBaselineIntervalH) &&
01089             ! isInValidContext( theNextBaselineIntervalH )) {
01090 
01091             ErrMsg(error) << errorString << endl
01092                           << "    Specified interval " << theNextBaselineIntervalH.sprint( ) << " does not belong" << endl
01093                           << "    to the current context, which is:" << endl
01094                           << "        DETECTOR:  " << _detectorName  << endl
01095                           << "        CONTAINER: " << _containerName << endmsg;
01096 
01097             break;
01098         }
01099 
01100       // Get (if any) and modify (if found) the old interval.
01101 
01102         theIntervalH->getBaselineNext( theOldNextBaselineIntervalH );
01103         if( ! BdbIsNull(theOldNextBaselineIntervalH)) {
01104             BdbHandle(BdbIntervalR) theNullIntervalH;
01105             theNullIntervalH = 0;
01106             theOldNextBaselineIntervalH->setBaselinePrevious( theNullIntervalH );
01107         }
01108 
01109       // Modify both intervals (if applied).
01110 
01111         theIntervalH->setBaselineNext( theNextBaselineIntervalH );
01112         if( ! BdbIsNull(theNextBaselineIntervalH)) {
01113             theNextBaselineIntervalH->setBaselinePrevious( theIntervalH );
01114         }
01115 
01116       // Success.
01117 
01118         status = BdbcSuccess;
01119 
01120     } while( false );
01121 
01122     return status;
01123 }
01124 
01125 BdbStatus
01126 BdbCondDebug::setPrevTopmostInterval( BdbHandle(BdbIntervalR)& theIntervalH,
01127                                       BdbHandle(BdbIntervalR)& thePrevTopmostIntervalH,
01128                                       BdbHandle(BdbIntervalR)& theOldPrevTopmostIntervalH )
01129 {
01130     const char* errorString = "BdbCondDebug::setPrevTopmostInterval() -- error.";
01131 
01132     BdbStatus status = BdbcError;
01133 
01134   // Do the rest in an exception alike loop.
01135 
01136     do {
01137 
01138       // Some safety checks.
01139 
01140         if( ! initialize( )) break;
01141         if( ! isInValidContext( theIntervalH )) {
01142 
01143             ErrMsg(error) << errorString << endl
01144                           << "    Specified interval " << theIntervalH.sprint( ) << " does not belong" << endl
01145                           << "    to the current context, which is:" << endl
01146                           << "        DETECTOR:  " << _detectorName  << endl
01147                           << "        CONTAINER: " << _containerName << endmsg;
01148 
01149             break;
01150         }
01151         if( ! BdbIsNull(thePrevTopmostIntervalH) &&
01152             ! isInValidContext( thePrevTopmostIntervalH )) {
01153 
01154             ErrMsg(error) << errorString << endl
01155                           << "    Specified interval " << thePrevTopmostIntervalH.sprint( ) << " does not belong" << endl
01156                           << "    to the current context, which is:" << endl
01157                           << "        DETECTOR:  " << _detectorName  << endl
01158                           << "        CONTAINER: " << _containerName << endmsg;
01159 
01160             break;
01161         }
01162 
01163       // Get (if any) and modify (if found) the old interval.
01164 
01165         theIntervalH->getTopPrevious( theOldPrevTopmostIntervalH );
01166         if( ! BdbIsNull(theOldPrevTopmostIntervalH)) {
01167             BdbHandle(BdbIntervalR) theNullIntervalH;
01168             theNullIntervalH = 0;
01169             theOldPrevTopmostIntervalH->setTopNext( theNullIntervalH );
01170         }
01171 
01172       // Modify both intervals (if applied).
01173 
01174         theIntervalH->setTopPrevious( thePrevTopmostIntervalH );
01175         if( ! BdbIsNull(thePrevTopmostIntervalH)) {
01176             thePrevTopmostIntervalH->setTopNext( theIntervalH );
01177         }
01178 
01179       // Success.
01180 
01181         status = BdbcSuccess;
01182 
01183     } while( false );
01184 
01185     return status;
01186 }
01187 
01188 BdbStatus
01189 BdbCondDebug::setNextTopmostInterval( BdbHandle(BdbIntervalR)& theIntervalH,
01190                                       BdbHandle(BdbIntervalR)& theNextTopmostIntervalH,
01191                                       BdbHandle(BdbIntervalR)& theOldNextTopmostIntervalH )
01192 {
01193     const char* errorString = "BdbCondDebug::setNextTopmostInterval() -- error.";
01194 
01195     BdbStatus status = BdbcError;
01196 
01197   // Do the rest in an exception alike loop.
01198 
01199     do {
01200 
01201       // Some safety checks.
01202 
01203         if( ! initialize( )) break;
01204         if( ! isInValidContext( theIntervalH )) {
01205 
01206             ErrMsg(error) << errorString << endl
01207                           << "    Specified interval " << theIntervalH.sprint( ) << " does not belong" << endl
01208                           << "    to the current context, which is:" << endl
01209                           << "        DETECTOR:  " << _detectorName  << endl
01210                           << "        CONTAINER: " << _containerName << endmsg;
01211 
01212             break;
01213         }
01214         if( ! BdbIsNull(theNextTopmostIntervalH) &&
01215             ! isInValidContext( theNextTopmostIntervalH )) {
01216 
01217             ErrMsg(error) << errorString << endl
01218                           << "    Specified interval " << theNextTopmostIntervalH.sprint( ) << " does not belong" << endl
01219                           << "    to the current context, which is:" << endl
01220                           << "        DETECTOR:  " << _detectorName  << endl
01221                           << "        CONTAINER: " << _containerName << endmsg;
01222 
01223             break;
01224         }
01225 
01226       // Get (if any) and modify (if found) the old interval.
01227 
01228         theIntervalH->getTopNext( theOldNextTopmostIntervalH );
01229         if( ! BdbIsNull(theOldNextTopmostIntervalH)) {
01230             BdbHandle(BdbIntervalR) theNullIntervalH;
01231             theNullIntervalH = 0;
01232             theOldNextTopmostIntervalH->setTopPrevious( theNullIntervalH );
01233         }
01234 
01235       // Modify both intervals (if applied).
01236 
01237         theIntervalH->setTopNext( theNextTopmostIntervalH );
01238         if( ! BdbIsNull(theNextTopmostIntervalH)) {
01239             theNextTopmostIntervalH->setTopPrevious( theIntervalH );
01240         }
01241 
01242       // Success.
01243 
01244         status = BdbcSuccess;
01245 
01246     } while( false );
01247 
01248     return status;
01249 }
01250 
01251 BdbStatus
01252 BdbCondDebug::setRevision( BdbHandle(BdbIntervalR)& theIntervalH,
01253                            d_ULong                  theRevision,
01254                            d_ULong&                 theOldRevision )
01255 {
01256     const char* errorString = "BdbCondDebug::setRevision() -- error.";
01257 
01258     BdbStatus status = BdbcError;
01259 
01260   // Do the rest in an exception alike loop.
01261 
01262     do {
01263 
01264       // Some safety checks.
01265 
01266         if( ! initialize( )) break;
01267         if( ! isInValidContext( theIntervalH )) {
01268 
01269             ErrMsg(error) << errorString << endl
01270                           << "    Specified interval " << theIntervalH.sprint( ) << " does not belong" << endl
01271                           << "    to the current context, which is:" << endl
01272                           << "        DETECTOR:  " << _detectorName  << endl
01273                           << "        CONTAINER: " << _containerName << endmsg;
01274 
01275             break;
01276         }
01277 
01278       // Find an old revision (if any).
01279 
01280         theOldRevision = BdbCondRevision::ILLEGAL;
01281         {
01282             BdbHandle(BdbCondRevision) theOldRevisionH;
01283             theIntervalH->getRevision( theOldRevisionH );
01284             if( ! BdbIsNull(theOldRevisionH)) theOldRevision = theOldRevisionH->id( );
01285         }
01286 
01287       // Find a revision object.
01288 
01289         BdbHandle(BdbCondRevision) theRevisionH;
01290         {
01291             BdbHandle(BdbCondRegistry) theRegistryH;
01292             {
01293                 _databasePtr->getRegistryH( theRegistryH );
01294                 if( BdbIsNull(theRegistryH)) {
01295 
01296                     ErrMsg(error) << errorString << endl
01297                                   << "    There is no revision Registry object" << endl
01298                                   << "    in the current context, which is:" << endl
01299                                   << "        DETECTOR:  " << _detectorName  << endl
01300                                   << "        CONTAINER: " << _containerName << endmsg;
01301 
01302                     break;
01303                 }
01304             }
01305             theRegistryH->getRevision( theRevisionH, theRevision );
01306             if( BdbIsNull(theRevisionH)) {
01307 
01308                 ErrMsg(error) << errorString << endl
01309                               << "    There is no such revision " << theRevision << endl
01310                               << "    in the current context, which is:" << endl
01311                               << "        DETECTOR:  " << _detectorName  << endl
01312                               << "        CONTAINER: " << _containerName << endmsg;
01313 
01314                 break;
01315             }
01316         }
01317         theIntervalH->setRevision( theRevisionH );
01318 
01319       // Success.
01320 
01321         status = BdbcSuccess;
01322 
01323     } while( false );
01324 
01325     return status;
01326 }
01327 
01328 BdbStatus
01329 BdbCondDebug::unSetRevision( BdbHandle(BdbIntervalR)& theIntervalH,
01330                              d_ULong&                 theOldRevision )
01331 {
01332     const char* errorString = "BdbCondDebug::unSetRevision() -- error.";
01333 
01334     BdbStatus status = BdbcError;
01335 
01336   // Do the rest in an exception alike loop.
01337 
01338     do {
01339 
01340       // Some safety checks.
01341 
01342         if( ! initialize( )) break;
01343         if( ! isInValidContext( theIntervalH )) {
01344 
01345             ErrMsg(error) << errorString << endl
01346                           << "    Specified interval " << theIntervalH.sprint( ) << " does not belong" << endl
01347                           << "    to the current context, which is:" << endl
01348                           << "        DETECTOR:  " << _detectorName  << endl
01349                           << "        CONTAINER: " << _containerName << endmsg;
01350 
01351             break;
01352         }
01353 
01354       // Find an old revision (if any).
01355 
01356         theOldRevision = BdbCondRevision::ILLEGAL;
01357         {
01358             BdbHandle(BdbCondRevision) theOldRevisionH;
01359             theIntervalH->getRevision( theOldRevisionH );
01360             if( ! BdbIsNull(theOldRevisionH)) theOldRevision = theOldRevisionH->id( );
01361         }
01362 
01363       // Set up a null revision object.
01364 
01365         BdbHandle(BdbCondRevision) theRevisionH;
01366         theRevisionH = 0;
01367 
01368         theIntervalH->setRevision( theRevisionH );
01369 
01370       // Success.
01371 
01372         status = BdbcSuccess;
01373 
01374     } while( false );
01375 
01376     return status;
01377 }
01378 
01379 // -------------
01380 // -- Helpers --
01381 // -------------
01382 
01383 bool
01384 BdbCondDebug::isInValidContext( const BdbHandle(BdbIntervalR)& theIntervalH )
01385 {
01386     BdbHandle(BdbContObj) theContH;
01387     _databasePtr->getIntervalContH( theContH );
01388 
01389     ooId intervalId  = theIntervalH;
01390     ooId containerId = theContH;
01391 
01392     return ( containerId.get_DB( ) == intervalId.get_DB( )) &&
01393            ( containerId.get_OC( ) == intervalId.get_OC( ));
01394 }
01395 
01396 bool
01397 BdbCondDebug::itIsBaseline( const BdbHandle(BdbIntervalR)& theIntervalH )
01398 {
01399     return ! theIntervalH->exist_prevVers( );
01400 }
01401 
01402 bool
01403 BdbCondDebug::itIsTopmost( const BdbHandle(BdbIntervalR)& theIntervalH )
01404 {
01405     BdbItr(BdbPersObj) theItr;
01406     theIntervalH->nextVers( theItr );
01407     return ! theItr.next( );
01408 }
01409 
01410 bool
01411 BdbCondDebug::itIsVersioned( const BdbHandle(BdbIntervalR)& theIntervalH )
01412 {
01413     return theIntervalH->exist_geneObj( );
01414 }
01415 
01416 void
01417 BdbCondDebug::findTopmostNeighborsInSubTree( const BdbTime&                 theBeginTime,
01418                                              const BdbTime&                 theEndTime,
01419                                              const BdbHandle(BdbIntervalR)& theIntervalH,
01420                                              BdbHandle(BdbIntervalR)&       thePrevTopmostIntervalH,
01421                                              BdbHandle(BdbIntervalR)&       theNextTopmostIntervalH,
01422                                              bool&                          ambiguousResult )
01423 {
01424   // Brows direct "children" of the specified interval.
01425 
01426     BdbItr(BdbPersObj) theItr;
01427 
01428     BdbHandle(BdbIntervalR) thisH;
01429     BdbHandle(BdbIntervalR) prevH;
01430     BdbHandle(BdbIntervalR) nextH;
01431 
01432     theIntervalH->nextVers( theItr );
01433     while( theItr.next( )) {
01434 
01435         thisH = (const BdbHandle(BdbIntervalR)&) theItr;
01436         if( itIsTopmost( thisH )) {
01437 
01438           // Check the neighbors of this TOPMOST interval.
01439 
01440             thisH->getTopPrevious( prevH );
01441             if( ! BdbIsNull(prevH)) {
01442                 if( prevH->endTime( ) <= theBeginTime ) {
01443                     if( BdbIsNull(thePrevTopmostIntervalH)) thePrevTopmostIntervalH = prevH;
01444                     else                                    ambiguousResult = true;
01445                 }
01446             }
01447 
01448             thisH->getTopNext( nextH );
01449             if( ! BdbIsNull(nextH)) {
01450                 if( nextH->beginTime( ) >= theEndTime ) {
01451                     if( BdbIsNull(theNextTopmostIntervalH)) theNextTopmostIntervalH = nextH;
01452                     else                                    ambiguousResult = true;
01453                 }
01454             }
01455 
01456         } else {
01457 
01458           // Proceed down the genealogy tree.
01459 
01460             findTopmostNeighborsInSubTree( theBeginTime,
01461                                            theEndTime,
01462                                            thisH,
01463                                            thePrevTopmostIntervalH,
01464                                            theNextTopmostIntervalH,
01465                                            ambiguousResult );
01466         }
01467     }
01468 }
01469 
01470 void
01471 BdbCondDebug::deleteIntervalsInSubTree( BdbHandle(BdbIntervalR)& theIntervalH )
01472 {
01473   // First remove its children (if any).
01474 
01475     BdbItr(BdbPersObj)      theItr;
01476     BdbHandle(BdbIntervalR) thisH;
01477 
01478     theIntervalH->nextVers( theItr );
01479     while( theItr.next( )) {
01480         thisH = (const BdbHandle(BdbIntervalR)&) theItr;
01481         deleteIntervalsInSubTree( thisH );
01482     }
01483 
01484   // And then remove the interval itself.
01485 
01486     BdbDelete(theIntervalH);
01487 }
01488 
01489 /////////////////
01490 // End Of File //
01491 /////////////////

 


BaBar Public Site | SLAC | News | Links | Who's Who | Contact Us

Page Owner: Jacek Becla
Last Update: October 04, 2002