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  

/BdbModules/BdbCollectionCommand.cc

Go to the documentation of this file.
00001 //--------------------------------------------------------------------------
00002 // File and Version Information:
00003 //      $Id: BdbCollectionCommand.cc,v 1.76.2.1 2002/06/29 00:34:48 becla Exp $
00004 //
00005 // Description:
00006 //      Class BdbCollectionCommand. Command handler for the "collection"
00007 //      command for the event store input module. Valid subcommands are:
00008 //
00009 // collection add[To] <source> [<source>] <dest>
00010 //                                    Add the source collection to the
00011 //                                      destination collection
00012 // collection cleanup -t[ree] <tree> -t[ree] <tree> <name>
00013 //                                    Cleanup the specified collection
00014 // collection contents [-[no]size] <name>
00015 //                                    Display the contents (collections)
00016 //                                      of the specified collection
00017 // collection create [-tree] [-vector] [-bridge] [-stream stream ]
00018 //                          <name> [<name>]
00019 //                                    Create the specified collection(s)
00020 // collection delete <name> [<name>]  Delete the specified collection(s)
00021 // collection events <name>           Display the contents (events) of
00022 //                                      the specified collection
00023 // collection help                    Show help information
00024 // collection list                    List collections for current user
00025 // collection list <collection>       List a single collection
00026 // collection list <node>             List collections for node <node>
00027 // collection list -a[ll]             List all collections
00028 // collection list -g[roup] <group>   List collections for group <group>
00029 // collection list -n[ode] <node>     Synonym for list <node>
00030 // collection list -s[ystem]          List system collections
00031 // collection list -u[ser] <user>     List collections for user <user>
00032 // collection map <source> [<source>] <federation>
00033 //                                    Map collections in specified
00034 //                                      federation onto matching bridge
00035 //                                      collections in this federation
00036 // collection moveTo <source> <dest>  Move the specified source
00037 //                                      collection to the destination
00038 // collection precreateCleanup        Cleanup following collection
00039 //                                      precreation
00040 // collection remove[From] <source> [<source>] <dest>
00041 //                                    Remove the source collection from
00042 //                                      the destination collection
00043 // collection rename <source> <dest>  Synonym for moveTo
00044 //
00045 //  Where <tree> is a tree name (and multiple of them may be specified
00046 //  and <name> is a collection name. The specified tree(s) will be
00047 //  removed for all events.
00048 //
00049 // Environment:
00050 //      Software developed for the BaBar Detector at the SLAC B-Factory.
00051 //
00052 // Author List:
00053 //      David R. Quarrie            Original Author
00054 //
00055 // Copyright Information:
00056 //      Copyright (C) 1999          Lawrence Berkeley Laboratory
00057 //
00058 //------------------------------------------------------------------------
00059 #include "BaBar/BaBar.hh"
00060 
00061 //-----------------------
00062 // This Class's Header --
00063 //-----------------------
00064 #include "BdbModules/BdbCollectionCommand.hh"
00065 
00066 //-------------
00067 // C Headers --
00068 //-------------
00069 #include <assert.h>
00070 #include <string.h>
00071 #include <stdlib.h>
00072 
00073 //-------------------------------
00074 // Collaborating Class Headers --
00075 //-------------------------------
00076 #include "BdbClustering/BdbEvsClusteringHint.hh"
00077 #include "BdbModules/BdbModulesUtility.hh"
00078 #include "BdbEventStore/BdbMetaDataCollTFactory.hh"
00079 #include "BdbEventStore/BdbFetchCollTFactory.hh"
00080 #include "BdbEventStore/BdbCollectionTCollTIterator.hh"
00081 #include "BdbEventStore/BdbCollectionTIterator.hh"
00082 #include "BdbEventStore/BdbEventStore.hh"
00083 #include "BdbEventStore/BdbEventStoreIterator.hh"
00084 #include "BdbEventStore/BdbBridgeCollTFactory.hh"
00085 #include "BdbEventStore/BdbTreeCollTFactory.hh"
00086 #include "BdbEventStore/BdbVectorCollTFactory.hh"
00087 #include "BdbEventStore/BdbCollPlacementManager.hh"
00088 #include "BdbEventStore/BdbTreeNodeCollectionTIterator.hh"
00089 #include "BdbTrees/BdbTreeNodeP.hh"
00090 #include "BdbTrees/BdbTreeNodeSimpleIterator.hh"
00091 #include "BdbUtil/BdbPathName.hh"
00092 #include "ErrLogger/ErrLog.hh"
00093 #include "Framework/APPFramework.hh"
00094 #include "Framework/APPModule.hh"
00095 #include "FrameUtil/AbsInterp.hh" 
00096 #include "BdbEventStore/BdbBridgeCollItemDesc.hh"
00097 #include "BdbEventStore/BdbCollTItemIterator.hh"
00098 
00099 //------------------------------------
00100 // Collaborating Class Declarations --
00101 //------------------------------------
00102 class BdbAbstractClusteringHint;
00103 
00104 //-----------------------------------------------------------------------
00105 // Local Macros, Typedefs, Structures, Unions and Forward Declarations --
00106 //-----------------------------------------------------------------------
00107 
00108 
00109 //      -----------------------------------------------
00110 //      -- Static Data & Function Member Definitions --
00111 //      -----------------------------------------------
00112 
00113 const int
00114 BdbCollectionCommand::_defaultMaxNodeCount = 32;
00115 int
00116 BdbCollectionCommand::_maxNodeCount = _defaultMaxNodeCount;
00117 
00118 int 
00119 BdbCollectionCommand::maxNodeCount( )
00120 {
00121     return _maxNodeCount;
00122 }
00123 
00124 void 
00125 BdbCollectionCommand::setMaxNodeCount( int maxCount )
00126 {
00127     if ( maxCount > 0 ) {
00128         _maxNodeCount = maxCount;
00129     } else {
00130         _maxNodeCount = _defaultMaxNodeCount;
00131     }
00132 }
00133 
00134 //              ----------------------------------------
00135 //              -- Public Function Member Definitions --
00136 //              ----------------------------------------
00137 
00138 //----------------
00139 // Constructors --
00140 //----------------
00141 
00142 BdbCollectionCommand::BdbCollectionCommand(const char* const theCommand, AppModule* theTarget )
00143     : APPCommand( theCommand, theTarget ),
00144       _isInitialized( d_False ),
00145       _placement( 0 ),
00146       _streamPlacement( 0 ),
00147       _isDifferentStream( true )
00148 {
00149 }
00150 
00151 //--------------
00152 // Destructor --
00153 //--------------
00154 
00155 BdbCollectionCommand::~BdbCollectionCommand( )
00156 {
00157     delete [] _streamPlacement;
00158     delete _placement;
00159 }
00160 
00161 //-----------
00162 // Handler --
00163 //-----------
00164 
00165 int 
00166 BdbCollectionCommand::handle( int argc, char* argv[] )
00167 {
00168     int result = AbsInterp::ERROR;
00169 
00170     // Setup the default mode flags
00171     _oneLine    = d_False;
00172     _listEvents = d_True;
00173     _listMeta   = d_False;
00174     _checkOwner = d_False;
00175     _fixupOwner = d_False;
00176     _badOnly    = d_False;
00177     _descend    = d_True;
00178     _listOwned  = d_False;
00179     _listOID    = d_False;
00180     _listColl   = d_False;
00181 
00182     setArgs( argc, argv );
00183     if ( 2 <= argc ) {
00184         if        ( 0 == strcmp( argv[1], "addTo" ) || 
00185                     0 == strcmp( argv[1], "add"   ) ) { 
00186             result = addHandler( argc, argv );
00187         } else if ( 0 == strcmp( argv[1], "cleanup" ) || 
00188                     0 == strcmp( argv[1], "cl"      ) ) { 
00189             result = cleanupHandler( argc, argv );
00190         } else if ( 0 == strcmp( argv[1], "contents" ) || 
00191                     0 == strcmp( argv[1], "co"       ) ) { 
00192             result = contentsHandler( argc, argv );
00193         } else if ( 0 == strcmp( argv[1], "create" ) || 
00194                     0 == strcmp( argv[1], "cr"     ) ) { 
00195             result = createHandler( argc, argv );
00196         } else if ( 0 == strcmp( argv[1], "delete" ) ) {
00197             result = deleteHandler(  argc, argv );
00198         } else if ( 0 == strcmp( argv[1], "events" ) || 
00199                     0 == strcmp( argv[1], "ev"     ) ) { 
00200             result = eventsHandler( argc, argv );
00201         } else if ( 0 == strcmp( argv[1], "help" ) ||
00202                     0 == strcmp( argv[1], "he"   ) ) {
00203             result = helpHandler( );
00204         } else if ( 0 == strcmp( argv[1], "list" ) || 
00205                     0 == strcmp( argv[1], "li"   ) ) {
00206             result = listHandler( argc, argv );
00207         } else if ( 0 == strcmp( argv[1], "map" ) || 
00208                     0 == strcmp( argv[1], "ma"   ) ) {
00209             result = mapHandler( argc, argv );
00210         } else if ( 0 == strcmp( argv[1], "moveTo" ) ||
00211                     0 == strcmp( argv[1], "move"   ) ||
00212                     0 == strcmp( argv[1], "rename" ) ||
00213                     0 == strcmp( argv[1], "rena"   ) ) {
00214             result = moveHandler( argc, argv );
00215         } else if ( 0 == strcmp( argv[1], "precreateCleanup" ) ||
00216                     0 == strcmp( argv[1], "precreate"        ) ||
00217                     0 == strcmp( argv[1], "prec"             ) ) {
00218             result = precreateCleanupHandler( argc, argv );
00219         } else if ( 0 == strcmp( argv[1], "removeFrom" ) ||
00220                     0 == strcmp( argv[1], "remove"     ) ) {
00221             result = removeHandler( argc, argv );
00222         } else {
00223             target( )->setError( "invalid command name" );
00224         }
00225     } else {
00226         target( )->setError( "wrong # args" );
00227     }
00228     return result;
00229 }
00230 
00231 int 
00232 BdbCollectionCommand::helpHandler( )
00233 {
00234     AppFramework* theFrame = target( )->framework( );
00235   
00236     theFrame->fullReport( "" );
00237     theFrame->partialReport( "collection addTo <source> <dest>        " );
00238     theFrame->fullReport("Add the source collection to the" ); 
00239   
00240     theFrame->partialReport( "                                        " );  
00241     theFrame->fullReport( "destination collection" );
00242   
00243     theFrame->fullReport( "collection cleanup -t[ree] <tree> <name>" );
00244     theFrame->partialReport( "                                        " );  
00245     theFrame->fullReport("Cleanup a collection." );
00246     theFrame->partialReport( "                                        " );  
00247     theFrame->fullReport( "Multiple trees may be specified." );
00248   
00249     theFrame->fullReport( "collection contents [-[no]events] <name>" );
00250     theFrame->partialReport( "                                        " );  
00251     theFrame->fullReport("Display the contents (collections)" ); 
00252     theFrame->partialReport( "                                        " );  
00253     theFrame->fullReport( "of a collection" );
00254   
00255     theFrame->fullReport( "collection create [-tree] [-vector] <name> [<name>]");
00256     theFrame->partialReport( "                                        " );  
00257     theFrame->fullReport("Create the specified collection(s)" );
00258 
00259     theFrame->partialReport( "collection delete <name> [<name>]       " );
00260     theFrame->fullReport("Delete the specified collection(s)" );
00261 
00262     theFrame->partialReport( "collection events <name>                " );
00263     theFrame->fullReport("Display the contents (events) of" ); 
00264     theFrame->partialReport( "                                        " );  
00265     theFrame->fullReport( "a collection" );
00266 
00267     theFrame->partialReport( "collection help                         " );
00268     theFrame->fullReport("Show this help information" );
00269 
00270     theFrame->partialReport( "collection list                         " );
00271     theFrame->fullReport("List collections for current user" );
00272 
00273     theFrame->partialReport( "collection list <node>                  " );
00274     theFrame->fullReport("List collections for node <node>" );
00275 
00276     theFrame->partialReport( "collection list -a[ll]                  " );
00277     theFrame->fullReport("List all collections" );
00278 
00279     theFrame->partialReport( "collection list -g[roup] <group>        " );
00280     theFrame->fullReport("List collections for group <group>" );
00281   
00282     theFrame->partialReport( "collection list -n[ode] <node>          " );
00283     theFrame->fullReport("List collections for node <node>" );
00284   
00285     theFrame->partialReport( "collection list -s[ystem]               " );
00286     theFrame->fullReport("List system collections" );
00287   
00288     theFrame->partialReport( "collection list -u[ser] <user>          " );
00289     theFrame->fullReport("List collections for user <user>" );
00290   
00291     theFrame->partialReport( "  list options are: -o[neline]          " );
00292     theFrame->fullReport("List one line per node/collection" );
00293     theFrame->partialReport( "                  : -m[ultiline]        " );
00294     theFrame->fullReport( "List multi-line per node/collection" ); 
00295     theFrame->partialReport( "                  : -e[vents]           " );
00296     theFrame->fullReport( "List events per collection (default)" );
00297     theFrame->partialReport( "                  : -noe[events]        " );
00298     theFrame->fullReport( "Don't list events per collection" );
00299     theFrame->partialReport( "                  : -r[ecursive]        " );
00300     theFrame->fullReport( "Recursively descend into child nodes" );
00301     theFrame->partialReport( "                  : -nor[ecursive]      " );
00302     theFrame->fullReport( "Don't recursively descend into child" );
00303     theFrame->partialReport( "                                        " );
00304     theFrame->fullReport("nodes");
00305     theFrame->partialReport( "                  : -meta               " );
00306     theFrame->fullReport("Show metainformation" );
00307     theFrame->partialReport( "                  : -ow[ned]            " );
00308     theFrame->fullReport("Show owned events" );
00309     theFrame->partialReport( "                  : -oid                " );
00310     theFrame->fullReport("Show collection OID" );
00311 
00312     theFrame->partialReport( "collection moveTo <source> <dest>       " );
00313     theFrame->fullReport( "Move the source collection to the" );
00314     theFrame->partialReport( "                                        " );
00315     theFrame->fullReport( "destination location" );
00316 
00317     theFrame->partialReport( "collection precreateCleanup             " );
00318     theFrame->fullReport( "Cleanup following collection" );
00319     theFrame->partialReport( "                                        " );
00320     theFrame->fullReport( "precreation" );
00321 
00322     theFrame->partialReport( "collection removeFrom <source> <dest>   " );
00323     theFrame->fullReport("Remove the source collection" );
00324     theFrame->partialReport( "                                        " ); 
00325     theFrame->fullReport( "from the destination collection" );
00326 
00327     theFrame->partialReport( "collection rename <source> <dest>       " );
00328     theFrame->fullReport("Synonym for moveTo" );
00329 
00330     return AbsInterp::OK;
00331 }
00332 
00333 void
00334 BdbCollectionCommand::show( ) const 
00335 {
00336 }
00337 
00338 bool
00339 BdbCollectionCommand::isShowable( ) const 
00340 {
00341     return false; 
00342 }
00343 
00344 //              -------------------------------------------
00345 //              -- Protected Function Member Definitions --
00346 //              -------------------------------------------
00347 
00348 //      ---------------------
00349 //      --Primary Handlers --
00350 //      ---------------------
00351 
00352 int 
00353 BdbCollectionCommand::addHandler( int argc, char* argv[] )
00354 {
00355     BdbEventStore* theStore = BdbEventStore::instance( );
00356     BdbStatus status = BdbcError;
00357     AppFramework* theFrame = target( )->framework( );
00358     AbsInterp* interp = AbsInterp::theInterpreter();
00359 
00360     int result = AbsInterp::OK;
00361 
00362     if ( 4 <= argc ) {
00363 
00364         // Ensure the event store is initialized
00365         initialize( );
00366 
00367         // Start an update transaction if not already in one
00368         theStore->activate( );
00369         BdbMode theMode = theStore->change( BdbcUpdate );
00370 
00371         // Test whether the destination collection exists
00372         int last = argc - 1;
00373         BdbAbsCollectionT<BdbEventT>* theDestination = 
00374               theStore->collection( argv[last], (*(BdbEventT*)0) );
00375         if ( 0 != theDestination ) {
00376 
00377             status = BdbcSuccess;
00378 
00379             // Loop over source collection(s). All arguments apart from
00380             // the last one are treated as source collections to be added
00381             // to the destination, which is the last one.
00382             int i = 1; 
00383             const int finished( last - 1 );
00384             while ( i != finished ) {
00385                 i++;
00386 
00387                 // Check to see if source collection can be added to
00388                 // destination and if so switch to federation containing
00389                 // source collection
00390                 const char* collName;
00391                 const char* collFed;
00392                 BdbModulesUtility::parseCollectionSpecifier( argv[i],
00393                                                              collName,
00394                                                              collFed );
00395                 if( 0 == collName ) {
00396                     cerr << "Error: Invalid specification of a collection \""
00397                          << argv[i] << "\"" << endl;
00398                     delete [] const_cast< char* >( collName );
00399                     delete [] const_cast< char* >( collFed );
00400                     continue;
00401                 }
00402 
00403                 status = theDestination->setFed( collFed );
00404                 delete [] const_cast< char* >( collFed );
00405                 if( BdbcSuccess != status ) {
00406                     cerr << "Error: Collection "
00407                          << argv[i]
00408                          << " can not be added to collection "
00409                          << argv[last]
00410                          << endl;
00411                     delete [] const_cast< char* >( collName );
00412                     continue;
00413                 }
00414 
00415                 // Check whether the source collection exists
00416                 BdbAbsCollectionT<BdbEventT>* theSource = 
00417                     theStore->collection(  collName, (*(BdbEventT*)0) );
00418                 delete [] const_cast< char* >( collName );
00419                 if ( 0 == theSource ) {
00420                     status = BdbcError;
00421                     cerr << "Error: Collection " << argv[i]
00422                          << " doesn't exist" << endl;
00423                     continue;
00424                 }
00425 
00426                 // Source and destination both exist. Is the source
00427                 // already contained within the destination?
00428                 addNonDuplicate( argv[ i ], theSource,
00429                                  argv[ last ], theDestination );
00430                 delete theSource;
00431             }
00432 
00433             // Return to original federation
00434             theDestination->setFed();
00435             delete theDestination;
00436         } else {
00437             cout << "Error: Collection " << argv[last]
00438                  << " doesn't exist" << endl;
00439         }
00440 
00441         // Restore the previous transaction state, forcing a commit if
00442         // necessary
00443         theStore->change( theMode, d_True );
00444         theStore->deactivate( );
00445     } else {
00446         cout << "Error: no collection(s) specified - request ignored"
00447              << endl;
00448         target( )->setError( "invalid command name" );
00449     } 
00450     return result;
00451 }
00452 
00453 int
00454 BdbCollectionCommand::addNonDuplicate( const char* sourceName ,
00455                                        BdbAbsCollectionT<BdbEventT>* sourceColl,
00456                                        const char* destName,
00457                                        BdbAbsCollectionT<BdbEventT>* destColl )
00458 {
00459     AbsInterp* interp = AbsInterp::theInterpreter();
00460     int result = AbsInterp::ERROR;
00461 
00462     if ( destColl->containsCollection( *sourceColl, d_True ) ) {
00463         ErrMsg( warning ) << "Collection " << sourceName
00464                           << " is already contained by collection "
00465                           << destName << endmsg;
00466         return( result );
00467     }
00468 
00469     // All checked ok - add the source to the destination
00470     BdbStatus status( destColl->addCollection( *sourceColl ) );
00471     if ( BdbcSuccess != status ) {
00472         ErrMsg( error ) << "Unable to add collection "
00473                         << sourceName << " to " << destName << endmsg;
00474         return( result );
00475     }
00476     interp->appendResult( "Collection " );
00477     interp->appendResult( sourceName );
00478     interp->appendResult( " added to collection " );
00479     interp->appendResult( destName );
00480     interp->appendResult( "\n" );
00481     result = AbsInterp::OK;
00482     return( result );
00483 }
00484 
00485 int 
00486 BdbCollectionCommand::cleanupHandler( int argc, char* argv[] )
00487 {
00488     const char* theName = 0;
00489     const char* theTrees[64];
00490     d_ULong nTrees = 0;
00491     int result = AbsInterp::OK;
00492 
00493     int i = 2;
00494     while ( i < argc ) {
00495         if ( 0 == strcmp( argv[i], "-t" ) ) {
00496             i++;
00497             theTrees[nTrees] = argv[i];
00498             nTrees++;
00499         } else if ( 0 == strcmp( argv[i], "-tree" ) ) {
00500             i++;
00501             theTrees[nTrees] = argv[i];
00502             nTrees++;
00503         } else {
00504             theName = argv[i];
00505         }
00506         i++;
00507     }
00508 
00509     if ( NULL != theName ) {
00510 
00511         BdbEventStore* theStore = BdbEventStore::instance( );
00512         BdbEventT::ObjyRef nullRef;
00513         BdbEventT anEvent(nullRef, d_True);
00514         BdbStatus status;
00515 
00516         // Ensure the event store is initialized
00517         initialize( );
00518 
00519         // Start an update transaction if not already in one
00520         theStore->activate( );
00521         BdbMode theMode = theStore->change( BdbcUpdate );
00522 
00523         // Check whether the collection exists
00524         BdbAbsCollectionT<BdbEventT>* theCollection = theStore->collection( theName, (*(BdbEventT*)0) );
00525         if ( 0 != theCollection ) {
00526             status = BdbcSuccess;
00527             BdbCollectionTIterator<BdbEventT>* collIter( theCollection->getIterator() );
00528             while ( BdbcSuccess == ( status = collIter->next( anEvent )) ) {
00529                 status = anEvent.cleanup( nTrees, theTrees );
00530             }
00531             delete collIter;
00532         } else {
00533             cout << "Error: collection " << theName << " doesn't exist" << endl;
00534         }
00535 
00536         // Restore the previous transaction state, forcing a commit if necessary
00537         theStore->change( theMode, d_True );
00538         theStore->deactivate( );
00539     } else {
00540         cout << "Error: no collection specified - request ignored" << endl;
00541     }
00542     return result;
00543 }
00544 
00545 int 
00546 BdbCollectionCommand::contentsHandler( int argc, char* argv[] )
00547 {
00548     BdbEventStore* theStore = BdbEventStore::instance( );
00549     BdbStatus status;
00550     const char* theName = 0;
00551 
00552     int result = AbsInterp::OK;
00553 
00554     int i = 2; 
00555     while ( i < argc ) {
00556         if        ( 0 == strcmp( argv[i], "-events" ) || 
00557                     0 == strcmp( argv[i], "-e"      ) ||
00558                     0 == strcmp( argv[i], "-size"   ) ||
00559                     0 == strcmp( argv[i], "-s"      ) ) {
00560             _listEvents = d_True;
00561         } else if ( 0 == strcmp( argv[i], "-noevents" ) || 
00562                     0 == strcmp( argv[i], "-noe"      ) ||
00563                     0 == strcmp( argv[i], "-nosize"   ) ||
00564                     0 == strcmp( argv[i], "-nos"      ) ) {
00565             _listEvents = d_False;
00566         } else if ( 0 == strcmp( argv[i], "-meta" ) ||
00567                     0 == strcmp( argv[i], "-m"    ) ) {
00568             _listMeta = d_True;
00569         } else if ( 0 == strcmp( argv[i], "-owned" ) ||
00570                     0 == strcmp( argv[i], "-ow"    ) ) {
00571                         _listOwned = d_True;
00572         } else if ( 0 == strcmp( argv[i], "-noowned" ) ||
00573                     0 == strcmp( argv[i], "-noow"    ) ) {
00574             _listOwned = d_False;
00575         } else if ( 0 == strcmp( argv[i], "-oid" ) ||
00576                     0 == strcmp( argv[i], "-OID" ) ) {
00577             _listOID = d_True;
00578         } else if ( 0 == strcmp( argv[i], "-nooid" ) ||
00579                     0 == strcmp( argv[i], "-noOID" ) ) {
00580             _listOID = d_False;
00581         } else if ( 0 == strcmp( argv[i], "-norecursive" ) ||
00582                     0 == strcmp( argv[i], "-nor"         ) ) {
00583             _descend = d_False;
00584         } else if ( 0 == strcmp( argv[i], "-collections" ) ||
00585                     0 == strcmp( argv[i], "-coll" ) ) {
00586             _listColl = d_True;
00587         } else {
00588             theName = argv[i];
00589         }
00590         i++;
00591     }
00592     if ( 0 != theName ) {
00593 
00594         // Ensure the event store is initialized
00595         initialize( );
00596         
00597         // Start a read transaction if necessary
00598         theStore->activate( );
00599         BdbMode oldMode = theStore->change( BdbcRead );
00600 
00601         // Check whether the collection exists
00602         BdbAbsCollectionT<BdbEventT>* theCollection = 
00603             theStore->collection( theName, (*(BdbEventT*)0) );
00604         if ( 0 != theCollection ) {
00605             // Collection exists - display the contents
00606             int stackDepth = 0;
00607             contentsCollHandler( theName, theCollection, stackDepth );
00608             delete theCollection;
00609         } else {
00610             cout << "Error: collection " << theName << " doesn't exist" << endl;
00611         }
00612 
00613         // Restore the transaction state - commiting the transaction if necessary
00614         theStore->change( oldMode, d_True );
00615         theStore->deactivate( );
00616     } else {
00617         cout << "Error: no collection specified - request ignored" << endl;
00618         target( )->setError( "invalid command name" );
00619     } 
00620     return result;
00621 }
00622 
00623 int 
00624 BdbCollectionCommand::createHandler( int argc, char* argv[] )
00625 {
00626     AbsInterp* interp = AbsInterp::theInterpreter();
00627     int result = AbsInterp::OK;
00628 
00629     d_Boolean createBridge = d_False;
00630     d_Boolean createTree   = d_False;
00631 
00632     bool streamSpecified( false );
00633     int collectionBegin( 2 );
00634     bool finishedModifiers = false;
00635     while( ( !finishedModifiers ) && 
00636            ( collectionBegin  != argc ) ) {
00637        
00638         if( 0 == strcmp( argv[ collectionBegin ], "-bridge" ) ||
00639             0 == strcmp( argv[ collectionBegin ], "-b"      ) ) {
00640             createBridge = d_True;
00641             collectionBegin++;
00642         } else if ( 0 == strcmp( argv[ collectionBegin ], "-tree" ) ||
00643                     0 == strcmp( argv[ collectionBegin ], "-t"      ) ) {
00644             createBridge = d_False;
00645             createTree = d_True;
00646             collectionBegin++;
00647         } else if ( 0 == strcmp( argv[ collectionBegin ], "-vector" ) ||
00648                     0 == strcmp( argv[ collectionBegin ], "-v"      ) ) {
00649             createBridge = d_False;
00650             createTree = d_False;
00651             collectionBegin++;
00652         } else if ( 0 == strcmp( argv[ collectionBegin ], "-stream" ) ||
00653                     0 == strcmp( argv[ collectionBegin ], "-s"      ) ) {
00654             collectionBegin++;
00655             if( argc == collectionBegin ) {
00656                 finishedModifiers = !false;
00657             }
00658             else {
00659                 const char* streamName( argv[ collectionBegin ] );
00660                 if( ( 0 == _streamPlacement ) ||
00661                     ( 0 != strcmp( _streamPlacement,
00662                                    streamName ) ) ) {
00663                     delete [] _streamPlacement;
00664                     _isDifferentStream = true;
00665                     _streamPlacement = new char[ strlen( streamName )+1 ];
00666                     strcpy( _streamPlacement,
00667                             streamName);
00668                 }
00669                 streamSpecified = true;
00670                 collectionBegin++;
00671             }
00672         } else {
00673             finishedModifiers = !false;
00674         }
00675     }
00676 
00677     const char* defaultName( BdbCollPlacementManager::defaultPlacementName() );
00678     if( ( !streamSpecified ) &&
00679         ( ( 0 == _streamPlacement ) ||
00680           ( 0 != strcmp( _streamPlacement, defaultName ) ) ) ) {
00681         delete [] _streamPlacement;
00682         _isDifferentStream = true;
00683         _streamPlacement = new char[ strlen( defaultName )+1 ];
00684         strcpy( _streamPlacement, defaultName );
00685     }
00686 
00687     int collectionCount( argc - collectionBegin );
00688     if( 0 < collectionCount ) {
00689         result = createCollections( collectionCount,
00690                                     &(argv[ collectionBegin ]),
00691                                     createTree,
00692                                     createBridge );
00693     } else {
00694         target()->setError( "No collection specified, creation request ignored" );
00695         result = AbsInterp::ERROR;
00696     }
00697     return result;
00698 
00699 }
00700 
00701 
00702 BdbCollPlacementManager*
00703 BdbCollectionCommand::placement()
00704 {
00705     BdbEventStore& evs( *BdbEventStore::instance() );
00706 
00707     if( ( 0 == _placement ) ||
00708         ( _isDifferentStream ) ||
00709         ( ! _placement->isBuiltInTrans( evs.currentTrans() ) ) ) {
00710         char* name( BdbModulesUtility::placementName( _streamPlacement,
00711                                                       evs ) );
00712         delete _placement;
00713         _placement = new BdbCollPlacementManager( evs,
00714                                                   name );
00715         _isDifferentStream = false;
00716         delete [] name;
00717     }
00718     return( _placement );
00719 }
00720 
00721 int
00722 BdbCollectionCommand::createCollections( int nameCount,
00723                                          char* names[],
00724                                          d_Boolean createTree,
00725                                          d_Boolean createBridge )
00726 {
00727     AbsInterp* interp = AbsInterp::theInterpreter();
00728     int result = AbsInterp::OK;
00729 
00730     BdbEventStore& evs( *BdbEventStore::instance() );
00731 
00732     // Ensure the event store is ready
00733     initialize( );
00734     evs.activate( );
00735     BdbMode theMode( evs.change( BdbcUpdate,
00736                                  d_True ) );
00737 
00738     d_Long oldWait = evs.lockWait( );
00739     evs.setLockWait(120); // wait max 2 minutes
00740 
00741     // Create collection for each name which does not already exist
00742     int name( 0 );
00743     BdbAbsCollectionT< BdbEventT >* theColl( 0 );
00744     BdbCollectionTFactory< BdbEventT >* factory( 0 );
00745     while( ( AbsInterp::OK == result ) &&
00746            ( nameCount != name ) ) {
00747         // the 'false' needs to be removed in collection creation is
00748         // moved into a nested factory.
00749         theColl = evs.collection( names[ name ],
00750                                   (*(BdbEventT*)0),
00751                                   false);
00752         if( 0 != theColl ) {
00753 
00754             // Collection already exists
00755             interp->appendResult( "Collection " );
00756             interp->appendResult( names[ name ] );
00757             interp->appendResult( " already exists.\n" );
00758         } else {
00759 
00760             if( ( ! createBridge ) &&
00761                 ( ! createTree ) ) {
00762                 // We call forceNewContainer( ) on the hint to force each
00763                 // collection to be created in a new container.
00764                 BdbAbstractClusteringHint* collectionHint( placement()->vectorCollectionHint() );
00765                 ((BdbEvsClusteringHint*)collectionHint)->forceNewContainer( );
00766             }
00767 
00768             // First collection that needs creation, prepare factory
00769             if( 0 == factory ) {
00770                 if( createBridge ) {
00771                     factory = new BdbBridgeCollTFactory< BdbEventT >( *(placement()->bridgeCollectionHint()),
00772                                                                       *(placement()->nodeHint()) );
00773                 }
00774                 else if( createTree ) {
00775                     factory = new BdbTreeCollTFactory< BdbEventT >( *(placement()->treeCollectionHint()),
00776                                                                     *(placement()->nodeHint()) );
00777                 }
00778                 else {
00779                     factory = new BdbVectorCollTFactory< BdbEventT >( *(placement()->vectorCollectionHint()),
00780                                                                       *(placement()->nodeHint()) );
00781                 }
00782 
00783                 factory = new BdbFetchCollTFactory< BdbEventT >( factory,
00784                                                                  120 );
00785                 factory = new BdbMetaDataCollTFactory< BdbEventT >( factory );
00786             }
00787 
00788             // Collection doesn't already exist, create it.
00789             char* theFullCollName = BdbPathName::absolute( evs.validLastPath(),
00790                                                            names[ name ] );
00791             BdbAbsCollectionT<BdbEventT>* theColl( factory->getCollection( theFullCollName ) );
00792 
00793             if ( ( 0 != theColl ) &&
00794                  ( ! theColl->isNull( ) ) ) {
00795                 if( BdbCollectionTFactory<BdbEventT>::kExistsFailure == factory->getResult() ) {
00796                     interp->appendResult( "Collection " );
00797                     interp->appendResult( names[ name ] );
00798                     interp->appendResult( " was created by another process.\n" );
00799                     target()->setError( "Collection created by other process" );
00800                     result = AbsInterp::ERROR;
00801                 }
00802                 else {
00803                     interp->appendResult( factory->typeName() );
00804                     interp->appendResult( " collection " ); 
00805                     interp->appendResult( names[ name ] ); 
00806                     interp->appendResult( " created ok\n" ); 
00807                 }
00808             } else {
00809                 interp->appendResult( "Failed to create " );
00810                 interp->appendResult( factory->typeName() );
00811                 interp->appendResult( " collection " ); 
00812                 interp->appendResult( names[ name ] ); 
00813                 interp->appendResult( ".\n" ); 
00814                 target()->setError( "Failed to create collection" );
00815                 result = AbsInterp::ERROR;
00816             }
00817             delete [] theFullCollName;
00818         }
00819         delete theColl;
00820         name++;
00821     }
00822     delete factory;
00823 
00824     // Restore the previous transaction state, forcing a commit
00825     // if necessary (and cleanin up the clustering hint!)
00826     evs.setLockWait(oldWait);
00827     evs.change( theMode, d_True );
00828     evs.deactivate( );
00829 
00830     return result;
00831 }
00832 
00833 int 
00834 BdbCollectionCommand::deleteHandler( int argc, char* argv[] )
00835 {
00836     BdbEventStore* theStore = BdbEventStore::instance( );
00837     BdbStatus status;
00838 
00839     AbsInterp* interp = AbsInterp::theInterpreter();
00840     int result = AbsInterp::OK;
00841 
00842     if ( 3 <= argc ) {
00843 
00844         // Ensure the event store is initialized
00845         initialize( );
00846 
00847         int i = 2; 
00848         while ( i < argc ) {
00849 
00850             // Start an update transaction, forcing any previous one to be committed.
00851             theStore->activate( );
00852             BdbMode theMode = theStore->change( BdbcUpdate, d_True );
00853 
00854             // Check whether the collection exists
00855             BdbAbsCollectionT<BdbEventT>* theCollection = 
00856                 theStore->collection( argv[i], (*(BdbEventT*)0) );
00857             if ( 0 != theCollection ) {
00858 
00859                 // First remove the collection from the store but don't delete it
00860                 status = theStore->removeCollection( theCollection, d_True );
00861                 if ( BdbcSuccess == status ) {
00862 
00863                     // Removal successful - now delete the collection within another transaction.
00864                     // This minimizes the duration of any locking of the tree nodes.
00865                     theStore->change( BdbcUpdate, d_True );
00866                     theCollection->setDeleted( );
00867                     AppFramework* theFrame = target( )->framework( );
00868                     interp->appendResult( "collection " ); 
00869                     interp->appendResult( argv[i] ); 
00870                     interp->appendResult( " deleted ok\n" ); 
00871                 } else {
00872                     cout << "Error: Unable to delete collection " << argv[i] << endl;
00873                 }
00874 
00875             } else {
00876                 cout << "Error: collection " << argv[i] << " doesn't exist" << endl;
00877             }
00878 
00879             // Restore the previous transaction state, forcing a commit it necessary
00880             theStore->change( theMode, d_True );
00881             theStore->deactivate( );
00882             i++;
00883         }
00884     } else {
00885         cout << "Error: no collection specified - request ignored" << endl;
00886     }
00887     return result;
00888 }
00889 
00890 int 
00891 BdbCollectionCommand::eventsHandler( int argc, char* argv[] )
00892 {
00893     BdbEventStore* theStore = BdbEventStore::instance( );
00894 
00895     AbsInterp* interp = AbsInterp::theInterpreter();
00896     int result = AbsInterp::OK;
00897 
00898     if ( 3 <= argc ) {
00899 
00900         // Ensure the event store is initialized
00901         initialize( );
00902 
00903         // Start a read transaction if necessary
00904         theStore->activate( );
00905         BdbMode theMode = theStore->change( BdbcRead );
00906 
00907         // Check whether the collection exists
00908         BdbAbsCollectionT<BdbEventT>* theCollection = 
00909             theStore->collection( argv[2], (*(BdbEventT*)0) );
00910         if ( 0 != theCollection ) {
00911 
00912             // Collection exists - display the events contents
00913             AppFramework* theFrame = target( )->framework( );
00914             interp->appendResult( "This command isn't implemented yet\n" ); 
00915         } else {
00916             cout << "Error: collection " << argv[2] << " doesn't exist" << endl;
00917         }
00918 
00919         // Restore the previous transaction state, forcing a commit if necessary
00920         theStore->change( theMode, d_True );
00921         theStore->deactivate( );
00922     } else {
00923         cout << "Error: no collection specified - request ignored" << endl;
00924         target( )->setError( "invalid command name" );
00925     } 
00926     return result;
00927 }
00928 
00929 int 
00930 BdbCollectionCommand::listHandler( int argc, char* argv[] )
00931 {
00932     int result = AbsInterp::OK;
00933 
00934     BdbEventStore* theStore = BdbEventStore::instance( );
00935 
00936     _nodeCount = 0;
00937 
00938     // Ensure the event store is initialized
00939     initialize( );
00940 
00941     // Start a read transaction if necessary
00942     theStore->activate( );
00943     BdbMode theMode = theStore->change( BdbcRead );
00944 
00945     if ( 2 == argc ) {
00946         result = listLevelHandler( BdbDomain::User, NULL );
00947     } else {
00948         int i = 2; 
00949         while ( i < argc && AbsInterp::OK == result ) {
00950             if        ( 0 == strcmp( argv[i], "-all" ) ||
00951                         0 == strcmp( argv[i], "-a"   ) ) {
00952                 result = listAllHandler( );
00953             } else if ( 0 == strcmp( argv[i], "-bad" ) ||
00954                         0 == strcmp( argv[i], "-b"   ) ) {
00955                 _badOnly = d_True;
00956                 _oneLine = d_True;
00957             } else if ( 0 == strcmp( argv[i], "-nobad" ) ||
00958                         0 == strcmp( argv[i], "-nob"   ) ) {
00959                 _badOnly = d_False;
00960             } else if ( 0 == strcmp( argv[i], "-check" ) ||
00961                         0 == strcmp( argv[i], "-c"     ) ) {
00962                 _checkOwner = d_True;
00963             } else if ( 0 == strcmp( argv[i], "-nocheck" ) ||
00964                         0 == strcmp( argv[i], "-noc"     ) ) {
00965                 _checkOwner = d_False;
00966             } else if ( 0 == strcmp( argv[i], "-events" ) ||
00967                         0 == strcmp( argv[i], "-e"      ) ) {
00968                 _listEvents = d_True;
00969             } else if ( 0 == strcmp( argv[i], "-noevents" ) ||
00970                         0 == strcmp( argv[i], "-noe"      ) ) {
00971                 _listEvents = d_False;
00972             } else if ( 0 == strcmp( argv[i], "-fixup" ) ||
00973                         0 == strcmp( argv[i], "-f"     ) ) {
00974                 _checkOwner = d_True;
00975                 _fixupOwner = d_True;
00976             } else if ( 0 == strcmp( argv[i], "-nofixup" ) ||
00977                         0 == strcmp( argv[i], "-nof"     ) ) {
00978                 _fixupOwner = d_False;
00979             } else if ( 0 == strcmp( argv[i], "-recursive" ) ||
00980                         0 == strcmp( argv[i], "-r"         ) ) {
00981                 _descend = d_True;
00982             } else if ( 0 == strcmp( argv[i], "-norecursive" ) ||
00983                         0 == strcmp( argv[i], "-nor"         ) ) {
00984                 _descend = d_False;
00985             } else if ( 0 == strcmp( argv[i], "-meta" ) ) {
00986                 _listMeta = d_True;
00987             } else if ( 0 == strcmp( argv[i], "-group" ) ||
00988                         0 == strcmp( argv[i], "-g"     ) ) {
00989                 i++;
00990                 if ( i < argc ) {
00991                     result = listLevelHandler( BdbDomain::Group, argv[i] );
00992                 } else {
00993                     result = AbsInterp::ERROR;
00994                 }
00995             } else if ( 0 == strcmp( argv[i], "-node" ) ||
00996                         0 == strcmp( argv[i], "-n"     ) ) {
00997                 i++;
00998                 if ( i < argc ) {
00999                     result = listNodeHandler( argv[i] );
01000                 } else {
01001                     result = AbsInterp::ERROR;
01002                 }
01003             } else if ( 0 == strcmp( argv[i], "-owned" ) ||
01004                         0 == strcmp( argv[i], "-ow"    ) ) {
01005                 _listOwned = d_True;
01006             } else if ( 0 == strcmp( argv[i], "-noowned" ) ||
01007                         0 == strcmp( argv[i], "-noow"    ) ) {
01008                 _listOwned = d_False;
01009             } else if ( 0 == strcmp( argv[i], "-oid" ) ||
01010                         0 == strcmp( argv[i], "-OID" ) ) {
01011                 _listOID = d_True;
01012             } else if ( 0 == strcmp( argv[i], "-nooid" ) ||
01013                         0 == strcmp( argv[i], "-noOID" ) ) {
01014                 _listOID = d_False;
01015             } else if ( 0 == strcmp( argv[i], "-oneline" ) ||
01016                         0 == strcmp( argv[i], "-one"     ) ||
01017                         0 == strcmp( argv[i], "-o"       ) ) {
01018                 _oneLine = d_True;
01019             } else if ( 0 == strcmp( argv[i], "-multiline" ) ||
01020                         0 == strcmp( argv[i], "-multi"     ) ||
01021                         0 == strcmp( argv[i], "-m"         ) ) {
01022                 _oneLine = d_False;
01023             } else if ( 0 == strcmp( argv[i], "-system" ) ||
01024                         0 == strcmp( argv[i], "-s"      ) ) {
01025                 result = listLevelHandler( BdbDomain::System, NULL);
01026             } else if ( 0 == strcmp( argv[i], "-user" ) ||
01027                         0 == strcmp( argv[i], "-u"    ) ) {
01028                 i++;
01029                 if ( i < argc ) {
01030                     result = listLevelHandler( BdbDomain::User, argv[i] );
01031                 } else {
01032                     result = AbsInterp::ERROR;
01033                 }
01034             } else {
01035                 result = listNodeHandler( argv[i] );
01036             }
01037             i++;
01038         }
01039     }
01040 
01041     // Restore the previous transaction state, forcing a commit if necessary
01042     theStore->change( theMode, d_True );
01043     theStore->deactivate( );
01044     if ( AbsInterp::OK != result ) {
01045         target( )->setError( "invalid command name" );
01046     }
01047     return result;
01048 }
01049 
01050 int
01051 BdbCollectionCommand::mapHandler( int argc, char* argv[] )
01052 {
01053     BdbEventStore& evs( *BdbEventStore::instance() );
01054     AppFramework* theFrame = target( )->framework( );
01055 
01056     AbsInterp* interp = AbsInterp::theInterpreter();
01057     int result = AbsInterp::OK;
01058 
01059     BdbStatus status;
01060     if ( 4 <= argc ) {
01061 
01062         // Ensure the event store ready for use
01063         initialize( );
01064         evs.activate( );
01065 
01066         // create list of existing slave collections
01067         BdbTransToken bridgeTrans( evs.retainTrans() );
01068         size_t last = argc - 1;
01069         char* slaveFed( BdbPathName::absolute( evs.bootName(),
01070                                                argv[ last ] ) );
01071         evs.newEvsTrans( slaveFed );
01072         delete [] slaveFed;
01073         BdbMode slaveMode( evs.change( BdbcRead ) );
01074         BdbTransToken slaveTrans( evs.retainTrans() );
01075 
01076         const size_t SOURCE_INDEX_BEGIN( 2 );
01077         char** sourceNames( new char*[last - SOURCE_INDEX_BEGIN ] );
01078         BdbAbsCollectionT<BdbEventT>** sourceColls( new BdbAbsCollectionT<BdbEventT>* [last - SOURCE_INDEX_BEGIN ]);
01079         size_t sourceCount( 0 );
01080         BdbAbsCollectionT<BdbEventT>* sourceColl = 0;
01081         for( size_t sourceIndex( SOURCE_INDEX_BEGIN ) ; last != sourceIndex ; sourceIndex++ ) {
01082             sourceColl = evs.collection( argv[ sourceIndex ], (*(BdbEventT*)0) );
01083             if ( 0 != sourceColl ) {
01084                 sourceNames[ sourceCount ] = argv[ sourceIndex ];
01085                 sourceColls[ sourceCount ] = sourceColl;
01086                 sourceCount++;
01087             } else {
01088                 ErrMsg( warning ) << "Collection " << argv[ sourceIndex ]
01089                                   << " doesn't exist, and will not be mapped." << endmsg;
01090             }
01091         }
01092         evs.setCurrentTrans( bridgeTrans );
01093 
01094         // build a bridge collection for each valid slave collection
01095         BdbMode bridgeMode( evs.change( BdbcUpdate ) );
01096         int creationResult = createCollections( sourceCount,
01097                                                 sourceNames,
01098                                                 d_False,
01099                                                 d_True );
01100         if( ( AbsInterp::OK != creationResult ) &&
01101             ( AbsInterp::OK == result ) ) {
01102             result == AbsInterp::ERROR;
01103             target( )->setError( "Unable to create all bridge collections" );
01104         }
01105 
01106         // fill each bridge collection with appropriate slave
01107         for( size_t source( 0 );
01108              sourceCount != source;
01109              source++ ) {
01110             evs.setCurrentTrans( bridgeTrans );
01111             BdbAbsCollectionT<BdbEventT>* destColl =
01112                 evs.collection( sourceNames[ source ], (*(BdbEventT*)0) );
01113             if ( 0 != destColl ) {
01114                 evs.setCurrentTrans( slaveTrans );
01115                 addNonDuplicate( sourceNames[ source ],
01116                                  *(sourceColls+source),
01117                                  sourceNames[ source ],
01118                                  destColl );
01119             } else {
01120                 ErrMsg( warning ) << "Collection " << sourceNames[ source ]
01121                                   << " failed to be mapped." << endmsg;
01122             }
01123         }
01124         evs.setCurrentTrans( slaveTrans );
01125         delete [] sourceColls;
01126         delete [] sourceNames;
01127         evs.change( slaveMode );
01128         evs.releaseTrans( slaveTrans );
01129 
01130         evs.setCurrentTrans( bridgeTrans );
01131         evs.change( bridgeMode,
01132                     d_True );
01133         evs.releaseTrans( bridgeTrans );
01134     }
01135     else {
01136         result == AbsInterp::ERROR;
01137         target( )->setError( "invalid command name" );
01138     }
01139     return result;
01140 }
01141 
01142 int
01143 BdbCollectionCommand::moveHandler( int argc, char* argv[] )
01144 {
01145     BdbEventStore* theStore = BdbEventStore::instance( );
01146     BdbStatus status;
01147     AppFramework* theFrame = target( )->framework( );
01148 
01149     AbsInterp* interp = AbsInterp::theInterpreter();
01150     int result = AbsInterp::OK;
01151 
01152     if ( 4 <= argc ) {
01153 
01154         // Ensure the event store is initialized
01155         initialize( );
01156 
01157         // Start an update transaction if not already in one
01158         theStore->activate( );
01159         BdbMode theMode = theStore->change( BdbcUpdate );
01160 
01161         // Check whether the source collection exists
01162         BdbAbsCollectionT<BdbEventT>* theSource = 
01163             theStore->collection( argv[2], (*(BdbEventT*)0) );
01164         if ( 0 != theSource ) {
01165 
01166             // Check whether the destination collection exists
01167             BdbAbsCollectionT<BdbEventT>* theDestination = 
01168                 theStore->collection( argv[3], (*(BdbEventT*)0) );
01169             if ( 0 == theDestination ) {
01170 
01171                 // All checked ok - move the source to the destination.
01172                 // Ensure that the clustering is configured for the event
01173                 // store since we are possibly about to create new tree
01174                 // nodes.
01175                 theStore->configureClustering( );
01176 
01177                 status = theStore->moveCollection( theSource, argv[3] );
01178                 if ( BdbcSuccess == status ) {
01179                     interp->appendResult( "Collection " );
01180                     interp->appendResult( argv[2] );
01181                     interp->appendResult( " moved to " );
01182                     interp->appendResult( argv[3] );
01183                     interp->appendResult( "\n" );
01184                 } else {
01185                     cout << "Error: Unable to move collection " << argv[3] << endl;
01186                 }
01187             } else {
01188                 cout << "Error: Collection " << argv[3] << " already exists" << endl;
01189             }
01190         } else {
01191             cout << "Error: Collection " << argv[2] << " doesn't exist" << endl;
01192         }
01193 
01194         // Restore the previous transaction state, forcing a commit if necessary
01195         theStore->change( theMode, d_True );
01196         theStore->deactivate( );
01197     } else {
01198         cout << "Error: no collection specified - request ignored" << endl;
01199         target( )->setError( "invalid command name" );
01200     }
01201     return result;
01202 }
01203 
01204 int
01205 BdbCollectionCommand::precreateCleanupHandler( int argc, char* argv[] )
01206 {
01207     BdbStatus status = BdbcSuccess;
01208     AppFramework* theFrame = target( )->framework( );
01209     int result = AbsInterp::OK;
01210 
01211     // Ensure the event store is initialized
01212     initialize( );
01213 
01214     // Cleanup following Collection precreation
01215     BdbEventStore* theStore = BdbEventStore::instance( );
01216     theStore->activate();
01217     status = BdbEvsClusteringHint::returnCollectedConts( );
01218     theStore->deactivate();
01219     if ( BdbcSuccess != status ) {
01220         cout << "Error: Bad status from BdbEvsClusteringHint::returnCollectedConts" << endl;
01221         target( )->setError( "bad command status" );
01222     }
01223     return result;
01224 }
01225 
01226 int
01227 BdbCollectionCommand::removeHandler( int argc, char* argv[] )
01228 {
01229     BdbEventStore* theStore = BdbEventStore::instance( );
01230     BdbStatus status;
01231     AppFramework* theFrame = target( )->framework( );
01232 
01233     AbsInterp* interp = AbsInterp::theInterpreter();
01234     int result = AbsInterp::OK;
01235 
01236     if ( 4 <= argc ) {
01237 
01238         // Ensure the event store is initialized
01239         initialize( );
01240 
01241         // Start an update transaction if not already in one
01242         theStore->activate( );
01243         BdbMode theMode = theStore->change( BdbcUpdate );
01244 
01245         // Test whether the destination collection exists
01246         int last = argc - 1;
01247         BdbAbsCollectionT<BdbEventT>* theDestination = 
01248             theStore->collection( argv[last], (*(BdbEventT*)0) );
01249         if ( 0 != theDestination ) {
01250 
01251             // Loop over source collection(s). All arguments apart from
01252             // the last one are treated as source collections to be added
01253             // to the destination, which is the last one.
01254             int i = 1; 
01255             const int finished( last - 1 );
01256             while ( i != finished ) {
01257                 i++;
01258 
01259                 // Check to see if source collection can be added to
01260                 // destination and if so switch to federation containing
01261                 // source collection
01262                 const char* collName;
01263                 const char* collFed;
01264                 BdbModulesUtility::parseCollectionSpecifier( argv[i],
01265                                                              collName,
01266                                                              collFed );
01267                 if( 0 == collName ) {
01268                     cerr << "Error: Invalid specification of a collection \""
01269                          << argv[i] << "\"" << endl;
01270                     delete [] const_cast< char* >( collName );
01271                     delete [] const_cast< char* >( collFed );
01272                     continue;
01273                 }
01274 
01275                 status = theDestination->setFed( collFed );
01276                 delete [] const_cast< char* >( collFed );
01277                 if( BdbcSuccess != status ) {
01278                     cerr << "Error: Collection " << argv[i]
01279                          << " can not be removed from collection "
01280                          << argv[last] << endl;
01281                     delete [] const_cast< char* >( collName );
01282                     continue;
01283                 }
01284 
01285                 // Check whether the source collection exists
01286                 BdbAbsCollectionT<BdbEventT>* theSource = 
01287                     theStore->collection( collName, (*(BdbEventT*)0) );
01288                 delete [] const_cast< char* >( collName );
01289                 if ( 0 == theSource ) {
01290                     cerr << "Error: Collection " << argv[i] << " doesn't exist" << endl;
01291                     continue;
01292                 }
01293 
01294                 // Source and destination both exist. Is the source
01295                 // already contained within the destination?
01296                 if ( ! theDestination->containsCollection( *theSource, d_True ) ) {
01297                     cerr << "Error: Collection " << argv[i] << " is not contained by collection "
01298                          << argv[last] << endl;
01299                     continue;
01300                 }
01301 
01302                 // All checked ok - add the source to the destination
01303                 status = theDestination->removeCollection( *theSource );
01304                 if ( BdbcSuccess == status ) {
01305                     interp->appendResult( "Collection " );
01306                     interp->appendResult( argv[2] );
01307                     interp->appendResult( " removed from collection " );
01308                     interp->appendResult( argv[3] );
01309                     interp->appendResult( "\n" );
01310                 } else {
01311                     cout << "Error: Unable to remove collection "
01312                          << argv[i] << " to " << argv[last] << endl;
01313                 }
01314 
01315             }
01316 
01317             // Return to original federation
01318             theDestination->setFed();
01319         } else {
01320             cout << "Error: Collection " << argv[last] << " doesn't exist" << endl;
01321         }
01322 
01323         // Restore the previous transaction state, forcing a commit if
01324         // necessary
01325         theStore->change( theMode, d_True );
01326         theStore->deactivate( );
01327     } else {
01328         cout << "Error: no collection(s) specified - request ignored" << endl;
01329         target( )->setError( "invalid command name" );
01330     } 
01331     return result;
01332 }
01333 
01334 //      ------------------------
01335 //      -- Secondary Handlers --
01336 //      ------------------------
01337 
01338 void 
01339 BdbCollectionCommand::contentsCollHandler( const char* const theName, 
01340                                            BdbAbsCollectionT<BdbEventT>* theCollection, 
01341                                            int& stackDepth )
01342 {
01343     AbsInterp* interp = AbsInterp::theInterpreter();
01344     BdbStatus status;
01345     BdbEventStore* theStore = BdbEventStore::instance( );
01346     AppFramework* theFrame = target( )->framework( );
01347     BdbHandle(BdbCollectionP) aCollP;
01348     char charbuf[256];
01349     for ( int i=0; i < 2*stackDepth; i++ ) {
01350         charbuf[i] = ' ';
01351     }
01352     charbuf[2*stackDepth] = '\0';
01353     interp->appendResult( charbuf );
01354     d_Long oldWait = theStore->lockWait( );
01355     theStore->setLockWait( BdbcNoWait );
01356     aCollP = theCollection->persistent( );
01357     if ( BdbcSuccess == ( status = theStore->readAttempt( aCollP ) ) ) {
01358         interp->appendResult( theCollection->pathName( ) );
01359         if ( _listOID ) {
01360             interp->appendResult( " [" );
01361             interp->appendResult( aCollP.sprint( ) );
01362             interp->appendResult( "] " );
01363         }
01364         if ( _listEvents ) {
01365             interp->appendResult( ": " );
01366             sprintf( charbuf, "%d", theCollection->size( ) );
01367             interp->appendResult( charbuf );
01368             interp->appendResult( " events" );
01369             if ( _listOwned ) {
01370                 interp->appendResult( " [" );
01371                 sprintf( charbuf, "%d", theCollection->ownedSize( ) );
01372                 interp->appendResult( charbuf );
01373                 interp->appendResult( " owned]" );
01374             }
01375         }
01376         interp->appendResult( "\n" );
01377         if ( _listMeta ) {
01378             BdbMetaData meta;
01379             theCollection->metaData(meta);
01380             if ( ! meta.isNull( ) ) {
01381                 d_Long count;
01382                 int i;
01383                 // display bools
01384                 count = meta.numBools();
01385                 for ( i=0; i< count; i++ ) {
01386                     interp->appendResult(meta.getBoolKey(i));
01387                     d_Boolean value;
01388                     meta.getBool(value, i);
01389                     sprintf( charbuf, " == %d\n", value);
01390                     interp->appendResult(charbuf);
01391                 }
01392                 // display longs
01393                 count = meta.numLongs();
01394                 for ( i=0; i< count; i++ ) {
01395                     interp->appendResult(meta.getLongKey(i));
01396                     int value;
01397                     meta.getLong(value, i);
01398                     sprintf( charbuf, " == %d\n", value);
01399                     interp->appendResult(charbuf);
01400                 }
01401                 // display floats
01402                 count = meta.numFloats();
01403                 for ( i=0; i< count; i++ ) {
01404                     interp->appendResult(meta.getFloatKey(i));
01405                     d_Float value;
01406                     meta.getFloat(value, i);
01407                     sprintf( charbuf, " == %g\n", value);
01408                     interp->appendResult(charbuf);
01409                 }
01410                 // display strings
01411                 count = meta.numStrings();
01412                 for ( i=0; i< count; i++ ) {
01413                     interp->appendResult(meta.getStringKey(i));
01414                     const char* value;
01415                     value = meta.getString(i);
01416                     sprintf( charbuf, " == ");
01417                     interp->appendResult(" == ");
01418                     interp->appendResult(value);
01419                     interp->appendResult("\n");
01420                 }
01421             }
01422         }
01423         if ( ( _descend ) &&
01424              ( ! _listColl ) ) {
01425             BdbAbsCollectionT<BdbEventT>* aMember;
01426             BdbCollectionTCollTIterator theIter( *theCollection );
01427             while ( BdbcSuccess == theIter.next( aMember ) ) {
01428                 aCollP = aMember->persistent( );
01429                 if ( BdbcSuccess == ( status = theStore->readAttempt( aCollP ) ) ) {
01430                     if ( 0 != aMember->name( ) ) {
01431                         stackDepth++;
01432                         contentsCollHandler( aMember->pathName( ), aMember, stackDepth );
01433                         stackDepth--;
01434                     }
01435                 } else {
01436                     interp->appendResult( "?? [member locked - no information available]\n" );
01437                 }
01438             }
01439         }
01440         if ( _listColl ) {
01441             interp->appendResult( "Bridge Collection:  " );
01442             interp->appendResult( theName );
01443             interp->appendResult( " contains the following collections:\n" );
01444             BdbBridgeCollItemDesc theDesc;
01445             BdbCollTItemIterator<BdbEventT>* theIter =  theCollection->getCollItemIterator();
01446             while ( BdbcSuccess == theIter->next( theDesc  ) ) {
01447                 interp->appendResult( "\t" );
01448                 interp->appendResult( theDesc.collName() );
01449                 interp->appendResult( "@" );
01450                 interp->appendResult( theDesc.bootName() );
01451         
01452                 interp->appendResult( "\n" );
01453             }
01454             delete theIter;
01455         }
01456     }else {
01457         interp->appendResult( theName );
01458         interp->appendResult( ": [locked - no information available]\n" );
01459     }
01460     theStore->setLockWait( oldWait );
01461 }
01462 
01463 int
01464 BdbCollectionCommand::listAllHandler( )
01465 {
01466     AbsInterp* interp = AbsInterp::theInterpreter();
01467     int result = AbsInterp::OK;
01468     BdbTreeNode aNode;
01469     BdbEventStoreIterator evsIter;
01470     BdbStatus status;
01471     bool empty = true;
01472 
01473     while ( BdbcSuccess == ( status = evsIter.next( aNode ) ) ) {
01474         listNodeHandler( &aNode );
01475         empty = false;
01476     }
01477     if ( empty ) {
01478         AppFramework* theFrame = target( )->framework( );
01479         interp->appendResult( "Event Store empty - no collections exist\n" );
01480     }
01481     return result;
01482 }
01483 
01484 int
01485 BdbCollectionCommand::listLevelHandler( BdbDomain::AuthLevels theLevel,
01486                                         const char* const theName )
01487 {
01488     BdbEventStore* theStore = BdbEventStore::instance( );
01489     BdbTreeNode theNode;
01490     AbsInterp* interp = AbsInterp::theInterpreter();
01491     int result = AbsInterp::OK;
01492     AppFramework* theFrame = target( )->framework( );
01493 
01494     BdbStatus status = theStore->treeNode( theNode, theLevel, theName );
01495     if ( BdbcSuccess == status ) {
01496         listNodeHandler( &theNode );
01497     } else {
01498         interp->appendResult( BdbDomain::AuthLevelNames[theLevel] );
01499         if ( 0 != theName ) {
01500             interp->appendResult( "/" );
01501             interp->appendResult( theName );
01502         }
01503         interp->appendResult( " non-existent\n" );
01504     }
01505     return result;
01506 }
01507 
01508 int
01509 BdbCollectionCommand::listNodeHandler( const char* const theName )
01510 {
01511     BdbEventStore* theStore = BdbEventStore::instance( );
01512     BdbTreeNode theNode;
01513     int result = AbsInterp::ERROR;
01514 
01515     // First test whether the supplied name is in fact a collection
01516     BdbAbsCollectionT<BdbEventT>* theCollection = 
01517         theStore->collection( theName, (*(BdbEventT*)0) );
01518     if ( 0 != theCollection ) {
01519 
01520         // The supplied name is a collection
01521         int stackDepth = 0;
01522         contentsCollHandler( theName, theCollection, stackDepth );
01523                 result = AbsInterp::OK;
01524     } else {
01525 
01526         // The supplied name isn't a collection - assume it's a tree node
01527         BdbStatus status = theStore->treeNode( theNode, theName );
01528         if ( BdbcSuccess == status ) {
01529             result = listNodeHandler( &theNode );
01530         } else {
01531             cout << "Error: " << theName << " doesn't exist" << endl;
01532         }
01533     }
01534     return result;
01535 }
01536 
01537 int
01538 BdbCollectionCommand::listNodeHandler( BdbTreeNode* theNode )
01539 {
01540     BdbEventStore* theStore = BdbEventStore::instance( );
01541     BdbHandleAny anItemP;
01542     BdbHandle(BdbCollectionP) aCollP;
01543     BdbHandle(BdbTreeNodeP) theNodeP = theNode->persistent( );
01544     BdbTreeNode aNode;
01545     const char* nodeName;
01546     BdbStatus status;
01547     AbsInterp* interp = AbsInterp::theInterpreter();
01548     int result = AbsInterp::OK;
01549     d_Boolean first = d_True;
01550     d_Boolean wasBad;
01551     d_Boolean wasFixed;
01552     ooTypeNumber theType = ooTypeN( BdbCollectionP );
01553     AppFramework* theFrame = target( )->framework( );
01554     BdbMode oldMode = theStore->mode( );
01555 
01556     // Force a transaction commit if the maximum node count has been exceeded
01557     _nodeCount++;
01558     if ( _nodeCount > _maxNodeCount ) {
01559         theStore->change( oldMode, d_True );
01560         _nodeCount = 0;
01561     }
01562 
01563     // Iterate over the collection contents of the node
01564     BdbTreeNodeSimpleIterator collIter( *theNode );
01565     if ( collIter.count( ) > 0 ) {
01566 
01567         // Disable lock waiting while examining the collections in this node
01568         d_Long oldWait = theStore->lockWait( );
01569         theStore->setLockWait( BdbcNoWait );
01570         while ( BdbcSuccess == ( status = collIter.next( anItemP ) ) ) {
01571             if ( first ) {
01572                 nodeName = theNode->pathName( );
01573                 if ( ! _oneLine ) {
01574                     interp->appendResult( "\n" );
01575                     interp->appendResult( nodeName );
01576                     interp->appendResult( "\n" );
01577                     first = d_False;
01578                 }
01579             }
01580 
01581             // Attempt to open the collection for reading
01582             if ( BdbcSuccess == ( status = theStore->readAttempt( anItemP ) ) ) {
01583 
01584                 // Read attempt successful - Check that this really is a collection
01585                 if ( anItemP->ooIsKindOf( theType ) ) {
01586 
01587                     // This is a collection
01588                     aCollP   = (BdbHandle(BdbCollectionP)&) anItemP;
01589                     wasBad   = d_False;
01590                     wasFixed = d_False;
01591                     if ( _checkOwner ) {
01592 
01593                         // Check for ownership consistency
01594                         BdbHandle(BdbTreeNodeP) ownerNodeP;
01595                         status = aCollP->treeNode( ownerNodeP );
01596                         if ( theNodeP != ownerNodeP ) {
01597 
01598                             // Ownership is inconsistent
01599                             wasBad = d_True;
01600                             if ( _fixupOwner ) {
01601 
01602                                 // Collection has a bad owner pointer and should be fixed
01603                                 // Promote the transaction to update mode if necessary
01604                                 theStore->change( BdbcUpdate, d_False );
01605                                 theStore->setLockWait( BdbcWait );
01606                                 aCollP->setTreeNode( theNodeP );
01607                                 theStore->setLockWait( BdbcNoWait );
01608                                 wasFixed = d_True;
01609                             }
01610                         }
01611                     }
01612                     if ( ( ! _badOnly ) || wasBad ) {
01613                         interp->appendResult( "    " );
01614                         if ( _oneLine ) {
01615                             interp->appendResult( nodeName );
01616                         }
01617                         interp->appendResult( collIter.name( ) );
01618                                                 if ( _listOID ) {
01619                                                 interp->appendResult( " [" );
01620                                         interp->appendResult( aCollP.sprint( ) );
01621                                         interp->appendResult( "] " );
01622                                         }
01623                         if ( _listEvents ) {
01624                             interp->appendResult( ": " );
01625                             char charbuf[256];
01626                             sprintf( charbuf, "%d", aCollP->size( ) );
01627                             interp->appendResult( charbuf );
01628                             interp->appendResult( " events" );
01629                                                         if ( _listOwned ) {
01630                                                 interp->appendResult( " [" );
01631                                                 sprintf( charbuf, "%d", aCollP->ownedSize( ) );
01632                                                 interp->appendResult( charbuf );
01633                                                 interp->appendResult( " owned]" );
01634                                                 }
01635                                                 }
01636                         if ( wasBad ) {
01637                             interp->appendResult( " - bad owner" );
01638                             if ( wasFixed ) {
01639                                 interp->appendResult( " - fixed" );
01640                             }
01641                         }
01642                         interp->appendResult( "\n" );
01643                     }
01644                 }
01645             } else {
01646                 interp->appendResult( "    " );
01647                 if ( _oneLine ) {
01648                     interp->appendResult( nodeName );
01649                 }
01650                 interp->appendResult( collIter.name( ) );
01651                 interp->appendResult( ": [locked - no information available]\n" );
01652             }
01653         }
01654         theStore->setLockWait( oldWait );
01655     }
01656 
01657     // Restore the original transaction mode if necessary
01658     theStore->change( oldMode, d_False );
01659 
01660     if ( _descend ) {
01661 
01662         // Descend flag set - Now iterate over child tree nodes
01663         BdbTreeNodeSimpleIterator nodeIter( *theNode );
01664         while ( BdbcSuccess == ( status = nodeIter.next( anItemP ) ) ) {
01665             if ( BdbcSuccess == ( status = theStore->readAttempt( anItemP ) ) ) {
01666                 if ( BdbTreeNodeP::isTreeNode( anItemP ) ) {
01667                     aNode.setPersistent( (BdbHandle(BdbTreeNodeP)&) anItemP );
01668                     result = listNodeHandler( &aNode );
01669                 }
01670             }
01671         }
01672     }
01673     return result;
01674 }
01675 
01676 void
01677 BdbCollectionCommand::initialize( )
01678 {
01679     BdbEventStore* theStore = BdbEventStore::instance( );
01680     // If clustering already configured this does nothing
01681     theStore->configureClustering( );
01682 
01683     if ( ! _isInitialized ) {
01684 
01685         // Ensure that data is readable only by users who belong to the
01686         // eventstore domain
01687         theStore->activate( );
01688         BdbMode oldMode = theStore->change( BdbcRead );
01689         if ( ! theStore->isAccessAllowed( theStore->userName( ) ) ) {
01690             ErrMsg( fatal ) << "**************************************************" << endl
01691                             << "User " << theStore->userName( ) 
01692                             << ", you are not a registered user of the "            << endl
01693                             << "event store for this federation. Access is denied." << endl
01694                             << "**************************************************" << endmsg;
01695             theStore->commit( );
01696             ::abort( );
01697         }
01698         theStore->change( oldMode );
01699         theStore->deactivate( );
01700         _isInitialized = d_True;
01701     }
01702 }

 


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

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