![]() |
|
|
Bdb packages | Design docs | Source docs | Guidelines | Recent releases |
|
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