![]() |
|
|
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 /BdbDistTools/BdbDbImport.cc
Go to the documentation of this file.00001 //-------------------------------------------------------------------------- 00002 // File and Version Information: 00003 // $Id: BdbDbImport.cc,v 1.32.2.2 2002/07/23 20:19:01 objysrv Exp $ 00004 // 00005 // Description: 00006 // BdbDbImport copies and attaches to the federation databases 00007 // imported by one of the "bdbXxxZzzz" scripts. 00008 // 00009 // Usage 00010 // BdbDbImport [options] 00011 // 00012 // Options 00013 // -[no]checksize: enable/disable the file size checking (def: enabled) 00014 // -delay <mn>: delay to wait to attach the databases 00015 // -forced: force the attach of the database bypassing ooattachdb 00016 // -group <name>: move the databases to this group (def: not changed) 00017 // -ignore: ignore the errors and try to continue (def: stop) 00018 // -lftp: use FTP to locally copy the files 00019 // -lock: create HPSS lock file 00020 // -quiet: don't print anything 00021 // -[no]read: turn the files read-only 00022 // -replace: replace existing bases and collections 00023 // -verbose: print all the possible information 00024 // -[no]wait: try to lock the database before replacing it 00025 // -bdb{xfr,sfcp,scp,bbcp}: use bdb* family to locally copy the files 00026 // -xfr: use ooss_xfr to locally copy the files 00027 // -fget: use ooss_fget to locally copy files 00028 // -cmdpath : use this path to copy command 00029 // -remapdbid : assign a db new dbid from target's local range and change it's name accordingly. the argument is a source federation's FD_NUMBER. 00030 // 00031 // Commands 00032 // BdbDbImport reads commands to execute from the standard input 00033 // The supported commands are: 00034 // IMPORT <db-sysname> <dbid> <filename> <subdir> <fullsize> 00035 // COLLECTION <collection> <oid> 00036 // 00037 // By default, the databases are turned in write mode for an import 00038 // and in read-only mode for a link 00039 // 00040 // Environment: 00041 // Software developed for the BaBar Detector at the SLAC B-Factory. 00042 // 00043 // Author List: 00044 // Jean-Noel Albert First author 00045 // 00046 // Modification List: 00047 // Jna July 1999 Remove the "LINK" command (not used) 00048 // Attach the database using "BdbDistInstall" 00049 // Support for the Large Files 00050 // DB March 2000 Add option -lock to create HPSS lock files 00051 // Artem July 2000 Add opt -printtdfline to print some more info 00052 // 00053 // Copyright Information 00054 // Copyright (C) 1999-2000 00055 // 00056 //------------------------------------------------------------------------ 00057 00058 #define HAS_UNREGISTERDB 1 00059 00060 //----------------------- 00061 // BaBar Headers -- 00062 //----------------------- 00063 #include "BaBar/BaBar.hh" 00064 #include "BdbUtil/Bdb.hh" 00065 #include "BdbUtil/BdbTString.hh" 00066 #include "BdbEventStore/BdbEventStore.hh" 00067 #include "BdbAccess/BdbFSMgr.hh" 00068 // #include "BdbEventStore/BdbDbName.hh" 00069 #include "BdbTrees/BdbDbRegistrator.hh" 00070 #include "BdbTrees/BdbTreeNode.hh" 00071 #include "BdbAccess/BdbDbTreeSingleton.hh" 00072 #include "BdbAccess/BdbDbInfo.hh" 00073 #include "BdbTrees/BdbTreeAccess.hh" 00074 #include "BdbDistTools/BdbDistDatabase.hh" 00075 #include "BdbDistTools/BdbDistFile.hh" 00076 #include "BdbDistTools/BdbDistMessage.hh" 00077 #include "BdbEvent/BdbEvent_001.hh" 00078 #include "BdbEventStore/BdbAbsCollectionT.hh" 00079 #include "BdbApplication/BdbDomain.hh" 00080 #include "BdbDistribution/BdbDbIdManager.hh" 00081 //--------------- 00082 // C++ Headers -- 00083 //--------------- 00084 #include <iostream.h> 00085 00086 //------------ 00087 // C Header -- 00088 //------------ 00089 00090 extern "C" { 00091 #include <stdio.h> 00092 #include <stdlib.h> 00093 #include <unistd.h> 00094 #include <strings.h> 00095 #include <sys/types.h> 00096 #include <sys/stat.h> 00097 #include <sys/wait.h> 00098 #include <grp.h> 00099 #include <assert.h> 00100 } 00101 00102 //----------------------------------------------------------------------- 00103 // Local Macros, Typedefs, Structures, Unions and Forward Declarations -- 00104 //----------------------------------------------------------------------- 00105 #define SUCCESS 0 00106 #define ERROR 1 00107 00108 //--------------- 00109 // Local flags -- 00110 //--------------- 00111 static d_Boolean checkonlyFlag = d_False; 00112 static d_Boolean checkSizeFlag = d_True; 00113 static d_Boolean forcedFlag = d_False; 00114 static d_Boolean ignoreFlag = d_False; 00115 static d_Boolean lftpFlag = d_False; 00116 static d_Boolean bdbxfrFlag = d_False; 00117 static d_Boolean bdbsfcpFlag = d_False; 00118 static d_Boolean bdbbbcpFlag = d_False; 00119 static d_Boolean bdbscpFlag = d_False; 00120 static d_Boolean xfrFlag = d_False; 00121 static d_Boolean fgetFlag = d_False; 00122 static char* cmdpath = 0; 00123 static char* remapDbid = 0; 00124 static d_Boolean replaceFlag = d_False; 00125 static d_Boolean quietFlag = d_False; 00126 static enum {Default, ReadOnly, ReadWrite} readFlag = Default; 00127 static d_Boolean verboseFlag = d_False; 00128 static char* groupname = 0; 00129 static int waitDelay = -1; // No limit 00130 static d_Boolean waitFlag = d_False; 00131 static d_Boolean lockFlag = d_False; // By default do not create HPSS lock file 00132 static d_Boolean printtdflineFlag = d_False; // if true - print tdf line for each collections. 00133 00134 //------------------- 00135 // Local variables -- 00136 //------------------- 00137 static BdbEventStore* estore; 00138 00139 //-------------------- 00140 // Working routines -- 00141 //-------------------- 00142 static inline void printtdfline (const char* name, const char* collid, 00143 const int events, const int select) 00144 { 00145 if (printtdflineFlag) { 00146 cout << "COLLECTION " << name << " COLLID " << collid+1 << 00147 " EVENTS " << events << " SELECT " << select << endl; 00148 } 00149 } 00150 00151 static inline void message (const char* s0=0, const char* s1=0, 00152 const char* s2=0, const char* s3=0, 00153 const char* s4=0, const char* s5=0, 00154 const char* s6=0, const char* s7=0, 00155 const char* s8=0, const char* s9=0) 00156 { 00157 BdbDistMessage::message (s0, s1, s2, s3, s4, s5, s6, s7, s8, s9); 00158 } 00159 00160 static inline void verbose (const char* s0=0, const char* s1=0, 00161 const char* s2=0, const char* s3=0, 00162 const char* s4=0, const char* s5=0, 00163 const char* s6=0, const char* s7=0, 00164 const char* s8=0, const char* s9=0, 00165 const char* sa=0, const char* sb=0) 00166 { 00167 BdbDistMessage::verbose (s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sa, sb); 00168 } 00169 00170 static inline void warning (const char* s0=0, const char* s1=0, 00171 const char* s2=0, const char* s3=0, 00172 const char* s4=0, const char* s5=0, 00173 const char* s6=0, const char* s7=0, 00174 const char* s8=0, const char* s9=0, 00175 const char* sa=0, const char* sb=0) 00176 { 00177 BdbDistMessage::warning (s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sa, sb); 00178 } 00179 00180 static inline void fail (const char* s0=0, const char* s1=0, 00181 const char* s2=0, const char* s3=0, 00182 const char* s4=0, const char* s5=0, 00183 const char* s6=0, const char* s7=0, 00184 const char* s8=0, const char* s9=0, 00185 const char* sa=0, const char* sb=0) 00186 { 00187 BdbDistMessage::warning (s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sa, sb); 00188 exit (ERROR); 00189 } 00190 00191 static inline const char* itoa (long i) { 00192 return BdbDistMessage::itoa (i); 00193 } 00194 00195 // Define the wait mode for the following operations 00196 static void setWaitMode() 00197 { 00198 if (!waitFlag) { 00199 BdbDomain::activeInstance()->setLockWait(BdbcNoWait); 00200 } 00201 else if (waitDelay < 0) { 00202 BdbDomain::activeInstance()->setLockWait(BdbcWait); 00203 } 00204 else { 00205 BdbDomain::activeInstance()->setLockWait(waitDelay); 00206 } 00207 } 00208 00209 // Send the command to execute to the shell 00210 // Signal the error and stop the application, 00211 // if the "checkSucess" flag is set. 00212 // 00213 // Note: the current transaction is automatically commited 00214 // at the beginning of the operation and restarted after 00215 // to avoid to maintain long locks on the federation. 00216 static int execute (const char* command, 00217 const d_Boolean checkSuccess = d_True, 00218 const int success = 0) 00219 { 00220 verbose (command); 00221 00222 estore->commit(); 00223 00224 // CAUTION: Don't use: int stt = WEXITSTATUS(system(command)); 00225 // On OSF, the command is executed twice 00226 int stt = system(command); stt = WEXITSTATUS(stt); 00227 if (checkSuccess && (success != stt)) { 00228 warning ("Command failed (", itoa(stt), "): ", command); 00229 exit(stt); 00230 } 00231 00232 estore->startUpdate(); 00233 setWaitMode(); 00234 return stt; 00235 } 00236 00237 // Import a given file as a database 00238 // The file is copied to the directory designated by FSMgr 00239 // (the directory is created if needed) and attached to the federation 00240 // using "BdbDistInstal". The file is registered in the BaBar book keeping. 00241 // If the PUD daemon is not used, the database group is changed to 00242 // <groupname> [by default "bfactory", then BaBar standard for the AMS server) 00243 // and the group protection is set to "rw". 00244 static void importDb(const char* original_dbname, 00245 const char* original_oid, 00246 const char* inpfile, 00247 const char* subdir, 00248 const char* original_filename, 00249 float fsize) 00250 { 00251 // Load the state of a special environment variable which is used 00252 // to modify a way the Conditions databases are being imported. 00253 // 00254 // If this variable "BDBCOND_RENAME_LINK_DB" is set then the following 00255 // database names: 00256 // 00257 // con_xxx_Link 00258 // 00259 // are renamed into: 00260 // 00261 // con_xxx_Link_<OID> 00262 // 00263 // Where: <OID> is the number (Object Id) of the database in a federation. 00264 // 00265 // If the database already has the <OID> attached then its name does not change. 00266 // This rule allows to avoid the names like: 00267 // 00268 // con_xxx_Link_<OID>_<OID>... 00269 00270 char* oid; 00271 char* dbname; 00272 char* filename; 00273 00274 verbose("Will import original database ", original_dbname, " dbid ", original_oid, " impfile ", inpfile, " filename ", original_filename,")"); 00275 00276 // Start a transaction 00277 estore->startUpdate(); 00278 setWaitMode(); 00279 00280 if (0 != getenv( "BDBCOND_RENAME_LINK_DB" )){ 00281 00282 verbose("Will rename con link db"); 00283 00284 oid = new char[ strlen( original_oid ) + 1 ]; 00285 strcpy( oid, original_oid ); 00286 00287 const char link_string[5] = "Link"; 00288 const char *linkTestStr; 00289 const char *oidTestStr; 00290 00291 linkTestStr = strstr(original_dbname,link_string); 00292 oidTestStr = strstr(original_dbname,oid); 00293 00294 if ((0 != linkTestStr) && (0 == oidTestStr)) { 00295 // message (" now db is ", original_dbname); 00296 00297 dbname = new char[ strlen( original_dbname ) 00298 + 1 00299 + strlen( oid ) 00300 + 1 ]; 00301 strcpy( dbname, original_dbname ); 00302 strcat( dbname, "_" ); 00303 strcat( dbname, oid ); 00304 00305 // Append "_<OID>" by the end of the file name if this name 00306 // does not have a file extention or 00307 // insert "_<OID>" before the file extention. 00308 00309 filename = new char[ strlen( original_filename ) 00310 + 1 00311 + strlen( oid ) 00312 + 1 ]; 00313 strcpy( filename, original_filename ); 00314 00315 char* dot = rindex( filename, '.' ); 00316 if( dot == (const char*) 0 ) { 00317 strcat( filename, "_" ); 00318 strcat( filename, oid ); 00319 } else { 00320 *dot = '\0'; // That would trancate the filename. 00321 strcat( filename, "_" ); 00322 strcat( filename, oid ); 00323 const char* original_dot = rindex( original_filename, '.' ); 00324 strcat( filename, original_dot ); 00325 } 00326 } else { 00327 dbname = new char[ strlen( original_dbname ) + 1 ]; 00328 strcpy( dbname, original_dbname ); 00329 00330 filename = new char[ strlen( original_filename ) + 1 ]; 00331 strcpy( filename, original_filename ); 00332 } 00333 } 00334 else if ( remapDbid != 0) { 00335 verbose("Will remap dbids"); 00336 //convert old database name to new name. 00337 //just a hook by now - until decide upon a convention 00338 dbname = new char[ strlen( original_dbname ) 00339 + 1 00340 + strlen( remapDbid ) 00341 + 1 ]; 00342 strcpy( dbname, original_dbname ); 00343 strcat( dbname, "_" ); 00344 strcat( dbname, remapDbid ); 00345 00346 filename = new char[ strlen( original_filename ) 00347 + 1 00348 + strlen( remapDbid ) 00349 + 1 ]; 00350 strcpy( filename, original_filename ); 00351 00352 char* dot = rindex( filename, '.' ); 00353 if( dot == (const char*) 0 ) { 00354 strcat( filename, "_" ); 00355 strcat( filename, remapDbid ); 00356 } else { 00357 *dot = '\0'; // That would trancate the filename. 00358 strcat( filename, "_" ); 00359 strcat( filename, remapDbid ); 00360 const char* original_dot = rindex( original_filename, '.' ); 00361 strcat( filename, original_dot ); 00362 } 00363 00364 message ("New dbname is ", dbname); 00365 00366 //check if it already exists in the federation 00367 BdbDistDatabase db(dbname); 00368 d_Boolean dbExist = db.isDbExist(); 00369 if (dbExist) { 00370 //get it's own dbid and filepath 00371 int dbid = db.dbid(); 00372 oid = new char[ 5 + 1 ]; 00373 // strcpy( oid, 00374 sprintf(oid,"%d",dbid); 00375 00376 const char* oldfilename = db.fileName().data(); 00377 filename = new char[strlen(oldfilename)+1]; 00378 strcpy(filename, oldfilename); 00379 00380 verbose("Db exists, will keep old id ", oid, 00381 " and filepath ", filename); 00382 } 00383 else { 00384 //if no - get new dbid 00385 BdbHandle( ooFDObj ) fdH ; 00386 ooTrans gTransaction ; 00387 00388 // Start a federation transaction 00389 // gTransaction.start() ; 00390 00391 if( oocError == fdH.open( 0 , oocUpdate , oocFalse ) ) { 00392 cout << "Failed to open Federated Database." << endl ; 00393 return; 00394 } 00395 const char* domain( "evs" ) ; 00396 BdbHandle( BdbDbIdManager ) manager ; 00397 manager = BdbDbIdManager::localInstance( fdH , domain ) ; 00398 00399 BdbDbId dbid = manager->issueNextDbId(); 00400 00401 // gTransaction.commit() ; 00402 00403 cout << "new dbid " << dbid <<endl; 00404 00405 oid = new char[ 5 + 1 ]; 00406 // strcpy( oid, 00407 sprintf(oid,"%d",dbid); 00408 00409 message (" now id is ", oid); 00410 00411 } 00412 } 00413 else { 00414 00415 verbose("Will import as is"); 00416 00417 oid = new char[ strlen( original_oid ) + 1 ]; 00418 strcpy( oid, original_oid ); 00419 00420 dbname = new char[ strlen( original_dbname ) + 1 ]; 00421 strcpy( dbname, original_dbname ); 00422 00423 filename = new char[ strlen( original_filename ) + 1 ]; 00424 strcpy( filename, original_filename ); 00425 00426 } 00427 00428 #if defined(BABAR_LARGEFILE) && defined(_FILE_OFFSET_BITS) 00429 /* Check if the includes are called in the correct order */ 00430 assert((sizeof(off_t)*8) == _FILE_OFFSET_BITS); 00431 #endif 00432 BdbTString cmd; 00433 BdbStatus status; 00434 00435 // Standard log 00436 message("Importing database ", dbname, " dbid ", oid, " impfile ", inpfile, " filename ", filename,")"); 00437 00438 // Check if the input inpfile exist 00439 if (0 != access(inpfile, F_OK)) { 00440 warning ("File ", inpfile, " does not exist"); 00441 delete dbname; 00442 delete filename; 00443 return; 00444 } 00445 00446 // Convert the object id to a base number 00447 int dbid = atoi(oid); 00448 if (dbid == 0) { 00449 warning ("Invalid Database id (", oid, ")"); 00450 delete dbname; 00451 delete filename; 00452 return; 00453 } 00454 00455 // Start a transaction 00456 // estore->startUpdate(); 00457 // setWaitMode(); 00458 00459 // Check if the database exists 00460 // If yes, and if the "replace" flag is not set, 00461 // this database can't be superseded... 00462 BdbDistDatabase db (dbname); 00463 d_Boolean dbExist = db.isDbExist(); 00464 if (dbExist && !replaceFlag) 00465 fail("Database ", dbname, " already exists - not superseded"); 00466 00467 // Autorization level 00468 if (!db.isAuthorized()) 00469 fail("Not autorized to manage the database ", dbname); 00470 00471 // Create a FS Manager, to execute the import operations 00472 // (Note: can't test return status: if no ASCII file loaded, return error) 00473 BdbFSMgr fsmgr; 00474 fsmgr.rebuildFSInfo(db.domainName(), db.authLevelName(), db.userGroupName(), 00475 db.componentName()); 00476 00477 // Name of the directory where the file will be copied 00478 BdbTString outdir = BdbTString(fsmgr.baseDir(), "/", subdir); 00479 00480 // Name of the copied file 00481 BdbTString outfile = BdbTString(outdir, "/", filename); 00482 BdbTString outfile2 = outfile; 00483 00484 // Check if the target directory exists 00485 // Create it if needed 00486 if (BdbcSuccess != fsmgr.checkExist(outdir)) { 00487 verbose("Creating target directory ", outdir); 00488 if (BdbcSuccess != fsmgr.mkDir(outdir)) 00489 fail("Error creating directory: ", outdir); 00490 00491 // If the PUD daemon is not used, the group and protection 00492 // of the directories must be changed to <groupname> (def: "bfactory) and "g:rw" 00493 if (fsmgr.daemonDisabled()) { 00494 // Change the protection of the directory 00495 cmd = "chmod -R g+rw " + outdir; 00496 execute(cmd); 00497 00498 // Change the group of the directory 00499 if (groupname != 0) { 00500 cmd = BdbTString("chgrp ", groupname, " ", outdir); 00501 execute(cmd); 00502 } 00503 } 00504 } 00505 00506 // Copy the inpfile 00507 // If the database already exists, the imported file is copied as "bdbimp" 00508 // then will be replaced by the BdbDistInstall tool to the correct one 00509 // under a lock protection 00510 if (dbExist && db.isFileExist()) 00511 outfile += "imp"; 00512 00513 cmd = "BdbDistCopy -replace"; 00514 if (verboseFlag) 00515 cmd += " -verbose"; 00516 if (lftpFlag) 00517 cmd += " -lftp"; 00518 else if (bdbxfrFlag) 00519 cmd += " -bdbxfr"; 00520 else if (bdbsfcpFlag) 00521 cmd += " -bdbsfcp"; 00522 else if (bdbbbcpFlag) 00523 cmd += " -bdbbbcp"; 00524 else if (bdbscpFlag) 00525 cmd += " -bdbscp"; 00526 else if (xfrFlag) 00527 cmd += " -xfr"; 00528 else if (fgetFlag) 00529 cmd += " -fget"; 00530 00531 cmd += " "; 00532 if (cmdpath) { cmd += "-cmdpath " ; cmd += cmdpath; } 00533 00534 cmd += " "; cmd += inpfile; 00535 cmd += " "; cmd += fsmgr.host(); cmd += ":" + outfile; 00536 verbose("Copying ", inpfile, " to ", outfile); 00537 execute(cmd); 00538 00539 // Create HPSS lock file 00540 00541 if (!lftpFlag && lockFlag) { 00542 verbose("Creating lock file ",cmd); 00543 cmd = "/usr/etc/ooss/ooss_Xeq mk "; 00544 cmd += outfile2; 00545 execute(cmd); 00546 } 00547 00548 // Attach the file 00549 cmd = "BdbDistInstall"; 00550 if (verboseFlag) 00551 cmd += " -verbose"; 00552 if (!waitFlag) 00553 cmd += " -nowait"; 00554 else if (waitDelay < 0) 00555 cmd += " -wait"; 00556 else 00557 cmd += " -wait -delay " + BdbTString(waitDelay); 00558 if (ReadOnly == readFlag) 00559 cmd += " -read"; 00560 if (0 != groupname) { 00561 cmd += " -group "; 00562 cmd += groupname; 00563 } 00564 if (forcedFlag) 00565 cmd += " -forced"; // Bypass "ooattachdb" 00566 00567 cmd += BdbTString(" -db ", dbname, " -id ", oid, 00568 " -host ", fsmgr.host(), 00569 " -filepath ", outfile); 00570 00571 verbose("Attaching ", dbname); 00572 int stt = execute(cmd, d_False); 00573 if (0 != stt) { 00574 warning ("Command failed (", itoa(stt), "): ", cmd); 00575 estore->abort(); 00576 exit(stt); 00577 } 00578 00579 // Done 00580 estore->commit(); 00581 00582 delete dbname; 00583 delete filename; 00584 } 00585 00586 // Fix the reference between a collection and its tree node parent. 00587 // The collection must exist 00588 // This is to fix a problem in previous imports 00589 static void fixTreeNode(char* name) 00590 { 00591 message("Fixing tree node collection ", name); 00592 00593 // Start a transaction 00594 estore->startUpdate(); 00595 setWaitMode(); 00596 00597 // Check if the collection exists 00598 BdbAbsCollectionT<BdbEventT>* coll; 00599 BdbHandle(BdbCollectionP) collH; 00600 BdbRef(BdbCollectionP) collR; 00601 00602 coll = estore->collection(name, (*(BdbEventT*)0)); 00603 if (0 == coll) { 00604 estore->abort(); 00605 fail("No such collection ", name); 00606 } 00607 00608 // Get the collection handle 00609 collH = coll->persistent(); 00610 00611 // Check for the tree node root 00612 char* treepath = name; 00613 char* collnode = strrchr(treepath, '/'); 00614 if (collnode == NULL) { 00615 warning ("Invalid collection path: ", name); 00616 return; 00617 } 00618 *collnode++ = '\0'; 00619 00620 BdbTreeNode node; 00621 if (BdbcSuccess != node.moveTo(treepath)) { 00622 estore->abort(); 00623 fail("No such tree node path ", treepath); 00624 } 00625 00626 // Replace the collection tree node, 00627 // if it is different of the current one 00628 BdbHandle(BdbTreeNodeP) nodeP; 00629 if (BdbcSuccess != collH->treeNode(nodeP)) 00630 fail("Internal error - can't get collection tree node"); 00631 00632 if (node.persistent() == nodeP) 00633 message("Collection tree node already fixed"); 00634 else { 00635 message("Fixing collection tree node"); 00636 nodeP = node.persistent(); 00637 collH->setTreeNode(nodeP); 00638 } 00639 00640 // Done 00641 estore->commit(); 00642 } 00643 00644 // Attach a collection 00645 // If the collection already exists with a different OID 00646 // this existin collection is deleted if the "replace" flag is set, 00647 // else, an error is signaled 00648 static void attachCollection(char* name, char* oid) 00649 { 00650 message("Attaching collection ", name); 00651 00652 // Parse the OID, remove the separator ("-") and read the numbers 00653 char* sep; 00654 while ((sep = strchr(oid, '-')) != 0) 00655 *sep = ' '; 00656 00657 int dbid, contid, pageid, slotid; 00658 if (sscanf(oid, "%d %d %d %d", &dbid, &contid, &pageid, &slotid) != 4) { 00659 warning ("Invalid collection id: ", oid); 00660 return; 00661 } 00662 00663 // Start a transaction 00664 estore->startUpdate(); 00665 setWaitMode(); 00666 00667 // Check if the collection reference is valid 00668 // (ie: check if the corresponding database exists) 00669 BdbRef(BdbCollectionP) collR; 00670 collR.set_DB(dbid); // Create a dummy reference for this 00671 collR.set_OC(contid); 00672 collR.set_page(pageid); 00673 collR.set_slot(slotid); 00674 if (!collR.isValid()) { 00675 warning ("Invalid collection reference: ", 00676 itoa(dbid), "-", itoa(contid), "-", 00677 itoa(pageid), "-", itoa(slotid), " (", name, ")"); 00678 return; 00679 } 00680 00681 BdbHandle(BdbCollectionP) collH; 00682 collH = collR; 00683 00684 // Check if the collection exists 00685 // If yes, and if the collection has the same "oid", it's OK 00686 // else, if the "replace" flag is not set, this is an error 00687 BdbAbsCollectionT<BdbEventT>* coll; 00688 char collid[100]; 00689 int size; 00690 00691 coll = estore->collection(name, (*(BdbEventT*)0)); 00692 if (0 != coll) { 00693 collH = coll->persistent(); 00694 collR = collH; 00695 00696 coll->persistent().sprint(collid); 00697 size = coll->size(); 00698 00699 // Check the collection OID 00700 if (collR.get_DB() == dbid && collR.get_OC() == contid && 00701 collR.get_page() == pageid && collR.get_slot() == slotid) { 00702 // Same id. nothing to do 00703 message("Collection ", name, " already exists with the same OID"); 00704 printtdfline(name, collid, size, 0); 00705 estore->commit(); 00706 00707 // Fix the tree node reference 00708 if (! replaceFlag) 00709 fixTreeNode(name); 00710 00711 return; 00712 } 00713 // Different id; "replace" not specified; 00714 // It's an error 00715 if (! replaceFlag) 00716 fail("Collection ", name, " already exist with a diff. OID"); 00717 00718 // Delete the collection 00719 verbose("Removing obsolete collection ", name, " (diff. OID)"); 00720 if (BdbcSuccess != estore->removeCollection(coll)) 00721 fail("Failed to remove existing collection ", name); 00722 } 00723 00724 // Check for the tree node root, or create it 00725 char* treepath = name; 00726 char* collnode = strrchr(treepath, '/'); 00727 if (collnode == NULL) { 00728 warning ("Invalid collection path: ", name); 00729 return; 00730 } 00731 *collnode++ = '\0'; 00732 00733 BdbTreeNode node; 00734 if (BdbcSuccess != node.moveTo(treepath)) { 00735 verbose("Creating tree node path ", treepath); 00736 00737 // Set up the autorization level 00738 if (BdbcSuccess != estore->BdbDomain::setAuthLevel(treepath)) 00739 fail("No privilege"); 00740 00741 if (BdbcSuccess != node.makeTo(treepath)) 00742 fail("Failed to create the tree node ", treepath); 00743 } 00744 00745 // Attaching the collection to this tree node 00746 BdbTreeAccess< BdbCollectionP > accessor; 00747 verbose("Attaching collection ", collnode); 00748 if (BdbcSuccess != accessor.add(node, collH, collnode)) 00749 fail("Failed to insert the collection ", collnode); 00750 BdbHandle(BdbTreeNodeP) nodeP = node.persistent(); 00751 collH->setTreeNode(nodeP); 00752 00753 // Done 00754 collH.sprint(collid); 00755 size = collH->size(); 00756 00757 printtdfline(name, collid, size, 1); 00758 00759 estore->commit(); 00760 } 00761 00762 //---------------------- 00763 // Small on-line help -- 00764 //---------------------- 00765 static void usage () 00766 { 00767 cerr << "BdbDbImport [options] " << endl << endl; 00768 00769 cerr << " Options: " << endl; 00770 // cerr << " -checkonly: print the status of the bases and collections" << endl; 00771 cerr << " -[no]checksize: enable/disable the file size checking (def: enabled)" << endl; 00772 cerr << " -delay <mn>: delay to wait to attach the databases" << endl; 00773 cerr << " -forced: force the attach of the database bypassing ooattachdb" << endl; 00774 cerr << " -group <name>: move the databases to this group (def: not changed)" << endl; 00775 cerr << " -ignore: ignore the errors and try to continue (def: stop)" << endl; 00776 cerr << " -lftp: use FTP to locally copy the files" << endl; 00777 cerr << " -quiet: don't print anything" << endl; 00778 cerr << " -[no]read: turn the files read-only" << endl; 00779 cerr << " -replace: replace existing bases and collections" << endl; 00780 cerr << " -verbose: print all the possible information" << endl; 00781 cerr << " -[no]wait: try to lock the database before replacing it" << endl; 00782 cerr << " -bdb{xfr,sfcp,scp,bbcp}: use bdb* to locally copy the files" << endl; 00783 cerr << " -xfr: use ooss_xfr to locally copy the files" << endl; 00784 cerr << " -fget: use ooss_fget to locally copy the files" << endl; 00785 cerr << " -cmdpath path : use this path to copy command "<< endl; 00786 cerr << endl; 00787 00788 cerr << " BdbDbImport reads commands to execute from the standard input" << endl; 00789 cerr << " The supported commands are:" << endl; 00790 cerr << " IMPORT <db-sysname> <dbid> <filename> <subdir> <fullsize>" << endl; 00791 cerr << " COLLECTION <collection> <oid>" << endl << endl; 00792 00793 cerr << " By default, the databases are turned in write mode for an import" << endl; 00794 cerr << " and in read-only mode for a link" << endl; 00795 00796 exit(0); 00797 } 00798 00799 static void help () 00800 { 00801 cout << "Supported commands are:" << endl; 00802 cout << " COLLECTION <collection> <oid>" << endl; 00803 cout << " IMPORT <dbsysname> <dbid> <inpfile> <subdir> <filename> <fullsize>" << endl; 00804 cout << " TREENODE <collection>" << endl; 00805 cout << " EXIT" << endl; 00806 cout << " HELP" << endl; 00807 } 00808 00809 //--------------------------------- 00810 // Starting point of the program -- 00811 //--------------------------------- 00812 int main (int argc, char* argv[]) 00813 { 00814 d_Boolean debugFlag = d_False; 00815 BdbDistMessage::verbosity (1); 00816 00817 // Initialize the Event Store 00818 BdbEventStore::instance()->activate(); 00819 00820 // Check the user arguments 00821 for (int a = 1; a < argc; a++) { 00822 int alen = strlen(argv[a]); 00823 if ('-' == argv[a][0] && 'h' == argv[a][1] && 00824 strncmp(argv[a], "-help", alen) == 0) { 00825 usage(); 00826 } 00827 // else if ('-' == argv[a][0] && 'c' == argv[a][1] && 00828 // strncmp(argv[a], "-checkonly", alen) == 0) { 00829 // checkonlyFlag = d_True; 00830 // warning ("Sorry - \"-checkonly\" not yet supported"); 00831 // return ERROR; 00832 // } 00833 else if ('-' == argv[a][0] && 'c' == argv[a][1] && 00834 strncmp(argv[a], "-checksize", alen) == 0) { 00835 checkSizeFlag = d_True; 00836 } 00837 // else if ('-' == argv[a][0] && 'd' == argv[a][1] && 00838 // strncmp(argv[a], "-debug", alen) == 0) { 00839 // debugFlag = d_True; 00840 // } 00841 else if ('-' == argv[a][0] && 'd' == argv[a][1] && 00842 strncmp(argv[a], "-delay", alen) == 0) { 00843 waitDelay = atoi(argv[++a]); 00844 if (waitDelay != 0) 00845 waitFlag = d_True; 00846 } 00847 else if ('-' == argv[a][0] && 'f' == argv[a][1] && 00848 strncmp(argv[a], "-forced", alen) == 0) { 00849 forcedFlag = d_True; 00850 } 00851 else if ('-' == argv[a][0] && 'g' == argv[a][1] && 00852 strncmp(argv[a], "-group", alen) == 0) { 00853 groupname = argv[++a]; 00854 } 00855 else if ('-' == argv[a][0] && 'i' == argv[a][1] && 00856 strncmp(argv[a], "-ignore", alen) == 0) { 00857 ignoreFlag = d_True; 00858 } 00859 else if ('-' == argv[a][0] && 'l' == argv[a][1] && 00860 strncmp(argv[a], "-lftp", alen) == 0) { 00861 lftpFlag = d_True; 00862 } 00863 else if ('-' == argv[a][0] && 'x' == argv[a][1] && 00864 strncmp(argv[a], "-xfr", alen) == 0) { 00865 xfrFlag = d_True; 00866 } 00867 else if ('-' == argv[a][0] && 'b' == argv[a][1] && 00868 strncmp(argv[a], "-bdbxfr", alen) == 0) { 00869 bdbxfrFlag = d_True; 00870 } 00871 else if ('-' == argv[a][0] && 'f' == argv[a][1] && 00872 strncmp(argv[a], "-fget", alen) == 0) { 00873 fgetFlag = d_True; 00874 } 00875 else if ('-' == argv[a][0] && 'c' == argv[a][1] && 00876 strncmp(argv[a], "-cmdpath", alen) == 0) { 00877 cmdpath = argv[++a]; 00878 } 00879 else if ('-' == argv[a][0] && 'r' == argv[a][1] && 00880 strncmp(argv[a], "-remapdbid", alen) == 0) { 00881 remapDbid = argv[++a]; 00882 } 00883 else if ('-' == argv[a][0] && 'n' == argv[a][1] && alen >= 4 && 00884 strncmp(argv[a], "-noread", alen) == 0) { 00885 readFlag = ReadWrite; 00886 } 00887 else if ('-' == argv[a][0] && 'n' == argv[a][1] && alen >= 4 && 00888 strncmp(argv[a], "-nochecksize", alen) == 0) { 00889 checkSizeFlag = d_False; 00890 } 00891 else if ('-' == argv[a][0] && 'n' == argv[a][1] && alen >= 4 && 00892 strncmp(argv[a], "-nowait", alen) == 0) { 00893 waitFlag = d_False; 00894 } 00895 else if ('-' == argv[a][0] && 'q' == argv[a][1] && 00896 strncmp(argv[a], "-quiet", alen) == 0) { 00897 quietFlag = d_True; 00898 } 00899 else if ('-' == argv[a][0] && 'p' == argv[a][1] && 00900 strncmp(argv[a], "-printtdfline", alen) == 0) { 00901 printtdflineFlag = d_True; 00902 } 00903 else if ('-' == argv[a][0] && 'r' == argv[a][1] && 00904 strncmp(argv[a], "-read", alen) == 0) { 00905 readFlag = ReadOnly; 00906 } 00907 else if ('-' == argv[a][0] && 'r' == argv[a][1] && 00908 strncmp(argv[a], "-replace", alen) == 0) { 00909 replaceFlag = d_True; 00910 } 00911 else if ('-' == argv[a][0] && 'v' == argv[a][1] && 00912 strncmp(argv[a], "-verbose", alen) == 0) { 00913 verboseFlag = d_True; 00914 } 00915 else if ('-' == argv[a][0] && 'w' == argv[a][1] && 00916 strncmp(argv[a], "-wait", alen) == 0) { 00917 waitFlag = d_True; 00918 } 00919 else if ('-' == argv[a][0] && 'l' == argv[a][1] && 00920 strncmp(argv[a], "-lock", alen) == 0) { 00921 lockFlag = d_True; 00922 } 00923 else if ('-' == argv[a][0]) 00924 fail("Unsupported option \"", argv[a], "\""); 00925 else 00926 fail("Unexpected argument \"", argv[a], "\""); 00927 } 00928 if (quietFlag && verboseFlag) { 00929 warning ("Conflicting \"verbose\" and \"quiet\" options - using verbose"); 00930 quietFlag = d_False; 00931 } 00932 if (quietFlag) 00933 BdbDistMessage::verbosity (0); 00934 else if (verboseFlag) 00935 BdbDistMessage::verbosity (2); 00936 00937 // Setup BdbDistMessage as default Objy message handler. 00938 BdbDistMessage::regMsgHandler(); 00939 00940 if (lftpFlag && xfrFlag && bdbxfrFlag && fgetFlag) 00941 fail("Cannot specify both -lftp -fget and/or -xfr -bdbxfr"); 00942 // Get access to the event store 00943 estore = BdbEventStore::instance(); 00944 00945 // Start a read-only transaction 00946 estore->startUpdate(); 00947 00948 // Initialization 00949 BdbDbTreeSingleton::instance()->setRegistrator(new BdbDbRegistrator); 00950 estore->configureClustering(); 00951 estore->commit(); 00952 00953 00954 // Read the names of the databases and collections from the standard input. 00955 // (typically, this tool is called by the "bdbCollImport" script 00956 char line[1024]; 00957 while (fgets(line, sizeof(line) - 1, stdin) != NULL) { 00958 if (debugFlag) 00959 continue; // Dummy mode 00960 00961 char key[32] = {0}; 00962 sscanf(line, "%s", key); 00963 if (strcasecmp("IMPORT", key) == 0) { 00964 char dbname[128]; 00965 char oid[64]; 00966 char inpfile[512]; 00967 char subdir[512]; 00968 char filename[128]; 00969 float fsize; 00970 sscanf(line, "%s %s %s %s %s %s %f", 00971 key, dbname, oid, inpfile, subdir, filename, &fsize); 00972 importDb(dbname, oid, inpfile, subdir, filename, fsize); 00973 } 00974 else if (strcasecmp("COLLECTION", key) == 0) { 00975 char name[128]; 00976 char oid[64]; 00977 sscanf(line, "%s %s %s", key, name, oid); 00978 attachCollection(name, oid); 00979 } 00980 else if (strcasecmp("TREENODE", key) == 0) { 00981 char name[128]; 00982 sscanf(line, "%s %s", key, name); 00983 fixTreeNode(name); 00984 } 00985 else if (strcasecmp("HELP", key) == 0) { 00986 help(); 00987 } 00988 else if (strcasecmp("EXIT", key) == 0) { 00989 break; 00990 } 00991 else 00992 warning ("Invalid line: ", line); 00993 } 00994 00995 // Done 00996 return SUCCESS; 00997 } 00998
BaBar Public Site | SLAC | News | Links | Who's Who | Contact Us
Page Owner: Jacek Becla
Last Update: October 04, 2002