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

CdbActiveSchemaTest.cc

Go to the documentation of this file.
00001 // File and Version Information:
00002 //      $Id: CdbActiveSchemaTest.cc,v 1.11 2004/12/08 09:49:40 gapon Exp $
00003 
00004 #include "BaBar/BaBar.hh"
00005 
00006 /// A collection of test of the Objectivity's Active Schema API.
00007 /**
00008   * - 
00009   */
00010 
00011 // Uncomment the following line if ActiveSchema exceptions are properly
00012 // trown by Active Schema library.
00013 //
00014 //   #define USE_ACTIVE_SCHEMA_EXCEPTIONS
00015 //
00016 
00017 #include "CdbBdb/CdbBdbSimpleCache.hh"
00018 #include "CdbBdb/CdbBdbSchemaUtils.hh"
00019 
00020 #include <ctype.h>      // isdigit)
00021 #include <stdlib.h>     // getenv()
00022 #include <string.h>     // strcmp(), strlen( )
00023 #include <assert.h>
00024 
00025 #include <fstream>      //
00026 #include <iostream>     // Use STD I/O streams to avoid conflicts with
00027                         // Objectivity/DB Active Schema API caused by a bug
00028                         // in its header file.
00029 #include <string>
00030 #include <vector>
00031 
00032 #include <oo.h>         // Objectivity/DB core API
00033 #include <ooMap.h>      // Objectivity/DB core API for the Map Dictionary class
00034 #include <ooas.h>       // Objectivity/DB Active Schema API
00035 using std::cout;
00036 using std::endl;
00037 using std::fstream;
00038 using std::ifstream;
00039 
00040 
00041 namespace {
00042 
00043   // This class accumulates class shape statistics.
00044 
00045     class ClassStatistics {
00046 
00047     public:
00048 
00049         ClassStatistics( ) :
00050             numStrings(0),
00051             numBasics(0),
00052             numEmbeds(0),
00053             numRefs(0),
00054             numBasicArrays(0),
00055             numEmbedArrays(0),
00056             numRefArrays(0),
00057             numRels(0)
00058         { }
00059 
00060     public:
00061 
00062         int numStrings;     // Number of strings
00063         int numBasics;      // Number of basic type elements
00064         int numEmbeds;      // Number of embedded (non basic type) classes
00065         int numRefs;        // Number of references
00066         int numBasicArrays; // Number of v-arrays of basic type elements
00067         int numEmbedArrays; // Number of v-arrays of embedded (non basic type) classes
00068         int numRefArrays;   // Number of v-arrays of references
00069         int numRels;        // Number of relationships (associations)
00070     };
00071 }
00072 
00073 /////////////
00074 // COMMAND //
00075 /////////////
00076 
00077 static void cmd_dumpClass( const char* theClassName );
00078 
00079 static void cmd_dumpObject( const char* theObjectIdentifier );
00080 
00081 static void cmd_createObject( const char* theClassName,
00082                               const char* theHintObjectIdentifier,
00083                                       int theNumberOfObjects );
00084 
00085 static void cmd_copyObject( const char* theObjectIdentifier,
00086                             const char* theHintObjectIdentifier,
00087                                     int theNumberOfObjects );
00088 
00089 static void cmd_copyObjectsList( const char* theFileName,
00090                                  const char* theHintObjectIdentifier );
00091 
00092 static void cmd_createContainer( const char* theHintObjectIdentifier,
00093                                  const char* theContainerName,
00094                                         bool hashedFlag,
00095                                          int theInitPagesNumber,
00096                                          int theGrowFactor );
00097 
00098 static void cmd_isA( const char* theDerivedTypeNumberOrClassName,
00099                      const char*    theBaseTypeNumberOrClassName );
00100 
00101 static void cmd_translate( const char* theTypeNumberOrClassName );
00102 
00103 static void cmd_subclasses( const char* theTypeNumberOrClassName = 0 );
00104 
00105 static void cmd_superclasses( const char* theTypeNumberOrClassName = 0 );
00106 
00107 ///////////////
00108 // UTILITIES //
00109 ///////////////
00110 
00111 static bool translate_OID( ooId&       theId,
00112                            const char* theString );
00113 
00114 static const char* bool2string( bool theFlag );
00115 
00116 static const char* access2string( d_Access_Kind theAccessKind );
00117 
00118 static bool translate_int( int&        theValue,
00119                            const char* theBuf );
00120 
00121 static bool translate_type_number( ooTypeNumber& theValue,
00122                                      const char* theBuf );
00123 
00124 static bool translate_class_identification(   const char* theTypeNumberOrClassName,
00125                                             ooTypeNumber& theTypeNumber,
00126                                              std::string& theClassName );
00127 
00128 static std::string string2html( const std::string& theString );
00129 
00130 //////////////////////
00131 // STATIC VARIABLES //
00132 //////////////////////
00133 
00134 static CdbBdbCache< ooRef(ooObj) >* transientCache = 0;
00135 
00136 static bool deepCopyMode = false;
00137 static bool  verboseMode = false;
00138 static bool    debugMode = false;
00139 static bool     longMode = false;
00140 static bool  compactMode = false;
00141 static bool     htmlMode = false;
00142 
00143 //////////
00144 // MAIN //
00145 //////////
00146 
00147 int
00148 main( int argc, char** argv )
00149 {
00150     int result = 1;
00151 
00152   // Translate input parameters
00153 
00154     const char* className     = 0;
00155     const char* objectId      = 0;
00156     const char* hintId        = 0;
00157     const char* containerName = 0;
00158     const char* fileName      = 0;
00159 
00160     int nObjects   = 1;
00161     int nInitPages = 1;
00162     int growFactor = 10;
00163 
00164     bool hashedFlag = false;
00165 
00166     const char* derivedTypeNumberOrClassName = 0;
00167     const char*    baseTypeNumberOrClassName = 0;
00168     const char*        typeNumberOrClassName = 0;
00169 
00170     enum Operation { OP_UNKNOWN = 0,
00171                      OP_BROWSE_CLASS,
00172                      OP_BROWSE_OBJECT,
00173                      OP_CREATE_OBJECT,
00174                      OP_COPY_OBJECT,
00175                      OP_COPY_OBJECTS_LIST,
00176                      OP_CREATE_CONTAINER,
00177                      OP_IS_A,
00178                      OP_TRANSLATE,
00179                      OP_SUBCLASSES,
00180                      OP_SUPERCLASSES };
00181 
00182     Operation op = OP_UNKNOWN;
00183 
00184     int numArgs = argc - 1;
00185     int nextArg = 1;
00186 
00187     if( numArgs >= 2 ) {
00188         if( 0 == strcmp( "-class", argv[nextArg] )) {
00189 
00190             op = OP_BROWSE_CLASS;
00191 
00192             className = argv[nextArg+1];
00193 
00194             numArgs = numArgs - 2;
00195             nextArg = nextArg + 2;
00196 
00197             if( numArgs >= 1 ) {
00198                 if( 0 == strcmp( "-compact", argv[nextArg] )) {
00199 
00200                     compactMode = true;
00201 
00202                     numArgs = numArgs - 1;
00203                     nextArg = nextArg + 1;
00204                 }
00205             }
00206             if( numArgs >= 1 ) {
00207                 if( 0 == strcmp( "-html", argv[nextArg] )) {
00208 
00209                     htmlMode = true;
00210 
00211                     numArgs = numArgs - 1;
00212                     nextArg = nextArg + 1;
00213                 }
00214             }
00215         }
00216     }
00217     if( numArgs >= 2 ) {
00218         if( 0 == strcmp( "-object", argv[nextArg] )) {
00219 
00220             op = OP_BROWSE_OBJECT;
00221 
00222             objectId = argv[nextArg+1];
00223 
00224             numArgs = numArgs - 2;
00225             nextArg = nextArg + 2;
00226         }
00227     }
00228     if( numArgs >= 3 ) {
00229         if( 0 == strcmp( "-create_object", argv[nextArg] )) {
00230 
00231             op = OP_CREATE_OBJECT;
00232 
00233             className = argv[nextArg+1];
00234             hintId    = argv[nextArg+2];
00235 
00236             numArgs = numArgs - 3;
00237             nextArg = nextArg + 3;
00238 
00239             if( numArgs >= 2 ) {
00240                 if( 0 == strcmp( "-objects", argv[nextArg] )) {
00241                     if( translate_int( nObjects,
00242                                        argv[nextArg+1] )) {
00243 
00244                         numArgs = numArgs - 2;
00245                         nextArg = nextArg + 2;
00246 
00247                     } else {
00248                         cout << "ERROR: Failed to translate the number of objects to be created." << endl;
00249                     }
00250                 }
00251             }
00252             if( numArgs >= 1 ) {
00253                 if( 0 == strcmp( "-verbose", argv[nextArg] )) {
00254 
00255                     verboseMode = true;
00256 
00257                     numArgs = numArgs - 1;
00258                     nextArg = nextArg + 1;
00259                 }
00260             }
00261         }
00262     }
00263     if( numArgs >= 3 ) {
00264         if( 0 == strcmp( "-copy_object", argv[nextArg] )) {
00265 
00266             op = OP_COPY_OBJECT;
00267 
00268             objectId = argv[nextArg+1];
00269             hintId   = argv[nextArg+2];
00270 
00271             numArgs = numArgs - 3;
00272             nextArg = nextArg + 3;
00273 
00274             if( numArgs >= 2 ) {
00275                 if( 0 == strcmp( "-objects", argv[nextArg] )) {
00276                     if( translate_int( nObjects,
00277                                        argv[nextArg+1] )) {
00278 
00279                         numArgs = numArgs - 2;
00280                         nextArg = nextArg + 2;
00281 
00282                     } else {
00283                         cout << "ERROR: Failed to translate the number of objects to be copied." << endl;
00284                     }
00285                 }
00286             }
00287             if( numArgs >= 1 ) {
00288                 if( 0 == strcmp( "-deep_copy", argv[nextArg] )) {
00289 
00290                     deepCopyMode = true;
00291 
00292                     numArgs = numArgs - 1;
00293                     nextArg = nextArg + 1;
00294                 }
00295             }
00296             if( numArgs >= 1 ) {
00297                 if( 0 == strcmp( "-verbose", argv[nextArg] )) {
00298 
00299                     verboseMode = true;
00300 
00301                     numArgs = numArgs - 1;
00302                     nextArg = nextArg + 1;
00303                 }
00304             }
00305         }
00306     }
00307     if( numArgs >= 3 ) {
00308         if( 0 == strcmp( "-copy_objects_list", argv[nextArg] )) {
00309 
00310             op = OP_COPY_OBJECTS_LIST;
00311 
00312             fileName = argv[nextArg+1];
00313             hintId   = argv[nextArg+2];
00314 
00315             numArgs = numArgs - 3;
00316             nextArg = nextArg + 3;
00317 
00318             if( numArgs >= 1 ) {
00319                 if( 0 == strcmp( "-deep_copy", argv[nextArg] )) {
00320 
00321                     deepCopyMode = true;
00322 
00323                     numArgs = numArgs - 1;
00324                     nextArg = nextArg + 1;
00325                 }
00326             }
00327             if( numArgs >= 1 ) {
00328                 if( 0 == strcmp( "-verbose", argv[nextArg] )) {
00329 
00330                     verboseMode = true;
00331 
00332                     numArgs = numArgs - 1;
00333                     nextArg = nextArg + 1;
00334                 }
00335             }
00336         }
00337     }
00338     if( numArgs >= 2 ) {
00339         if( 0 == strcmp( "-create_container", argv[nextArg] )) {
00340 
00341             op = OP_CREATE_CONTAINER;
00342 
00343             hintId = argv[nextArg+1];
00344 
00345             numArgs = numArgs - 2;
00346             nextArg = nextArg + 2;
00347 
00348             if( numArgs >= 2 ) {
00349                 if( 0 == strcmp( "-system", argv[nextArg] )) {
00350 
00351                     containerName = argv[nextArg+1];
00352 
00353                     numArgs = numArgs - 2;
00354                     nextArg = nextArg + 2;
00355                 }
00356             }
00357             if( numArgs >= 1 ) {
00358                 if( 0 == strcmp( "-hashed", argv[nextArg] )) {
00359 
00360                     hashedFlag = true;
00361 
00362                     numArgs = numArgs - 1;
00363                     nextArg = nextArg + 1;
00364                 }
00365             }
00366             if( numArgs >= 2 ) {
00367                 if( 0 == strcmp( "-init_pages", argv[nextArg] )) {
00368                     if( translate_int( nInitPages,
00369                                        argv[nextArg+1] )) {
00370 
00371                         numArgs = numArgs - 2;
00372                         nextArg = nextArg + 2;
00373 
00374                     } else {
00375                         cout << "ERROR: Failed to translate the number of initial pages." << endl;
00376                     }
00377                 }
00378             }
00379             if( numArgs >= 2 ) {
00380                 if( 0 == strcmp( "-grow_factor", argv[nextArg] )) {
00381                     if( translate_int( growFactor,
00382                                        argv[nextArg+1] )) {
00383 
00384                         numArgs = numArgs - 2;
00385                         nextArg = nextArg + 2;
00386 
00387                     } else {
00388                         cout << "ERROR: Failed to translate the growing factor." << endl;
00389                     }
00390                 }
00391             }
00392         }
00393     }
00394     if( numArgs >= 3 ) {
00395         if( 0 == strcmp( "-is_a", argv[nextArg] )) {
00396 
00397             op = OP_IS_A;
00398 
00399             derivedTypeNumberOrClassName = argv[nextArg+1];
00400                baseTypeNumberOrClassName = argv[nextArg+2];
00401 
00402             numArgs = numArgs - 3;
00403             nextArg = nextArg + 3;
00404 
00405             if( numArgs >= 1 ) {
00406                 if( 0 == strcmp( "-debug", argv[nextArg] )) {
00407 
00408                     debugMode = true;
00409 
00410                     numArgs = numArgs - 1;
00411                     nextArg = nextArg + 1;
00412                 }
00413             }
00414         }
00415     }
00416     if( numArgs >= 2 ) {
00417         if( 0 == strcmp( "-translate", argv[nextArg] )) {
00418 
00419             op = OP_TRANSLATE;
00420 
00421             typeNumberOrClassName = argv[nextArg+1];
00422 
00423             numArgs = numArgs - 2;
00424             nextArg = nextArg + 2;
00425 
00426             if( numArgs >= 1 ) {
00427                 if( 0 == strcmp( "-debug", argv[nextArg] )) {
00428 
00429                     debugMode = true;
00430 
00431                     numArgs = numArgs - 1;
00432                     nextArg = nextArg + 1;
00433                 }
00434             }
00435         }
00436     }
00437     if( numArgs >= 1 ) {
00438         if( 0 == strcmp( "-subclasses", argv[nextArg] )) {
00439 
00440             op = OP_SUBCLASSES;
00441 
00442             numArgs = numArgs - 1;
00443             nextArg = nextArg + 1;
00444 
00445             if( numArgs >= 2 ) {
00446                 if( 0 == strcmp( "-class", argv[nextArg] )) {
00447 
00448                     typeNumberOrClassName = argv[nextArg+1];
00449 
00450                     numArgs = numArgs - 2;
00451                     nextArg = nextArg + 2;
00452                 }
00453             }
00454             if( numArgs >= 1 ) {
00455                 if( 0 == strcmp( "-long", argv[nextArg] )) {
00456 
00457                     longMode = true;
00458 
00459                     numArgs = numArgs - 1;
00460                     nextArg = nextArg + 1;
00461                 }
00462             }
00463             if( numArgs >= 1 ) {
00464                 if( 0 == strcmp( "-html", argv[nextArg] )) {
00465 
00466                     htmlMode = true;
00467 
00468                     numArgs = numArgs - 1;
00469                     nextArg = nextArg + 1;
00470                 }
00471             }
00472             if( numArgs >= 1 ) {
00473                 if( 0 == strcmp( "-debug", argv[nextArg] )) {
00474 
00475                     debugMode = true;
00476 
00477                     numArgs = numArgs - 1;
00478                     nextArg = nextArg + 1;
00479                 }
00480             }
00481         }
00482     }
00483     if( numArgs >= 1 ) {
00484         if( 0 == strcmp( "-superclasses", argv[nextArg] )) {
00485 
00486             op = OP_SUPERCLASSES;
00487 
00488             numArgs = numArgs - 1;
00489             nextArg = nextArg + 1;
00490 
00491             if( numArgs >= 2 ) {
00492                 if( 0 == strcmp( "-class", argv[nextArg] )) {
00493 
00494                     typeNumberOrClassName = argv[nextArg+1];
00495 
00496                     numArgs = numArgs - 2;
00497                     nextArg = nextArg + 2;
00498                 }
00499             }
00500             if( numArgs >= 1 ) {
00501                 if( 0 == strcmp( "-long", argv[nextArg] )) {
00502 
00503                     longMode = true;
00504 
00505                     numArgs = numArgs - 1;
00506                     nextArg = nextArg + 1;
00507                 }
00508             }
00509             if( numArgs >= 1 ) {
00510                 if( 0 == strcmp( "-debug", argv[nextArg] )) {
00511 
00512                     debugMode = true;
00513 
00514                     numArgs = numArgs - 1;
00515                     nextArg = nextArg + 1;
00516                 }
00517             }
00518         }
00519     }
00520     if(( 0 != numArgs ) || ( OP_UNKNOWN == op )) {
00521         cout << "Illegal command syntax." << endl
00522              << "Usage: -class <name> [-compact] [-html]" << endl
00523              << "       -object <id>" << endl
00524              << "       -create_object <class_name> <hint> [-objects <number>] [-verbose]" << endl
00525              << "       -copy_object <object> <hint> [-objects <number>] [-verbose]" << endl
00526              << "       -copy_objects_list <file> <hint> [-deep_copy] [-verbose]" << endl
00527              << "       -create_container <hint> [-system <name>] [-hashed] [-init_pages <number>] [-grow_factor <percentage>]" << endl
00528              << "       -is_a <derived_type_number_or_class_name> <base_type_number_or_class_name> [-debug]" << endl
00529              << "       -translate <type_number_or_class_name> [-debug]" << endl
00530              << "       -subclasses [-class <type_number_or_class_name>] [-long] [-html] [-debug]" << endl
00531              << "       -superlasses [-class <type_number_or_class_name>] [-long] [-debug]" << endl;
00532         return result;
00533     }
00534 
00535   // Get the federation to be open.
00536 
00537     const char* bootfile = getenv( "OO_FD_BOOT" );
00538     if( 0 == bootfile ) {
00539         cout << "No OO_FD_BOOT found in the current environment." << endl;
00540         return result;
00541     }
00542 
00543 /**
00544  ** OPTIONAL ZONE:
00545  **
00546  **   The following code can been disabled due to a possible
00547  **   bug in the implementation of the ooas::CantFindRelInverse exception.
00548  **
00549  **   This bug will be fixed in Version 8 of Objectivity/C++.
00550  **/
00551 
00552 #ifdef USE_ACTIVE_SCHEMA_EXCEPTIONS
00553 
00554   // Enable Objectivity/DB exceptions and do the rest withing
00555   // exception catching zone.
00556 
00557     ooException::enable( );
00558 
00559 #endif
00560 
00561 /**
00562  ** END OF THE OPTIONAL ZONE.
00563  **/
00564 
00565     try {
00566 
00567       // Initialize the main context
00568 
00569         ooInit( );
00570 
00571       // Start the test witing a transaction
00572 
00573         ooTrans transaction;
00574 
00575         transaction.start( );
00576         do {
00577 
00578           // Open the federation
00579 
00580             ooMode fdOpenMode = (( OP_CREATE_OBJECT     == op ) ||
00581                                  ( OP_COPY_OBJECT       == op ) ||
00582                                  ( OP_COPY_OBJECTS_LIST == op ) ||
00583                                  ( OP_CREATE_CONTAINER  == op ) ? oocUpdate : oocRead );
00584             ooHandle(ooFDObj) fdH;
00585 
00586             if( oocSuccess != fdH.open( bootfile, fdOpenMode )) {
00587                 cout << "Failed to open the federation." << endl;
00588                 break;
00589             }
00590             switch( op ) {
00591 
00592             case OP_BROWSE_CLASS :
00593 
00594                 cmd_dumpClass( className );
00595                 break;
00596 
00597             case OP_BROWSE_OBJECT :
00598 
00599                 cmd_dumpObject( objectId  );
00600                 break;
00601 
00602             case OP_CREATE_OBJECT :
00603 
00604                 cmd_createObject( className,
00605                                   hintId,
00606                                   nObjects );
00607                 break;
00608 
00609             case OP_COPY_OBJECT :
00610 
00611                 cmd_copyObject( objectId,
00612                                 hintId,
00613                                 nObjects );
00614                 break;
00615 
00616             case OP_COPY_OBJECTS_LIST :
00617 
00618                 cmd_copyObjectsList( fileName,
00619                                      hintId );
00620                 break;
00621 
00622             case OP_CREATE_CONTAINER :
00623 
00624                 cmd_createContainer( hintId,
00625                                      containerName,
00626                                      hashedFlag,
00627                                      nInitPages,
00628                                      growFactor );
00629                 break;
00630 
00631             case OP_IS_A :
00632 
00633                 cmd_isA( derivedTypeNumberOrClassName,
00634                             baseTypeNumberOrClassName );
00635                 break;
00636 
00637             case OP_TRANSLATE :
00638 
00639                 cmd_translate( typeNumberOrClassName );
00640                 break;
00641 
00642             case OP_SUBCLASSES :
00643 
00644                 cmd_subclasses( typeNumberOrClassName );
00645                 break;
00646 
00647             case OP_SUPERCLASSES :
00648 
00649                 cmd_superclasses( typeNumberOrClassName );
00650                 break;
00651 
00652             case OP_UNKNOWN:
00653 
00654                 assert( 0 );
00655                 break;
00656             }
00657 
00658         } while( false );
00659 
00660         transaction.commit( );
00661 
00662     } catch( ooException& e ) {
00663 
00664         cout << endl
00665              << "ooException cought in main()." << endl
00666              << "  " << e.what( ) << endl;
00667         return 1;
00668     }
00669 
00670     return 0;
00671 }
00672 
00673 ///////////////////
00674 // Class Browser //
00675 ///////////////////
00676 
00677 static void dumpClassDescription( ClassStatistics&   theClassStatistics,
00678                                   const d_Class&     theClassDsc,
00679                                   const std::string& thePrefix );
00680 
00681 static
00682 void
00683 cmd_dumpClass( const char* theClassName )
00684 {
00685     assert( 0 != theClassName );
00686 
00687   // Find and examine the class using Objectivity's Active Schema API.
00688 
00689     const d_Module& topModule = d_Module::top_level( );
00690     const d_Class&  classDsc  = topModule.resolve_class( theClassName );
00691     if( !classDsc ) {
00692         cout << "No such class in the Schema." << endl;
00693         return;
00694     }
00695     if( htmlMode ) {
00696         cout << "<HTML>" << endl
00697              << "<BODY>" << endl
00698              << "<PRE>"  << endl;
00699         if( !compactMode ) {
00700             cout << "<FONT COLOR=\"#008000\">" << endl
00701                  << "================" << endl
00702                  << "== DEFINITION ==" << endl
00703                  << "================" << endl
00704                  << "</FONT>" << endl;
00705         }
00706     } else {
00707         if( !compactMode ) {
00708             cout << endl
00709                  << "================" << endl
00710                  << "== DEFINITION ==" << endl
00711                  << "================" << endl
00712                  << endl;
00713         }
00714     }
00715 
00716     ClassStatistics cs;
00717 
00718     dumpClassDescription( cs,
00719                           classDsc,
00720                           std::string( "" ));
00721 
00722     if( htmlMode ) {
00723         if( !compactMode ) {
00724             cout << "<FONT COLOR=\"#008000\">" << endl
00725                  << "=================" << endl
00726                  << "== STATISTICS  ==" << endl
00727                  << "=================" << endl
00728                  << "</FONT>" << endl
00729                  << "  STRINGS                             : " << cs.numStrings << endl
00730                  << "  BASIC TYPE ELEMENTS                 : " << cs.numBasics << endl
00731                  << "  EMBEDDED CLASS ELEMENTS             : " << cs.numEmbeds << endl
00732                  << "  REFERENCES                          : " << cs.numRefs << endl
00733                  << "  V_ARRAYS OF BASIC TYPE ELEMENTS     : " << cs.numBasicArrays << endl
00734                  << "  V_ARRAYS OF EMBEDDED CLASS ELEMENTS : " << cs.numEmbedArrays << endl
00735                  << "  V-ARRAYS OF REFERENCES              : " << cs.numRefArrays << endl
00736                  << "  RELATIONSHIPS (ASSOCIATIONS)        : " << cs.numRels << endl
00737                  << "</PRE>" << endl
00738                  << "</BODY>" << endl
00739                  << "</HTML>"  << endl;
00740         }
00741     } else {
00742         if( !compactMode ) {
00743             cout << endl
00744                  << "=================" << endl
00745                  << "== STATISTICS  ==" << endl
00746                  << "=================" << endl
00747                  << endl
00748                  << "  STRINGS                             : " << cs.numStrings << endl
00749                  << "  BASIC TYPE ELEMENTS                 : " << cs.numBasics << endl
00750                  << "  EMBEDDED CLASS ELEMENTS             : " << cs.numEmbeds << endl
00751                  << "  REFERENCES                          : " << cs.numRefs << endl
00752                  << "  V_ARRAYS OF BASIC TYPE ELEMENTS     : " << cs.numBasicArrays << endl
00753                  << "  V_ARRAYS OF EMBEDDED CLASS ELEMENTS : " << cs.numEmbedArrays << endl
00754                  << "  V-ARRAYS OF REFERENCES              : " << cs.numRefArrays << endl
00755                  << "  RELATIONSHIPS (ASSOCIATIONS)        : " << cs.numRels << endl
00756                  << endl;
00757         }
00758     }
00759 }
00760 
00761 static
00762 void
00763 dumpClassDescription( ClassStatistics&   theClassStatistics,
00764                       const d_Class&     theClassDsc,
00765                       const std::string& thePrefix )
00766 {
00767     assert( theClassDsc );
00768 
00769     const char* htmlSuffix = ( compactMode ? "_compact.html" : ".html" );
00770 
00771   // We're only interested in a user defined (non-internal) classes.
00772 
00773     if( ! theClassDsc.is_class( )) return;
00774     if( theClassDsc.is_internal( )) return;
00775 
00776     std::string prefix = thePrefix + std::string( "  " );
00777 
00778   // Find all base classes
00779 
00780     if( htmlMode ) {
00781         cout << prefix.c_str( ) << "class <A HREF=\"" << theClassDsc.id( ) << htmlSuffix << "\">" << string2html( std::string( theClassDsc.name( ))).c_str( ) << "</A>";
00782     } else {
00783         cout << prefix.c_str( ) << "class " << theClassDsc.name( );
00784     }
00785     {
00786         std::vector<std::string>  baseClassesAccessKind;
00787         std::vector<std::string>  baseClassesNames;
00788         std::vector<ooTypeNumber> baseClassesTypeNumbers;
00789         {
00790             inheritance_iterator itr = theClassDsc.base_class_list_begin( );
00791             while( theClassDsc.base_class_list_end( ) != itr ) {
00792 
00793                 const d_Inheritance& inh = *itr;
00794 
00795                 baseClassesAccessKind.push_back( std::string( access2string( inh.access_kind( ))) + std::string( " " ));
00796                 baseClassesNames.push_back( inh.derives_from( ).name( ));
00797                 baseClassesTypeNumbers.push_back( inh.derives_from( ).id( ));
00798 
00799                 ++itr;
00800             }
00801         }
00802         std::vector<std::string>::size_type num = baseClassesNames.size( );
00803         for( std::vector<std::string>::size_type i = 0; i < num; ++i ) {
00804             if( 0 == i ) cout << " : ";
00805             if( htmlMode ) {
00806                 cout << baseClassesAccessKind[i] << "<A HREF=\"" << baseClassesTypeNumbers[i] << htmlSuffix << "\">" << string2html( baseClassesNames[i] ).c_str( ) << "</A>";
00807             } else {
00808                 cout << baseClassesAccessKind[i] << baseClassesNames[i].c_str( );
00809             }
00810             if( i < num - 1 ) cout << ", ";
00811         }
00812     }
00813     cout << " {" << endl;
00814 
00815   // Browse all attributes
00816 
00817     {
00818         attribute_iterator itr = theClassDsc.defines_attribute_begin( );
00819         while( theClassDsc.defines_attribute_end( ) != itr ) {
00820 
00821             const d_Attribute& attrDsc = *itr;
00822 
00823             if( attrDsc.is_base_class( )) {
00824 
00825                 if( !compactMode ) {
00826                     dumpClassDescription( theClassStatistics,
00827                                           attrDsc.class_type_of( ),
00828                                           prefix );
00829                 }
00830 
00831             } else if( attrDsc.is_relationship( )) {
00832 
00833                 const d_Relationship& relDsc = (const d_Relationship&)attrDsc;
00834 
00835                 cout << prefix << "  " << access2string( attrDsc.access_kind( )) << " ";
00836                 if( relDsc.is_inline( )) cout << "inline ";
00837                 if( relDsc.is_short( )) {
00838                     if( htmlMode ) {
00839                         cout << "ooShortRef(<A HREF=\"" << relDsc.other_class( ).id( ) << htmlSuffix << "\">" << string2html( std::string( relDsc.other_class( ).name( ))).c_str( ) << "</A>) ";
00840                     } else {
00841                         cout << "ooShortRef(" << relDsc.other_class( ).name( ) << ") ";
00842                     }
00843                 } else {
00844                     if( htmlMode ) {
00845                         cout << "ooRef(<A HREF=\"" << relDsc.other_class( ).id( ) << htmlSuffix << "\">" << string2html( std::string( relDsc.other_class( ).name( ))).c_str( ) << "</A>) ";
00846                     } else {
00847                         cout << "ooRef(" << relDsc.other_class( ).name( ) << ") ";
00848                     }
00849                 }
00850                 cout << relDsc.name( );
00851                 if( relDsc.is_to_many( )) cout << "[]";
00852 
00853               // The following stuff is only available if the reverse association
00854               // can be resolved.
00855 
00856 /**
00857  ** OPTIONAL ZONE:
00858  **
00859  **   The following code can been disabled due to a possible
00860  **   bug in the implementation of the ooas::CantFindRelInverse exception.
00861  **
00862  **   This bug will be fixed in Version 8 of Objectivity/C++.
00863  **/
00864 
00865 #ifdef USE_ACTIVE_SCHEMA_EXCEPTIONS
00866 
00867               // Inquire the information on the association on its reverse side.
00868 
00869                 asException::enable_exceptions( );
00870                 try {
00871 
00872                     const d_Relationship& invDsc = relDsc.inverse( );
00873 
00874                     cout << " <-> ";
00875                     cout << invDsc.name( );
00876                     if( invDsc.is_to_many( )) cout << "[]";
00877 
00878                     std::vector<std::string> behaviors;
00879 
00880                     uint8 versioningMode = relDsc.versioning( );
00881                     switch( versioningMode ) {
00882                     case oocVersionDrop : { behaviors.push_back( std::string( "version(delete)" )); break; }
00883                     case oocVersionMove : { behaviors.push_back( std::string( "version(move)" ));   break; }
00884                     case oocVersionCopy : { behaviors.push_back( std::string( "version(copy)" ));   break; }
00885                     }
00886                     uint8 propagationMode = relDsc.propagation( );
00887                     switch( propagationMode ) {
00888                     case oocLockPropagationYesDeletePropagationNo  : { behaviors.push_back( std::string( "delete(propagate)" )); break; }
00889                     case oocLockPropagationNoDeletePropagationYes  : { behaviors.push_back( std::string( "lock(propagate)" ));   break; }
00890                     case oocLockPropagationYesDeletePropagationYes :
00891                         {
00892                             behaviors.push_back( std::string( "delete(propagate)" ));
00893                             behaviors.push_back( std::string( "lock(propagate)" ));
00894                             break;
00895                         }
00896                     }
00897                     uint8 copyMode = relDsc.copy_mode( );
00898                     switch( copyMode ) {
00899                     case oocCopyDrop : { behaviors.push_back( std::string( "copy(delete)" )); break; }
00900                     case oocCopyMove : { behaviors.push_back( std::string( "copy(move)" ));   break; }
00901                     case oocCopyCopy : { behaviors.push_back( std::string( "copy(copy)" ));   break; }
00902                     }
00903                     std::vector<std::string>::size_type num = behaviors.size( );
00904                     for( std::vector<std::string>::size_type i = 0; i < num; ++i ) {
00905                         if( 0 == i ) cout << " : ";
00906                         cout << behaviors[i].c_str( );
00907                         if( i < num - 1 ) cout << ", ";
00908                     }
00909 
00910                 } catch( ooas::CantFindRelInverse& e ) {
00911 
00912                     cout << endl
00913                          << "CantRelInverse cought in dumpClassDescription()." << endl
00914                          << "  " << e.what( ) << endl;
00915 
00916                   // Ignore this exception and finish the definition of the current
00917                   // association.
00918 
00919                     ;
00920                 }
00921 #endif
00922 
00923 /**
00924  ** END OF THE OPTIONAL ZONE.
00925  **/
00926 
00927                 cout << ";" << endl;
00928 
00929                 ++(theClassStatistics.numRels);
00930 
00931             } else {
00932 
00933                 const d_Type& typeDsc = attrDsc.type_of( );
00934 
00935                 int numFaces = 0;
00936 
00937                 if( typeDsc.is_string_type( )) {
00938 
00939                     ++numFaces;
00940 
00941                     cout << prefix << "  " << access2string( attrDsc.access_kind( )) << " " << typeDsc.name( ) << " " << attrDsc.name( );
00942 
00943                     size_t arraySize = attrDsc.array_size( );
00944                     if( arraySize > 1 ) cout << "[" << arraySize << "]";
00945 
00946                     cout << ";" << endl;
00947 
00948                     ++(theClassStatistics.numStrings);
00949                 }
00950                 if( typeDsc.is_basic_type( )) {
00951 
00952                     ++numFaces;
00953 
00954                     cout << prefix << "  " << access2string( attrDsc.access_kind( )) << " " << typeDsc.name( ) << " " << attrDsc.name( );
00955 
00956                     size_t arraySize = attrDsc.array_size( );
00957                     if( arraySize > 1 ) cout << "[" << arraySize << "]";
00958 
00959                     cout << ";" << endl;
00960 
00961                     ++(theClassStatistics.numBasics);
00962                 }
00963                 if( typeDsc.is_class( )) {
00964 
00965                     ++numFaces;
00966 
00967                     if( !typeDsc.is_string_type( )) {
00968 
00969                         if( htmlMode ) {
00970                             cout << prefix << "  " << access2string( attrDsc.access_kind( )) << " <A HREF=\"" << typeDsc.id( ) << htmlSuffix << "\">" << string2html( std::string( typeDsc.name( ))).c_str( ) << "</A> " << attrDsc.name( );
00971                         } else {
00972                             cout << prefix << "  " << access2string( attrDsc.access_kind( )) << " " << typeDsc.name( ) << " " << attrDsc.name( );
00973                         }
00974                         size_t arraySize = attrDsc.array_size( );
00975                         if( arraySize > 1 ) cout << "[" << arraySize << "]";
00976 
00977                         cout << ";" << endl;
00978 
00979                         if( !compactMode ) {
00980                             dumpClassDescription( theClassStatistics,
00981                                                   attrDsc.class_type_of( ),
00982                                                   "  " + prefix );
00983                         }
00984                         ++(theClassStatistics.numEmbeds);
00985                     }
00986                 }
00987                 if( typeDsc.is_ref_type( )) {
00988 
00989                     ++numFaces;
00990 
00991                     if( htmlMode ) {
00992                         const d_Ref_Type& referenceType = (const d_Ref_Type&)typeDsc;
00993                         const d_Type&     elementType   = referenceType.referenced_type( );
00994                         cout << prefix << "  " << access2string( attrDsc.access_kind( )) << " ooRef(<A HREF=\"" << elementType.id( ) << htmlSuffix << "\">" << string2html( std::string( elementType.name( ))).c_str( ) << "</A>) " << attrDsc.name( );
00995                     } else {
00996                         cout << prefix << "  " << access2string( attrDsc.access_kind( )) << " " << typeDsc.name( ) << " " << attrDsc.name( );
00997                     }
00998                     size_t arraySize = attrDsc.array_size( );
00999                     if( arraySize > 1 ) cout << "[" << arraySize << "]";
01000 
01001                     cout << ";" << endl;
01002 
01003                     ++(theClassStatistics.numRefs);
01004                 }
01005                 if( typeDsc.is_varray_basic_type( )) {
01006 
01007                     ++numFaces;
01008 
01009                     cout << prefix << "  " << access2string( attrDsc.access_kind( )) << " " << typeDsc.name( ) << " " << attrDsc.name( );
01010 
01011                     size_t arraySize = attrDsc.array_size( );
01012                     if( arraySize > 1 ) cout << "[" << arraySize << "]";
01013 
01014                     cout << ";" << endl;
01015 
01016                     ++(theClassStatistics.numBasicArrays);
01017                 }
01018                 if( typeDsc.is_varray_embedded_class_type( )) {
01019 
01020                     ++numFaces;
01021 
01022                     if( htmlMode ) {
01023                         const d_Class& elementClassDsc = ((const VArray_Embedded_Class_Type&)typeDsc).element_class_type( );
01024                         cout << prefix << "  " << access2string( attrDsc.access_kind( )) << " ooVArray(<A HREF=\"" << elementClassDsc.id( ) << htmlSuffix << "\">" << string2html( std::string( elementClassDsc.name( ))).c_str( ) << "</A>) " << attrDsc.name( );
01025                     } else {
01026                         cout << prefix << "  " << access2string( attrDsc.access_kind( )) << " " << typeDsc.name( ) << " " << attrDsc.name( );
01027                     }
01028                     size_t arraySize = attrDsc.array_size( );
01029                     if( arraySize > 1 ) cout << "[" << arraySize << "]";
01030 
01031                     cout << ";" << endl;
01032 
01033                     if( !compactMode ) {
01034                         dumpClassDescription( theClassStatistics,
01035                                               ((const VArray_Embedded_Class_Type&)typeDsc).element_class_type( ),
01036                                               "  " + prefix );
01037                     }
01038                     ++(theClassStatistics.numEmbedArrays);
01039                 }
01040                 if( typeDsc.is_varray_ref_type( )) {
01041 
01042                     ++numFaces;
01043 
01044                     if( htmlMode ) {
01045                         const d_Ref_Type& referenceType = ((const VArray_Ref_Type&)typeDsc).element_ref_type( );
01046                         const d_Type&     elementType  = referenceType.referenced_type( );
01047                         cout << prefix << "  " << access2string( attrDsc.access_kind( )) << " ooVArray(ooRef(<A HREF=\"" << elementType.id( ) << htmlSuffix << "\">" << string2html( std::string( elementType.name( ))).c_str( ) << "</A>)) " << attrDsc.name( );
01048                     } else {
01049                         cout << prefix << "  " << access2string( attrDsc.access_kind( )) << " " << typeDsc.name( ) << " " << attrDsc.name( );
01050                     }
01051                     size_t arraySize = attrDsc.array_size( );
01052                     if( arraySize > 1 ) cout << "[" << arraySize << "]";
01053 
01054                     cout << ";" << endl;
01055 
01056                     ++(theClassStatistics.numRefArrays);
01057                 }
01058                 if( !numFaces ) {
01059 
01060                     cout << prefix << "  " << access2string( attrDsc.access_kind( )) << " " << typeDsc.name( ) << " " << attrDsc.name( );
01061 
01062                     size_t arraySize = attrDsc.array_size( );
01063                     if( arraySize > 1 ) cout << "[" << arraySize << "]";
01064 
01065                     cout << "; // (UNKNOWN) " << endl;
01066                 }
01067             }
01068             ++itr;
01069         }
01070     }
01071     cout << prefix.c_str( ) << "}" << endl;
01072 }
01073 
01074 ////////////////////
01075 // Object Browser //
01076 ////////////////////
01077 
01078 static void dumpClassObject( size_t&             theObjectSize,
01079                              const Class_Object& theClassObject,
01080                              const std::string&  thePrefix );
01081 
01082 static
01083 void
01084 cmd_dumpObject( const char* theObjectIdentifier )
01085 { 
01086     assert( 0 != theObjectIdentifier );
01087 
01088   // Get the reference for an object to be examined.
01089  
01090     ooRef(ooObj) oRef;
01091     {
01092         ooId oId;
01093         if( ! translate_OID( oId, theObjectIdentifier )) return;
01094 
01095         oRef = oId;
01096         if( !oRef.isValid( )) {
01097             cout << "An invalid reference found." << endl;
01098             return;
01099         }
01100     }
01101  
01102   // Examine the persistent object using Objectivity's Active Schema API.
01103  
01104     Class_Object classObj( oRef ); 
01105     if( !classObj ) {
01106         cout << "No Class_Object for this reference." << endl;
01107         return;
01108     }
01109 
01110     cout << endl
01111          << "============" << endl
01112          << "== OBJECT ==" << endl
01113          << "============" << endl
01114          << endl
01115          << oRef.sprint( ) << " = {" << endl
01116          << "  %class = \"" << classObj.type_of( ).name( ) << "\"" << endl;
01117 
01118     size_t      objectSize = 0;
01119     std::string prefix     = "  ";
01120 
01121     dumpClassObject( objectSize,
01122                      classObj,
01123                      prefix );
01124 
01125     cout << "}" << endl;
01126 
01127     return;
01128 }
01129 
01130 static void dumpNumericValue( size_t&              theObjectSize,
01131                               const Numeric_Value& theNumericValue );
01132 
01133 static void dumpStringValue( size_t&      theObjectSize,
01134                              String_Value theStringValue );
01135 
01136 static void dumpReference( size_t&             theObjectSize,
01137                            const ooRef(ooObj)& theRef );
01138 
01139 static void dumpVArrayObject( size_t&              theObjectSize,
01140                               const VArray_Object& theVArrayObject,
01141                               const d_Type&        theVArrayTypeDsc,
01142                               const std::string&   thePrefix );
01143 
01144 static
01145 void
01146 dumpClassObject( size_t&             theObjectSize,
01147                  const Class_Object& theClassObject,
01148                  const std::string&  thePrefix )
01149 {
01150     assert( theClassObject );
01151 
01152   // Get the class object
01153 
01154     const d_Class& classDsc = theClassObject.type_of( );
01155 
01156   // We're only interested in a user defined (non-internal) classes.
01157 
01158     if( ! classDsc.is_class( )) return;
01159     if( classDsc.is_internal( )) return;
01160 
01161   // Browse all attributes
01162 
01163     {
01164         attribute_iterator itr = classDsc.defines_attribute_begin( );
01165         while( classDsc.defines_attribute_end( ) != itr ) {
01166 
01167             const d_Attribute& attrDsc = *itr;
01168 
01169             if( attrDsc.is_base_class( )) {
01170 
01171                 const Class_Object& classObj = theClassObject.get_class_obj( attrDsc.position( ));
01172 
01173                 dumpClassObject( theObjectSize,
01174                                  classObj,
01175                                  thePrefix );
01176 
01177             } else if( attrDsc.is_relationship( )) {
01178 
01179                 const d_Relationship& relDsc = (const d_Relationship&)attrDsc;
01180                 Relationship_Object   rObj   = theClassObject.get_relationship( attrDsc.position( ));
01181 
01182                 cout << thePrefix << attrDsc.name( ) << " = {" << endl;
01183                 if( rObj ) {
01184                     if( relDsc.is_to_many( )) {
01185                         ooItr(ooObj) itr;
01186                         rObj.get_iterator( itr );
01187                         while( itr.next( )) {
01188                             cout << thePrefix << "  ";
01189                             dumpReference( theObjectSize,
01190                                            itr );
01191                             cout << endl;
01192                         }
01193                     } else {
01194                         cout << thePrefix << "  ";
01195                         dumpReference( theObjectSize,
01196                                        rObj.get_ooref( ));
01197                         cout << endl;
01198                     }
01199                 }
01200                 cout << thePrefix << "}" << endl;
01201 
01202             } else {
01203 
01204                 const d_Type& typeDsc        = attrDsc.type_of( );
01205                 size_t        fixedArraySize = attrDsc.array_size( );
01206 
01207                 cout << thePrefix << attrDsc.name( ) << " = ";
01208 
01209                 if( typeDsc.is_basic_type( )) {
01210 
01211                     if( fixedArraySize > 1 ) {
01212                         cout << " {" << endl;
01213                         for( size_t i = 0; i < fixedArraySize; ++i ) {
01214                             cout << thePrefix << "  [" << i << "] ";
01215                             dumpNumericValue( theObjectSize,
01216                                               theClassObject.get( attrDsc.position( ),
01217                                                                   i ));
01218                             cout << endl;
01219                         }
01220                         cout << thePrefix << "}" << endl;
01221                     } else {
01222                         dumpNumericValue( theObjectSize,
01223                                           theClassObject.get( attrDsc.position( )));
01224                         cout << ";" << endl;
01225                     }
01226 
01227                 } else if( typeDsc.is_ref_type( )) {
01228 
01229                     if( fixedArraySize > 1 ) {
01230                         cout << " {" << endl;
01231                         for( size_t i = 0; i < fixedArraySize; ++i ) {
01232                             cout << thePrefix << "  [" << i << "] ";
01233                             dumpReference( theObjectSize,
01234                                            theClassObject.get_ooref( attrDsc.position( ),
01235                                                                      i ));
01236                             cout << endl;
01237                         }
01238                         cout << thePrefix << "}" << endl;
01239                     } else {
01240                         dumpReference( theObjectSize,
01241                                        theClassObject.get_ooref( attrDsc.position( )));
01242                         cout << ";" << endl;
01243                     }
01244 
01245                 } else if( typeDsc.is_string_type( )) {     // It may also be an embedded string class,
01246                                                             // so we make thi scheck before the next one.
01247 
01248                     if( fixedArraySize > 1 ) {
01249                         cout << " {" << endl;
01250                         for( size_t i = 0; i < fixedArraySize; ++i ) {
01251                             cout << thePrefix << "  [" << i << "] ";
01252                             dumpStringValue( theObjectSize,
01253                                              theClassObject.get_string( attrDsc.position( ),
01254                                                                         i ));
01255                             cout << endl;
01256                         }
01257                         cout << thePrefix << "}" << endl;
01258                     } else {
01259                         dumpStringValue( theObjectSize,
01260                                          theClassObject.get_string( attrDsc.position( )));
01261                         cout << ";" << endl;
01262                     }
01263 
01264                 } else if( typeDsc.is_class( )) {
01265 
01266                     if( fixedArraySize > 1 ) {
01267                         cout << " {" << endl;
01268                         for( size_t i = 0; i < fixedArraySize; ++i ) {
01269                             cout << thePrefix << "  [" << i << "] {" << endl;
01270                             dumpClassObject( theObjectSize,
01271                                              theClassObject.get_class_obj( attrDsc.position( ),
01272                                                                            i ),
01273                                              thePrefix + "  " + "  " );
01274                             cout << thePrefix << "  }" << endl;
01275                         }
01276                         cout << thePrefix << "}" << endl;
01277                     } else {
01278                         cout << "{" << endl;
01279                         dumpClassObject( theObjectSize,
01280                                          theClassObject.get_class_obj( attrDsc.position( )),
01281                                          thePrefix + "  " );
01282                         cout << thePrefix << "}" << endl;
01283                     }
01284 
01285                 } else if( typeDsc.is_varray_type( )) {
01286 
01287                     cout << "{" << endl;
01288                     dumpVArrayObject( theObjectSize,
01289                                       theClassObject.get_varray( attrDsc.position( )),
01290                                       typeDsc,
01291                                       thePrefix );
01292                     cout << thePrefix << "}" << endl;
01293 
01294                 } else {
01295                     cout << " = (unknown type value);" << endl;
01296                 }
01297             }
01298             ++itr;
01299         }
01300     }
01301 }
01302 
01303 static
01304 void
01305 dumpNumericValue( size_t&              theObjectSize,
01306                   const Numeric_Value& theNumericValue )
01307 {
01308     ooBaseType baseType = theNumericValue.type( );
01309 
01310     switch( baseType ) {
01311     case ooCHAR    : { cout << (char)        theNumericValue;  break; }
01312     case ooINT8    : { cout << (int)(int8)   theNumericValue;  break; }
01313     case ooUINT8   : { cout << (int)(uint8)  theNumericValue;  break; }
01314     case ooINT16   : { cout << (int16)       theNumericValue;  break; }
01315     case ooUINT16  : { cout << (uint16)      theNumericValue;  break; }
01316     case ooINT32   : { cout << (int32)       theNumericValue;  break; }
01317     case ooUINT32  : { cout << (uint32)      theNumericValue;  break; }
01318     case ooINT64   : { cout << (int64)       theNumericValue;  break; }
01319     case ooUINT64  : { cout << (uint64)      theNumericValue;  break; }
01320     case ooFLOAT32 : { cout << (float32)     theNumericValue;  break; }
01321     case ooFLOAT64 : { cout << (float64)     theNumericValue;  break; }
01322     case ooPTR     : { cout << (void*)       theNumericValue;  break; }
01323     default        : { cout << "(unknown numeric value type)"; break; }
01324     }
01325 }
01326 
01327 static
01328 void
01329 dumpStringValue( size_t&      theObjectSize,
01330                  String_Value theStringValue )
01331 {
01332     cout << "\"";
01333     switch( theStringValue.type( )) {
01334     case ooAsStringVSTRING   : { ooVString* vStr = theStringValue;
01335                                  cout << (const char*)(*vStr);                               break; }
01336     case ooAsStringUTF8      : { ooUtf8String* utf8Str = theStringValue;
01337                                  cout << (const char*)(*utf8Str);                            break; }
01338     case ooAsStringOPTIMIZED : { char* str = Optimized_String_Value(theStringValue).get_copy( );
01339                                  cout << str;
01340                                  delete [] str;     // NOTE: get_copy() allocates new string
01341                                  break; }
01342     case ooAsStringST        : { cout << "(Smalltalk string)";                               break; }
01343     default                  : { cout << "(unrecognized string class)";                      break; }
01344     }
01345     cout << "\"";
01346 }
01347 
01348 static
01349 void
01350 dumpReference( size_t&             theObjectSize,
01351                const ooRef(ooObj)& theRef )
01352 {
01353     theObjectSize += sizeof( theRef );
01354     cout << theRef.sprint( );
01355 }
01356 
01357 static
01358 void
01359 dumpVArrayObject( size_t&              theObjectSize,
01360                   const VArray_Object& theVArrayObject,
01361                   const d_Type&        theVArrayTypeDsc,
01362                   const std::string&   thePrefix )
01363 {
01364     const std::string prefix = thePrefix + "  ";
01365 
01366     uint32 num = theVArrayObject.size( );
01367     for( uint32 i = 0; i < num; ++i ) {
01368 
01369         cout << prefix << "[" << i << "] ";
01370         if( theVArrayTypeDsc.is_varray_basic_type( )) {
01371 
01372             dumpNumericValue( theObjectSize,
01373                               theVArrayObject.get( i ));
01374 
01375         } else if( theVArrayTypeDsc.is_varray_ref_type( )) {
01376 
01377             dumpReference( theObjectSize,
01378                            theVArrayObject.get_ooref( i ));
01379 
01380         } else if( theVArrayTypeDsc.is_string_type( )) {    // It may also be an embedded string class,
01381                                                             // so we make thi scheck before the next one.
01382 
01383             dumpStringValue( theObjectSize,
01384                              theVArrayObject.get_string( i ));
01385 
01386         } else if( theVArrayTypeDsc.is_varray_embedded_class_type( )) {
01387 
01388             cout << "{" << endl;
01389             dumpClassObject( theObjectSize,
01390                              theVArrayObject.get_class_obj( i ),
01391                              prefix + "  " );
01392             cout << prefix << "}";
01393 
01394         } else {
01395             assert( 0 );
01396         }
01397         cout << endl;
01398     }
01399 }
01400 
01401 ////////////////////
01402 // OBJECT CREATOR //
01403 ////////////////////
01404 
01405 static
01406 void
01407 cmd_createObject( const char* theClassName,
01408                   const char* theHintObjectIdentifier,
01409                           int theNumberOfObjects )
01410 {
01411     assert( 0 != theClassName );
01412     assert( theNumberOfObjects > 0 );
01413 
01414   // Find and examine the class using Objectivity's Active Schema API.
01415 
01416     const d_Module& topModule = d_Module::top_level( );
01417     const d_Class&  classDsc  = topModule.resolve_class( theClassName );
01418     if( !classDsc ) {
01419         cout << "ERROR: no such class in the Schema." << endl;
01420         return;
01421     }
01422 
01423   // Get the reference for an object to be used as clustering hint.
01424  
01425     ooRef(ooObj) oHintRef;
01426     {
01427         ooId oId;
01428         if( ! translate_OID( oId, theHintObjectIdentifier )) return;
01429 
01430         oHintRef = oId;
01431         if( !oHintRef.isValid( )) {
01432             cout << "ERROR: an invalid reference to the clustering hint object found." << endl;
01433             return;
01434         }
01435     }
01436 
01437   // Create objects one-by-one
01438 
01439     for( int i = 0; i < theNumberOfObjects; ++i ) {
01440         Class_Object classObj = Class_Object::new_persistent_object( classDsc,
01441                                                                      oHintRef,
01442                                                                      NULL,
01443                                                                      oocTrue );
01444         if( verboseMode ) {
01445             cout << classObj.object_handle( ).sprint( ) << endl;
01446         }
01447     }
01448 }
01449 
01450 /////////////////
01451 // OBJECT COPY //
01452 /////////////////
01453 
01454 static void copyObjectContents(    const Class_Object& theClassObject,
01455                                          Class_Object& theOutputClassObject,
01456                                 const ooHandle(ooObj)& theHintH,
01457                                     const std::string& thePrefix );
01458 
01459 static
01460 void
01461 cmd_copyObject( const char* theObjectIdentifier,
01462                 const char* theHintObjectIdentifier,
01463                         int theNumberOfObjects )
01464 {
01465   // Get the reference for an input object to be copied
01466 
01467     ooHandle(ooObj) inputH;
01468     {
01469         ooId oid;
01470         if( ! translate_OID( oid, theObjectIdentifier )) return;
01471 
01472         inputH = (ooRef(ooObj))oid;
01473         if( !inputH.isValid( )) {
01474             cout << "ERROR: an invalid reference to the input object found." << endl;
01475             return;
01476         }
01477     }
01478 
01479   // Get the reference for a hint object where the output one will be created
01480 
01481     ooHandle(ooObj) hintH;
01482     {
01483         ooId oid;
01484         if( ! translate_OID( oid, theHintObjectIdentifier )) return;
01485 
01486         hintH = (ooRef(ooObj))oid;
01487         if( !hintH.isValid( )) {
01488             cout << "ERROR: an invalid reference to the clustering hint object found." << endl;
01489             return;
01490         }
01491     }
01492 
01493   // Find and examine the class using Objectivity's Active Schema API.
01494 
01495     Class_Object classObj( inputH ); 
01496     if( !classObj ) {
01497         cout << "ERROR: no Class_Object for the input object reference." << endl;
01498         return;
01499     }
01500 
01501   // Copy the same object one-by-one
01502 
01503     transientCache = 0; // DO NOT USE THE CACHE FOR THIS TEST!!!
01504     {
01505         for( int i = 0; i < theNumberOfObjects; ++i ) {
01506 
01507           // Create an empty output object of the same type the input one has.
01508 
01509             Class_Object outputClassObj
01510                 = Class_Object::new_persistent_object( classObj.type_of( ),
01511                                                        hintH,
01512                                                        NULL,
01513                                                        oocTrue );
01514             copyObjectContents(       classObj,
01515                                 outputClassObj,
01516                                 hintH,
01517                                 "  " );
01518 
01519             if( verboseMode ) {
01520                 std::string  inStr = inputH.sprint( );
01521                 std::string outStr = outputClassObj.object_handle( ).sprint( );
01522                 cout << "  " << inStr.c_str( ) << " -> " << outStr.c_str( ) << " ()" << " \"" << inputH.typeName( ) << "\"" << endl;
01523             }
01524         }
01525     }
01526 }
01527 
01528 static void copyStringValue( const String_Value& theStringValue,
01529                                    String_Value& theOutputStringValue );
01530 
01531 static void copyVArrayObject(   const VArray_Object& theVArrayObject,
01532                                       VArray_Object& theOutputVArrayObject,
01533                                        const d_Type& theVArrayTypeDsc,
01534                               const ooHandle(ooObj)& theHintH,
01535                                   const std::string& thePrefix );
01536 
01537 static bool cloneObject( const ooHandle(ooObj)& theH,
01538                          const ooHandle(ooObj)& theHintH,
01539                                ooHandle(ooObj)& theOutputH,
01540                              const std::string& thePrefix );
01541 
01542 static
01543 void
01544 copyObjectContents(    const Class_Object& theClassObject,
01545                              Class_Object& theOutputClassObject,
01546                     const ooHandle(ooObj)& theHintH,
01547                         const std::string& thePrefix )
01548 {
01549     assert(       theClassObject );
01550     assert( theOutputClassObject );
01551 
01552   // Get the class object
01553 
01554     const d_Class& classDsc = theClassObject.type_of( );
01555 
01556   // We're only interested in a user defined (non-internal) classes.
01557 
01558     if( ! classDsc.is_class   ( )) return;
01559     if(   classDsc.is_internal( )) return;
01560 
01561   // Browse all attributes
01562 
01563     {
01564         attribute_iterator itr = classDsc.defines_attribute_begin( );
01565         while( classDsc.defines_attribute_end( ) != itr ) {
01566 
01567             const d_Attribute& attrDsc = *itr;
01568 
01569             if( attrDsc.is_base_class( )) {
01570 
01571                 cout << thePrefix.c_str( ) << "BASE CLASS" << endl;
01572 
01573                 Class_Object  inputClassObj =       theClassObject.get_class_obj( attrDsc.position( ));
01574                 Class_Object outputClassObj = theOutputClassObject.get_class_obj( attrDsc.position( ));
01575 
01576                 copyObjectContents(  inputClassObj,
01577                                     outputClassObj,
01578                                     theHintH,
01579                                     thePrefix );
01580 
01581             } else if( attrDsc.is_relationship( )) {
01582 
01583                 const d_Relationship& relDsc = (const d_Relationship&)attrDsc;
01584 
01585                 Relationship_Object       relationshipObj =       theClassObject.get_relationship( attrDsc.position( ));
01586                 Relationship_Object outputRelationshipObj = theOutputClassObject.get_relationship( attrDsc.position( ));
01587 
01588                 if( relationshipObj ) {
01589                     if( relDsc.is_to_many( )) {
01590 
01591                         cout << thePrefix.c_str( ) << "n-RELATIONSHIP" << endl;
01592 
01593                         ooItr(ooObj) itr;
01594                         relationshipObj.get_iterator( itr );
01595 
01596                         bool failed = false;
01597                         while( itr.next( )) {
01598 
01599                             ooHandle(ooObj)  inputH;
01600                             ooHandle(ooObj) outputH;
01601 
01602                             inputH = itr;
01603 
01604                             if( deepCopyMode ) {
01605                                 if( !cloneObject(   inputH,
01606                                                   theHintH,
01607                                                    outputH,
01608                                                   thePrefix + "  " )) {
01609                                     failed = true;
01610                                     break;
01611                                 }
01612                             } else {
01613                                 outputH = inputH;
01614                                 cout << "WARNING: performing the shallow copy of " << outputH.sprint( ) << endl;
01615                             }
01616 
01617                           // Only add if does not exist. Otherwise we'll get an exception.
01618 
01619                             if( oocTrue != outputRelationshipObj.exist( outputH ))
01620                                 outputRelationshipObj.add( outputH );
01621                         }
01622                         if( failed ) break;
01623 
01624                     } else {
01625 
01626                         cout << thePrefix.c_str( ) << "1-RELATIONSHIP" << endl;
01627 
01628                         ooHandle(ooObj)  inputH;
01629                         ooHandle(ooObj) outputH;
01630 
01631                         inputH = relationshipObj.get_ooref( );
01632 
01633                         if( deepCopyMode ) {
01634                             if( !cloneObject(   inputH,
01635                                               theHintH,
01636                                                outputH,
01637                                               thePrefix + "  " )) {
01638                                 break;
01639                             }
01640                         } else {
01641                             outputH = inputH;
01642                             cout << "WARNING: performing the shallow copy of " << outputH.sprint( ) << endl;
01643                         }
01644 
01645                       // Only add if does not exist. Otherwise we'll get an exception.
01646 
01647                         if( oocTrue != outputRelationshipObj.exist( outputH ))
01648                             outputRelationshipObj.set( outputH );
01649                     }
01650                 }
01651 
01652             } else {
01653 
01654                 const d_Type& typeDsc        = attrDsc.type_of( );
01655                        size_t fixedArraySize = attrDsc.array_size( );
01656 
01657                 if( typeDsc.is_basic_type( )) {
01658 
01659 //                    if( fixedArraySize > 1 ) {
01660 
01661                     cout << thePrefix.c_str( ) << "BASIC TYPE";
01662                     if( fixedArraySize > 1 ) cout << "[" << fixedArraySize << "]";
01663                     cout << endl;
01664 
01665 //                        cout << thePrefix.c_str( ) << "BASIC TYPE[" << fixedArraySize << "]" << endl;
01666 
01667                         for( size_t i = 0; i < fixedArraySize; ++i ) {
01668                             theOutputClassObject.set( attrDsc.position( ), i,
01669                                                       theClassObject.get( attrDsc.position( ), i ));
01670                         }
01671  /*
01672                     } else {
01673 
01674                         cout << thePrefix.c_str( ) << "BASIC TYPE" << endl;
01675 
01676                         theOutputClassObject.set( attrDsc.position( ),
01677                                                   theClassObject.get( attrDsc.position( )));
01678                     }
01679 */
01680                 } else if( typeDsc.is_ref_type( )) {
01681 
01682 //                    if( fixedArraySize > 1 ) {
01683 
01684                     cout << thePrefix.c_str( ) << "REFERENCE";
01685                     if( fixedArraySize > 1 ) cout << "[" << fixedArraySize << "]";
01686                     cout << endl;
01687 
01688 //                        cout << thePrefix.c_str( ) << "REFERENCE[" << fixedArraySize << "]" << endl;
01689 
01690                         bool failed = false;
01691                         for( size_t i = 0; i < fixedArraySize; ++i ) {
01692 
01693                             ooHandle(ooObj)  inputH;
01694                             ooHandle(ooObj) outputH;
01695 
01696                             inputH = theClassObject.get_ooref( attrDsc.position( ), i );
01697 
01698                             if( deepCopyMode ) {
01699                                 if( !cloneObject(   inputH,
01700                                                   theHintH,
01701                                                    outputH,
01702                                                   thePrefix + "  " )) {
01703                                     failed = true;
01704                                     break;
01705                                 }
01706                             } else {
01707                                 outputH = inputH;
01708                                 cout << "WARNING: performing the shallow copy of " << outputH.sprint( ) << endl;
01709                             }
01710                             theOutputClassObject.set_ooref( attrDsc.position( ),
01711                                                             i,
01712                                                             outputH );
01713                         }
01714                         if( failed ) break;
01715 /*
01716                     } else {
01717 
01718                         cout << thePrefix.c_str( ) << "REFERENCE" << endl;
01719 
01720                         ooHandle(ooObj)  inputH;
01721                         ooHandle(ooObj) outputH;
01722 
01723                         inputH = theClassObject.get_ooref( attrDsc.position( ));
01724 
01725                         if( deepCopyMode ) {
01726                             if( !cloneObject(   inputH,
01727                                               theHintH,
01728                                                outputH,
01729                                               thePrefix + "  " )) {
01730                                 break;
01731                             }
01732                         } else {
01733                             outputH = inputH;
01734                             cout << "WARNING: performing the shallow copy of " << outputH.sprint( ) << endl;
01735                         }
01736                         theOutputClassObject.set_ooref( attrDsc.position( ),
01737                                                         outputH );
01738                     }
01739 */
01740                 } else if( typeDsc.is_string_type( )) {     // It may also be an embedded string class,
01741                                                             // so we make thi scheck before the next one.
01742 
01743                     cout << thePrefix.c_str( ) << "STRING";
01744                     if( fixedArraySize > 1 ) cout << "[" << fixedArraySize << "]";
01745                     cout << endl;
01746 
01747 //                    if( fixedArraySize > 1 ) {
01748 
01749 //                        cout << thePrefix.c_str( ) << "STRING[" << fixedArraySize << "]" << endl;
01750 
01751                         for( size_t i = 0; i < fixedArraySize; ++i ) {
01752 
01753                             String_Value  inputStringVal =       theClassObject.get_string( attrDsc.position( ), i );
01754                             String_Value outputStringVal = theOutputClassObject.get_string( attrDsc.position( ), i );
01755 
01756                             copyStringValue(  inputStringVal,
01757                                               outputStringVal );
01758                         }
01759 /*
01760                     } else {
01761 
01762                         cout << thePrefix.c_str( ) << "STRING" << endl;
01763 
01764                         String_Value  inputStringVal =       theClassObject.get_string( attrDsc.position( ));
01765                         String_Value outputStringVal = theOutputClassObject.get_string( attrDsc.position( ));
01766 
01767                         copyStringValue(       inputStringVal ),
01768                                          outputStringVal );
01769                     }
01770 */
01771                 } else if( typeDsc.is_class( )) {
01772 
01773 //                    if( fixedArraySize > 1 ) {
01774 
01775                     cout << thePrefix.c_str( ) << "EMBEDDED OBJECT";
01776                     if( fixedArraySize > 1 ) cout << "[" << fixedArraySize << "]";
01777                     cout << endl;
01778 
01779 //                        cout << thePrefix.c_str( ) << "EMBEDDED OBJECT[" << fixedArraySize << "]" << endl;
01780 
01781                         for( size_t i = 0; i < fixedArraySize; ++i ) {
01782 
01783                             Class_Object  inputClassObj =       theClassObject.get_class_obj( attrDsc.position( ), i );
01784                             Class_Object outputClassObj = theOutputClassObject.get_class_obj( attrDsc.position( ), i );
01785 
01786                             copyObjectContents(  inputClassObj,
01787                                                 outputClassObj,
01788                                                 theHintH,
01789                                                 thePrefix );
01790                         }
01791 /*
01792                     } else {
01793 
01794                         cout << thePrefix.c_str( ) << "EMBEDDED OBJECT" << endl;
01795 
01796                         copyObjectContents(       theClassObject.get_class_obj( attrDsc.position( )),
01797                                             theOutputClassObject.get_class_obj( attrDsc.position( )),
01798                                             theHintH,
01799                                             thePrefix );
01800                     }
01801 */
01802                 } else if( typeDsc.is_varray_type( )) {
01803 
01804                     cout << thePrefix.c_str( ) << "V-ARRAY" << endl;
01805 
01806                     VArray_Object  inputVArrayObject =       theClassObject.get_varray( attrDsc.position( ));
01807                     VArray_Object outputVArrayObject = theOutputClassObject.get_varray( attrDsc.position( ));
01808 
01809                     copyVArrayObject(  inputVArrayObject,
01810                                       outputVArrayObject,
01811                                       typeDsc,
01812                                       theHintH,
01813                                       thePrefix );
01814                 } else {
01815                     cout << "ERROR: unknown type value found. Unable to copy." << endl;
01816                     assert( 0 );
01817                     return;
01818                 }
01819             }
01820             ++itr;
01821         }
01822     }
01823 }
01824 
01825 static
01826 void
01827 copyStringValue( const String_Value& theStringValue,
01828                        String_Value& theOutputStringValue )
01829 {
01830   // IMPLEMENTATION NOTES:
01831   //
01832   //    (1) Note, that we can't simply copy the input String_Value object into the output one
01833   //        because these objects are bound to the corresponding persistent objects.
01834   //
01835   //    (2) For internal string classes we take pointers onto the actual memory locations
01836   //        of the input and output strings inside their String_Value objects. Then we
01837   //        perform a kind of "memory-to-memory" copy operations to update the output
01838   //        string in its current location.
01839   //
01840   //    (3) In case of optimized strings the information exchange is performed through
01841   //        a copy of the input string stored stored in a dynamically allocated
01842   //        buffer by Optimized_String_Value::get_copy(). Then this pointer is passed
01843   //        down to the Optimized_String_Value::set() method of the output string.
01844   //        Finally we need to cleanup since the Optimized_String_Value::set()
01845   //        operation does not take over the ownership of teh passed string.
01846   //
01847     switch( theStringValue.type( )) {
01848 
01849     case ooAsStringVSTRING :
01850         {
01851             ooVString*       str = (String_Value&)theStringValue;
01852             ooVString* outputStr =                theOutputStringValue;
01853             (*outputStr) = (*str);
01854             break;
01855         }
01856 
01857 #ifndef OO_NO_CXX_JAVA
01858 
01859     case ooAsStringUTF8 :
01860         {
01861             ooUtf8String*       str = (String_Value&)theStringValue;
01862             ooUtf8String* outputStr =                theOutputStringValue;
01863             (*outputStr) = (*str);
01864             break;
01865         }
01866 #endif
01867 
01868 #ifndef OO_NO_CXX_SMALLTALK
01869 
01870     case ooAsStringST :
01871         {
01872             ooSTString*       str = (String_Value&)theStringValue;
01873             ooSTString* outputStr =                theOutputStringValue;
01874             (*outputStr) = (*str);
01875             break;
01876         }
01877 #endif
01878 
01879     case ooAsStringOPTIMIZED :
01880         {
01881             assert(       theStringValue.is_optimized_string( ));
01882             assert( theOutputStringValue.is_optimized_string( ));
01883 
01884             Optimized_String_Value  inputStringValue(       theStringValue );
01885             Optimized_String_Value outputStringValue( theOutputStringValue );
01886 
01887             char* str = new char [ inputStringValue.length( ) + 1];
01888             inputStringValue.get_copy( str );
01889 /*
01890             cout << "copying optimized string: \"" << str << "\"" << endl
01891                  << "  input  fixed length = " <<  inputStringValue.fixed_length( ) << endl
01892                  << "  input        length = " <<  inputStringValue.length( )       << endl
01893                  << "  output fixed length = " << outputStringValue.fixed_length( ) << endl
01894                  << "  output       length = " << outputStringValue.length( )       << " (before)" << endl;
01895  */
01896 // IMPLEMENTATION NOTE: The method below has an apparent bug in its implementation
01897 //                      when the dynamic size of the string is more than its fized one.
01898 //                      This causes the following memory access problem reported by "valgrind":
01899 
01900 /**
01901   ...
01902   STRING
01903 ==4047== 
01904 ==4047== Use of uninitialised value of size 4
01905 ==4047==    at 0x400497F2: strcpy (vg_clientfuncs.c:440)
01906 ==4047==    by 0x4080D99C: ooas::Optimized_String_Value::set(char const *) (in /afs/slac.stanford.edu/g/babar/package/objyvols/vol5/objy7.1/linux86/lib/liboo_as.so.7.1)
01907 ==4047==    by 0x80566BF: copyStringValue(ooas::String_Value const &, ooas::String_Value &) (/afs/slac.stanford.edu/u/ec/gapon/vol0/release/13.2.0/CdbBdbTests/CdbActiveSchemaTest.cc:1566)
01908 ==4047==    by 0x8055F07: copyObjectContents(ooas::Class_Object const &, ooas::Class_Object &, opiHandle<ooObj> const &, bool, bool, basic_string<char, string_char_traits<char>, __default_alloc_template<true, 0> > const &) (/afs/slac.stanford.edu/u/ec/gapon/vol0/release/13.2.0/CdbBdbTests/CdbActiveSchemaTest.cc:1417)
01909   EMBEDDED OBJECT
01910   ...
01911  **/
01912 
01913 // The problem strikes in some other place due to probably overwritten memory contents.
01914 // It's been seen a number of times in various places.
01915 //
01916 //            outputStringValue.resize( inputStringValue.length( ));
01917 //
01918 // END OF IMPLEMENTATION NOTE
01919 /*
01920             cout << "  output length = " << outputStringValue.length( ) << " (after resize)" << endl;
01921  */
01922             outputStringValue.set( str );
01923 
01924             delete [] str;
01925 
01926             break;
01927         }
01928     default :
01929         {
01930             cout << "ERROR: unsupported string type found. Unable to copy." << endl;
01931             assert( 0 );
01932             break;
01933         }
01934     }
01935 }
01936 
01937 static
01938 void
01939 copyVArrayObject(   const VArray_Object& theVArrayObject,
01940                           VArray_Object& theOutputVArrayObject,
01941                            const d_Type& theVArrayTypeDsc,
01942                   const ooHandle(ooObj)& theHintH,
01943                       const std::string& thePrefix )
01944 {
01945   // Don't forget to resize the output array before copying elements
01946   // from the input one. Otherwise we're going to have a run-time exception.
01947 
01948     uint32 num = theVArrayObject.size( );
01949     theOutputVArrayObject.resize( num );
01950 
01951   // Now proceed with the copy.
01952 
01953     for( uint32 i = 0; i < num; ++i ) {
01954 
01955         if( theVArrayTypeDsc.is_varray_basic_type( )) {
01956 
01957             theOutputVArrayObject.set( i, theVArrayObject.get( i ));
01958 
01959         } else if( theVArrayTypeDsc.is_varray_ref_type( )) {
01960 
01961             ooHandle(ooObj)  inputH;
01962             ooHandle(ooObj) outputH;
01963 
01964             inputH = theVArrayObject.get_ooref( i );
01965 
01966             if( deepCopyMode ) {
01967                 if( !cloneObject(   inputH,
01968                                   theHintH,
01969                                    outputH,
01970                                   thePrefix + "  " )) {
01971                     return;
01972                 }
01973             } else {
01974                 outputH = inputH;
01975                 cout << "WARNING: performing the shallow copy of " << outputH.sprint( ) << endl;
01976             }
01977             theOutputVArrayObject.set_ooref( i, outputH );
01978 
01979         } else if( theVArrayTypeDsc.is_string_type( )) {    // It may also be an embedded string class,
01980                                                             // so we make this scheck before the next one.
01981 
01982             String_Value  inputStringVal =       theVArrayObject.get_string( i );
01983             String_Value outputStringVal = theOutputVArrayObject.get_string( i );
01984 
01985             copyStringValue(  inputStringVal,
01986                              outputStringVal );
01987 
01988         } else if( theVArrayTypeDsc.is_varray_embedded_class_type( )) {
01989 
01990             Class_Object  inputClassObj =       theVArrayObject.get_class_obj( i );
01991             Class_Object outputClassObj = theOutputVArrayObject.get_class_obj( i );
01992 
01993             copyObjectContents(  inputClassObj,
01994                                 outputClassObj,
01995                                 theHintH,
01996                                 thePrefix );
01997 
01998         } else {
01999             cout << "ERROR: unknown V-Array type." << endl;
02000             assert( 0 );
02001         }
02002     }
02003 }
02004 
02005 static
02006 bool
02007 cloneObject( const ooHandle(ooObj)& theH,
02008              const ooHandle(ooObj)& theHintH,
02009                    ooHandle(ooObj)& theOutputH,
02010                  const std::string& thePrefix )
02011 {
02012     if( verboseMode ) {
02013         std::string  inStr = theH.sprint( );
02014         cout << thePrefix.c_str( ) << inStr.c_str( ) << " >> " << endl;
02015     }
02016 
02017   // Simply return the null objects. It's not a error conditions since its quite
02018   // normal for persistent objects to have null references.
02019 
02020     if( oocTrue != theH.isValid( )) {
02021 
02022         theOutputH = theH;
02023 
02024         if( verboseMode ) {
02025 
02026             std::string  inStr =       theH.sprint( );
02027             std::string outStr = theOutputH.sprint( );
02028 
02029             cout << thePrefix.c_str( ) << inStr.c_str( ) << " -- " << outStr.c_str( ) << " (NULL) \"\"" << endl;
02030         }
02031 
02032     } else {
02033 
02034       // Find an object in the transient cache first if the cache is present
02035       // in the current test's environment.
02036 
02037         theOutputH = 0;
02038         if( 0 != transientCache ) theOutputH = transientCache->findObject( theH );
02039 
02040         if( oocTrue == theOutputH.isValid( )) {
02041 
02042             if( verboseMode ) {
02043 
02044                 std::string  inStr =       theH.sprint( );
02045                 std::string outStr = theOutputH.sprint( );
02046 
02047                 cout << thePrefix.c_str( ) << inStr.c_str( ) << " -- " << outStr.c_str( ) << " (CACHED) \"" << theOutputH.typeName( ) << "\"" << endl;
02048             }
02049 
02050         } else {
02051 
02052           // Check for special case of the ooMap class. Use regular (as opposed to the Active
02053           // Schema API) to copy the map.
02054           //
02055           // IMPLEMENTATION NOTE: In theory this operation could also be resolved for
02056           //                      user defined subclasses of the ooMap class. Besides we have
02057           //                      a set of other internal classes defined by Objectivity itself
02058           //                      (containers, sets, B-Trees, etc.) It's unclear whether they
02059           //                      can also be copied in this way.
02060 
02061             ooTypeNumber typeN = theH.typeN( );
02062 
02063             if( ooTypeN(ooMap) == typeN ) {
02064 
02065                 ooHandle(ooMap)  inputMapH;     // non-const handle is needed to set up an iterator
02066                 ooHandle(ooMap) outputMapH;
02067 
02068                  inputMapH = (ooHandle(ooMap))theH;
02069                 outputMapH = new( theHintH ) ooMap( inputMapH->nBin( ),
02070                                                     inputMapH->maxAvgDensity( ),
02071                                                     inputMapH->percentGrow( ));
02072 
02073               // ATTENTION: update the cache _before_ copying the object to prevent
02074               //            "copy self" loop. This may cause crashes when copying
02075               //            optmized strings.
02076 
02077                 theOutputH = outputMapH;
02078                 if( 0 != transientCache ) transientCache->addObject(       theH,
02079                                                                      theOutputH );
02080                 if( verboseMode ) {
02081 
02082                     std::string  inStr =       theH.sprint( );
02083                     std::string outStr = theOutputH.sprint( );
02084 
02085                     cout << thePrefix.c_str( ) << inStr.c_str( ) << " -- " << outStr.c_str( ) << " (NEW) \"" << theOutputH.typeName( ) << "\"" << endl;
02086                 }
02087                 {
02088                     ooMapItr itr( inputMapH );
02089                     while( itr.next( )) {
02090 
02091                         std::string  key = itr->name( );
02092 
02093                         ooHandle(ooObj)  inputH;
02094                         ooHandle(ooObj) outputH;
02095 
02096                         ooRef(ooObj) inputRef = itr->oid( );
02097                         inputH = inputRef;
02098 
02099                         if( deepCopyMode ) {
02100 
02101                             if( !cloneObject(   inputH,
02102                                               theHintH,
02103                                                outputH,
02104                                               thePrefix + "  " )) {
02105 
02106                                 cout << "ERROR: failed to copy: " << inputH.sprint( ) << endl;
02107 
02108                                 assert( 0 );
02109                                 return false;
02110                             }
02111                         } else {
02112                             outputH = inputH;
02113                             cout << "WARNING: performing the shallow copy of " << outputH.sprint( ) << endl;
02114                         }
02115 
02116                       // Put the clone into the output map
02117 
02118                         if( oocSuccess != outputMapH->add( key.c_str( ),
02119                                                            outputH )) {
02120 
02121                             cout << "ERROR: failed to insert" << endl
02122                                  << "    Key        : \"" << key.c_str( ) << "\"" << endl
02123                                  << "    Reference  : " << outputH.sprint( ) << endl
02124                                  << "  Into the output map:" << endl
02125                                  << "    Input  Map : " <<  inputMapH.sprint( ) << endl
02126                                  << "    Output Map : " << outputMapH.sprint( ) << endl;
02127 
02128                             assert( 0 );
02129                             return false;
02130                         }
02131                     }
02132                 }
02133 
02134             } else {
02135 
02136               // Copy the persisten object using recursive algorithm.
02137               //
02138               // NOTE: The cast is needed as a workaround of the buggy interface
02139               //       of the "ooas::Class_Object" class. It does not really need
02140               //       non-const handle.
02141 
02142                 Class_Object classObj((ooHandle(ooObj)&)theH ); 
02143                 if( !classObj ) {
02144                     cout << "ERROR: no Class_Object for the input object reference: " << theH.sprint( ) << endl;
02145 
02146                     assert( 0 );
02147                     return false;
02148                 }
02149                 Class_Object outputClassObj
02150                     = Class_Object::new_persistent_object( classObj.type_of( ), // new object type
02151                                                            theHintH,            // create new object next to thsi one
02152                                                            NULL,                // no special clustering strategy
02153                                                            oocTrue              // initialize base class by 0-es
02154                                                          );
02155 
02156               // ATTENTION: update the cache _before_ copying the object to prevent
02157               //            "copy self" loop. This may cause crashes when copying
02158               //            optmized strings.
02159 
02160                 theOutputH = outputClassObj.object_handle( );
02161                 if( 0 != transientCache ) transientCache->addObject(       theH,
02162                                                                      theOutputH );
02163                 if( verboseMode ) {
02164 
02165                     std::string  inStr =       theH.sprint( );
02166                     std::string outStr = theOutputH.sprint( );
02167 
02168                     cout << thePrefix.c_str( ) << inStr.c_str( ) << " -- " << outStr.c_str( ) << " (NEW) \"" << theOutputH.typeName( ) << "\"" << endl;
02169                 }
02170                 copyObjectContents(       classObj,
02171                                     outputClassObj,
02172                                     theHintH,
02173                                     thePrefix );
02174             }
02175         }
02176     }
02177     if( verboseMode ) {
02178         std::string  inStr = theH.sprint( );
02179         cout << thePrefix.c_str( ) << inStr.c_str( ) << " << " << endl;
02180     }
02181     return true;
02182 }
02183 
02184 ///////////////////////
02185 // OBJECTS LIST COPY //
02186 ///////////////////////
02187 
02188 static
02189 void
02190 cmd_copyObjectsList( const char* theFileName,
02191                      const char* theHintObjectIdentifier )
02192 {
02193     assert( 0 != theFileName );
02194     assert( 0 != theHintObjectIdentifier );
02195 
02196   // Open a file with a list of OID-s to be copied
02197 
02198     ifstream inFile( theFileName );
02199     if( !inFile.good( )) {
02200         cout << "ERROR: failed to open specified input file." << endl;
02201         return;
02202     }
02203 
02204   // Get the reference for a hint object where the output ones will be created
02205 
02206     ooHandle(ooObj) hintH;
02207     {
02208         ooId oid;
02209         if( ! translate_OID( oid, theHintObjectIdentifier )) return;
02210 
02211         hintH = (ooRef(ooObj))oid;
02212         if( !hintH.isValid( )) {
02213             cout << "ERROR: an invalid reference to the clustering hint object found." << endl;
02214             return;
02215         }
02216     }
02217 
02218   // Read OID-s from the input file one-by-one and create them
02219   // at the output destination.
02220 
02221     transientCache = new CdbBdbSimpleCache( );
02222     {
02223         ooHandle(ooObj)  inputH;
02224         ooHandle(ooObj) outputH;
02225 
02226         char str[256];
02227         while( inFile >> str ) {
02228 
02229             if( verboseMode ) cout << "INPUT OBJECT: " << str << endl;
02230 
02231             ooId oid;
02232             if( ! translate_OID( oid, str )) break;
02233 
02234             inputH = (ooRef(ooObj))oid;
02235             if( !inputH.isValid( )) {
02236                 cout << "ERROR: an invalid reference to the input object found." << endl;
02237                 break;
02238             }
02239 
02240             if( !cloneObject(  inputH,
02241                                 hintH,
02242                               outputH,
02243                               "  " )) break;
02244         }
02245     }
02246     delete transientCache;
02247     transientCache = 0;
02248 }
02249 
02250 ///////////////////////
02251 // CONTAINER CREATOR //
02252 ///////////////////////
02253 
02254 static
02255 void
02256 cmd_createContainer( const char* theHintObjectIdentifier,
02257                      const char* theContainerName,
02258                             bool hashedFlag,
02259                              int theInitPagesNumber,
02260                              int theGrowFactor )
02261 {
02262     assert( theInitPagesNumber > 0 );
02263     assert( theGrowFactor > 0 );
02264 
02265   // Find and examine the container class using Objectivity's Active Schema API.
02266 
02267     const d_Module& topModule = d_Module::top_level( );
02268     const d_Class&  classDsc  = topModule.resolve_class( "ooContObj" );
02269     if( !classDsc ) {
02270         cout << "ERROR: no ooContObj class in the Schema." << endl;
02271         return;
02272     }
02273 
02274   // Get the reference for a database object to be used as clustering hint.
02275 
02276     ooRef(ooObj) oHintRef;
02277     {
02278         ooId oId;
02279         if( ! translate_OID( oId, theHintObjectIdentifier )) return;
02280 
02281         oHintRef = oId;
02282         if( !oHintRef.isValid( )) {
02283             cout << "ERROR: an invalid reference to the clustering hint object found." << endl;
02284             return;
02285         }
02286     }
02287 
02288   // Create the container object
02289 
02290     Class_Object classObj = Class_Object::new_persistent_container_object( classDsc,
02291                                                                            theContainerName,
02292                                                                            oHintRef,
02293                                                                            ( hashedFlag ? 1 : 0 ),
02294                                                                            theInitPagesNumber,
02295                                                                            theGrowFactor,
02296                                                                            oocTrue );
02297     cout << classObj.object_handle( ).sprint( ) << endl;
02298 }
02299 
02300 ///////////////////////////
02301 // CLASS DEPENDENCY TEST //
02302 ///////////////////////////
02303 
02304 static
02305 void
02306 cmd_isA( const char* theDerivedTypeNumberOrClassName,
02307          const char*    theBaseTypeNumberOrClassName )
02308 {
02309     assert( 0 != theDerivedTypeNumberOrClassName );
02310     assert( 0 != theBaseTypeNumberOrClassName );
02311 
02312     CdbBdbSchemaUtils::debugMode = debugMode;
02313 
02314     ooTypeNumber derivedTypeNumber;
02315     ooTypeNumber    baseTypeNumber;
02316 
02317     std::string derivedClassName = theDerivedTypeNumberOrClassName;
02318     std::string    baseClassName = theBaseTypeNumberOrClassName;
02319 
02320     if( !translate_type_number( derivedTypeNumber,
02321                                 theDerivedTypeNumberOrClassName )) {
02322 
02323         if( !CdbBdbSchemaUtils::instance( ).classNameToTypeNumber( theDerivedTypeNumberOrClassName,
02324                                                                       derivedTypeNumber )) {
02325 
02326             cout << "ERROR: Failed to translate the derived class name into its type number." << endl
02327                  << "       The type number may not be valid." << endl;
02328             return;
02329         }
02330     }
02331     if( !translate_type_number( baseTypeNumber,
02332                                 theBaseTypeNumberOrClassName )) {
02333 
02334         if( !CdbBdbSchemaUtils::instance( ).classNameToTypeNumber( theBaseTypeNumberOrClassName,
02335                                                                       baseTypeNumber )) {
02336 
02337             cout << "ERROR: Failed to translate the base class name into its type number." << endl
02338                  << "       The type number may not be valid." << endl;
02339             return;
02340         }
02341     }
02342     if( CdbBdbSchemaUtils::instance( ).isA( derivedTypeNumber,
02343                                                baseTypeNumber )) {
02344 
02345         cout << derivedTypeNumber << " : \"" << derivedClassName.c_str( ) << "\" derives from "         << baseTypeNumber << " : \"" << baseClassName.c_str( ) << "\"" << endl;
02346     } else {
02347         cout << derivedTypeNumber << " : \"" << derivedClassName.c_str( ) << "\" does not derive from " << baseTypeNumber << " : \"" << baseClassName.c_str( ) << "\"" << endl;
02348     }
02349 }
02350 
02351 static
02352 void
02353 cmd_translate( const char* theTypeNumberOrClassName )
02354 {
02355     assert( 0 != theTypeNumberOrClassName );
02356 
02357     CdbBdbSchemaUtils::debugMode = debugMode;
02358 
02359     ooTypeNumber typeNumber;
02360     std::string  className;
02361 
02362     if( !translate_class_identification( theTypeNumberOrClassName,
02363                                          typeNumber,
02364                                          className )) return;
02365 
02366     cout << typeNumber << " : \"" << className.c_str( ) << "\"" << endl;
02367 }
02368 
02369 static
02370 void
02371 print_subclasses( const CdbBdbSchemaUtils::Node* theNode,
02372                               const std::string& thePrefix )
02373 {
02374     assert( 0 != theNode );
02375 
02376     const char* htmlSuffix = ( longMode ? ".html" : "_compact.html" );
02377 
02378     ooTypeNumber typeNumber = theNode->typeNumber;
02379 
02380     std::string className;
02381     if( !CdbBdbSchemaUtils::instance( ).typeNumberToClassName( typeNumber,
02382                                                                className )) {
02383         cout << "print_subclasses: failed to obtain the class name for the type number " << typeNumber << endl;
02384         return;
02385     }
02386     if( longMode ) {
02387         if( htmlMode ) {
02388             cout << thePrefix.c_str( ) << "+-- " << typeNumber << " : <A HREF=\"" << typeNumber << htmlSuffix << "\">" << string2html( className ).c_str( ) << "</A>" << endl;
02389         } else {
02390             cout << thePrefix.c_str( ) << "+-- " << typeNumber << " : \"" << className.c_str( ) << "\"" << endl;
02391         }
02392     } else {
02393         if( htmlMode ) {
02394            cout << thePrefix.c_str( ) << "+-- <A HREF=\"" << typeNumber << htmlSuffix << "\">" << string2html( className ).c_str( ) << "</A>" << endl;
02395         } else {
02396             cout << thePrefix.c_str( ) << "+-- " << typeNumber << " : \"" << className.c_str( ) << "\"" << endl;
02397         }
02398     }
02399 
02400     int num = 0;
02401     std::map<ooTypeNumber, CdbBdbSchemaUtils::Node* >::const_iterator itr = theNode->subclasses.begin( );
02402     while( theNode->subclasses.end( ) != itr ) {
02403         if( theNode->subclasses.begin( ) == itr ) {
02404             cout << thePrefix.c_str( ) << "|   |" << endl;
02405         }
02406         print_subclasses( itr->second,
02407                           thePrefix + "|   " );
02408         ++num;
02409         ++itr;
02410     }
02411     if( 0 != num ) {
02412         cout << thePrefix.c_str( ) << "|" << endl;
02413     }
02414 }
02415 
02416 static
02417 void
02418 cmd_subclasses( const char* theTypeNumberOrClassName )
02419 {
02420     CdbBdbSchemaUtils::debugMode = debugMode;
02421 
02422   // Build the full tree.
02423 
02424     CdbBdbSchemaUtils::Tree fullDependencyTree;
02425     if( !CdbBdbSchemaUtils::instance( ).loadDependencyTree( fullDependencyTree )) {
02426         cout << "cmd_subclasses: ERROR - failed to load full dependency tree." << endl;
02427         return;
02428     }
02429 
02430   // Print just one class (if specified) or the whole tree
02431 
02432     if( htmlMode ) {
02433         cout << "<HTML>" << endl
02434              << "<BODY>" << endl
02435              << "<PRE>"  << endl;
02436     }
02437     cout << endl;
02438 
02439     if( 0 != theTypeNumberOrClassName ) { 
02440 
02441       // FOR A CLASS
02442 
02443         ooTypeNumber typeNumber;
02444         std::string  className;
02445 
02446         if( !translate_class_identification( theTypeNumberOrClassName,
02447                                              typeNumber,
02448                                              className )) return;
02449 
02450         const CdbBdbSchemaUtils::Node* node = fullDependencyTree.type_to_node( typeNumber );
02451         if( 0 == node ) {
02452             cout << "cmd_subclasses: ERROR - no schema information for: \"" << theTypeNumberOrClassName << "\"" << endl;
02453             return;
02454         }
02455         print_subclasses( node,
02456                           std::string( "  " ));
02457 
02458     } else {
02459 
02460       // ALL CLASSES
02461 
02462         std::map<ooTypeNumber, CdbBdbSchemaUtils::Node*>::iterator itr = fullDependencyTree.root.begin( );
02463         while( fullDependencyTree.root.end( ) != itr ) {
02464             print_subclasses( itr->second,
02465                               std::string( "  " ));
02466             ++itr;
02467         }
02468     }
02469     cout << endl;
02470     if( htmlMode ) {
02471         cout << "</PRE>" << endl
02472              << "</BODY>" << endl
02473              << "</HTML>"  << endl;
02474     }
02475 }
02476 
02477 static
02478 void
02479 print_superclasses( const CdbBdbSchemaUtils::Node* theNode,
02480                                 const std::string& thePrefix )
02481 {
02482     assert( 0 != theNode );
02483 
02484     ooTypeNumber typeNumber = theNode->typeNumber;
02485 
02486     std::string className;
02487     if( !CdbBdbSchemaUtils::instance( ).typeNumberToClassName( typeNumber,
02488                                                                className )) {
02489         cout << "print_superclasses: failed to obtain the class name for the type number " << typeNumber << endl;
02490         return;
02491     }
02492     if( longMode ) {
02493         cout << thePrefix.c_str( ) << "+-- " << typeNumber << " : \"" << className.c_str( ) << "\"" << endl;
02494     } else {
02495         cout << thePrefix.c_str( ) << "+-- " << className.c_str( ) << endl;
02496     }
02497 
02498     int num = 0;
02499     std::map<ooTypeNumber, CdbBdbSchemaUtils::Node* >::const_iterator itr = theNode->superclasses.begin( );
02500     while( theNode->superclasses.end( ) != itr ) {
02501         if( theNode->superclasses.begin( ) == itr ) {
02502             cout << thePrefix.c_str( ) << "|   |" << endl;
02503         }
02504         print_superclasses( itr->second,
02505                             thePrefix + "|   " );
02506         ++num;
02507         ++itr;
02508     }
02509     if( 0 != num ) {
02510         cout << thePrefix.c_str( ) << "|" << endl;
02511     }
02512 }
02513 
02514 static
02515 void
02516 cmd_superclasses( const char* theTypeNumberOrClassName )
02517 {
02518     CdbBdbSchemaUtils::debugMode = debugMode;
02519 
02520   // Build the full tree.
02521 
02522     CdbBdbSchemaUtils::Tree fullDependencyTree;
02523     if( !CdbBdbSchemaUtils::instance( ).loadDependencyTree( fullDependencyTree )) {
02524         cout << "cmd_superclasses: ERROR - failed to load full dependency tree." << endl;
02525         return;
02526     }
02527 
02528   // Print just one class (if specified) or all known ones
02529 
02530     cout << endl;
02531 
02532     if( 0 != theTypeNumberOrClassName ) { 
02533 
02534       // FOR A CLASS
02535 
02536         ooTypeNumber typeNumber;
02537         std::string  className;
02538 
02539         if( !translate_class_identification( theTypeNumberOrClassName,
02540                                              typeNumber,
02541                                              className )) return;
02542 
02543         const CdbBdbSchemaUtils::Node* node = fullDependencyTree.type_to_node( typeNumber );
02544         if( 0 == node ) {
02545             cout << "cmd_superclasses: ERROR - no schema information for: \"" << theTypeNumberOrClassName << "\"" << endl;
02546             return;
02547         }
02548         print_superclasses( node,
02549                             std::string( "  " ));
02550 
02551     } else {
02552 
02553       // FOR ALL CLASSES
02554 
02555         std::map<ooTypeNumber, CdbBdbSchemaUtils::Node*>::iterator itr = fullDependencyTree.all.begin( );
02556         while( fullDependencyTree.all.end( ) != itr ) {
02557             print_superclasses( itr->second,
02558                                 std::string( "  " ));
02559             ++itr;
02560         }
02561     }
02562     cout << endl;
02563 }
02564 
02565 ///////////////
02566 // Utilities //
02567 ///////////////
02568 
02569 static
02570 const char*
02571 access2string( d_Access_Kind theAccessKind )
02572 {
02573          if( d_PRIVATE   == theAccessKind ) return "private";
02574     else if( d_PROTECTED == theAccessKind ) return "protected";
02575     else if( d_PUBLIC    == theAccessKind ) return "public";
02576     return "<unknown access kind>";
02577 }
02578 
02579 static
02580 bool
02581 translate_OID( ooId&       theId,
02582                const char* theString )
02583 {
02584     bool result = false;
02585 
02586     do {
02587         if( 0 == theString ) {
02588             cout << "ERROR: empty string passed where an OID was expeted." << endl;
02589             break;
02590         }
02591 
02592         int db;
02593         int cont;
02594         int page;
02595         int slot;
02596 
02597         if( 4 != sscanf( theString, "%d-%d-%d-%d", &db, &cont, &page, &slot )) {
02598             cout << "ERROR: illegal format of the OID string: \"" << theString << "\"." << endl;
02599             break;
02600         }
02601         theId.set_DB  ( db );
02602         theId.set_OC  ( cont );
02603         theId.set_page( page );
02604         theId.set_slot( slot );
02605 
02606         result = true;
02607 
02608     } while( false );
02609 
02610     return true;
02611 }
02612 
02613 static
02614 bool
02615 translate_int( int&        theValue,
02616                const char* theBuf )
02617 {
02618     assert( 0 != theBuf );
02619  
02620     int v;
02621  
02622     if( 1 == sscanf( theBuf, "%d", &v )) {
02623         theValue = v;
02624         return true;
02625     }
02626     return false;
02627 }
02628 
02629 static
02630 bool
02631 translate_type_number( ooTypeNumber& theValue,
02632                          const char* theBuf )
02633 {
02634     assert( 0 != theBuf );
02635 
02636     const int num = strlen( theBuf );
02637     for( int i = 0; i < num; ++i )
02638         if( !isdigit( theBuf[i] )) return false;
02639  
02640     unsigned int v;
02641  
02642     if( 1 == sscanf( theBuf, "%ud", &v )) {
02643         theValue = v;
02644         return true;
02645     }
02646     return false;
02647 }
02648 
02649 static
02650 bool
02651 translate_class_identification(   const char* theTypeNumberOrClassName,
02652                                 ooTypeNumber& theTypeNumber,
02653                                  std::string& theClassName )
02654 {
02655     assert( 0 != theTypeNumberOrClassName );
02656 
02657     if( translate_type_number( theTypeNumber,
02658                                theTypeNumberOrClassName )) {
02659 
02660         if( !CdbBdbSchemaUtils::instance( ).typeNumberToClassName( theTypeNumber,
02661                                                                    theClassName )) {
02662 
02663             cout << "ERROR: Failed to translate the type number into its class name." << endl
02664                  << "       The class name may not be valid." << endl;
02665             return false;
02666         }
02667 
02668     } else {
02669 
02670         if( !CdbBdbSchemaUtils::instance( ).classNameToTypeNumber( theTypeNumberOrClassName,
02671                                                                    theTypeNumber )) {
02672 
02673             cout << "ERROR: Failed to translate the class name into its type number." << endl
02674                  << "       The type number may not be valid." << endl;
02675             return false;
02676         }
02677         theClassName = theTypeNumberOrClassName;
02678     }
02679     return true;
02680 }
02681 
02682 static
02683 std::string
02684 string2html( const std::string& theString )
02685 {
02686     std::string result = "";
02687     unsigned int num = theString.size( );
02688     for( unsigned int i = 0; i < num; ++i ) {
02689         char c = theString[i];
02690         switch( c ) {
02691         case '<': result += "&lt"; break;
02692         case '>': result += "&gt"; break;
02693         default: result += c;
02694         }
02695     }
02696     return result;
02697 }
02698 
02699 /////////////////
02700 // End Of File //
02701 /////////////////

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