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

CdbBdb2MySQLConversionTool.cc

Go to the documentation of this file.
00001 // A conversion tool to convert the contents of an Objectivity/DD base
00002 // CDB installation into the MySQL based one.
00003 
00004 #include "BaBar/BaBar.hh"
00005 
00006 #include "BdbUtil/Bdb.hh"
00007 
00008 #include "CdbBase/CdbPathName.hh"
00009 #include "CdbBase/CdbTimeUtils.hh"
00010 #include "CdbBase/CdbTransaction.hh"
00011 
00012 #include "CdbBdbShared/CdbBdbShared.hh"
00013 #include "CdbBdbShared/CdbBdbSRegistryP.hh"
00014 #include "CdbBdbShared/CdbBdbSOriginCollectionP.hh"
00015 #include "CdbBdbShared/CdbBdbSOriginP.hh"
00016 #include "CdbBdbShared/CdbBdbSConditionCollectionP.hh"
00017 #include "CdbBdbShared/CdbBdbSConditionP.hh"
00018 #include "CdbBdbShared/CdbBdbSViewCollectionP.hh"
00019 #include "CdbBdbShared/CdbBdbSViewP.hh"
00020 #include "CdbBdbShared/CdbBdbSConfigCollectionP.hh"
00021 #include "CdbBdbShared/CdbBdbSConfigInterval.hh"
00022 #include "CdbBdbShared/CdbBdbSClusterCollectionP.hh"
00023 #include "CdbBdbShared/CdbBdbSClusterP.hh"
00024 #include "CdbBdbShared/CdbBdbSSimpleClusterP.hh"
00025 #include "CdbBdbShared/CdbBdbSIncrement.hh"
00026 #include "CdbBdbShared/CdbBdbSPartitionsLayoutP.hh"
00027 #include "CdbBdbShared/CdbBdbSPartitionP.hh"
00028 #include "CdbBdbShared/CdbBdbSMetaDataP.hh"
00029 #include "CdbBdbShared/CdbBdbSUtils.hh"
00030 #include "CdbBdbShared/CdbBdbSOiCollectionP.hh"
00031 #include "CdbBdbShared/CdbBdbSRevisionP.hh"
00032 #include "CdbBdbShared/CdbBdbSViCollectionP.hh"
00033 
00034 #include "CdbMySQL/CdbMySQLConnection.hh"
00035 #include "CdbMySQL/CdbMySQLQueryUtils.hh"
00036 
00037 #include "RdbMySQL/RdbMySQLResult.hh"
00038 
00039 #include <assert.h>
00040 #include <stdio.h>
00041 #include <string.h>     // strlen()
00042 
00043 #include <string>
00044 #include <vector>
00045 #include <map>
00046 
00047 #include <sstream>
00048 using std::ostringstream;
00049 
00050 #include <iostream>
00051 #include <fstream>
00052 using std::cin;
00053 using std::cout;
00054 using std::cerr;
00055 using std::endl;
00056 
00057 namespace {
00058 
00059     bool verboseModeFlag          = false;
00060     bool excludeRegularFlag       = false;
00061     bool excludePartitionableFlag = false;
00062 
00063     CdbCPtr<CdbMySQLConnection> myConnectionPtr;
00064 
00065     bool
00066     translate_uint( unsigned int&      theValue,
00067                     const std::string& theString )
00068     {
00069         unsigned v;
00070 
00071         if( 1 == sscanf( theString.c_str( ), "%u", &v )) {
00072             theValue = v;
00073             return true;
00074         }
00075         return false;
00076     }
00077 
00078     bool
00079     execute_sql_query( const std::string& theQuery )
00080     {
00081         const char* context = "Bdb2MySQLConversionTool::execute_sql_query()";
00082 
00083         if( verboseModeFlag )
00084             cout << theQuery << endl;
00085 
00086         CdbCPtr<RdbMySQLResult> resultPtr;
00087         if( CdbStatus::Success != CdbMySQLQueryUtils::execute_query( resultPtr,
00088                                                                      myConnectionPtr,
00089                                                                      theQuery,
00090                                                                      context )) return false;
00091         return true;
00092     }
00093     
00094     CdbStatus convertOrigins( const BdbHandle(CdbBdbSRegistryP)& theInRegistryH );
00095 
00096     CdbStatus convertClusters( const BdbHandle(CdbBdbSRegistryP)& theInRegistryH );
00097 
00098     CdbStatus convertPartitionsLayout( const BdbHandle(CdbBdbSRegistryP)& theMasterRegistryH,
00099                                        const BdbHandle(CdbBdbSRegistryP)& theInRegistryH );
00100 
00101     CdbStatus convertPhysicalConditions( const BdbHandle(CdbBdbSRegistryP)& theMasterRegistryH,
00102                                          const BdbHandle(CdbBdbSRegistryP)& theInRegistryH );
00103 
00104     CdbStatus convertViews( const BdbHandle(CdbBdbSRegistryP)& theInRegistryH );
00105 
00106     CdbStatus convertFoldersAndConditions( const std::string&               theFoldersConditionsTableName,
00107                                            const std::string&               theConditionsConfigsTableName,
00108                                            const BdbHandle(CdbBdbSViewP)&   theInViewH,
00109                                            const BdbHandle(CdbBdbSFolderP)& theInFolderH,
00110                                            const CdbPathName&               theCurrentPathName );
00111 
00112     CdbStatus convertConfigCollection( const std::string&                      theConditionsConfigsTableName,
00113                                        const BdbRef(CdbBdbSConfigCollectionP)& theInputConfigCollectionRef );
00114 
00115     CdbStatus testMetaDataConversion( ) { return CdbStatus::NotImplemented; }
00116 
00117     CdbStatus convertMetaDataOfRegularCondition( const BdbHandle(CdbBdbSConditionP)& theConditionH,
00118                                                  const BdbHandle(CdbBdbSRegistryP)&  theMasterRegistryH,
00119                                                  d_UShort                            theOwnerOriginId );
00120 
00121     CdbStatus convertMetaDataOfPartitionableCondition( const BdbHandle(CdbBdbSConditionP)& theConditionH,
00122                                                        const BdbHandle(CdbBdbSRegistryP)&  theMasterRegistryH );
00123 
00124     CdbStatus convertMetaData( const BdbHandle(CdbBdbSMetaDataP)& theInMetaDataH,
00125                                d_UShort                           theOriginId,
00126                                d_UShort                           theConditionId,
00127                                d_UShort                           theClusterId,
00128                                bool                               isPartitionableFlag,
00129                                d_UShort                           thePartitionId,
00130                                d_UShort                           theIncrementId );
00131 
00132     CdbStatus printPersistentClasses( );
00133 
00134     CdbStatus printPersistentConditions( );
00135 }
00136 
00137 static
00138 void
00139 usage( )
00140 {
00141     cerr << "Usage: [-h <host>] [-u <user>] [-port <number>] [-db <database>] <command> [<parameters>]" << endl
00142          << "       help" << endl
00143          << "       conversion [-noregular] [-nopartitionable] [-verbose]" << endl
00144          << "       testing                                    [-verbose]" << endl
00145          << "       classes    [-noregular] [-nopartitionable] [-verbose]" << endl
00146          << "       conditions [-noregular] [-nopartitionable] [-verbose]" << endl;
00147 }
00148 
00149 int
00150 main( int argc, char* argv[] )
00151 {
00152   // Parameters of a MySQL connection
00153 
00154     std::string  myHost     = "yakut01";
00155     std::string  myUser     = "gapon";
00156     std::string  myPassword = "";       // no password
00157     unsigned int myPort     = 0;        // default port in the current MySQL installation
00158     std::string  myDatabase = "cdb";
00159 
00160   // Get the command name
00161 
00162     enum CommandType {
00163         CMD_CONVERSION = 0,
00164         CMD_TESTING,
00165         CMD_CLASSES,
00166         CMD_CONDITIONS
00167     };
00168     CommandType command = CMD_CONVERSION;
00169 
00170     int numArgs = argc - 1;
00171     int nextArg = 1;
00172 
00173     if( numArgs >= 2 ) {
00174         if( std::string( "-h" ) == argv[nextArg] ) {
00175             myHost = argv[nextArg+1];
00176             nextArg += 2;
00177             numArgs -= 2;
00178         }
00179     }
00180     if( numArgs >= 2 ) {
00181         if( std::string( "-u" ) == argv[nextArg] ) {
00182             myUser = argv[nextArg+1];
00183             nextArg += 2;
00184             numArgs -= 2;
00185         }
00186     }
00187     if( numArgs >= 2 ) {
00188         if( std::string( "-port" ) == argv[nextArg] ) {
00189             if( !translate_uint( myPort,
00190                                  argv[nextArg+1] )) {
00191                 cerr << "failed to translate the port number." << endl;
00192                 usage( );
00193                 return 1;
00194             }
00195             nextArg += 2;
00196             numArgs -= 2;
00197         }
00198     }
00199     if( numArgs >= 2 ) {
00200         if( std::string( "-db" ) == argv[nextArg] ) {
00201             myDatabase = argv[nextArg+1];
00202             nextArg += 2;
00203             numArgs -= 2;
00204         }
00205     }
00206     if( 0 == numArgs ) {
00207         usage( );
00208         return 1;
00209     }
00210     if( numArgs > 0 ) {
00211 
00212         const std::string commandName = argv[nextArg];
00213 
00214         if( commandName == "help" ) {
00215 
00216             usage( );
00217 
00218             return 1;
00219 
00220         } else if( commandName == "conversion" ) {
00221 
00222             command = CMD_CONVERSION;
00223 
00224             numArgs --;
00225             nextArg ++;
00226 
00227         } else if( commandName == "testing" ) {
00228 
00229             command = CMD_TESTING;
00230 
00231             numArgs --;
00232             nextArg ++;
00233 
00234         } else if( commandName == "classes" ) {
00235 
00236             command = CMD_CLASSES;
00237 
00238             numArgs --;
00239             nextArg ++;
00240 
00241         } else if( commandName == "conditions" ) {
00242 
00243             command = CMD_CONDITIONS;
00244 
00245             numArgs --;
00246             nextArg ++;
00247 
00248         } else {
00249 
00250             cerr << "unknown command: \"" << commandName << "\"." << endl;
00251             usage( );
00252             return 1;
00253         }
00254     }
00255     if( numArgs > 0 ) {
00256         if( argv[nextArg] == std::string( "-noregular" )) {
00257 
00258             excludeRegularFlag = true;
00259 
00260             numArgs --;
00261             nextArg ++;
00262         }
00263     }
00264     if( numArgs > 0 ) {
00265         if( argv[nextArg] == std::string( "-nopartitionable" )) {
00266 
00267             excludePartitionableFlag = true;
00268 
00269             numArgs --;
00270             nextArg ++;
00271         }
00272     }
00273     if( numArgs > 0 ) {
00274         if( std::string( "-verbose" ) == argv[nextArg] ) {
00275 
00276             verboseModeFlag = true;
00277 
00278             numArgs --;
00279             nextArg ++;
00280 
00281         } else {
00282             cerr << "unknown command option or parameter: \"" << argv[nextArg] << "\"." << endl;
00283             usage( );
00284             return 1;
00285         }
00286     }
00287 
00288    // Initialize Ojectivity/DB base CDB API context
00289 
00290     CdbBdbShared::forceLoad( );
00291 
00292     CdbTransaction readOnlyTransaction( CdbBdbShared::technology( ),
00293                                         CdbBdbShared::implementation( ));
00294 
00295   // Open a connection with the database. The connection object is made
00296   // visible in this file scope.
00297 
00298     const bool notExistingDatabaseFlag = true;
00299 
00300     myConnectionPtr = new CdbMySQLConnection( myHost,
00301                                               myUser,
00302                                               myPassword,
00303                                               notExistingDatabaseFlag,
00304                                               myDatabase,
00305                                               myPort );
00306 
00307   // Proceed directly to the simple tests if required.
00308 
00309     switch( command ) {
00310     case CMD_TESTING   : return ( CdbStatus::Success == ::testMetaDataConversion   ( ) ? 0 : 1 );
00311     case CMD_CLASSES   : return ( CdbStatus::Success == ::printPersistentClasses   ( ) ? 0 : 1 );
00312     case CMD_CONDITIONS: return ( CdbStatus::Success == ::printPersistentConditions( ) ? 0 : 1 );
00313     default:
00314         break;
00315     }
00316 
00317   // Recreate the output database
00318 
00319     cerr << CdbTimeUtils::time2string( BdbTime::now( )) << "::" << endl;
00320 
00321     if( !execute_sql_query( "DROP DATABASE IF EXISTS " + myDatabase )) return 1;
00322     if( !execute_sql_query( "CREATE DATABASE " + myDatabase )) return 1;
00323 
00324   // Create a table with the informaton about the "local" origin and default
00325   // view of the current database installation.
00326 
00327     {
00328         std::string localTableName;
00329         {
00330             ostringstream s;
00331             s << myConnectionPtr->database( ) << ".local";
00332             localTableName = s.str( );
00333         }
00334         if(!execute_sql_query( "DROP TABLE IF EXISTS " + localTableName )) return 1;
00335         {
00336             const std::string query =
00337                 "CREATE TABLE " + localTableName + " ( " +
00338                 "origin_id SMALLINT UNSIGNED, " +
00339                 "origin_name VARCHAR(32), " +
00340                 "default_view TEXT " +
00341                 ") COMMENT = 'This table describes local identity and some other information in this CDB installation. " +
00342                 "There may be just one, instance of the table in the CDB. Each CDB installation has its own local copy of this table.'";
00343 
00344             if( !execute_sql_query( query )) return 1;
00345         }
00346         {
00347             const std::string query =
00348                 "INSERT INTO " + localTableName + " (origin_id,origin_name,default_view) VALUES ( " +
00349                 "0, " +
00350                 "'MASTER', " +
00351                 "'<local>::<recent>' )";
00352             if( !execute_sql_query( query )) return 1;
00353         }
00354         cerr << CdbTimeUtils::time2string( BdbTime::now( )) << "::" << localTableName << endl;
00355     }
00356 
00357   // Get the MASTER registry and the collection of origins, which we'll
00358   // be using for a few things below.
00359 
00360     BdbHandle(CdbBdbSRegistryP) masterRegistryH;
00361     CdbStatus result = CdbBdbSRegistryP::findMaster( masterRegistryH );
00362     if( CdbStatus::Success != result ) {
00363         cerr << "failed to find the MASTER registry." << endl;
00364         return 1;
00365     }
00366     assert( masterRegistryH->isMaster( ));
00367 
00368     BdbHandle(CdbBdbSOriginCollectionP) originCollectionH = masterRegistryH->originCollection( );
00369     assert( !BdbIsNull(originCollectionH));
00370 
00371   // Convert the collection of origins which belongs to MASTER.
00372 
00373     if( CdbStatus::Success != ( result = convertOrigins( masterRegistryH ))) {
00374         cerr << "failed to convert the collection of origins." << endl;
00375         return 1;
00376     }
00377 
00378   // Iterate over known registries and convert them one-by-one if the corresponding origins
00379   // are instantiated in the input database.
00380 
00381     CdbBdbSOriginCollectionP::IteratorOfIdentifiers itr = originCollectionH->iterator_identifiers( );
00382     while( itr.next( )) {
00383 
00384         d_UShort originId = itr.value( );
00385 
00386       // Try to get the corresponding registry. If it doesn't exist (not instantiated) then we
00387       // will _NOT_ create the output data structures for that registry.
00388 
00389         BdbHandle(CdbBdbSRegistryP) registryH;
00390         {
00391             CdbStatus result = CdbBdbSRegistryP::findByOrigin( registryH,
00392                                                                originId );
00393             if( CdbStatus::Success != result ) {
00394                 if( CdbStatus::NotFound == result ) {
00395 
00396                   // The origin is not currently instantiated in the input database. This may happen
00397                   // when the origin's data are yet to be imported.
00398 
00399                     continue;
00400 
00401                 } else {
00402                     cerr << "failed to find a registry for origin ID = " << originId << "." << endl;
00403                     return 1;
00404                 }
00405             }
00406         }
00407 
00408       // MASTER & SLAVE collections only
00409 
00410         if( !BdbIsNull( registryH->partitionsLayout( ))) {
00411 
00412             if( CdbStatus::Success != ( result = ::convertPartitionsLayout( masterRegistryH,
00413                                                                             registryH ))) {
00414                 cerr << "Failed to convert Partitions Layout." << endl
00415                      << "for origin ID = " << originId << endl;
00416                 return 1;
00417             }
00418         }
00419 
00420       // Convert and store some local collections
00421 
00422         if( registryH->hasLocalCollections( )) {
00423 
00424             if( CdbStatus::Success != ( result = ::convertClusters( registryH ))) {
00425 
00426                 cerr << "Failed to convert a collection of condition clusters." << endl
00427                      << "for origin ID = " << originId << endl;
00428                 return 1;
00429             }
00430             if( CdbStatus::Success != ( result = ::convertViews( registryH ))) {
00431 
00432                 cerr << "Failed to convert a collection of views." << endl
00433                      << "for origin ID = " << originId << endl;
00434                 return 1;
00435             }
00436         }
00437     }
00438     cerr << CdbTimeUtils::time2string( BdbTime::now( )) << "::" << endl;
00439 
00440   // Proceed to local collections
00441   //
00442   // NOTE: A reason why we're doing this in a separate loop is that the prebvious loop
00443   //       over origins should create the tables for 'physical conditions'
00444 
00445     itr.reset( );
00446 
00447     while( itr.next( )) {
00448 
00449         d_UShort originId = itr.value( );
00450 
00451       // Try to get the corresponding registry. If it doesn't exist (not instantiated) then we
00452       // will _NOT_ create the output data structures for that registry.
00453 
00454         BdbHandle(CdbBdbSRegistryP) registryH;
00455         {
00456             CdbStatus result = CdbBdbSRegistryP::findByOrigin( registryH,
00457                                                                originId );
00458             if( CdbStatus::Success != result ) {
00459                 if( CdbStatus::NotFound == result ) {
00460 
00461                   // The origin is not currently instantiated in the input database. This may happen
00462                   // when the origin's data are yet to be imported.
00463 
00464                     continue;
00465 
00466                 } else {
00467                     cerr << "failed to find a registry for origin ID = " << originId << "." << endl;
00468                     return 1;
00469                 }
00470             }
00471         }
00472 
00473       // Convert and store remaining local collections
00474 
00475         if( registryH->hasLocalCollections( )) {
00476 
00477             if( CdbStatus::Success != ( result = ::convertPhysicalConditions( masterRegistryH,
00478                                                                               registryH ))) {
00479 
00480                 cerr << "Failed to convert a collection of 'physical' conditions." << endl
00481                      << "for origin ID = " << originId << endl;
00482                 return 1;
00483             }
00484         }
00485     }
00486     cerr << CdbTimeUtils::time2string( BdbTime::now( )) << "::" << endl;
00487 
00488   // Done.
00489 
00490     return 0;
00491 }
00492 
00493 /////////////
00494 // Helpers //
00495 /////////////
00496 
00497 namespace {
00498 
00499     CdbStatus
00500     convertOrigins( const BdbHandle(CdbBdbSRegistryP)& theInRegistryH )
00501     {
00502         const char* errorStr = "::convertOrigins() - ERROR.";
00503 
00504         assert( !BdbIsNull(theInRegistryH));
00505 
00506         CdbStatus result = CdbStatus::Error;
00507 
00508       // Recreate the table
00509 
00510         std::string tableName;
00511         {
00512             ostringstream s;
00513             s << myConnectionPtr->database( ) << ".o" << theInRegistryH->originId( ) << "_origins";
00514             tableName = s.str( );
00515         }
00516         if(!execute_sql_query( "DROP TABLE IF EXISTS " + tableName )) return CdbStatus::Error;
00517         {
00518             const std::string query =
00519                 "CREATE TABLE " + tableName + " ( " +
00520                 "id SMALLINT UNSIGNED, " +
00521                 "name VARCHAR(32), " +
00522                 "type ENUM('M','S', 'T', 'R'), " +
00523                 "created BIGINT UNSIGNED, " +
00524                 "description TEXT, " +
00525                 "is_instantiated ENUM('Y','N') " +
00526                 ") COMMENT = 'This table describes known origins in CDB." +
00527                 "There may be just one, MASTER owned, instance of the table in CDB.'";
00528 
00529             if( !execute_sql_query( query )) return CdbStatus::Error;
00530         }
00531 
00532       // Convert origins from the input collection and put them into the table
00533 
00534         BdbHandle(CdbBdbSOriginCollectionP) originCollectionH = theInRegistryH->originCollection( );
00535         assert( !BdbIsNull(originCollectionH));
00536 
00537         CdbBdbSOriginCollectionP::IteratorOfIdentifiers itr = originCollectionH->iterator_identifiers( );
00538         while( itr.next( )) {
00539 
00540           // Get the input condition
00541 
00542             d_UShort originId = itr.value( );
00543 
00544             BdbHandle(CdbBdbSOriginP) originH;
00545             {
00546                 BdbRef(CdbBdbSOriginP) originRef;
00547                 if( CdbStatus::Success != ( result = originCollectionH->find( originId,
00548                                                                               originRef ))) {
00549                     cerr << errorStr << endl
00550                          << "    An origin with ID = " << originId << " was not found." << endl;
00551                     return result;
00552                 }
00553                 originH = originRef;
00554             }
00555 
00556           // Remap the origin type
00557 
00558             char originType = 'M';
00559 
00560             switch( originH->type( )) {
00561 
00562             case CdbBdbSOriginP::MASTER  : originType = 'M'; break;
00563             case CdbBdbSOriginP::SLAVE   : originType = 'S'; break;
00564             case CdbBdbSOriginP::REPLICA : originType = 'R'; break;
00565             case CdbBdbSOriginP::TEST    : originType = 'T'; break;
00566 
00567             default:
00568 
00569                 cerr << errorStr << endl
00570                      << "    An unknown (to the current algorithm) origin type: " << originH->type( ) << endl;
00571                 return CdbStatus::Error;
00572             }
00573 
00574           // Try to find the corresponding registry to see if it's instantaited or not
00575           // in the current database installation.
00576 
00577             bool originIsInstantiatedFlag = false;
00578             {
00579                 BdbHandle(CdbBdbSRegistryP) registryHandle;
00580                 originIsInstantiatedFlag = CdbStatus::Success == CdbBdbSRegistryP::findByOrigin( registryHandle, originH->id( ));
00581 
00582             }
00583 
00584           // Create the output one and put into the collection
00585 
00586             std::string query;
00587             {
00588                 ostringstream s;
00589 
00590                 s << "INSERT INTO " << tableName << " "
00591                   << "(id,name,type,created,description,is_instantiated) VALUES ("
00592                   << originH->id( ) << ","
00593                   << "'" << myConnectionPtr->translate_string_to_escaped( originH->name( ).head( )) << "',"
00594                   << "'" << originType << "',"
00595                   << CdbTimeUtils::to_nsec( originH->created( )) << ","
00596                   << "'" << myConnectionPtr->translate_string_to_escaped( originH->description( ).head( )) << "',"
00597                   << "'" << (originIsInstantiatedFlag ? 'Y' : 'N' ) << "')";
00598 
00599                 query = s.str( );
00600             }
00601             if(!execute_sql_query( query )) return CdbStatus::Error;
00602         }
00603         cerr << CdbTimeUtils::time2string( BdbTime::now( )) << "::" << tableName << endl;
00604 
00605         return CdbStatus::Success;
00606     }
00607 
00608     CdbStatus
00609     convertPhysicalConditions( const BdbHandle(CdbBdbSRegistryP)& theMasterRegistryH,
00610                                const BdbHandle(CdbBdbSRegistryP)& theInRegistryH )
00611     {
00612         const char* errorStr = "::convertPhysicalConditions() - ERROR.";
00613 
00614         assert( !BdbIsNull(theInRegistryH));
00615 
00616         CdbStatus result = CdbStatus::Error;
00617 
00618       // Recreate the table
00619 
00620         std::string tableName;
00621         {
00622             ostringstream s;
00623             s << myConnectionPtr->database( ) << ".o" << theInRegistryH->originId( ) << "_physical_conditions";
00624             tableName = s.str( );
00625         }
00626         if(!execute_sql_query( "DROP TABLE IF EXISTS " + tableName  )) return CdbStatus::Error;
00627         {
00628             const std::string query =
00629                 "CREATE TABLE " + tableName + " ( " +
00630                 "id SMALLINT UNSIGNED, " +
00631                 "name VARCHAR(255), " +
00632                 "type ENUM('P','R'), " +
00633                 "cluster SMALLINT UNSIGNED, " +
00634                 "created BIGINT UNSIGNED, " +
00635                 "description TEXT " +
00636                 ") COMMENT = 'This table describes known physical conditions in this origin of CDB.'";
00637 
00638             if( !execute_sql_query( query )) return CdbStatus::Error;
00639         }
00640 
00641       // Convert conditions from the input collection and put them into the table
00642 
00643         BdbHandle(CdbBdbSConditionCollectionP) conditionCollectionH = theInRegistryH->conditionCollection( );
00644 
00645         CdbBdbSConditionCollectionP::IteratorOfIdentifiers itr = conditionCollectionH->iterator_identifiers( );
00646         while( itr.next( )) {
00647 
00648           // Get the input condition
00649 
00650             d_UShort conditionId = itr.value( );
00651 
00652             BdbHandle(CdbBdbSConditionP) conditionH;
00653             {
00654                 BdbRef(CdbBdbSConditionP) conditionRef;
00655                 if( CdbStatus::Success != ( result = conditionCollectionH->find( conditionId,
00656                                                                                  conditionRef ))) {
00657                     cerr << errorStr << endl
00658                          << "    A condition with ID = " << conditionId << " was not found." << endl;
00659                     return result;
00660                 }
00661                 conditionH = conditionRef;
00662             }
00663 
00664           // See if we need to exclude it
00665 
00666             if( conditionH->isPartitionable( )) {
00667                 if( excludePartitionableFlag ) continue;
00668             } else {
00669                 if( excludeRegularFlag ) continue;
00670             }
00671 
00672             char conditionType = ( conditionH->isPartitionable( ) ? 'P' : 'R' );
00673 
00674           // Create the output one and put into the collection
00675 
00676             std::string query;
00677             {
00678                 ostringstream s;
00679 
00680                 s << "INSERT INTO " << tableName << " "
00681                   << "(id,name,type,cluster,created,description) VALUES ("
00682                   << conditionH->id( ) << ","
00683                   << "'" << myConnectionPtr->translate_string_to_escaped( conditionH->name( ).head( )) << "',"
00684                   << "'" << conditionType << "',"
00685                   << conditionH->cluster( )->id( ) << ","
00686                   << CdbTimeUtils::to_nsec( conditionH->created( )) << ","
00687                   << "'" << myConnectionPtr->translate_string_to_escaped( conditionH->description( ).head( )) << "')";
00688 
00689                 query = s.str( );
00690             }
00691             if(!execute_sql_query( query )) return CdbStatus::Error;
00692 
00693           // Find all relevant MetaData objects and convert them too
00694 
00695             if( !conditionH->isPartitionable( )) {
00696 
00697                 if( CdbStatus::Success != ( result = ::convertMetaDataOfRegularCondition( conditionH,
00698                                                                                           theMasterRegistryH,
00699                                                                                           theInRegistryH->originId( )))) {
00700                     cerr << errorStr << endl
00701                          << "    Failed to convert MetaDaa of a 'regular' condition with ID = " << conditionId << "." << endl;
00702                     return result;
00703                 }
00704 
00705             } else {
00706 
00707                 if( CdbStatus::Success != ( result = ::convertMetaDataOfPartitionableCondition( conditionH,
00708                                                                                                 theMasterRegistryH ))) {
00709                     cerr << errorStr << endl
00710                          << "    Failed to convert MetaData of a 'partitionable' condition with ID = " << conditionId << "." << endl;
00711                     return result;
00712                 }
00713             }
00714         }
00715         cerr << CdbTimeUtils::time2string( BdbTime::now( )) << "::" << tableName << endl;
00716 
00717         return CdbStatus::Success;
00718     }
00719 
00720     CdbStatus
00721     convertClusters( const BdbHandle(CdbBdbSRegistryP)& theInRegistryH )
00722     {
00723         const char* errorStr = "::convertClusters() - ERROR.";
00724 
00725         assert( !BdbIsNull(theInRegistryH));
00726 
00727         CdbStatus result = CdbStatus::Error;
00728 
00729       // Recreate the tables
00730 
00731         std::string clustersTableName;
00732         {
00733             ostringstream s;
00734             s << myConnectionPtr->database( ) << ".o" << theInRegistryH->originId( ) << "_clusters";
00735             clustersTableName = s.str( );
00736         }
00737         if(!execute_sql_query( "DROP TABLE IF EXISTS " + clustersTableName )) return CdbStatus::Error;
00738         {
00739             const std::string query =
00740                 "CREATE TABLE " + clustersTableName + " ( " +
00741                 "id SMALLINT UNSIGNED," +
00742                 "name VARCHAR(255), " +
00743                 "type ENUM( 'R', 'P' ), " +
00744                 "created BIGINT UNSIGNED, " +
00745                 "description TEXT " +
00746                 ") COMMENT = 'This table describes clusters in this origin of CDB.'";
00747 
00748             if( !execute_sql_query( query )) return CdbStatus::Error;
00749         }
00750         std::string rIncrementsTableName;
00751         {
00752             ostringstream s;
00753             s << myConnectionPtr->database( ) << ".o" << theInRegistryH->originId( ) << "_cluster_increments";
00754             rIncrementsTableName = s.str( );
00755         }
00756         if(!execute_sql_query( "DROP TABLE IF EXISTS " + rIncrementsTableName )) return CdbStatus::Error;
00757         {
00758             const std::string query =
00759                 "CREATE TABLE " + rIncrementsTableName + " ( " +
00760                 "cluster_id SMALLINT UNSIGNED," +
00761                 "id SMALLINT UNSIGNED, " +
00762                 "begin BIGINT UNSIGNED, " +
00763                 "end BIGINT UNSIGNED " +
00764                 ") COMMENT = 'This table describes increments of REGULAR clusters in this origin of CDB.'";
00765 
00766             if( !execute_sql_query( query )) return CdbStatus::Error;
00767         }
00768 
00769       // Convert 'partitionable' clusters if they're defined for the specifid registry.
00770 
00771         {
00772             BdbHandle(CdbBdbSClusterCollectionP) clusterCollectionH = theInRegistryH->pClusterCollection( );
00773             if( !BdbIsNull(clusterCollectionH)) {
00774 
00775                 CdbBdbSClusterCollectionP::IteratorOfIdentifiers itr = clusterCollectionH->iterator_identifiers( );
00776                 while( itr.next( )) {
00777 
00778                   // Get the input cluster
00779 
00780                     d_UShort clusterId = itr.value( );
00781 
00782                     BdbHandle(CdbBdbSClusterP) clusterH;
00783                     {
00784                         BdbRef(CdbBdbSClusterP) clusterRef;
00785                         if( CdbStatus::Success != ( result = clusterCollectionH->find( clusterId,
00786                                                                                        clusterRef ))) {
00787                             cerr << errorStr << endl
00788                                  << "    A 'partitionable' cluster with ID = " << clusterId << " was not found." << endl;
00789                             return result;
00790                         }
00791                         clusterH = clusterRef;
00792                     }
00793                     const char clusterTypeFlag = 'P';
00794 
00795                   // Create the output cluster and store it in the collection
00796 
00797                     {
00798                         std::string query;
00799 
00800                         ostringstream s;
00801 
00802                         s << "INSERT INTO " << clustersTableName << " "
00803                           << "(id,name,type,created,description) VALUES ("
00804                           << clusterH->id( ) << ","
00805                           << "'" << myConnectionPtr->translate_string_to_escaped( clusterH->name( ).head( )) << "',"
00806                           << "'" << clusterTypeFlag << "',"
00807                           << CdbTimeUtils::to_nsec( clusterH->created( )) << ","
00808                           << "'" << myConnectionPtr->translate_string_to_escaped( clusterH->description( ).head( )) << "')";
00809 
00810                         query = s.str( );
00811 
00812                         if(!execute_sql_query( query )) return CdbStatus::Error;
00813                     }
00814                 }
00815             }
00816         }
00817 
00818       // Convert 'regular' clusters if they're defined for the specifid registry.
00819       // Also put the information about increments into a separate table.
00820 
00821         {
00822             BdbHandle(CdbBdbSClusterCollectionP) clusterCollectionH = theInRegistryH->clusterCollection( );
00823             if( !BdbIsNull(clusterCollectionH)) {
00824 
00825                 CdbBdbSClusterCollectionP::IteratorOfIdentifiers itr = clusterCollectionH->iterator_identifiers( );
00826                 while( itr.next( )) {
00827 
00828                   // Get the input cluster
00829 
00830                     d_UShort clusterId = itr.value( );
00831 
00832                     BdbHandle(CdbBdbSSimpleClusterP) clusterH;
00833                     {
00834                         BdbRef(CdbBdbSSimpleClusterP) clusterRef;
00835                         if( CdbStatus::Success != ( result = clusterCollectionH->find( clusterId,
00836                                                                                        clusterRef ))) {
00837                             cerr << errorStr << endl
00838                                  << "    A 'regular' cluster with ID = " << clusterId << " was not found." << endl;
00839                             return result;
00840                         }
00841                         clusterH = clusterRef;
00842                     }
00843                     const char clusterTypeFlag = 'R';
00844 
00845                   // Create the output cluster and store it in the collection
00846 
00847                     {
00848                         std::string query;
00849 
00850                         ostringstream s;
00851 
00852                         s << "INSERT INTO " << clustersTableName << " "
00853                           << "(id,name,type,created,description) VALUES ("
00854                           << clusterH->id( ) << ","
00855                           << "'" << myConnectionPtr->translate_string_to_escaped( clusterH->name( ).head( )) << "',"
00856                           << "'" << clusterTypeFlag << "',"
00857                           << CdbTimeUtils::to_nsec( clusterH->created( )) << ","
00858                           << "'" << myConnectionPtr->translate_string_to_escaped( clusterH->description( ).head( )) << "')";
00859 
00860                         query = s.str( );
00861 
00862                         if(!execute_sql_query( query )) return CdbStatus::Error;
00863                     }
00864 
00865                   // Prepare a vector with increments converted from the input cluster
00866 
00867                     d_UShort numIncrements = clusterH->numIncrements( );
00868                     for( d_UShort incrementId = 0; incrementId < numIncrements; ++incrementId ) {
00869 
00870                         CdbBdbSIncrement inputIncrement;
00871 
00872                         if( CdbStatus::Success != ( result = clusterH->increment( incrementId,
00873                                                                                   inputIncrement ))) {
00874                             cerr << errorStr << endl
00875                                  << "    An increment with ID = " << incrementId << " was not found in a cluster with ID = " << clusterId << endl;
00876                             return result;
00877                         }
00878 
00879                       // Create the output increments and put them into the collection
00880 
00881                         {
00882                             std::string query;
00883 
00884                             ostringstream s;
00885 
00886                             s << "INSERT INTO " << rIncrementsTableName << " "
00887                               << "(cluster_id,id,begin,end) VALUES ("
00888                               << clusterH->id( ) << ","
00889                               << incrementId << ","
00890                               << CdbTimeUtils::to_nsec( inputIncrement.begin ) << ","
00891                               << CdbTimeUtils::to_nsec( inputIncrement.end ) << ")";
00892 
00893                             query = s.str( );
00894 
00895                             if(!execute_sql_query( query )) return CdbStatus::Error;
00896                         }
00897 
00898                       // Also create tables for metadata of regular conditions
00899 
00900                         std::string baseTableName;
00901                         {
00902                             ostringstream s;
00903                             s << myConnectionPtr->database( ) << ".o" << theInRegistryH->originId( )
00904                               << "_c" << clusterId
00905                               << "_i" << incrementId
00906                               << "_";
00907                             baseTableName = s.str( );
00908                         }
00909                         const std::string payloadObjectsTableName    = baseTableName + "payload";
00910                         const std::string originalIntervalsTableName = baseTableName + "original";
00911                         const std::string revisionsTableName         = baseTableName + "revisions";
00912                         const std::string visibleIntervalsTableName  = baseTableName + "visible";
00913 
00914                         if(!execute_sql_query( "DROP TABLE IF EXISTS " + payloadObjectsTableName )) return CdbStatus::Error;
00915                         {
00916                             const std::string query =
00917                                 "CREATE TABLE " + payloadObjectsTableName + " ( " +
00918                                 "id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY, " +    // PRIMARY
00919                                 "legacy_id TEXT, " +
00920                                 "type TEXT, " +
00921                                 "size INT UNSIGNED, " +
00922                                 "value MEDIUMBLOB " +
00923                                 ") COMMENT = 'This table represents PAYLOAD objects for REGULAR conditions in a scope of this PARTITION, CLUSTER and an INCREMENT.'";
00924 
00925                             if( !execute_sql_query( query )) return CdbStatus::Error;
00926                         }
00927                         if(!execute_sql_query( "DROP TABLE IF EXISTS " + originalIntervalsTableName )) return CdbStatus::Error;
00928                         {
00929                             const std::string query =
00930                                 "CREATE TABLE " + originalIntervalsTableName + " ( " +
00931                                 "condition_id SMALLINT UNSIGNED, " +                // COMPOSITE PRIMARY, ALSO FOREIGN -> "physical_conditions" @ MASTER origin
00932                                 "stored BIGINT UNSIGNED," +                         // COMPOSITE PRIMARY
00933                                 "begin BIGINT UNSIGNED, " +
00934                                 "end BIGINT UNSIGNED, " +
00935                                 "object_id INTEGER UNSIGNED " +                     // FOREIGN -> "payload" objects within the same scope
00936                                 ") COMMENT = 'This table represents ORIGINAL objects for REGULAR conditions in a scope of this PARTITION, CLUSTER and an INCREMENT.'";
00937 
00938                             if( !execute_sql_query( query )) return CdbStatus::Error;
00939                         }
00940                         if(!execute_sql_query( "DROP TABLE IF EXISTS " + revisionsTableName )) return CdbStatus::Error;
00941                         {
00942                             const std::string query =
00943                                 "CREATE TABLE " + revisionsTableName + " ( " +
00944                                 "condition_id SMALLINT UNSIGNED, " +    // COMPOSITE PRIMARY, ALSO FOREIGN -> "physical_conditions" @ MASTER origin
00945                                 "id BIGINT UNSIGNED, " +                // COMPOSITE PRIMARY
00946                                 "name TEXT, " + 
00947                                 "created BIGINT UNSIGNED, " +
00948                                 "description TEXT " +
00949                                 ") COMMENT = 'This table represents REVISIONS for REGULAR conditions in a scope of this PARTITION, CLUSTER and an INCREMENT.'";
00950 
00951                             if( !execute_sql_query( query )) return CdbStatus::Error;
00952                         }
00953                         if(!execute_sql_query( "DROP TABLE IF EXISTS " + visibleIntervalsTableName )) return CdbStatus::Error;
00954                         {
00955                             const std::string query =
00956                                 "CREATE TABLE " + visibleIntervalsTableName + " ( " +
00957                                 "condition_id SMALLINT UNSIGNED, " +    // COMPOSITE PRIMARY, FOREIGN -> "physical_conditions" @ MASTER origin
00958                                 "revision_id BIGINT UNSIGNED, " +       // COMPOSITE PRIMARY, FOREIGN -> "revisions"
00959                                 "begin BIGINT UNSIGNED, " +             // COMPOSITE PRIMARY
00960                                 "end BIGINT UNSIGNED, " +               // COMPOSITE PRIMARY
00961                                 "original_stored BIGINT UNSIGNED " +    // FOREIGN KEY -> "original"
00962                                 ") COMMENT = 'This table represents VISIBLE objects for REGULAR conditions in a scope of this PARTITION, CLUSTER and an INCREMENT.'";
00963 
00964                             if( !execute_sql_query( query )) return CdbStatus::Error;
00965                         }
00966                         cerr << CdbTimeUtils::time2string( BdbTime::now( )) << "::" << payloadObjectsTableName << "\n"
00967                              << CdbTimeUtils::time2string( BdbTime::now( )) << "::" << originalIntervalsTableName << "\n"
00968                              << CdbTimeUtils::time2string( BdbTime::now( )) << "::" << revisionsTableName << "\n"
00969                              << CdbTimeUtils::time2string( BdbTime::now( )) << "::" << visibleIntervalsTableName << endl;
00970                     }
00971                 }
00972             }
00973         }
00974         cerr << CdbTimeUtils::time2string( BdbTime::now( )) << "::" << clustersTableName << endl;
00975         cerr << CdbTimeUtils::time2string( BdbTime::now( )) << "::" << rIncrementsTableName << endl;
00976 
00977         return CdbStatus::Success;
00978     }
00979 
00980     CdbStatus
00981     convertPartitionsLayout( const BdbHandle(CdbBdbSRegistryP)& theMasterRegistryH,
00982                              const BdbHandle(CdbBdbSRegistryP)& theInRegistryH )
00983     {
00984         const char* errorStr = "::convertPartitionsLayout() - ERROR.";
00985 
00986         assert( !BdbIsNull(theInRegistryH));
00987 
00988         CdbStatus result = CdbStatus::Error;
00989 
00990       // Recreate the tables
00991 
00992         std::string pLayoutTableName;
00993         {
00994             ostringstream s;
00995             s << myConnectionPtr->database( ) << ".o" << theInRegistryH->originId( ) << "_partitions";
00996             pLayoutTableName = s.str( );
00997         }
00998         if(!execute_sql_query( "DROP TABLE IF EXISTS " + pLayoutTableName )) return CdbStatus::Error;
00999         {
01000             const std::string query =
01001                 "CREATE TABLE " + pLayoutTableName + " ( " +
01002                 "id SMALLINT UNSIGNED," +
01003                 "origin_id SMALLINT UNSIGNED, " +
01004                 "is_instantiated  ENUM( 'Y', 'N' ), " +
01005                 "is_closed ENUM( 'Y', 'N' ), " +
01006                 "created BIGINT UNSIGNED, " +
01007                 "modified BIGINT UNSIGNED, " +
01008                 "v_begin BIGINT UNSIGNED, " +
01009                 "v_end BIGINT UNSIGNED, " +
01010                 "i_begin BIGINT UNSIGNED, " +
01011                 "i_end BIGINT UNSIGNED, " +
01012                 "description TEXT " +
01013                 ") COMMENT = 'This table describes the Partitions Layout of this origin of CDB.'";
01014 
01015             if( !execute_sql_query( query )) return CdbStatus::Error;
01016         }
01017         std::string pIncrementsTableName;
01018         {
01019             ostringstream s;
01020             s << myConnectionPtr->database( ) << ".o" << theInRegistryH->originId( ) << "_partition_increments";
01021             pIncrementsTableName = s.str( );
01022         }
01023         if(!execute_sql_query( "DROP TABLE IF EXISTS " + pIncrementsTableName )) return CdbStatus::Error;
01024         {
01025             const std::string query =
01026                 "CREATE TABLE " + pIncrementsTableName + " ( " +
01027                 "partition_id SMALLINT UNSIGNED," +
01028                 "id SMALLINT UNSIGNED, " +
01029                 "begin BIGINT UNSIGNED, " +
01030                 "end BIGINT UNSIGNED " +
01031                 ") COMMENT = 'This table describes increments of PARTITIONS in this origin of CDB.'";
01032 
01033             if( !execute_sql_query( query )) return CdbStatus::Error;
01034         }
01035 
01036       // Get a number of partitionable clusters from the Master registry. We'll need
01037       // this information to create tables for partitionable conditions.
01038       //
01039       // NOTES:
01040       //
01041       //   - We're asuming that partitionable clusters (as well as conditions themselves)
01042       //   can only created in MASTER CDB. At least at the current implementation of CDB.
01043 
01044         BdbHandle(CdbBdbSClusterCollectionP) pClusterCollectionH = theMasterRegistryH->clusterCollection( );
01045         assert( !BdbIsNull(pClusterCollectionH));
01046 
01047         CdbBdbSClusterCollectionP::IteratorOfIdentifiers pClusterItr = pClusterCollectionH->iterator_identifiers( );
01048 
01049       // Convert partitions from the input collection and put them into the table.
01050       // Also put the information about increments into a separet table.
01051 
01052         BdbHandle(CdbBdbSPartitionsLayoutP) partitionsLayoutH = theInRegistryH->partitionsLayout( );
01053         assert( !BdbIsNull(partitionsLayoutH));
01054 
01055         CdbItr<d_UShort> itr = partitionsLayoutH->iterator( );
01056         while( itr.next( )) {
01057 
01058             d_UShort partitionId = itr.value( );
01059 
01060           // Get the input partition
01061 
01062             BdbHandle(CdbBdbSPartitionP) partitionH;
01063             {
01064                 BdbRef(CdbBdbSPartitionP) partitionRef;
01065                 if( CdbStatus::Success != ( result = partitionsLayoutH->find( partitionId,
01066                                                                               partitionRef ))) {
01067                     cerr << errorStr << endl
01068                          << "    A partition with ID = " << partitionId << " was not found." << endl;
01069                     return result;
01070                 }
01071                 partitionH = partitionRef;
01072             }
01073 
01074             char isInstantiatedFlag = ( partitionH->isInstantiated( ) ? 'Y' : 'N' );
01075             char isClosedFlag       = ( partitionH->isClosed( )       ? 'Y' : 'N' );
01076 
01077           // Create the output partition and put into the collection
01078 
01079             {
01080                 std::string query;
01081 
01082                 ostringstream s;
01083 
01084                 s << "INSERT INTO " << pLayoutTableName << " "
01085                   << "(id,origin_id,is_instantiated,is_closed,created,modified,v_begin,v_end,i_begin,i_end,description) VALUES ("
01086                   << partitionH->id( ) << ","
01087                   << partitionH->originId( ) << ","
01088                   << "'" << isInstantiatedFlag << "',"
01089                   << "'" << isClosedFlag << "',"
01090                   << CdbTimeUtils::to_nsec( partitionH->created( )) << ","
01091                   << CdbTimeUtils::to_nsec( partitionH->modified( )) << ","
01092                   << CdbTimeUtils::to_nsec( partitionH->cell( ).beginValidity ) << ","
01093                   << CdbTimeUtils::to_nsec( partitionH->cell( ).endValidity) << ","
01094                   << CdbTimeUtils::to_nsec( partitionH->cell( ).beginInsertion) << ","
01095                   << CdbTimeUtils::to_nsec( partitionH->cell( ).endInsertion) << ","
01096                   << "'" << myConnectionPtr->translate_string_to_escaped( partitionH->description( ).head( )) << "')";
01097 
01098                 query = s.str( );
01099 
01100                 if(!execute_sql_query( query )) return CdbStatus::Error;
01101             }
01102 
01103           // Convert a collection of increments
01104 
01105             d_UShort numIncrements = partitionH->numIncrements( );
01106             for( d_UShort incrementId = 0; incrementId < numIncrements; ++incrementId ) {
01107 
01108                 CdbBdbSIncrement inputIncrement;
01109 
01110                 if( CdbStatus::Success != ( result = partitionH->increment( incrementId,
01111                                                                             inputIncrement ))) {
01112                     cerr << errorStr << endl
01113                          << "    An increment with ID = " << incrementId << " was not found in a partition with ID = " << partitionId << endl;
01114                     return result;
01115                 }
01116 
01117               // Create the output increments and put them into the collection
01118 
01119                 {
01120                     std::string query;
01121 
01122                     ostringstream s;
01123 
01124                     s << "INSERT INTO " << pIncrementsTableName << " "
01125                       << "(partition_id,id,begin,end) VALUES ("
01126                       << partitionH->id( ) << ","
01127                       << incrementId << ","
01128                       << CdbTimeUtils::to_nsec( inputIncrement.begin ) << ","
01129                       << CdbTimeUtils::to_nsec( inputIncrement.end ) << ")";
01130 
01131                     query = s.str( );
01132 
01133                     if(!execute_sql_query( query )) return CdbStatus::Error;
01134                 }
01135 
01136               // Get identifiers of all partitionable clusters and create tables for methadata
01137               // of partitionable conditions.
01138               //
01139               // NOTES:
01140               //
01141               //   - Tables will only be created for partitions owned by the local origin (the one passed
01142               //   as a parameter)
01143 
01144                 if( theInRegistryH->originId( ) == partitionH->originId( )) {
01145 
01146                     pClusterItr.reset( );
01147 
01148                     while( pClusterItr.next( )) {
01149 
01150                         d_UShort clusterId = pClusterItr.value( );
01151 
01152                         std::string baseTableName;
01153                         {
01154                             ostringstream s;
01155                             s << myConnectionPtr->database( ) << ".o" << partitionH->originId( )
01156                               << "_p" << partitionH->id( )
01157                               << "_c" << clusterId
01158                               << "_i" << incrementId
01159                               << "_";
01160                             baseTableName = s.str( );
01161                         }
01162                         const std::string payloadObjectsTableName    = baseTableName + "payload";
01163                         const std::string originalIntervalsTableName = baseTableName + "original";
01164                         const std::string revisionsTableName         = baseTableName + "revisions";
01165                         const std::string visibleIntervalsTableName  = baseTableName + "visible";
01166 
01167                         if(!execute_sql_query( "DROP TABLE IF EXISTS " + payloadObjectsTableName )) return CdbStatus::Error;
01168                         {
01169                             const std::string query =
01170                                 "CREATE TABLE " + payloadObjectsTableName + " ( " +
01171                                 "id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY, " +    // PRIMARY
01172                                 "legacy_id TEXT, " +
01173                                 "type TEXT, " +
01174                                 "size INT UNSIGNED, " +
01175                                 "value MEDIUMBLOB " +
01176                                 ") COMMENT = 'This table represents PAYLOAD objects for PARTITIONABLE conditions in a scope of this PARTITION, CLUSTER and an INCREMENT.'";
01177 
01178                             if( !execute_sql_query( query )) return CdbStatus::Error;
01179                         }
01180                         if(!execute_sql_query( "DROP TABLE IF EXISTS " + originalIntervalsTableName )) return CdbStatus::Error;
01181                         {
01182                             const std::string query =
01183                                 "CREATE TABLE " + originalIntervalsTableName + " ( " +
01184                                 "condition_id SMALLINT UNSIGNED, " +        // COMPOSITE PRIMARY, ALSO FOREIGN -> "physical_conditions" @ MASTER origin
01185                                 "stored BIGINT UNSIGNED," +                 // COMPOSITE PRIMARY
01186                                 "begin BIGINT UNSIGNED, " +
01187                                 "end BIGINT UNSIGNED, " +
01188                                 "object_id INTEGER UNSIGNED NOT NULL " +    // FOREIGN -> "payload" objects within the same scope
01189                                 ") COMMENT = 'This table represents ORIGINAL objects for PARTITIONABLE conditions in a scope of this PARTITION, CLUSTER and an INCREMENT.'";
01190 
01191                             if( !execute_sql_query( query )) return CdbStatus::Error;
01192                         }
01193                         if(!execute_sql_query( "DROP TABLE IF EXISTS " + revisionsTableName )) return CdbStatus::Error;
01194                         {
01195                             const std::string query =
01196                                 "CREATE TABLE " + revisionsTableName + " ( " +
01197                                 "condition_id SMALLINT UNSIGNED, " +    // COMPOSITE PRIMARY, ALSO FOREIGN -> "physical_conditions" @ MASTER origin
01198                                 "id BIGINT UNSIGNED, " +                // COMPOSITE PRIMARY
01199                                 "name TEXT, " + 
01200                                 "created BIGINT UNSIGNED, " +
01201                                 "description TEXT " +
01202                                 ") COMMENT = 'This table represents REVISIONS for PARTITIONABLE conditions in a scope of this PARTITION, CLUSTER and an INCREMENT.'";
01203 
01204                             if( !execute_sql_query( query )) return CdbStatus::Error;
01205                         }
01206                         if(!execute_sql_query( "DROP TABLE IF EXISTS " + visibleIntervalsTableName )) return CdbStatus::Error;
01207                         {
01208                             const std::string query =
01209                                 "CREATE TABLE " + visibleIntervalsTableName + " ( " +
01210                                 "condition_id SMALLINT UNSIGNED, " +    // COMPOSITE PRIMARY, FOREIGN -> "physical_conditions" @ MASTER origin
01211                                 "revision_id BIGINT UNSIGNED, " +       // COMPOSITE PRIMARY, FOREIGN -> "revisions"
01212                                 "begin BIGINT UNSIGNED, " +             // COMPOSITE PRIMARY
01213                                 "end BIGINT UNSIGNED, " +               // COMPOSITE PRIMARY
01214                                 "original_stored BIGINT UNSIGNED " +    // FOREIGN KEY -> "original"
01215                                 ") COMMENT = 'This table represents VISIBLE objects for PARTITIONABLE conditions in a scope of this PARTITION, CLUSTER and an INCREMENT.'";
01216 
01217                             if( !execute_sql_query( query )) return CdbStatus::Error;
01218                         }
01219                         cerr << CdbTimeUtils::time2string( BdbTime::now( )) << "::" << payloadObjectsTableName << "\n"
01220                              << CdbTimeUtils::time2string( BdbTime::now( )) << "::" << originalIntervalsTableName << "\n"
01221                              << CdbTimeUtils::time2string( BdbTime::now( )) << "::" << revisionsTableName << "\n"
01222                              << CdbTimeUtils::time2string( BdbTime::now( )) << "::" << visibleIntervalsTableName << endl;
01223                     }
01224                 }
01225             }
01226         }
01227         cerr << CdbTimeUtils::time2string( BdbTime::now( )) << "::" << pLayoutTableName << "\n"
01228              << CdbTimeUtils::time2string( BdbTime::now( )) << "::" << pIncrementsTableName << endl;
01229 
01230         return CdbStatus::Success;
01231     }
01232 
01233     CdbStatus
01234     convertViews( const BdbHandle(CdbBdbSRegistryP)& theInRegistryH )
01235     {
01236         const char* errorStr = "::convertViews() - ERROR.";
01237 
01238         assert( !BdbIsNull(theInRegistryH));
01239 
01240         CdbStatus result = CdbStatus::Error;
01241 
01242      // Recreate the tables
01243 
01244         std::string viewsTableName;
01245         {
01246             ostringstream s;
01247             s << myConnectionPtr->database( ) << ".o" << theInRegistryH->originId( ) << "_views";
01248             viewsTableName = s.str( );
01249         }
01250         if(!execute_sql_query( "DROP TABLE IF EXISTS " + viewsTableName )) return CdbStatus::Error;
01251         {
01252             const std::string query =
01253                 "CREATE TABLE " + viewsTableName + " ( " +
01254                 "id SMALLINT UNSIGNED," +
01255                 "name VARCHAR(255), " +
01256                 "has_default_config ENUM( 'Y', 'N' ), " +
01257                 "is_frozen ENUM( 'Y', 'N' ), " +
01258                 "created BIGINT UNSIGNED, " +
01259                 "min_validity BIGINT UNSIGNED, " +
01260                 "max_validity BIGINT UNSIGNED, " +
01261                 "description TEXT " +
01262                 ") COMMENT = 'This table describes the Views of this origin of CDB.'";
01263 
01264             if( !execute_sql_query( query )) return CdbStatus::Error;
01265         }
01266         std::string foldersConditionsTableName;
01267         {
01268             ostringstream s;
01269             s << myConnectionPtr->database( ) << ".o" << theInRegistryH->originId( ) << "_folders_conditions";
01270             foldersConditionsTableName = s.str( );
01271         }
01272         if(!execute_sql_query( "DROP TABLE IF EXISTS " + foldersConditionsTableName )) return CdbStatus::Error;
01273         {
01274             const std::string query =
01275                 "CREATE TABLE " + foldersConditionsTableName + " ( " +
01276                 "id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE, " +
01277                 "view_id SMALLINT UNSIGNED, " +
01278                 "path TEXT, " +
01279                 "entry_type ENUM('F','C'), " +
01280                 "created BIGINT UNSIGNED, " +
01281                 "description TEXT, " +
01282                 "pcond_origin_id SMALLINT UNSIGNED, " +
01283                 "pcond_local_id  SMALLINT UNSIGNED " +
01284                 ") COMMENT = 'This table describes Folders and Conditions in each View of this origin of CDB.'";
01285 
01286             if( !execute_sql_query( query )) return CdbStatus::Error;
01287         }
01288         std::string defaultConfigsTableName;
01289         {
01290             ostringstream s;
01291             s << myConnectionPtr->database( ) << ".o" << theInRegistryH->originId( ) << "_default_configs";
01292             defaultConfigsTableName = s.str( );
01293         }
01294         if(!execute_sql_query( "DROP TABLE IF EXISTS " + defaultConfigsTableName )) return CdbStatus::Error;
01295         {
01296             const std::string query =
01297                 "CREATE TABLE " + defaultConfigsTableName + " ( " +
01298                 "view_id SMALLINT UNSIGNED, " +
01299                 "begin BIGINT UNSIGNED, " +
01300                 "end BIGINT UNSIGNED, " +
01301                 "use_revision ENUM('Y','N'), " +
01302                 "partition_id SMALLINT UNSIGNED, " +
01303                 "revision BIGINT UNSIGNED " +
01304                 ") COMMENT = 'This table describes default Configuratins of Conditions in each View of this origin of CDB.'";
01305 
01306             if( !execute_sql_query( query )) return CdbStatus::Error;
01307         }
01308         std::string conditionsConfigsTableName;
01309         {
01310             ostringstream s;
01311             s << myConnectionPtr->database( ) << ".o" << theInRegistryH->originId( ) << "_conditions_configs";
01312             conditionsConfigsTableName = s.str( );
01313         }
01314         if(!execute_sql_query( "DROP TABLE IF EXISTS " + conditionsConfigsTableName )) return CdbStatus::Error;
01315         {
01316             const std::string query =
01317                 "CREATE TABLE " + conditionsConfigsTableName + " ( " +
01318                 "entry_id INTEGER UNSIGNED, " +
01319                 "begin BIGINT UNSIGNED, " +
01320                 "end BIGINT UNSIGNED, " +
01321                 "use_revision ENUM('Y','N'), " +
01322                 "partition_id SMALLINT UNSIGNED, " +
01323                 "revision BIGINT UNSIGNED " +
01324                 ") COMMENT = 'This table describes local Configuratins of Conditions in each View of this origin of CDB.'";
01325 
01326             if( !execute_sql_query( query )) return CdbStatus::Error;
01327         }
01328 
01329       // Convert views from the input collection and put them into the tables.
01330 
01331         BdbHandle(CdbBdbSViewCollectionP) viewCollectionH = theInRegistryH->viewCollection( );
01332         assert( !BdbIsNull(viewCollectionH));
01333 
01334         CdbBdbSViewCollectionP::IteratorOfIdentifiers itr = viewCollectionH->iterator_identifiers( );
01335         while( itr.next( )) {
01336 
01337           // Get the input view
01338 
01339             d_UShort viewId = itr.value( );
01340 
01341             BdbHandle(CdbBdbSViewP) viewH;
01342             {
01343                 BdbRef(CdbBdbSViewP) viewRef;
01344                 if( CdbStatus::Success != ( result = viewCollectionH->find( viewId,
01345                                                                             viewRef ))) {
01346                     cerr << errorStr << endl
01347                          << "    A view with ID = " << viewId << " was not found." << endl;
01348                     return result;
01349                 }
01350                 viewH = viewRef;
01351             }
01352 
01353           // Check if the view has the default configuration
01354 
01355             const char hasDefaultConfigFlag = ( !BdbIsNull( viewH->defaultConfig( )) ? 'Y' : 'N' );
01356             const char isFrozenFlag         = ( viewH->isFrozen( )                   ? 'Y' : 'N' );
01357 
01358           // Store the view
01359 
01360             {
01361                 std::string query;
01362 
01363                 ostringstream s;
01364 
01365                 s << "INSERT INTO " << viewsTableName << " "
01366                   << "(id,name,has_default_config,is_frozen,created,min_validity,max_validity,description) VALUES ("
01367                   << viewH->id( ) << ","
01368                   << "'" << myConnectionPtr->translate_string_to_escaped( viewH->name( ).head( )) << "',"
01369                   << "'" << hasDefaultConfigFlag << "',"
01370                   << "'" << isFrozenFlag << "',"
01371                   << CdbTimeUtils::to_nsec( viewH->created( )) << ","
01372                   << CdbTimeUtils::to_nsec( viewH->minValidity( )) << ","
01373                   << CdbTimeUtils::to_nsec( viewH->maxValidity( )) << ","
01374                   << "'" << myConnectionPtr->translate_string_to_escaped( viewH->description( ).head( )) << "')";
01375 
01376                 query = s.str( );
01377 
01378                 if(!execute_sql_query( query )) return CdbStatus::Error;
01379             }
01380 
01381           // If the view has a default configuration then store it too
01382 
01383             BdbHandle(CdbBdbSConfigCollectionP) configCollectionH = viewH->defaultConfig( );
01384 
01385             if( !BdbIsNull(configCollectionH)) {
01386 
01387                 CdbBdbSConfigCollectionP::IteratorOfIntervals itr = configCollectionH->iterator( );
01388                 while( itr.next( )) {
01389 
01390                     CdbBdbSConfigInterval iVal = itr.value( );
01391 
01392                     const char userRevisionFlag = ( iVal.value.useRevision ? 'Y' : 'N' );
01393                     {
01394                         std::string query;
01395 
01396                         ostringstream s;
01397 
01398                         s << "INSERT INTO " << defaultConfigsTableName << " "
01399                           << "(view_id,begin,end,use_revision,partition_id,revision) VALUES ("
01400                           << viewH->id( ) << ","
01401                           << CdbTimeUtils::to_nsec( iVal.begin ) << ","
01402                           << CdbTimeUtils::to_nsec( iVal.end ) << ","
01403                           << "'" << userRevisionFlag << "',"
01404                           << iVal.value.partition << ","
01405                           << CdbTimeUtils::to_nsec( iVal.value.revision ) << ")";
01406 
01407                         query = s.str( );
01408 
01409                         if(!execute_sql_query( query )) return CdbStatus::Error;
01410                     }
01411                 }
01412             }
01413 
01414           // Proceed down to folders
01415           //
01416           // NOTES:
01417           //
01418           //   (1) The "/" folder must already exist in the output collection as it's created
01419           //       automatically at the same time the view gets created.
01420           //
01421           //   (2) The path name would be automatically extended as the recursive copying
01422           //       procedure of folders and conditions will keep going.
01423 
01424             BdbHandle(CdbBdbSFolderP) rootFolderH = viewH->rootFolder( );
01425             assert( !BdbIsNull(rootFolderH));
01426 
01427             if( CdbStatus::Success != ( result = ::convertFoldersAndConditions( foldersConditionsTableName,
01428                                                                                 conditionsConfigsTableName,
01429                                                                                 viewH,
01430                                                                                 rootFolderH,
01431                                                                                 CdbPathName( rootFolderH->name( ).head( ))))) {
01432                 cerr << errorStr << endl
01433                      << "    Failed to convert folders starting from \"/\"" << endl
01434                      << "    when copying view \"" << viewH->name( ).head( ) << "\"" << endl;
01435                 return result;
01436             }
01437         }
01438         cerr << CdbTimeUtils::time2string( BdbTime::now( )) << "::" << viewsTableName << "\n"
01439              << CdbTimeUtils::time2string( BdbTime::now( )) << "::" << foldersConditionsTableName << "\n"
01440              << CdbTimeUtils::time2string( BdbTime::now( )) << "::" << defaultConfigsTableName << "\n"
01441              << CdbTimeUtils::time2string( BdbTime::now( )) << "::" << conditionsConfigsTableName << endl;
01442 
01443         return CdbStatus::Success;
01444     }
01445 
01446     CdbStatus
01447     convertFoldersAndConditions( const std::string&               theFoldersConditionsTableName,
01448                                  const std::string&               theConditionsConfigsTableName,
01449                                  const BdbHandle(CdbBdbSViewP)&   theInViewH,
01450                                  const BdbHandle(CdbBdbSFolderP)& theFolderH,
01451                                  const CdbPathName&               theCurrentPathName )
01452     {
01453         const char* errorStr = "::convertFoldersAndConditions() - ERROR.";
01454 
01455         assert( !BdbIsNull(theInViewH));
01456         assert( !BdbIsNull(theFolderH));
01457 
01458         CdbStatus result = CdbStatus::Error;
01459 
01460       // Save the current folder first
01461 
01462         {
01463             std::string query;
01464 
01465             ostringstream s;
01466 
01467             s << "INSERT INTO " << theFoldersConditionsTableName << " "
01468               << "(view_id,path,entry_type,created,description) VALUES ("
01469               << theInViewH->id( ) << ","
01470               << "'" << myConnectionPtr->translate_string_to_escaped( theCurrentPathName.toString( )) << "',"
01471               << "'F',"
01472               << CdbTimeUtils::to_nsec( theFolderH->created( )) << ","
01473               << "'" << myConnectionPtr->translate_string_to_escaped( theFolderH->description( ).head( )) << "')";
01474 
01475             query = s.str( );
01476 
01477             if(!execute_sql_query( query )) return CdbStatus::Error;
01478         }
01479 
01480       // Browse conditions in the input folder and copy them
01481 
01482         {
01483             CdbItr< const char* > itr;
01484             if( CdbStatus::Success != ( result = theFolderH->conditionIterator( itr ))) {
01485                 cerr << errorStr << endl
01486                      << "    Failed to obtain an iterator of condition names." << endl
01487                      << "        CURRENT FOLDER: \"" << theCurrentPathName << "\"" << endl;
01488                 return result;
01489             }
01490             while( itr.next( )) {
01491 
01492               // Find the input condition objct
01493 
01494                 BdbHandle(CdbBdbSConditionAtFolderP) conditionH;
01495                 {
01496                     BdbRef(CdbBdbSConditionAtFolderP) conditionRef;
01497                     if( CdbStatus::Success != ( result = theFolderH->findCondition( CdbPathName( itr.value( )),
01498                                                                                     conditionRef ))) {
01499                         cerr << errorStr << endl
01500                              << "    Failed to find the condition in the current folder." << endl
01501                              << "        CURRENT FOLDER: \"" << theCurrentPathName << "\"" << endl
01502                              << "        CONDITION:      \"" << itr.value( ) << "\"" << endl;
01503                         return result;
01504                     }
01505                     conditionH = conditionRef;
01506                 }
01507                 assert( !BdbIsNull(conditionH));
01508 
01509               // Save the condition
01510 
01511                 CdbPathName conditionFullPathName = theCurrentPathName + CdbPathName( itr.value( ));
01512                 {
01513                     std::string query;
01514 
01515                     ostringstream s;
01516 
01517                     s << "INSERT INTO " << theFoldersConditionsTableName << " "
01518                       << "(view_id,path,entry_type,created,description,pcond_origin_id,pcond_local_id) VALUES ("
01519                       << theInViewH->id( ) << ","
01520                       << "'" << myConnectionPtr->translate_string_to_escaped( conditionFullPathName.toString( )) << "',"
01521                       << "'C',"
01522                       << CdbTimeUtils::to_nsec( conditionH->created( )) << ","
01523                       << "'" << myConnectionPtr->translate_string_to_escaped( conditionH->description( ).head( )) << "',"
01524                       << conditionH->id( ).origin << ","
01525                       << conditionH->id( ).local << ")";
01526 
01527                     query = s.str( );
01528 
01529                     if(!execute_sql_query( query )) return CdbStatus::Error;
01530                 }
01531 
01532               // Convert the configuration collection (if any)
01533               //
01534               // NOTE: The null input collection is considered a normal result since some conditions
01535               //       may be used through a default collection of their parent view.
01536 
01537                 if( CdbStatus::Success != ( result = ::convertConfigCollection( theConditionsConfigsTableName,
01538                                                                                 conditionH->config( )))) {
01539                     cerr << errorStr << endl
01540                          << "    Failed to convert the configuration collection of the condition in the current folder." << endl
01541                          << "        CURRENT FOLDER: \"" << theCurrentPathName << "\"" << endl
01542                          << "        CONDITION:      \"" << itr.value( ) << "\"" << endl;
01543                     return result;
01544                 }
01545             }
01546         }
01547 
01548         // Browse folders in the input folder and copy them
01549 
01550         {
01551             CdbItr< const char* > itr;
01552             if( CdbStatus::Success != ( result = theFolderH->folderIterator( itr ))) {
01553                 cerr << errorStr << endl
01554                      << "    Failed to obtain an iterator of folder names." << endl
01555                      << "        CURRENT FOLDER: \"" << theCurrentPathName << "\"" << endl;
01556                 return result;
01557             }
01558             while( itr.next( )) {
01559 
01560               // Find the input folder objct
01561 
01562                 BdbHandle(CdbBdbSFolderP) folderH;
01563                 {
01564                     BdbRef(CdbBdbSFolderP) folderRef;
01565                     if( CdbStatus::Success != ( result = theFolderH->findFolder( CdbPathName( itr.value( )),
01566                                                                                  folderRef ))) {
01567                         cerr << errorStr << endl
01568                              << "    Failed to find the folder in the current folder." << endl
01569                              << "        CURRENT FOLDER: \"" << theCurrentPathName << "\"" << endl
01570                              << "        FOLDER:         \"" << itr.value( ) << "\"" << endl;
01571                         return result;
01572                     }
01573                     folderH = folderRef;
01574                 }
01575                 assert( !BdbIsNull(folderH));
01576 
01577               // Proceed down to the found folder
01578 
01579                 CdbPathName folderFullPathName = theCurrentPathName + itr.value( );
01580 
01581                 if( CdbStatus::Success != ( result = ::convertFoldersAndConditions( theFoldersConditionsTableName,
01582                                                                                     theConditionsConfigsTableName,
01583                                                                                     theInViewH,
01584                                                                                     folderH,
01585                                                                                     folderFullPathName ))) {
01586                     cerr << errorStr << endl
01587                          << "    Failed to convert folders starting from the found one." << endl
01588                          << "        CURRENT FOLDER: \"" << theCurrentPathName << "\"" << endl
01589                          << "        FOLDER:         \"" << itr.value( ) << "\"" << endl;
01590                     return result;
01591                 }
01592             }
01593         }
01594         return CdbStatus::Success;
01595     }
01596 
01597     CdbStatus
01598     convertConfigCollection( const std::string&                      theConditionsConfigsTableName,
01599                              const BdbRef(CdbBdbSConfigCollectionP)& theInputConfigCollectionRef )
01600     {
01601         if( BdbIsNull(theInputConfigCollectionRef)) return CdbStatus::Success;
01602 
01603         CdbBdbSConfigCollectionP::IteratorOfIntervals itr = theInputConfigCollectionRef->iterator( );
01604         while( itr.next( )) {
01605 
01606             CdbBdbSConfigInterval iVal = itr.value( );
01607 
01608             const char userRevisionFlag = ( iVal.value.useRevision ? 'Y' : 'N' );
01609             {
01610                 std::string query;
01611 
01612                 ostringstream s;
01613 
01614                 s << "INSERT INTO " << theConditionsConfigsTableName << " "
01615                   << "(entry_id,begin,end,use_revision,partition_id,revision) VALUES ("
01616                   << "LAST_INSERT_ID(),"
01617                   << CdbTimeUtils::to_nsec( iVal.begin ) << ","
01618                   << CdbTimeUtils::to_nsec( iVal.end ) << ","
01619                   << "'" << userRevisionFlag << "',"
01620                   << iVal.value.partition << ","
01621                   << CdbTimeUtils::to_nsec( iVal.value.revision ) << ")";
01622 
01623                 query = s.str( );
01624 
01625                 if(!execute_sql_query( query )) return CdbStatus::Error;
01626             }
01627         }
01628         return CdbStatus::Success;
01629     }
01630 /*
01631     CdbStatus
01632     testMetaDataConversion( )
01633     {
01634         const char* errorStr = "::testMetaDataConversion() - ERROR.";
01635 
01636         CdbStatus result = CdbStatus::Error;
01637 
01638       // Ask a user which collection to convert
01639 
01640         d_UShort originId = 0;
01641 
01642         cout << endl
01643              << "Please, enter the parameters of a condition." << endl
01644              << endl;
01645 
01646         d_UShort conditionId = 0xFFFF;
01647         {
01648             cout << "  Condition identifier : "; cin >> conditionId;
01649         }
01650         bool isPartitionableFlag = false;
01651         {
01652             int yesOrNo;
01653             cout << "Is partitionable [0/1] : "; cin >> yesOrNo;
01654             isPartitionableFlag = ( 0 != yesOrNo );
01655         }
01656         d_UShort partitionId = 0xFFFF;
01657         {
01658             cout << "  Partition identifier : "; cin >> partitionId;
01659         }
01660         d_UShort clusterId = 0xFFFF;
01661         {
01662             cout << "    Cluster identifier : "; cin >> clusterId;
01663         }
01664         d_UShort incrementNumber = 0xFFFF;
01665         {
01666             cout << "      Increment number : "; cin >> incrementNumber;
01667         }
01668         std::string dbIdRange = "";
01669         {
01670             cout << "       DBID Range Name : "; cin >> dbIdRange;
01671         }
01672         cout << endl
01673              << "Just for the record, you've entered the following parameters:" << endl
01674              << endl
01675              << "  Condition identifier : "   << conditionId << endl
01676              << "      Is partitionable : "   << ( isPartitionableFlag ? "Yes" : "No" ) << endl
01677              << "  Partition identifier : "   << partitionId << endl
01678              << "    Cluster identifier : "   << clusterId << endl
01679              << "      Increment number : "   << incrementNumber << endl
01680              << "       DBID Range Name : \"" << dbIdRange << "\"" << endl
01681              << endl;
01682 
01683       // Find the input metadata collection 
01684 
01685         BdbHandle(CdbBdbSMetaDataP) mdH;
01686         {
01687             BdbRef(CdbBdbSMetaDataP) mdRef;
01688             if( CdbStatus::Success != ( result = CdbBdbSUtils::findMetaData( mdRef,
01689                                                                              conditionId,
01690                                                                              isPartitionableFlag,
01691                                                                              partitionId,
01692                                                                              clusterId,
01693                                                                              incrementNumber,
01694                                                                              dbIdRange ))) {
01695                 cerr << errorStr << endl
01696                      << "    Failed to locate the input MetaData object." << endl;
01697                 return result;
01698             }
01699             mdH = mdRef;
01700         }
01701 
01702       // Create the output file
01703 
01704         TFile databaseFile( "con_cdb_test.root", "recreate" );
01705         if( databaseFile.IsZombie( )) {
01706             cerr << errorStr << endl
01707                  << "    Failed to (re-)create the file: \"" << databaseFile.GetName( ) << "\"." << endl;
01708             return CdbStatus::Error;
01709         }
01710 
01711       // Create a fake descriptor
01712 
01713         CdbRooRoRegistryDescriptorR registryDescriptor;
01714 
01715       // Proceed to the converion of the found MetaData object
01716 
01717         return ::convertMetaData( mdH,
01718                                   originId,
01719                                   conditionId,
01720                                   clusterId,
01721                                   isPartitionableFlag,
01722                                   partitionId,
01723                                   incrementNumber );
01724     }
01725 */
01726     CdbStatus
01727     convertMetaDataOfRegularCondition( const BdbHandle(CdbBdbSConditionP)& theConditionH,
01728                                        const BdbHandle(CdbBdbSRegistryP)&  theMasterRegistryH,
01729                                        d_UShort                            theOwnerOriginId )
01730     {
01731         const char* errorStr = "::convertMetaDataOfRegularCondition() - ERROR.";
01732 
01733         assert( !BdbIsNull(theConditionH));
01734         assert( !theConditionH->isPartitionable( ));
01735         assert( !BdbIsNull(theMasterRegistryH));
01736 
01737         CdbStatus result = CdbStatus::Error;
01738 
01739       // Get the DBID range of the condition's origin.
01740 
01741         std::string dbidRangeName;
01742         {
01743             BdbRef(CdbBdbSOriginP) originRef;
01744             if( CdbStatus::Success != ( result = theMasterRegistryH->originCollection( )->find( theOwnerOriginId,
01745                                                                                                 originRef ))) {
01746                 cerr << errorStr << endl
01747                      << "    An origin with ID=" << theOwnerOriginId << " was not found." << endl;
01748                 return result;
01749             }
01750             dbidRangeName = originRef->dbidrange( ).head( );
01751         }
01752 
01753       // Browse through increments of a cluster the condition is a member of. Select only
01754       // those increments the condition is participating in.
01755       //
01756       // NOTE: The condition might be creaed after certain increments were already
01757       //       closed. That's why we shoul skip those ones closed before.
01758 
01759         BdbHandle(CdbBdbSSimpleClusterP) clusterH = (const BdbRef(CdbBdbSSimpleClusterP)&)theConditionH->cluster( );
01760 
01761         d_ULong numIncrements = clusterH->numIncrements( );
01762         for( d_ULong incrementId = 0; incrementId < numIncrements; ++incrementId ) {
01763 
01764             if( verboseModeFlag ) {
01765                 cout << "increment=" << incrementId << endl;
01766             }
01767 
01768             CdbBdbSIncrement increment;
01769             if( CdbStatus::Success != ( result = clusterH->increment( incrementId,
01770                                                                       increment ))) {
01771                 cerr << errorStr << endl
01772                      << "    Failed to get increment " << incrementId << " from cluster " << clusterH->id( ) << endl
01773                      << "    of condition \"" << theConditionH->name( ) << "\"" << endl
01774                      << "    of the origin " << theOwnerOriginId << endl;
01775                 return result;
01776             }
01777 
01778           // Skip increments closed at or before the condition creation time.
01779           // These increments are not supposed to know about this condition.
01780 
01781             if( increment.end <= theConditionH->created( )) {
01782                 if( verboseModeFlag ) {
01783                     cout << "skipping the increment=" << incrementId << " since it was" << endl
01784                          << "    ended before the condition was created." << endl
01785                          << "    CONDITION CREATED: " << theConditionH->created( ) << endl
01786                          << "    PARTITION CLOSED : " << increment.end << endl;
01787                 }
01788                 continue;
01789             }
01790 
01791           // Find out the input "MetaData" object
01792 
01793             BdbHandle(CdbBdbSMetaDataP) mdH;
01794             {
01795                 BdbRef(CdbBdbSMetaDataP) mdRef;
01796                 if( CdbStatus::Success != ( result = CdbBdbSUtils::findMetaData( mdRef,
01797                                                                                  theConditionH->id( ),
01798                                                                                  theConditionH->isPartitionable( ),
01799                                                                                  0,
01800                                                                                  clusterH->id( ),
01801                                                                                  incrementId,
01802                                                                                  dbidRangeName.c_str( )))) {
01803                     cerr << errorStr << endl
01804                          << "    Failed to find the metadata object for condition \"" << theConditionH->name( ) << "\"." << endl
01805                          << "    See details above." << endl;
01806                     return result;
01807                 }
01808                 mdH = mdRef;
01809             }
01810 
01811           // Convert the object
01812 
01813             if( CdbStatus::Success != ( result = ::convertMetaData( mdH,
01814                                                                     theOwnerOriginId,
01815                                                                     theConditionH->id( ),
01816                                                                     clusterH->id( ),
01817                                                                     theConditionH->isPartitionable( ),
01818                                                                     0,
01819                                                                     incrementId ))) {
01820                 cerr << errorStr << endl
01821                      << "    Failed to translate the metadata object for condition \"" << theConditionH->name( ) << "\"." << endl
01822                      << "    See details above." << endl;
01823                 return result;
01824             }
01825         }
01826         return CdbStatus::Success;
01827     }
01828 
01829     CdbStatus
01830     convertMetaDataOfPartitionableCondition( const BdbHandle(CdbBdbSConditionP)& theConditionH,
01831                                              const BdbHandle(CdbBdbSRegistryP)&  theMasterRegistryH )
01832     {
01833         const char* errorStr = "::convertMetaDataOfPartitionableCondition() : ";
01834 
01835         assert( !BdbIsNull(theConditionH));
01836         assert( theConditionH->isPartitionable( ));
01837         assert( !BdbIsNull(theMasterRegistryH));
01838 
01839         CdbStatus result = CdbStatus::Error;
01840 
01841       // Get to the cluster.
01842 
01843         BdbHandle(CdbBdbSSimpleClusterP) clusterH = (const BdbRef(CdbBdbSSimpleClusterP)&)theConditionH->cluster( );
01844 
01845       // Get to the PartitinLayout at MASTER's Registry and iterate over
01846       // _instantiated_ partitions only.
01847 
01848         BdbHandle(CdbBdbSPartitionsLayoutP) pLayoutH = theMasterRegistryH->partitionsLayout( );
01849 
01850         CdbItr< d_UShort > pItr = pLayoutH->iterator( );
01851         while( pItr.next( )) {
01852 
01853             d_UShort partitionId = pItr.value( );
01854 
01855             if( verboseModeFlag ) {
01856                 cout << "partition ID=" << partitionId << endl;
01857             }
01858 
01859             BdbHandle( CdbBdbSPartitionP ) partitionH;
01860             {
01861                 BdbRef( CdbBdbSPartitionP ) partitionRef;
01862                 if( CdbStatus::Success != ( result = pLayoutH->find( partitionId,
01863                                                                      partitionRef ))) {
01864                     cerr << errorStr << endl
01865                          << "   Failed to find the partition corresponding to ID=" << partitionId << endl;
01866                     return result;
01867                 }
01868                 partitionH = partitionRef;
01869             }
01870 
01871           // Skip this partition if it's not instantiated yet or if it's closed at the time
01872           // of before the current condition was created.
01873 
01874             if( !partitionH->isInstantiated( )) {
01875                 if( verboseModeFlag ) {
01876                     cout << "skipping non-instantiated partition ID=" << partitionId << endl;
01877                 }
01878                 continue;
01879             }
01880             if( partitionH->isClosed( ) && ( partitionH->cell( ).endInsertion <= theConditionH->created( ))) {
01881                 if( verboseModeFlag ) {
01882                     cout << "skipping closed partition ID=" << partitionId << " since it was" << endl
01883                          << "    closed before the condition was created." << endl
01884                          << "    CONDITION CREATED: " << theConditionH->created( ) << endl
01885                          << "    PARTITION CLOSED : " << partitionH->cell( ).endInsertion << endl;
01886                 }
01887                 continue;
01888             }
01889 
01890           // Get the DBID range of the partition's orgin.
01891 
01892             std::string dbidRangeName;
01893             {
01894                 d_UShort originId = partitionH->originId( );
01895 
01896                 BdbRef(CdbBdbSOriginP) originRef;
01897                 if( CdbStatus::Success != ( result = theMasterRegistryH->originCollection( )->find( originId,
01898                                                                                                     originRef ))) {
01899                     cerr << errorStr << endl
01900                          << "    An origin with ID=" << originId << " was not found." << endl;
01901                     return result;
01902                 }
01903                 dbidRangeName = originRef->dbidrange( ).head( );
01904             }
01905 
01906           //  Browse through increments
01907 
01908             d_ULong numIncrements = partitionH->numIncrements( );
01909             for( d_ULong incrementId = 0; incrementId < numIncrements; ++incrementId ) {
01910 
01911                 if( verboseModeFlag ) {
01912                     cout << "increment=" << incrementId << endl;
01913                 }
01914 
01915                 CdbBdbSIncrement increment;
01916                 if( CdbStatus::Success != ( result = partitionH->increment( incrementId,
01917                                                                             increment ))) {
01918                     cerr << errorStr << endl
01919                          << "    Failed to get increment " << incrementId << " from partition " << partitionId << endl
01920                          << "    of condition \"" << theConditionH->name( ) << "\"" << endl;
01921                     return result;
01922                 }
01923 
01924               // Skip increments closed at or before the condition creation time.
01925               // These increments are not supposed to know about this condition.
01926 
01927                 if( increment.end <= theConditionH->created( )) {
01928                     if( verboseModeFlag ) {
01929                         cout << "skipping the increment=" << incrementId << " since it was" << endl
01930                          << "    ended before the condition was created." << endl
01931                          << "    CONDITION CREATED: " << theConditionH->created( ) << endl
01932                          << "    PARTITION CLOSED : " << increment.end << endl;
01933                     }
01934                     continue;
01935                 }
01936 
01937               // Find out the input "MetaData" object
01938 
01939                 BdbHandle(CdbBdbSMetaDataP) mdH;
01940                 {
01941                     BdbRef(CdbBdbSMetaDataP) mdRef;
01942                     if( CdbStatus::Success != ( result = CdbBdbSUtils::findMetaData( mdRef,
01943                                                                                      theConditionH->id( ),
01944                                                                                      theConditionH->isPartitionable( ),
01945                                                                                      partitionId,
01946                                                                                      clusterH->id( ),
01947                                                                                      incrementId,
01948                                                                                      dbidRangeName ))) {
01949                         cerr << errorStr << endl
01950                              << "    Failed to find the metadata object for condition \"" << theConditionH->name( ) << "\"." << endl
01951                              << "    See details above." << endl;
01952                         return result;
01953                     }
01954                     mdH = mdRef;
01955                 }
01956 
01957               // Convert the object
01958 
01959                 if( CdbStatus::Success != ( result = ::convertMetaData( mdH,
01960                                                                         partitionH->originId( ),
01961                                                                         theConditionH->id( ),
01962                                                                         clusterH->id( ),
01963                                                                         theConditionH->isPartitionable( ),
01964                                                                         partitionId,
01965                                                                         incrementId ))) {
01966                     cerr << errorStr << endl
01967                          << "    Failed to translate the metadata object for condition \"" << theConditionH->name( ) << "\"." << endl
01968                          << "    See details above." << endl;
01969                     return result;
01970                 }
01971             }
01972         }
01973         return CdbStatus::Success;
01974     }
01975 
01976     CdbStatus
01977     convertMetaData( const BdbHandle(CdbBdbSMetaDataP)& theInMetaDataH,
01978                      d_UShort                           theOriginId,
01979                      d_UShort                           theConditionId,
01980                      d_UShort                           theClusterId,
01981                      bool                               isPartitionableFlag,
01982                      d_UShort                           thePartitionId,
01983                      d_UShort                           theIncrementId )
01984     {
01985         const char* errorStr = "::convertMetaData() - ERROR.";
01986 
01987         assert( !BdbIsNull(theInMetaDataH));
01988 
01989         CdbStatus result = CdbStatus::Error;
01990 
01991       // Build the names of relevant tables
01992 
01993         std::string baseTableName;
01994         {
01995             ostringstream s;
01996             s << myConnectionPtr->database( ) << ".o" << theOriginId;
01997             if( isPartitionableFlag ) s << "_p" << thePartitionId;
01998             s << "_c" << theClusterId
01999               << "_i" << theIncrementId
02000               << "_";
02001             baseTableName = s.str( );
02002         }
02003         const std::string payloadObjectsTableName    = baseTableName + "payload";
02004         const std::string originalIntervalsTableName = baseTableName + "original";
02005         const std::string revisionsTableName         = baseTableName + "revisions";
02006         const std::string visibleIntervalsTableName  = baseTableName + "visible";
02007 
02008       // Translate the collection of 'original intervals
02009       //
02010       // NOTE; We'll also need 'stored' timestamps from this collection later when  
02011       //       translating 'visible' intervals. The timestamps will be used as a sort
02012       //       of 'foreign' keys for 'visible' intervals.
02013       //
02014       //       ATTENTION: This is based on an assumption that no two (or more) original
02015       //                  intervals will have the same 'stored' time. Actually we're
02016       //                  going to perform this check below when converting 'original'
02017       //                  intervals.
02018       //
02019       //       Indexes of the vector with 'stored' values to be filled below are used
02020       //       by "Bdb/Shared" implementation of CDB as a back link from 'visible'
02021       //       to 'original' intervals.
02022 
02023         std::vector<BdbTime> oiStoredTimestamps;
02024         {
02025             BdbHandle(CdbBdbSOiCollectionP) oiCollectionH = theInMetaDataH->originaIntervalsCollection( );
02026             d_ULong numOriginalElements = oiCollectionH->size( );
02027             assert( numOriginalElements > 0 );
02028 
02029           // Note, that it's very important that the 0 element had BdbTime::minusInfinity
02030           // as some 'visible' intervals representing 'holes' (no actual persistnet object behind)
02031           // would be using this below.
02032 
02033             oiStoredTimestamps.resize( numOriginalElements, BdbTime::minusInfinity );
02034 
02035             for( d_ULong idx = 1; idx < numOriginalElements; ++idx ) {
02036 
02037                 CdbBdbSOi oi;
02038 
02039                 BdbTime beginDuration;  // will be filled by the call, but we're not going to use it
02040                 BdbTime endDuration;    // -//-
02041 
02042                 if( CdbStatus::Success != ( result = oiCollectionH->find( idx,
02043                                                                           oi,
02044                                                                           beginDuration,
02045                                                                           endDuration ))) {
02046                     cerr << errorStr << endl
02047                          << "    Failed to obtain an 'original' interval with IDX = " << idx << " from the collection." << endl;
02048                     return result;
02049                 }
02050 
02051               // Verify if the 'stored' time of the interval is _strictly_ more than the one
02052               // previously stored. This test is meant to ensure two things:
02053               //
02054               // 1. That there is no corruption in the collection.
02055               // 2. The collection doesn't have two (or more) intervals stored at exactly
02056               //    the same moment of time.
02057 
02058                 if( oi.inserted <= oiStoredTimestamps[idx-1] ) {
02059                     cerr << errorStr << endl
02060                          << "    Found an 'original' interval with IDX = " << idx << " whose 'inserted' timestamp" << endl
02061                          << "    is not strictly newer than the previously stored one. The collection can be corrupted." << endl
02062                          << "        CONDITION ID:           " << theConditionId << endl
02063                          << "        DESTINATION TABLE NAME: \"" << originalIntervalsTableName << "\"" << endl
02064                          << "        PREVIOUS TIMESTAMP:     " << CdbTimeUtils::time2string( oiStoredTimestamps[idx-1] ) << " : " << oiStoredTimestamps[idx-1] << endl
02065                          << "        CURRENT  TIMESTAMP:     " << CdbTimeUtils::time2string( oi.inserted )               << " : " << oi.inserted << endl;
02066                     return CdbStatus::Error;
02067                 }
02068                 oiStoredTimestamps[idx] = oi.inserted;
02069 
02070               // Create an output "payload" object
02071 
02072                 {
02073                     std::string query;
02074 
02075                     ostringstream s;
02076 
02077                     s << "INSERT INTO " << payloadObjectsTableName << " "
02078                       << "(legacy_id) VALUES ("
02079                       << "'" << oi.object.sprint( ) << "')";
02080 
02081                     query = s.str( );
02082 
02083                     if(!execute_sql_query( query )) return CdbStatus::Error;
02084                 }
02085 
02086               // Create an output "original" object
02087 
02088                 {
02089                     std::string query;
02090 
02091                     ostringstream s;
02092 
02093                     s << "INSERT INTO " << originalIntervalsTableName << " "
02094                       << "(condition_id,stored,begin,end,object_id) VALUES ("
02095                       << theConditionId << ","
02096                       << CdbTimeUtils::to_nsec( oi.inserted ) << ","
02097                       << CdbTimeUtils::to_nsec( oi.begin ) << ","
02098                       << CdbTimeUtils::to_nsec( oi.end ) << ","
02099                       << "LAST_INSERT_ID())";
02100 
02101                     query = s.str( );
02102 
02103                     if(!execute_sql_query( query )) return CdbStatus::Error;
02104                 }
02105             }
02106 
02107           // Insert a special original object which will be reffered to by 'visible' intervals
02108           // representing 'holes' (no actaul 'original' object) in the validity timeline of
02109           // the local MetaData.
02110           //
02111           // NOTES:
02112           //
02113           //   1. There is just one special object of this type per conditions and per MetaData.
02114           //   2. This object has a special "stored/insertion" timestamp in the minus infinity.
02115           //   3. There won't be any "payload" entry for this object.
02116 
02117             {
02118                 std::string query;
02119 
02120                 ostringstream s;
02121 
02122                 s << "INSERT INTO " << originalIntervalsTableName << " "
02123                   << "(condition_id,stored) VALUES ("
02124                   << theConditionId << ","
02125                   << CdbTimeUtils::to_nsec( BdbTime::minusInfinity ) << ")";
02126 
02127                 query = s.str( );
02128 
02129                 if(!execute_sql_query( query )) return CdbStatus::Error;
02130             }
02131 
02132             cout << CdbTimeUtils::time2string( BdbTime::now( )) << "::" << originalIntervalsTableName << " [" << theOriginId << "::" << theConditionId << "] " << numOriginalElements-1 << " objects" << endl;
02133         }
02134 
02135       // Iterate over known revisions and convert them
02136 
02137         CdbItr<BdbTime> itr;
02138         if( CdbStatus::Success != ( result = theInMetaDataH->revisionIdIterator( itr ))) {
02139             cerr << errorStr << endl
02140                  << "    Failed to set up an iterator of revision identifiers." << endl;
02141             return result;
02142         }
02143         while( itr.next( )) {
02144 
02145             BdbTime revisionId = itr.value( );
02146 
02147           // Find the input revision
02148 
02149             BdbHandle(CdbBdbSRevisionP) revisionH;
02150             {
02151                 BdbRef(CdbBdbSRevisionP) revisionRef;
02152                 if( CdbStatus::Success != ( result = theInMetaDataH->findRevision( revisionId,
02153                                                                                    revisionRef ))) {
02154                     cerr << errorStr << endl
02155                         << "    Failed to find a revision with ID = " << CdbTimeUtils::time2string( revisionId ) << endl;
02156                     return result;
02157                 }
02158                 revisionH = revisionRef;
02159             }
02160 
02161           // Create the output revision object
02162 
02163             {
02164                 std::string query;
02165 
02166                 ostringstream s;
02167 
02168                 s << "INSERT INTO " << revisionsTableName << " "
02169                   << "(condition_id,id,name,created,description) VALUES ("
02170                   << theConditionId << ","
02171                   << CdbTimeUtils::to_nsec( revisionH->id( )) << ","
02172                   << "'" << myConnectionPtr->translate_string_to_escaped( revisionH->name( ).head( )) << "',"
02173                   << CdbTimeUtils::to_nsec( revisionH->created( )) << ","
02174                   << "'" << myConnectionPtr->translate_string_to_escaped( revisionH->description( ).head( )) << "')";
02175 
02176                 query = s.str( );
02177 
02178                 if(!execute_sql_query( query )) return CdbStatus::Error;
02179             }
02180 
02181           // Iterate over 'visible' intervals and convert them
02182 
02183             BdbHandle(CdbBdbSViCollectionP) viCollectionH = revisionH->collection( );
02184             assert( !BdbIsNull(viCollectionH));
02185 
02186             CdbBdbSViCollectionP::IteratorOfIntervals viItr = viCollectionH->iterator( );
02187             while( viItr.next( )) {
02188 
02189                 CdbBdbSVi iVal = viItr.value( );
02190 
02191               // Create an output "visible" object
02192 
02193                 {
02194                     std::string query;
02195 
02196                     ostringstream s;
02197 
02198                     s << "INSERT INTO " << visibleIntervalsTableName << " "
02199                       << "(condition_id,revision_id,begin,end,original_stored) VALUES ("
02200                       << theConditionId << ","
02201                       << CdbTimeUtils::to_nsec( revisionH->id( )) << ","
02202                       << CdbTimeUtils::to_nsec( iVal.begin ) << ","
02203                       << CdbTimeUtils::to_nsec( iVal.end ) << ","
02204                       << CdbTimeUtils::to_nsec( oiStoredTimestamps[iVal.value] ) << ")";
02205 
02206                     query = s.str( );
02207 
02208                     if(!execute_sql_query( query )) return CdbStatus::Error;
02209                 }
02210             }
02211         }
02212         return CdbStatus::Success;
02213     }
02214 
02215     CdbStatus
02216     printPersistentClasses( )
02217     {
02218         const char* errorStr = "::printPersistentClasses() - ERROR.";
02219 
02220         CdbStatus result = CdbStatus::Error;
02221 
02222       // Get the MASTER registry.
02223 
02224         BdbHandle(CdbBdbSRegistryP) masterRegistryH;
02225         if( CdbStatus::Success != ( result = CdbBdbSRegistryP::findMaster( masterRegistryH ))) {
02226             cerr << errorStr << endl
02227                  << "    Failed to find the MASTER registry." << endl;
02228             return result;
02229         }
02230 
02231       // Iterate over known registries and analyses them one-by-one if the corresponding origins
02232       // are instantiated in the input database.
02233 
02234         BdbHandle(CdbBdbSOriginCollectionP) originCollectionH = masterRegistryH->originCollection( );
02235 
02236         CdbBdbSOriginCollectionP::IteratorOfIdentifiers itr = originCollectionH->iterator_identifiers( );
02237         while( itr.next( )) {
02238 
02239           // Get the persistent registry object
02240 
02241             d_UShort conditionOwnerOriginId = itr.value( );
02242 
02243             BdbHandle(CdbBdbSOriginP) originH;
02244             {
02245                 BdbRef(CdbBdbSOriginP) originRef;
02246                 if( CdbStatus::Success != ( result = originCollectionH->find( conditionOwnerOriginId,
02247                                                                               originRef ))) {
02248 
02249                     cerr << errorStr << endl
02250                          << "    Failed to find an origin with ID = " << conditionOwnerOriginId << "." << endl
02251                          << "    The input database may not be properly initialized." << endl;
02252                     return result;
02253                 }
02254                 originH = originRef;
02255             }
02256 
02257           // Try to get the corresponding registry. If it doesn't exist (not instantiated)
02258           // then we will skip that registry.
02259 
02260             BdbHandle(CdbBdbSRegistryP) registryH;
02261             {
02262                 if( CdbStatus::Success != ( result = CdbBdbSRegistryP::findByOrigin( registryH,
02263                                                                                      conditionOwnerOriginId ))) {
02264                     if( CdbStatus::NotFound == result ) {
02265 
02266                       // The origin is not currently instantiated in the input database. This may happen
02267                       // when the origin's data are yet to be imported.
02268 
02269                         continue;
02270 
02271                     } else {
02272                         cerr << errorStr << endl
02273                              << "    Failed to find a registry for origin ID = " << conditionOwnerOriginId << "." << endl;
02274                         return result;
02275                     }
02276                 }
02277             }
02278 
02279           // Proceed to 'physical' conditions of the collection
02280 
02281             if( registryH->hasLocalCollections( )) {
02282 
02283                 BdbHandle(CdbBdbSConditionCollectionP) conditionCollectionH = registryH->conditionCollection( );
02284 
02285                 CdbBdbSConditionCollectionP::IteratorOfIdentifiers itr = conditionCollectionH->iterator_identifiers( );
02286                 while( itr.next( )) {
02287 
02288                   // Get the input condition
02289 
02290                     d_UShort conditionId = itr.value( );
02291 
02292                     BdbHandle(CdbBdbSConditionP) conditionH;
02293                     {
02294                         BdbRef(CdbBdbSConditionP) conditionRef;
02295                         if( CdbStatus::Success != ( result = conditionCollectionH->find( conditionId,
02296                                                                                          conditionRef ))) {
02297                             cerr << errorStr << endl
02298                                  << "    A condition with ID = " << conditionId << " was not found." << endl;
02299                             return result;
02300                         }
02301                         conditionH = conditionRef;
02302                     }
02303 
02304                   // Find all relevant MetaData objects
02305 
02306                     if( conditionH->isPartitionable( )) {
02307 
02308                       // ** PARTITIONABLE **
02309 
02310                         if( excludePartitionableFlag ) continue;
02311 
02312                         BdbHandle(CdbBdbSSimpleClusterP) clusterH = (const BdbRef(CdbBdbSSimpleClusterP)&)conditionH->cluster( );
02313 
02314                       // Get to the PartitinLayout at MASTER's Registry and iterate over
02315                       // _instantiated_ partitions only.
02316 
02317                         BdbHandle(CdbBdbSPartitionsLayoutP) pLayoutH = masterRegistryH->partitionsLayout( );
02318 
02319                         CdbItr< d_UShort > pItr = pLayoutH->iterator( );
02320                         while( pItr.next( )) {
02321 
02322                             d_UShort partitionId = pItr.value( );
02323 
02324                             BdbHandle( CdbBdbSPartitionP ) partitionH;
02325                             {
02326                                 BdbRef( CdbBdbSPartitionP ) partitionRef;
02327                                 if( CdbStatus::Success != ( result = pLayoutH->find( partitionId,
02328                                                                                      partitionRef ))) {
02329                                     cerr << errorStr << endl
02330                                          << "   Failed to find the partition corresponding to ID=" << partitionId << endl;
02331                                     return result;
02332                                 }
02333                                 partitionH = partitionRef;
02334                             }
02335 
02336                           // Skip this partition if it's not instantiated yet or if it's closed at the time
02337                           // of before the current condition was created.
02338 
02339                             if( !partitionH->isInstantiated( )) continue;
02340                             if( partitionH->isClosed( ) && ( partitionH->cell( ).endInsertion <= conditionH->created( ))) continue;
02341 
02342                           // Get the DBID range of the partition's orgin.
02343 
02344                             std::string dbidRangeName;
02345                             {
02346                                 BdbRef(CdbBdbSOriginP) originRef;
02347                                 if( CdbStatus::Success != ( result = masterRegistryH->originCollection( )->find( partitionH->originId( ),
02348                                                                                                                  originRef ))) {
02349                                     cerr << errorStr << endl
02350                                          << "    An origin with ID=" << partitionH->originId( ) << " was not found." << endl;
02351                                     return result;
02352                                 }
02353                                 dbidRangeName = originRef->dbidrange( ).head( );
02354                             }
02355 
02356                           //  Browse through increments
02357 
02358                             d_ULong numIncrements = partitionH->numIncrements( );
02359                             for( d_ULong i = 0; i < numIncrements; ++i ) {
02360 
02361                                 CdbBdbSIncrement increment;
02362                                 if( CdbStatus::Success != ( result = partitionH->increment( i,
02363                                                                                             increment ))) {
02364                                     cerr << errorStr << endl
02365                                          << "    Failed to get increment " << i << " from partition " << partitionId << endl
02366                                          << "    of condition \"" << conditionH->name( ) << "\"" << endl;
02367                                     return result;
02368                                 }
02369 
02370                               // Skip increments closed at or before the condition creation time.
02371                               // These increments are not supposed to know about this condition.
02372 
02373                                 if( increment.end <= conditionH->created( )) continue;
02374 
02375                               // Find out the input "MetaData" object
02376 
02377                                 BdbHandle(CdbBdbSMetaDataP) mdH;
02378                                 {
02379                                     BdbRef(CdbBdbSMetaDataP) mdRef;
02380                                     if( CdbStatus::Success != ( result = CdbBdbSUtils::findMetaData( mdRef,
02381                                                                                                      conditionH->id( ),
02382                                                                                                      conditionH->isPartitionable( ),
02383                                                                                                      partitionId,
02384                                                                                                      clusterH->id( ),
02385                                                                                                      i,
02386                                                                                                      dbidRangeName ))) {
02387                                         cerr << errorStr << endl
02388                                              << "    Failed to find the metadata object for condition \"" << conditionH->name( ) << "\"." << endl
02389                                              << "    See details above." << endl;
02390                                         return result;
02391                                     }
02392                                     mdH = mdRef;
02393                                 }
02394 
02395                               // Browse the 'original' collection
02396 
02397                                 std::map<std::string,unsigned int> counters;
02398 
02399                                 const BdbHandle(CdbBdbSOiCollectionP) collectionH = mdH->originaIntervalsCollection( );
02400 
02401                                 d_ULong numOriginalElements = collectionH->size( );
02402 
02403                                 for( d_ULong idx = 1; idx < numOriginalElements; ++idx ) {
02404 
02405                                     CdbBdbSOi oi;
02406 
02407                                     BdbTime beginDuration;  // will be filled by the call, but we're not going to use it
02408                                     BdbTime endDuration;    // -//-
02409 
02410                                     if( CdbStatus::Success != ( result = collectionH->find( idx,
02411                                                                                             oi,
02412                                                                                             beginDuration,
02413                                                                                             endDuration ))) {
02414                                         cerr << errorStr << endl
02415                                              << "    Failed to obtain an 'original' interval with IDX = " << idx << " from the collection." << endl;
02416                                         return result;
02417                                     }
02418 
02419                                     std::string typeName = oi.object.typeName( );
02420 
02421                                     unsigned int nObjectsOfThisClass = 0;
02422                                     if( 0 != counters.count( typeName )) nObjectsOfThisClass = counters[ typeName ];
02423                                     counters[ typeName ] = ++nObjectsOfThisClass;
02424                                 }
02425 
02426                               // Print results
02427 
02428                                 for( std::map<std::string,unsigned int>::const_iterator itr = counters.begin( );
02429                                                                                         itr != counters.end( );
02430                                                                                       ++itr ) {
02431                                     std::string typeName = (*itr).first;
02432                                     unsigned int nObjectsOfThisClass = (*itr).second;
02433                                     cout << conditionOwnerOriginId << "::" << conditionH->id( ) << " [" << partitionH->id( ) << "," << clusterH->id( ) << "," << i << "] \"" << typeName << "\" " << nObjectsOfThisClass << endl;
02434                                 }
02435                             }
02436                         }
02437 
02438                     } else {
02439 
02440                       // ** REGULAR **
02441 
02442                         if( excludeRegularFlag ) continue;
02443 
02444                       // Get the DBID range of the condition's origin.
02445 
02446                         std::string dbidRangeName;
02447                         {
02448                             BdbRef(CdbBdbSOriginP) originRef;
02449                             if( CdbStatus::Success != ( result = masterRegistryH->originCollection( )->find( conditionOwnerOriginId,
02450                                                                                                              originRef ))) {
02451                                 cerr << errorStr << endl
02452                                      << "    An origin with ID=" << conditionOwnerOriginId << " was not found." << endl;
02453                                 return result;
02454                             }
02455                             dbidRangeName = originRef->dbidrange( ).head( );
02456                         }
02457 
02458                       // Browse through increments of a cluster the condition is a member of. Select only
02459                       // those increments the condition is participating in.
02460                       //
02461                       // NOTE: The condition might be creaed after certain increments were already
02462                       //       closed. That's why we shoul skip those ones closed before.
02463 
02464                         BdbHandle(CdbBdbSSimpleClusterP) clusterH = (const BdbRef(CdbBdbSSimpleClusterP)&)conditionH->cluster( );
02465 
02466                         d_ULong numIncrements = clusterH->numIncrements( );
02467                         for( d_ULong i = 0; i < numIncrements; ++i ) {
02468 
02469                             CdbBdbSIncrement increment;
02470                             if( CdbStatus::Success != ( result = clusterH->increment( i,
02471                                                                                       increment ))) {
02472                                 cerr << errorStr << endl
02473                                      << "    Failed to get increment " << i << " from cluster " << clusterH->id( ) << endl
02474                                      << "    of condition \"" << conditionH->name( ) << "\"" << endl;
02475                                 return result;
02476                             }
02477 
02478                           // Skip increments closed at or before the condition creation time.
02479                           // These increments are not supposed to know about this condition.
02480 
02481                             if( increment.end <= conditionH->created( )) continue;
02482 
02483                           // Find out the input "MetaData" object
02484 
02485                             BdbHandle(CdbBdbSMetaDataP) mdH;
02486                             {
02487                                 BdbRef(CdbBdbSMetaDataP) mdRef;
02488                                 if( CdbStatus::Success != ( result = CdbBdbSUtils::findMetaData( mdRef,
02489                                                                                                  conditionH->id( ),
02490                                                                                                  conditionH->isPartitionable( ),
02491                                                                                                  0,
02492                                                                                                  clusterH->id( ),
02493                                                                                                  i,
02494                                                                                                  dbidRangeName.c_str( )))) {
02495                                     cerr << errorStr << endl
02496                                          << "    Failed to find the metadata object for condition \"" << conditionH->name( ) << "\"." << endl
02497                                          << "    See details above." << endl;
02498                                     return result;
02499                                 }
02500                                 mdH = mdRef;
02501                             }
02502 
02503                           // Browse the 'original' collection
02504 
02505                             std::map<std::string,unsigned int> counters;
02506 
02507                             const BdbHandle(CdbBdbSOiCollectionP) collectionH = mdH->originaIntervalsCollection( );
02508 
02509                             d_ULong numOriginalElements = collectionH->size( );
02510 
02511                             for( d_ULong idx = 1; idx < numOriginalElements; ++idx ) {
02512 
02513                                 CdbBdbSOi oi;
02514 
02515                                 BdbTime beginDuration;  // will be filled by the call, but we're not going to use it
02516                                 BdbTime endDuration;    // -//-
02517 
02518                                 if( CdbStatus::Success != ( result = collectionH->find( idx,
02519                                                                                         oi,
02520                                                                                         beginDuration,
02521                                                                                         endDuration ))) {
02522                                     cerr << errorStr << endl
02523                                          << "    Failed to obtain an 'original' interval with IDX = " << idx << " from the collection." << endl;
02524                                     return result;
02525                                 }
02526 
02527                                 std::string typeName = oi.object.typeName( );
02528 
02529                                 unsigned int nObjectsOfThisClass = 0;
02530                                 if( 0 != counters.count( typeName )) nObjectsOfThisClass = counters[ typeName ];
02531                                 counters[ typeName ] = ++nObjectsOfThisClass;
02532                             }
02533 
02534                           // Print results
02535 
02536                             for( std::map<std::string,unsigned int>::const_iterator itr = counters.begin( );
02537                                                                                     itr != counters.end( );
02538                                                                                   ++itr ) {
02539                                 std::string typeName = (*itr).first;
02540                                 unsigned int nObjectsOfThisClass = (*itr).second;
02541                                 cout << conditionOwnerOriginId << "::" << conditionH->id( ) << " [" << 0 << "," << clusterH->id( ) << "," << i << "] \"" << typeName << "\" " << nObjectsOfThisClass << endl;
02542                             }
02543                         }
02544                     }
02545                 }
02546             }
02547         }
02548         return CdbStatus::Success;
02549     }
02550 
02551     CdbStatus
02552     browseConditionsInFolder( d_UShort                      theOriginId,
02553                               d_UShort                      theViewId,
02554                               const CdbPathName&            theParentFolderPath,
02555                               const BdbRef(CdbBdbSFolderP)& theParentFolderRef  )
02556     {
02557         const char* errorStr = "::browseConditionsInFolder() - ERROR.";
02558 
02559         assert( theParentFolderPath.isAbsolute( ));
02560         assert( !BdbIsNull(theParentFolderRef));
02561 
02562         const BdbHandle(CdbBdbSFolderP) parentFolderH = theParentFolderRef;
02563 
02564         CdbStatus result = CdbStatus::Error;
02565 
02566       // Find all conditions directly attached to the parent folder
02567 
02568         {
02569             CdbItr< const char* > itr;
02570             if( CdbStatus::Success != ( result = parentFolderH->conditionIterator( itr ))) {
02571                 cerr << errorStr << endl
02572                      << "    Failed to set up an iterator of conditions for folder \"" << theParentFolderPath.toString( ) << "\"." << endl;
02573                 return result;
02574             }
02575             while( itr.next( )) {
02576 
02577                 CdbPathName conditionPath( itr.value( ));
02578 
02579                 BdbRef(CdbBdbSConditionAtFolderP) conditionRef;
02580                 if( CdbStatus::Success != ( result = parentFolderH->findCondition( conditionPath,
02581                                                                                    conditionRef ))) {
02582                     cerr << errorStr << endl
02583                          << "    Failed to find the condition \"" <<  conditionPath.toString( ) << "\"" << endl
02584                          << "    in folder \"" << theParentFolderPath.toString( ) << "\"." << endl;
02585                     return result;
02586                 }
02587 
02588                 CdbBdbSId   id                = conditionRef->id( );
02589                 CdbPathName conditionFullPath = theParentFolderPath + conditionPath;
02590 
02591                 cout << theOriginId << "::" << theViewId << " " << id.origin << "::" << id.local << " \"" << conditionFullPath.toString( ) << "\"" << endl;
02592             }
02593         }
02594 
02595       // Find all sub-folders directly attached to the parent folder and proceed to them
02596 
02597         {
02598             CdbItr< const char* > itr;
02599             if( CdbStatus::Success != ( result = parentFolderH->folderIterator( itr ))) {
02600                 cerr << errorStr << endl
02601                      << "    Failed to set up an iterator of sub-folders for folder \"" << theParentFolderPath.toString( ) << "\"." << endl;
02602                 return result;
02603             }
02604             while( itr.next( )) {
02605 
02606                 CdbPathName folderPath( itr.value( ));
02607 
02608                 BdbRef(CdbBdbSFolderP) folderRef;
02609                 if( CdbStatus::Success != ( result = parentFolderH->findFolder( folderPath,
02610                                                                                 folderRef ))) {
02611                     cerr << errorStr << endl
02612                          << "    Failed to find the sub-folder \"" <<  folderPath.toString( ) << "\"" << endl
02613                          << "    in folder \"" << theParentFolderPath.toString( ) << "\"." << endl;
02614                     return result;
02615                 }
02616 
02617                 CdbPathName folderFullPath = theParentFolderPath + folderPath;
02618 
02619                 if( CdbStatus::Success != ( result = ::browseConditionsInFolder( theOriginId,
02620                                                                                  theViewId,
02621                                                                                  folderFullPath,
02622                                                                                  folderRef ))) {
02623                     cerr << errorStr << endl
02624                          << "    Failed to browse conditions in the sub-folder \"" <<  folderPath.toString( ) << "\"" << endl
02625                          << "    of folder \"" << theParentFolderPath.toString( ) << "\"." << endl;
02626                     return result;
02627                 }
02628             }
02629         }
02630         return CdbStatus::Success;
02631     }
02632 
02633     CdbStatus
02634     printPersistentConditions( )
02635     {
02636         const char* errorStr = "::printPersistentConditions() - ERROR.";
02637 
02638         CdbStatus result = CdbStatus::Error;
02639 
02640       // Get the MASTER registry.
02641 
02642         BdbHandle(CdbBdbSRegistryP) masterRegistryH;
02643         if( CdbStatus::Success != ( result = CdbBdbSRegistryP::findMaster( masterRegistryH ))) {
02644             cerr << errorStr << endl
02645                  << "    Failed to find the MASTER registry." << endl;
02646             return result;
02647         }
02648 
02649       // Iterate over known registries and analyses them one-by-one if the corresponding origins
02650       // are instantiated in the input database.
02651 
02652         BdbHandle(CdbBdbSOriginCollectionP) originCollectionH = masterRegistryH->originCollection( );
02653 
02654         CdbBdbSOriginCollectionP::IteratorOfIdentifiers itr = originCollectionH->iterator_identifiers( );
02655         while( itr.next( )) {
02656 
02657           // Get the persistent registry object
02658 
02659             d_UShort viewOwnerOriginId = itr.value( );
02660 
02661             BdbHandle(CdbBdbSOriginP) originH;
02662             {
02663                 BdbRef(CdbBdbSOriginP) originRef;
02664                 if( CdbStatus::Success != ( result = originCollectionH->find( viewOwnerOriginId,
02665                                                                               originRef ))) {
02666 
02667                     cerr << errorStr << endl
02668                          << "    Failed to find an origin with ID = " << viewOwnerOriginId << "." << endl
02669                          << "    The input database may not be properly initialized." << endl;
02670                     return result;
02671                 }
02672                 originH = originRef;
02673             }
02674 
02675           // Try to get the corresponding registry. If it doesn't exist (not instantiated)
02676           // then we will skip that registry.
02677 
02678             BdbHandle(CdbBdbSRegistryP) registryH;
02679             {
02680                 if( CdbStatus::Success != ( result = CdbBdbSRegistryP::findByOrigin( registryH,
02681                                                                                      viewOwnerOriginId ))) {
02682                     if( CdbStatus::NotFound == result ) {
02683 
02684                       // The origin is not currently instantiated in the input database. This may happen
02685                       // when the origin's data are yet to be imported.
02686 
02687                         continue;
02688 
02689                     } else {
02690                         cerr << errorStr << endl
02691                              << "    Failed to find a registry for origin ID = " << viewOwnerOriginId << "." << endl;
02692                         return result;
02693                     }
02694                 }
02695             }
02696 
02697           // Proceed to 'views' of this registry
02698 
02699             if( registryH->hasLocalCollections( )) {
02700 
02701                 BdbHandle(CdbBdbSViewCollectionP) viewCollectionH = registryH->viewCollection( );
02702 
02703                 CdbBdbSViewCollectionP::IteratorOfIdentifiers itr = viewCollectionH->iterator_identifiers( );
02704                 while( itr.next( )) {
02705 
02706                   // Get the view
02707 
02708                     d_UShort viewId = itr.value( );
02709 
02710                     BdbHandle(CdbBdbSViewP) viewH;
02711                     {
02712                         BdbRef(CdbBdbSViewP) viewRef;
02713                         if( CdbStatus::Success != ( result = viewCollectionH->find( viewId,
02714                                                                                     viewRef ))) {
02715                             cerr << errorStr << endl
02716                                  << "    A view with ID = " << viewId << " was not found." << endl;
02717                             return result;
02718                         }
02719                         viewH = viewRef;
02720                     }
02721 
02722                   // Skip the "main" view as it's not supposed to have any valueable information
02723 
02724                     if( std::string( "main" ) == viewH->name( ).head( )) continue;
02725 
02726                   // Browse the view
02727 
02728                     if( CdbStatus::Success != ( result = ::browseConditionsInFolder( viewOwnerOriginId,
02729                                                                                      viewId,
02730                                                                                      CdbPathName( viewH->rootFolder( )->name( ).head( )),
02731                                                                                      viewH->rootFolder( )))) {
02732                         cerr << errorStr << endl
02733                              << "    Failed to browse conditions in the 'root' folder of a view with ID = " << viewId << "." << endl;
02734                         return result;
02735                     }
02736                 }
02737             }
02738         }
02739         return CdbStatus::Success;
02740     }
02741 }
02742 
02743 /////////////////
02744 // End Of File //
02745 /////////////////

Generated on Mon Dec 5 18:21:59 2005 for CDB by doxygen1.3-rc3