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

CdbBdbNTupleConversionImpl.cc

Go to the documentation of this file.
00001 // File and Version Information:
00002 //      $Id: CdbBdbNTupleConversionImpl.cc,v 1.4 2004/08/06 05:54:31 bartoldu Exp $
00003 
00004 /// The implementation of the CdbBdbNTupleConversionImpl class.
00005 /**
00006   * @see CdbBdbNTupleConversionImpl
00007   */
00008 
00009 #include "BaBar/BaBar.hh"
00010 
00011 #include "CdbBdbTable/CdbBdbNTupleConversionImpl.hh"
00012 #include "CdbBdbTable/CdbBdbNTupleSimpleImplP_PrimitiveTypes.hh"
00013 #include "CdbBdbTable/CdbBdbNTupleSimpleImplP_ooVString.hh"
00014 
00015 #include "CdbTable/CdbNTupleFactoryFE.hh"
00016 
00017 #include "CdbBdb/CdbBdbSchemaUtils.hh"
00018 
00019 #include <assert.h>
00020 #include <iostream>
00021 using std::cout;
00022 using std::endl;
00023 
00024 ////////////////////////////////////////////////////////////////////////////////////////
00025 // CdbBdbNTupleConversionImpl_Helper< PERSISTENT, T, NCOL, ELEMENT_CONVERSION_RULES > //
00026 ////////////////////////////////////////////////////////////////////////////////////////
00027 
00028 /// Internal implementation helper class
00029 /**
00030   * This class will perform the actual conversion operations based on the persistent class
00031   * specified as its template parameter.
00032   *
00033   * DESIGN NOTES:
00034   *
00035   *   The model of a class passed as a value of the 'PERSISTENT' parameter must be the same one
00036   *   as in case of the "CdbBdbNTupleP<T>" class except signatures for constructors (the issue
00037   *   of different constructors will be solved later).
00038   */
00039 template < class        PERSISTENT,
00040            class        T,
00041            unsigned int NCOL,
00042            class        ELEMENT_CONVERSION_RULES >
00043 
00044 struct CdbBdbNTupleConversionImpl_Helper {
00045 
00046   /// Try to convert into a transient form
00047   /**
00048     * The method will check if the specified reference matches the specified persistent type
00049     * as well as parameters of the transient n-tuple.
00050     */
00051     static CdbStatus to_transient( CdbNTuple< T, NCOL >*&  thePtr,
00052                                    const ooRef(BdbObject)& thePersRef )
00053     {
00054         const char* errorStr = "CdbBdbNTupleConversionImpl_Helper< PERSISTENT, T, NCOL, ELEMENT_CONVERSION_RULES >::to_transient() - ERROR";
00055 
00056         if( BdbIsNull(thePersRef))  return CdbStatus::IllegalParameters;
00057         if( !thePersRef.isValid( )) return CdbStatus::IllegalParameters;
00058 
00059       // Verify the actual type and configuration of the persistent tuple
00060       //
00061       // NOTE: Perhaps we should use the Active Schema API to avoid problems
00062       //       with partially loaded v-tables.
00063 
00064         const ooTypeNumber expectedTypeNumber = ooTypeN( PERSISTENT );
00065         const ooTypeNumber   actualTypeNumber = thePersRef.typeN( );
00066 
00067         if( expectedTypeNumber != actualTypeNumber ) {
00068 
00069             std::string expectedTypeName = "<unknon type name>";
00070 
00071             if( !CdbBdbSchemaUtils::instance( ).typeNumberToClassName( expectedTypeNumber,
00072                                                                        expectedTypeName )) {
00073                 assert( 0 );
00074             }
00075             cout << errorStr << endl
00076                  << "    A type of persistent object " << thePersRef.sprint( ) << " does not match" << endl
00077                  << "    the one expected for the transient n-tuple." << endl
00078                  << "        EXPECTED TYPE: " << actualTypeNumber   << " : \"" << thePersRef.typeName( )    << "\"" << endl
00079                  << "        ACTUAL TYPE:   " << expectedTypeNumber << " : \"" << expectedTypeName.c_str( ) << "\"." << endl;
00080 
00081             return CdbStatus::Error;
00082         }
00083 
00084       // Turn it into a reference and then handle (for the performance reason) of
00085       // the required persistent type.
00086 
00087         ooRef   ( PERSISTENT ) tupleRef = ( ooRef( PERSISTENT )) thePersRef;
00088         ooHandle( PERSISTENT ) tupleH   = tupleRef;
00089 
00090         assert( tupleH.isValid( ));
00091 
00092         if( NCOL != tupleH->columns( )) {
00093 
00094             cout << errorStr << endl
00095                  << "    A persistent tuple object " << tupleH.sprint( ) << " passed for the conversion" << endl
00096                  << "    has incompatible number of columns " << tupleH->columns( ) << "." << endl
00097                  << "    Meanwhile the following number " << NCOL << " was expected." << endl
00098                  << "    The further conversion is not possible." << endl;
00099 
00100             return CdbStatus::Error;
00101         }
00102 
00103       // Create a transient tuple object using the factory and metadata obtained
00104       // from the persistent object.
00105 
00106         std::vector<std::string> columnNames;
00107         tupleH->column_names( columnNames );
00108 
00109         CdbNTuple<T,NCOL>* resultPtr = 0;
00110 
00111         CdbNTupleFactoryFE::createSimple( resultPtr,
00112                                           columnNames,
00113                                           tupleH->name( ),
00114                                           tupleH->description( ));
00115         if( 0 == resultPtr ) {
00116             cout << errorStr << endl
00117                  << "    Failed to create a transient n-tuple." << endl;
00118             return CdbStatus::Error;
00119         }
00120 
00121       // Copy over rows from the transient tuple into the persistent one
00122 
00123         unsigned int nRows = tupleH->rows( );
00124         for( unsigned int r = 0; r < nRows; ++r ) {
00125 
00126             std::vector< typename PERSISTENT::ElementType > pRow;
00127             if( CdbStatus::Success != tupleH->get_row( pRow, r )) {
00128 
00129                 cout << errorStr << endl
00130                      << "    Failed to get a row number " << r << " from a persistent tuple object " << tupleH.sprint( ) << endl;
00131 
00132                 return CdbStatus::Error;
00133             }
00134             assert( NCOL == pRow.size( ));
00135 
00136             std::vector<T> trRow( NCOL );
00137             for( unsigned int c = 0; c < NCOL; ++c ) {
00138                 trRow[c] = ELEMENT_CONVERSION_RULES::to_transient( pRow[c] );
00139             }
00140             if( CdbStatus::Success != resultPtr->append_row( trRow )) {
00141 
00142                 cout << errorStr << endl
00143                      << "    Failed to append a new row number " << r << " to the transient tuple object." << endl;
00144 
00145                 return CdbStatus::Error;
00146             }
00147         }
00148 
00149       // Return a smart pointer onto the newely created transient tuple
00150 
00151         thePtr = resultPtr;
00152 
00153         return CdbStatus::Success;
00154     }
00155 
00156   /// Try to produce a persistent object out of a transient tuple
00157   /**
00158     * The method will attempt to use the specified persistent type to store the contents of
00159     * the specified transient tuple.
00160     */
00161     static CdbStatus to_persistent( ooRef(BdbObject)&                      thePersRef,
00162                                     const CdbCPtr< CdbNTuple< T, NCOL > >& thePtr,
00163                                     const BdbRefAny&                       theHintRef )
00164     {
00165         const char* errorStr = "CdbBdbNTupleConversionImpl_Helper< PERSISTENT, T, NCOL, ELEMENT_CONVERSION_RULES >::to_persistent() - ERROR";
00166 
00167         if( thePtr.isNull( ))      return CdbStatus::IllegalParameters;
00168         if( BdbIsNull(theHintRef)) return CdbStatus::IllegalParameters;
00169 
00170       // Create a persistent n-tuple objects with specified type and configuration.
00171       // Copy over the metadata.
00172       //
00173       // NOTE: We're using the Persistent type definition from the ELEMENT_CONVERSION_RULES
00174       //       instead of a type of elements of the transient n-tuple. That's because
00175       //       users may decide to provide their own type mapping.
00176 
00177         std::vector<std::string> columnNames;
00178         thePtr->column_names( columnNames );
00179 
00180         ooHandle( PERSISTENT ) tupleH = new( theHintRef ) PERSISTENT( NCOL,
00181                                                                       thePtr->name( ),
00182                                                                       thePtr->description( ),
00183                                                                       columnNames );
00184         if( !tupleH.isValid( )) {
00185 
00186             cout << errorStr << endl
00187                  << "    Failed to create a persistent n-tuple object." << endl;
00188 
00189             return CdbStatus::Error;
00190         }
00191 
00192       // Now, copy over rows from the transient tuple into the persistent one
00193 
00194         unsigned int nRows = thePtr->rows( );
00195         for( unsigned int r = 0; r < nRows; ++r ) {
00196 
00197             std::vector<T> trRow;
00198             if( CdbStatus::Success != thePtr->get_row( trRow, r )) {
00199 
00200                 cout << errorStr << endl
00201                      << "    Failed to get a row number " << r << " from a transient tuple." << endl;
00202 
00203                 BdbDelete(tupleH);
00204 
00205                 return CdbStatus::Error;
00206             }
00207             assert( NCOL == trRow.size( ));
00208 
00209             std::vector< typename PERSISTENT::ElementType > pRow( NCOL );
00210             for( unsigned int c = 0; c < NCOL; ++c ) {
00211                 pRow[c] = ELEMENT_CONVERSION_RULES::to_persistent( trRow[c] );
00212             }
00213             if( CdbStatus::Success != tupleH->append_row( pRow )) {
00214 
00215                 cout << errorStr << endl
00216                      << "    Failed to append a new row number " << r << " to the persistent tuple object." << endl;
00217 
00218                 BdbDelete(tupleH);
00219 
00220                 return CdbStatus::Error;
00221             }
00222         }
00223 
00224       // Repack the persistent tuple for the space utilization efficiency
00225 
00226         if( CdbStatus::Success != tupleH->repack( )) {
00227 
00228             cout << errorStr << endl
00229                  << "    Failed to repack the newely created persistent n-tuple object" << endl
00230                  << "    for space utilization efficiency." << endl;
00231 
00232             BdbDelete(tupleH);
00233 
00234             return CdbStatus::Error;
00235         }
00236 
00237       // Return back the reference
00238 
00239         thePersRef = tupleH;
00240 
00241         return CdbStatus::Success;
00242     }
00243 };
00244 
00245 /////////////////////////////////////////////////////////////////////
00246 // CdbBdbNTupleConversionImpl< T, NCOL, ELEMENT_CONVERSION_RULES > //
00247 /////////////////////////////////////////////////////////////////////
00248 
00249 // This is an implementation of the generic conversion facility for (currently only) primitive
00250 // types of elements.
00251 //
00252 // It uses the templated "CdbBdbNTupleSimpleImplP" class as the persistent "back-end".
00253 
00254 template < class        T,
00255            unsigned int NCOL,
00256            class        ELEMENT_CONVERSION_RULES >
00257 CdbStatus
00258 CdbBdbNTupleConversionImpl<T,NCOL,ELEMENT_CONVERSION_RULES>::to_transient( CdbCPtr< CdbNTuple< T,NCOL > >& thePtr,
00259                                                                            const ooRef(BdbObject)&         thePersRef )
00260 {
00261     CdbNTuple< T, NCOL >* ptr    = 0;
00262     CdbStatus             status = to_transient( ptr, thePersRef );
00263 
00264     if( CdbStatus::Success == status ) thePtr = ptr;
00265 
00266     return status;
00267 }
00268 
00269 template < class        T,
00270            unsigned int NCOL,
00271            class        ELEMENT_CONVERSION_RULES >
00272 CdbStatus
00273 CdbBdbNTupleConversionImpl<T,NCOL,ELEMENT_CONVERSION_RULES>::to_transient( CdbNTuple< T,NCOL >*&   thePtr,
00274                                                                            const ooRef(BdbObject)& thePersRef )
00275 {
00276     return CdbBdbNTupleConversionImpl_Helper< CdbBdbNTupleSimpleImplP< typename ELEMENT_CONVERSION_RULES::Persistent >,
00277                                               T,
00278                                               NCOL,
00279                                               ELEMENT_CONVERSION_RULES >::to_transient( thePtr,
00280                                                                                         thePersRef );
00281 }
00282 
00283 template < class        T,
00284            unsigned int NCOL,
00285            class        ELEMENT_CONVERSION_RULES >
00286 CdbStatus
00287 CdbBdbNTupleConversionImpl<T,NCOL,ELEMENT_CONVERSION_RULES>::to_persistent( ooRef(BdbObject)&                     thePersRef,
00288                                                                             const CdbCPtr< CdbNTuple< T,NCOL > >& thePtr,
00289                                                                             const BdbRefAny&                      theHintRef )
00290 {
00291     return CdbBdbNTupleConversionImpl_Helper< CdbBdbNTupleSimpleImplP< typename ELEMENT_CONVERSION_RULES::Persistent >,
00292                                               T,
00293                                               NCOL,
00294                                               ELEMENT_CONVERSION_RULES >::to_persistent( thePersRef,
00295                                                                                          thePtr,
00296                                                                                          theHintRef );
00297 }
00298 
00299 ///////////////////////////////////////////////////////////////////////////////
00300 // CdbBdbNTupleConversionImpl< std::string, NCOL, ELEMENT_CONVERSION_RULES > //
00301 ///////////////////////////////////////////////////////////////////////////////
00302 
00303 // This is an implementation of the specialized conversion facility for the std::string
00304 // types of elements.
00305 //
00306 // It uses the non-=templated "CdbBdbNTupleSimpleImplP_ooVString" class as the persistent "back-end".
00307 
00308 template < unsigned int NCOL,
00309            class        ELEMENT_CONVERSION_RULES >
00310 CdbStatus
00311 CdbBdbNTupleConversionImpl<std::string,NCOL,ELEMENT_CONVERSION_RULES>::to_transient( CdbCPtr< CdbNTuple< std::string, NCOL > >& thePtr,
00312                                                                                      const ooRef(BdbObject)&                    thePersRef )
00313 {
00314     CdbNTuple< std::string , NCOL >* ptr    = 0;
00315     CdbStatus                        status = to_transient( ptr, thePersRef );
00316 
00317     if( CdbStatus::Success == status ) thePtr = ptr;
00318 
00319     return status;
00320 }
00321 
00322 template < unsigned int NCOL,
00323            class        ELEMENT_CONVERSION_RULES >
00324 CdbStatus
00325 CdbBdbNTupleConversionImpl<std::string,NCOL,ELEMENT_CONVERSION_RULES>::to_transient( CdbNTuple< std::string, NCOL >*& thePtr,
00326                                                                                      const ooRef(BdbObject)&          thePersRef )
00327 {
00328     return CdbBdbNTupleConversionImpl_Helper< CdbBdbNTupleSimpleImplP_ooVString,
00329                                               std::string,
00330                                               NCOL,
00331                                               ELEMENT_CONVERSION_RULES >::to_transient( thePtr,
00332                                                                                         thePersRef );
00333 }
00334 
00335 template < unsigned int NCOL,
00336            class        ELEMENT_CONVERSION_RULES >
00337 CdbStatus
00338 CdbBdbNTupleConversionImpl<std::string,NCOL,ELEMENT_CONVERSION_RULES>::to_persistent( ooRef(BdbObject)&                                thePersRef,
00339                                                                                       const CdbCPtr< CdbNTuple< std::string, NCOL > >& thePtr,
00340                                                                                       const BdbRefAny&                                 theHintRef )
00341 {
00342     return CdbBdbNTupleConversionImpl_Helper< CdbBdbNTupleSimpleImplP_ooVString,
00343                                               std::string,
00344                                               NCOL,
00345                                               ELEMENT_CONVERSION_RULES >::to_persistent( thePersRef,
00346                                                                                          thePtr,
00347                                                                                          theHintRef );
00348 }
00349 
00350 /////////////////
00351 // End Of File //
00352 /////////////////

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