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

Search | Site Map .

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

/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