Gaudi Framework, version v21r8

Home   Generated: 17 Mar 2010

PoolDbNTupleCnv.cpp

Go to the documentation of this file.
00001 // $Id: PoolDbNTupleCnv.cpp,v 1.16 2008/10/27 16:41:33 marcocle Exp $
00002 //------------------------------------------------------------------------------
00003 //
00004 // Implementation of class :  PoolDbNTupleCnv
00005 //
00006 // Author :                   Markus Frank
00007 //
00008 //------------------------------------------------------------------------------
00009 
00010 // FIXME: missing in CORAL
00011 #include <algorithm>
00012 
00013 #define ALLOW_ALL_TYPES
00014 // Include files
00015 #include "GaudiPoolDb/IPoolDbMgr.h"
00016 #include "GaudiPoolDb/PoolDbAddress.h"
00017 #include "GaudiPoolDb/PoolDbNTupleCnv.h"
00018 #include "GaudiPoolDb/PoolDbLinkManager.h"
00019 #include "GaudiPoolDb/PoolDbNTupleDescriptor.h"
00020 #include "GaudiPoolDb/PoolDbTupleCallback.h"
00021 
00022 #include "GaudiKernel/xtoa.h"
00023 #include "GaudiKernel/NTuple.h"
00024 #include "GaudiKernel/SmartIF.h"
00025 #include "GaudiKernel/SmartRef.h"
00026 #include "GaudiKernel/MsgStream.h"
00027 #include "GaudiKernel/INTupleSvc.h"
00028 #include "GaudiKernel/IRegistry.h"
00029 #include "GaudiKernel/ISelectStatement.h"
00030 #include "GaudiKernel/ContainedObject.h"
00031 #include "GaudiKernel/GenericAddress.h"
00032 #include "GaudiKernel/CnvFactory.h"
00033 
00034 #include "StorageSvc/DbSelect.h"
00035 #include "StorageSvc/DbReflex.h"
00036 #include "StorageSvc/DbColumn.h"
00037 #include "StorageSvc/DbTypeInfo.h"
00038 #include "StorageSvc/DbObjectCallBack.h"
00039 
00040 #define S_OK   StatusCode::SUCCESS
00041 #define S_FAIL StatusCode::FAILURE
00042 #include "Reflex/Builder/ReflexBuilder.h"
00043 
00044 #include <memory>
00045 
00046 namespace pool  {
00047   const std::string typeName(const std::type_info& typ);
00048 }
00049 
00050 void popCurrentDataObject();
00051 void pushCurrentDataObject(DataObject** pobjAddr);
00052 
00053 namespace pool { void genMD5(const std::string& s, void* code); }
00054 using pool::genMD5;
00055 
00056 template <class T> static inline
00057 void* save(pool::DbBlob& s, const void* buffer, int len, bool save_len)  {
00058   const T* buff = (const T*)buffer;
00059   if ( len > 1 )  {
00060     s << len;
00061     s.swapToBuffer(buff, len*sizeof(T));
00062     return 0;
00063   }
00064   else if ( save_len )  {
00065     s << len;
00066     return 0;
00067   }
00068   return (void*)buff;
00069 }
00070 
00071 static void* save(const void* b, PoolDbTokenWrap* lnk)  {
00072   IOpaqueAddress* pA = (*(IOpaqueAddress**)b);
00073   pool::Token& tok   = lnk->token;
00074   pool::Guid guid(pool::Guid::null());
00075   if ( pA )  {
00076     const std::string*   spar = pA->par();
00077     const unsigned long* ipar = pA->ipar();
00078     guid.Data1 = pA->clID();
00079     tok.setTechnology(pA->svcType());
00080     tok.setDb(spar[0]).setCont(spar[1]);
00081     tok.oid().first  = ipar[0];
00082     tok.oid().second = ipar[1];
00083   }
00084   else {
00085     tok.setTechnology(0).setDb("").setCont("");
00086     tok.oid().first = tok.oid().second = pool::INVALID;
00087   }
00088   tok.setClassID(guid);
00089   return lnk;
00090 }
00091 
00092 // Helper to read
00093 template <class T> static inline int load(pool::DbBlob& s, void* buff)  {
00094   int len;
00095   s >> len;
00096   s.swapFromBuffer(buff, len*sizeof(T));
00097   return 0;
00098 }
00099 
00100 // Helper to read specialized for strings
00101 template <> inline int load<std::string>(pool::DbBlob& s, void* ptr)   {
00102   std::string* str = (std::string*)ptr;
00103   s >> (*str);
00104   return 0;
00105 }
00106 
00107 // Helper to read specialized for opaque addresses
00108 static inline int load(void* ptr,PoolDbTokenWrap* lnk)   {
00109   IOpaqueAddress* pA = *(IOpaqueAddress**)ptr;
00110   GenericAddress* pAddr = (GenericAddress*)(pA);
00111   if ( 0 != pAddr )  {
00112     pool::Token&    tok = lnk->token;
00113     std::string*   spar = (std::string*)pAddr->par();
00114     unsigned long* ipar = (unsigned long*)pAddr->ipar();
00115     pAddr->setClID(tok.classID().Data1);
00116     pAddr->setSvcType(tok.technology());
00117     ipar[0] = tok.oid().first;
00118     ipar[1] = tok.oid().second;
00119     spar[0] = tok.dbID();
00120     spar[1] = tok.contID();
00121     return 0;
00122   }
00123   else if ( pA ) {
00124     return 10;
00125         }
00126   return 11;
00127 }
00128 
00129 // Instantiation of a static factory class used by clients to create
00130 // instances of this service
00131 PLUGINSVC_FACTORY_WITH_ID( PoolDbNTupleCnv,
00132                            ConverterID(POOL_StorageType,CLID_RowWiseTuple),
00133                            IConverter*(long, CLID, ISvcLocator*) )
00134 
00135 PLUGINSVC_FACTORY_WITH_ID( PoolDbNTupleCnv,
00136                            ConverterID(POOL_StorageType,CLID_ColumnWiseTuple),
00137                            IConverter*(long, CLID, ISvcLocator*) )
00138 
00139 static inline std::istream&
00140 operator>>(std::istream& is, IOpaqueAddress*& /*pObj*/)   {
00141   long i;
00142   is >> i;
00143   return is;
00144 }
00145 
00146 template<class TYP> static
00147 StatusCode createItem ( INTuple* tuple, std::istream& is,
00148                         const std::string& name,
00149                         const TYP& null)
00150 {
00151   std::string idxName;
00152   long len, ndim, dim[4], hasIdx, idxLow, idxLen;
00153   long dim1 = 1, dim2 = 1;
00154   INTupleItem* it = 0;
00155   char c;
00156   is >> len    >> c
00157      >> ndim   >> c
00158      >> hasIdx >> c;
00159   if ( hasIdx )  {
00160     std::getline(is, idxName, ';') >> idxLow >> c >> idxLen >> c;
00161   }
00162   for ( int i = 0; i < ndim; i++ )
00163     is >> dim[i] >> c;
00164 
00165   TYP low = null, high = null;
00166   is >> low >> c >> high >> c;
00167   is >> c;
00168   switch( ndim )  {
00169   case 0:
00170     it = NTuple::_Item<TYP>::create (tuple, name, typeid(TYP), low, high, null);
00171     break;
00172   case 1:
00173     dim1 = (hasIdx) ? idxLen : dim[0];
00174     it = NTuple::_Array<TYP>::create (tuple,
00175                                       name,
00176                                       typeid(TYP),
00177                                       idxName,
00178                                       dim1,
00179                                       low,
00180                                       high,
00181                                       null);
00182     break;
00183   case 2:
00184     dim1 = (hasIdx) ? idxLen : dim[0];
00185     dim2 = (hasIdx) ? dim[0] : dim[1];
00186     it = NTuple::_Matrix<TYP>::create ( tuple,
00187                                         name,
00188                                         typeid(TYP),
00189                                         idxName,
00190                                         dim1,
00191                                         dim2,
00192                                         low,
00193                                         high,
00194                                         null);
00195     break;
00196   default:
00197     return S_FAIL;
00198   }
00199   return tuple->add(it);
00200 }
00201 
00202 template <class T> static inline
00203 void putRange(std::ostream& os, NTuple::_Data<T>* it)
00204 {
00205   const NTuple::Range<T>& x = it->range();
00206   os << x.lower() << ';' << x.upper() << ';';
00207 }
00208 
00210 PoolDbNTupleCnv::PoolDbNTupleCnv(long typ, const CLID& clid, ISvcLocator* svc)
00211 : PoolDbStatCnv(typ, clid, svc)
00212 {
00213   m_class = 0;
00214 }
00215 
00216 PoolDbNTupleCnv::~PoolDbNTupleCnv()  {
00217 }
00218 
00219 // Converter overrides: Update the references of an updated transient object.
00220 StatusCode
00221 PoolDbNTupleCnv::createObj(IOpaqueAddress* pAddress, DataObject*& refpObject)
00222 {
00223   StatusCode status = S_FAIL;
00224   PoolDbAddress* pdbA = dynamic_cast<PoolDbAddress*>(pAddress);
00225   if ( 0 != pdbA )  {
00226     const pool::Token* tok = pdbA->token();
00227     if ( tok )  {
00228       pool::DbContainer cntH(tok->technology());
00229       status = m_dbMgr->connect(tok->dbID(),tok->contID(),cntH);
00230       if ( status.isSuccess() ) {
00231         std::string par_val, par_guid, par_typ;
00232         std::auto_ptr<pool::DbSelect> iter(m_dbMgr->createSelect("*", tok->dbID(), "GaudiStatisticsDescription"));
00233         if ( iter.get() )  {
00234           pool::Token* token;
00235           ROOT::Reflex::Type typ = pool::DbReflex::forTypeName("PoolDbNTupleDescriptor");
00236           pool::DbObjectCallBack* call = new pool::DbObjectCallBack(typ);
00237           while( iter->next(token).isSuccess() )  {
00238             typedef pool::DbObjectHandle<pool::DbObject> ObjH;
00239             pool::DbContainer& cH = iter->container();
00240             if ( ObjH::openEx(cH, *token, call, pool::READ).isSuccess() )  {
00241               PoolDbNTupleDescriptor* ref = (PoolDbNTupleDescriptor*)call->object();
00242               if ( ref->container == tok->contID() )  {
00243                 par_val  = ref->description;
00244                 par_typ  = ref->optional;
00245                 par_guid = ref->guid;
00246                 token->release();
00247                 call->release();
00248                 call = 0;
00249                 delete ref;
00250                 break;
00251               }
00252               delete ref;
00253             }
00254             token->release();
00255           }
00256           if ( call ) call->release();
00257         }
00258         if ( !par_val.empty() && !par_guid.empty() && !par_typ.empty() )
00259         {
00260           SmartIF<INTupleSvc> ntupleSvc(dataProvider());
00261           if ( ntupleSvc.isValid() )  {
00262             char c;
00263             CLID clid;
00264             int siz, typ;
00265             std::string title;
00266             NTuple::Tuple* nt = 0;
00267             std::istringstream is(par_val);
00268             std::getline(is, title, ';') >> clid >> c >> siz >> c;
00269             status = ntupleSvc->create(clid, title, nt);
00270             for ( int j = 0; j < siz && status.isSuccess(); j++ ) {
00271               is >> c;
00272               std::getline(is, title, ';') >> typ >> c;
00273               switch ( typ )    {
00274               case DataTypeInfo::UCHAR:
00275                 status = createItem(nt, is, title, (unsigned char)0);
00276                 break;
00277               case DataTypeInfo::USHORT:
00278                 status = createItem(nt, is, title, (unsigned short)0);
00279                 break;
00280               case DataTypeInfo::UINT:
00281                 status = createItem(nt, is, title, (unsigned int)0);
00282                 break;
00283               case DataTypeInfo::ULONG:
00284                 status = createItem(nt, is, title, (unsigned long)0);
00285                 break;
00286               case DataTypeInfo::CHAR:
00287                 status = createItem(nt, is, title, char(0));
00288                 break;
00289               case DataTypeInfo::SHORT:
00290                 status = createItem(nt, is, title, short(0));
00291                 break;
00292               case DataTypeInfo::INT:
00293                 status = createItem(nt, is, title, int(0));
00294                 break;
00295               case DataTypeInfo::LONG:
00296                 status = createItem(nt, is, title, long(0));
00297                 break;
00298               case DataTypeInfo::BOOL:
00299                 status = createItem(nt, is, title, false);
00300                 break;
00301               case DataTypeInfo::FLOAT:
00302                 status = createItem(nt, is, title, float(0.0));
00303                 break;
00304               case DataTypeInfo::DOUBLE:
00305                 status = createItem(nt, is, title, double(0.0));
00306                 break;
00307                 /*
00308               case DataTypeInfo::NTCHAR:
00309               case DataTypeInfo::LONG_NTCHAR:
00310                 status =
00311                 createItem(nt, is, title, (char*)0);
00312                 break;
00313               case DataTypeInfo::STRING:
00314               case DataTypeInfo::LONG_STRING:
00315                 status =
00316                 createItem(nt, is, title, std::string(""));
00317                 break;
00318                 */
00319               case DataTypeInfo::OBJECT_ADDR:
00320                 status = createItem(nt, is, title, (IOpaqueAddress*)0);
00321                 break;
00322               case DataTypeInfo::POINTER:
00323                 status = createItem(nt, is, title, (void*)0);
00324                 break;
00325               case DataTypeInfo::UNKNOWN:
00326               default:
00327                 status = S_FAIL;
00328                 break;
00329               }
00330               if ( !status.isSuccess() )  {
00331                 MsgStream err(msgSvc(),"NTupleCnv");
00332                 err << MSG::FATAL
00333                     << "Error connecting (Unknown) column:" << j << endmsg
00334                     << par_val << endmsg;
00335                 return makeError("createObj[NTuple]> Cannot determine column!");
00336               }
00337             }
00338             if ( status.isSuccess() )  {
00339               PoolDbTupleCallback* hdlr = new PoolDbTupleCallback(nt);
00340               const pool::DbTypeInfo* typ1 = pool::DbTypeInfo::fromString(par_typ);
00341               hdlr->configure(nt, typ1, cntH);
00342               pdbA->setHandler(hdlr);
00343               refpObject  = nt;
00344             }
00345             else {
00346               refpObject = 0;
00347               if ( nt ) nt->release();
00348             }
00349           }
00350         }
00351       }
00352     }
00353   }
00354   return status;
00355 }
00356 
00357 // Update the transient object: NTuples end here when reading records
00358 StatusCode
00359 PoolDbNTupleCnv::updateObj(IOpaqueAddress* pAddr, DataObject* pObj)  {
00360   INTuple*       tupl = dynamic_cast<INTuple*>(pObj);
00361   PoolDbAddress* pdbA = dynamic_cast<PoolDbAddress*>(pAddr);
00362   if ( 0 != tupl && 0 != pdbA )  {
00363     PoolDbTupleCallback* hdlr = dynamic_cast<PoolDbTupleCallback*>(pdbA->handler());
00364     pool::DbSelect* it = hdlr->iterator();
00365     if ( 0 == it )  {
00366       it = hdlr->select(tupl->selector());
00367     }
00368     if ( it )  {
00369       pool::Token* t = 0;
00370       if ( hdlr->iterator()->next(t).isSuccess() )  {
00371         std::auto_ptr<pool::Token> next(t);
00372         // Now reload!
00373         if ( bindRead(tupl, hdlr).isSuccess() )  {
00374           // No support for SmartRefs<T> for N-tuples
00375           //pushCurrentDataObject((DataObject**)&pObj);
00376           if ( m_dbMgr->read(hdlr, *next.get()).isSuccess() )  {
00377             if ( readData(tupl, hdlr).isSuccess() )  {
00378               //popCurrentDataObject();
00379               return S_OK;
00380             }
00381             //popCurrentDataObject();
00382             return makeError("updateObj> Cannot interprete data.");
00383           }
00384           //popCurrentDataObject();
00385           return makeError("updateObj> Cannot read data.");
00386         }
00387         return makeError("updateObj> Cannot bind data.");
00388       }
00389       return S_FAIL;
00390     }
00391     return makeError("updateObj> Token selection failed!");
00392   }
00393   return makeError("updateObj> Invalid Tuple reference.");
00394 }
00395 
00397 StatusCode
00398 PoolDbNTupleCnv::createRep(DataObject* pObj, IOpaqueAddress*& pAddr)  {
00399   IRegistry* pRegistry = pObj->registry();
00400   if ( 0 != pRegistry )  {
00401     pAddr = pRegistry->address();
00402     PoolDbAddress* pdbA = dynamic_cast<PoolDbAddress*>(pAddr);
00403     if ( 0 == pdbA )  {
00404       const INTuple* nt  = dynamic_cast<const INTuple*>(pObj);
00405       if ( 0 != nt )  {
00406         const INTuple::ItemContainer& items = nt->items();
00407         std::vector<const pool::DbColumn*> cols;
00408         std::vector<int> item_map(items.size()+1,-1);
00409         std::ostringstream os;
00410         int pool_type = 0;
00411         size_t item_no;
00412         os << nt->title()<<';'<<pObj->clID()<<';'<<items.size()<< ';';
00413         for(item_no = 0; item_no < items.size(); ++item_no ) {
00414           pool::DbColumn* col = 0;
00415           INTupleItem* it = items[item_no];
00416           os << '{'
00417              << it->name()      << ';'
00418              << it->type()      << ';'
00419              << it->length()    << ';'
00420              << it->ndim()      << ';'
00421              << it->hasIndex()  << ';';
00422           if ( it->hasIndex() )   {
00423             os << it->index() << ';';
00424             INTupleItem* itm = it->indexItem();
00425             switch( itm->type() )    {
00426             case DataTypeInfo::UCHAR:
00427               putRange(os, dynamic_cast<NTuple::_Data<unsigned char>*>(itm));
00428               break;
00429             case DataTypeInfo::USHORT:
00430               putRange(os, dynamic_cast<NTuple::_Data<unsigned short>*>(itm));
00431               break;
00432             case DataTypeInfo::UINT:
00433               putRange(os, dynamic_cast<NTuple::_Data<unsigned int>*>(itm));
00434               break;
00435             case DataTypeInfo::ULONG:
00436               putRange(os, dynamic_cast<NTuple::_Data<unsigned long>*>(itm));
00437               break;
00438             case DataTypeInfo::CHAR:
00439               putRange(os, dynamic_cast<NTuple::_Data<char>*>(itm));
00440               break;
00441             case DataTypeInfo::SHORT:
00442               putRange(os, dynamic_cast<NTuple::_Data<short>*>(itm));
00443               break;
00444             case DataTypeInfo::INT:
00445               putRange(os, dynamic_cast<NTuple::_Data<int>*>(itm));
00446               break;
00447             case DataTypeInfo::LONG:
00448               putRange(os, dynamic_cast<NTuple::_Data<long>*>(itm));
00449               break;
00450             default: {
00451               MsgStream err(msgSvc(), "NTuple:"+pRegistry->name());
00452               err << MSG::ERROR << "Column " << it->index()
00453                   << " is not a valid index column!" << endmsg;
00454               return S_FAIL;
00455               }
00456             }
00457           }
00458           for ( long k = 0; k < it->ndim(); k++ )  {
00459             os << it->dim(k) << ';';
00460           }
00461           switch(it->type())  {
00462             case DataTypeInfo::STRING:
00463               pool_type = pool::DbColumn::STRING;
00464               os << 0 << ';' << 0 << ';';
00465               break;
00466             case DataTypeInfo::NTCHAR:
00467               pool_type = pool::DbColumn::NTCHAR;
00468               os << 0 << ';' << 0 << ';';
00469               break;
00470             case DataTypeInfo::OBJECT_ADDR:
00471               if ( it->length() == 1 )  {
00472                 col = new pool::DbColumn(it->name(),
00473                                          pool::typeName(typeid(PoolDbTokenWrap)),
00474                                          pool::DbColumn::POINTER,
00475                                          0);
00476                 item_map[item_no] = cols.size();
00477                 cols.push_back(col);
00478               }
00479               os << 0 << ';' << 0 << ';';
00480               break;
00481             case DataTypeInfo::POINTER:
00482               if ( it->length() == 1 )  {
00483                 ROOT::Reflex::Type typ = ROOT::Reflex::Type::ByName(it->typeName());
00484                 col = new pool::DbColumn(it->name(),
00485                                          typ.Name(ROOT::Reflex::SCOPED),
00486                                          pool::DbColumn::POINTER,
00487                                          0);
00488                 item_map[item_no] = cols.size();
00489                 cols.push_back(col);
00490                 os << 0 << ';' << 0 << ';';
00491               }
00492               break;
00493             case DataTypeInfo::UCHAR:
00494               pool_type = pool::DbColumn::UCHAR;
00495               putRange(os, dynamic_cast<NTuple::_Data<unsigned char>*>(it));
00496               goto MakeCol;
00497             case DataTypeInfo::USHORT:
00498               pool_type = pool::DbColumn::USHORT;
00499               putRange(os, dynamic_cast<NTuple::_Data<unsigned short>*>(it));
00500               goto MakeCol;
00501             case DataTypeInfo::UINT:
00502               pool_type = pool::DbColumn::UINT;
00503               putRange(os, dynamic_cast<NTuple::_Data<unsigned int>*>(it));
00504               goto MakeCol;
00505             case DataTypeInfo::ULONG:
00506               pool_type = pool::DbColumn::ULONG;
00507               putRange(os, dynamic_cast<NTuple::_Data<unsigned long>*>(it));
00508               goto MakeCol;
00509             case DataTypeInfo::CHAR:
00510               pool_type = pool::DbColumn::CHAR;
00511               putRange(os, dynamic_cast<NTuple::_Data<char>*>(it));
00512               goto MakeCol;
00513             case DataTypeInfo::SHORT:
00514               pool_type = pool::DbColumn::SHORT;
00515               putRange(os, dynamic_cast<NTuple::_Data<short>*>(it));
00516               goto MakeCol;
00517             case DataTypeInfo::INT:
00518               pool_type = pool::DbColumn::INT;
00519               putRange(os, dynamic_cast<NTuple::_Data<int>*>(it));
00520               goto MakeCol;
00521             case DataTypeInfo::LONG:
00522               pool_type = pool::DbColumn::LONG;
00523               putRange(os, dynamic_cast<NTuple::_Data<long>*>(it));
00524               goto MakeCol;
00525             case DataTypeInfo::BOOL:
00526               pool_type = pool::DbColumn::BOOL;
00527               putRange(os, dynamic_cast<NTuple::_Data<bool>*>(it));
00528               goto MakeCol;
00529             case DataTypeInfo::FLOAT:
00530               pool_type = pool::DbColumn::FLOAT;
00531               putRange(os, dynamic_cast<NTuple::_Data<float>*>(it));
00532               goto MakeCol;
00533             case DataTypeInfo::DOUBLE:
00534               pool_type = pool::DbColumn::DOUBLE;
00535               putRange(os, dynamic_cast<NTuple::_Data<double>*>(it));
00536               goto MakeCol;
00537   MakeCol:
00538               if ( it->length() == 1 )  {
00539                 col = new pool::DbColumn(it->name(),
00540                                          pool_type,
00541                                          0,
00542                                          DataTypeInfo::size(it->type()));
00543                 item_map[item_no] = cols.size();
00544                 cols.push_back(col);
00545               }
00546               // Everything else CANNOT be identified using SQL
00547             break;
00548             case DataTypeInfo::UNKNOWN:
00549             default:
00550               std::cout << "Create item[FAIL]]: " << it->name()
00551                         << " Typ:" << it->type() << std::endl;
00552               break;
00553           }
00554           os << '}';
00555         }
00556         item_map[item_no] = cols.size();
00557         pool::DbColumn* col =
00558           new pool::DbColumn("BlobData",
00559                              pool::DbColumn::BLOB,
00560                              0,
00561                              DataTypeInfo::size(pool::DbColumn::BLOB));
00562         cols.push_back(col);
00563         pool::Guid guid;
00564         std::string cntName = containerName(pRegistry);
00565         std::string path    = fileName(pRegistry);
00566         genMD5(os.str(), &guid);
00567         const pool::DbTypeInfo* typH = pool::DbTypeInfo::createEx(guid, cols);
00568         StatusCode sc = saveDescription(path,
00569                                         cntName,
00570                                         os.str(),
00571                                         typH->toString(),
00572                                         guid,
00573                                         pObj->clID(),
00574                                         "UPDATE");
00575         if ( sc.isSuccess() )  {
00576           // Check if the database container can be connected
00577           pool::DbContainer cntH(POOL_StorageType);
00578           sc = m_dbMgr->connectContainer(IPoolDbMgr::UNKNOWN,
00579                                          path,
00580                                          cntName,
00581                                          pool::RECREATE|pool::UPDATE,
00582                                          typH,
00583                                          cntH);
00584           if ( sc.isSuccess() )  {
00585             PoolDbTupleCallback* hdlr = new PoolDbTupleCallback(pObj);
00586             pool::Token*         tok = new pool::Token(cntH.token());
00587             PoolDbAddress*       add = new PoolDbAddress(tok);
00588             hdlr->configure(nt, typH, cntH);
00589             tok->oid().second = 0;
00590             tok->release();
00591             pAddr = add;
00592             add->setHandler(hdlr);
00593             return m_dbMgr->commitOutput(path, true);
00594           }
00595           return S_FAIL;
00596         }
00597         return sc;
00598       }
00599     }
00600     else  {
00601       return S_OK;
00602     }
00603   }
00604   return S_FAIL;
00605 }
00606 
00608 StatusCode
00609 PoolDbNTupleCnv::fillRepRefs(IOpaqueAddress* pAddr, DataObject* pObj)
00610 {
00611   INTuple* pTuple = dynamic_cast<INTuple*>(pObj);
00612   if ( pTuple )  {
00613     IRegistry* pRegistry = pObj->registry();
00614     if ( 0 != pRegistry )  {
00615       pAddr = pRegistry->address();
00616       PoolDbAddress* pdbA = dynamic_cast<PoolDbAddress*>(pAddr);
00617       if ( 0 != pdbA )  {
00618         PoolDbTupleCallback* cb = dynamic_cast<PoolDbTupleCallback*>(pdbA->handler());
00619         if ( cb )  {
00620           const pool::DbTypeInfo* typH = dynamic_cast<const pool::DbTypeInfo*>(cb->shape());
00621           if ( typH )  {
00622             if ( bindWrite(pTuple, cb).isSuccess() )  {
00623               std::string path = fileName(pRegistry);
00624               std::string cntName = containerName(pRegistry);
00625               if ( !m_dbMgr->connectOutput(path, "UPDATE").isSuccess() )  {
00626                 MsgStream log(msgSvc(), "PoolDbNTupleCnv");
00627                 log << MSG::ERROR << "Error: connectOutput(path, UPDATE)" << endmsg;
00628                 return S_FAIL;
00629               }
00630               if ( m_dbMgr->markWrite(cb->clone(), cntName, &pdbA).isSuccess() ) {
00631                             if ( m_dbMgr->commitOutput(path, true).isSuccess() )  {
00632                               typedef INTuple::ItemContainer Cont;
00633                               Cont& it = pTuple->items();
00634                               for(Cont::iterator i = it.begin(); i != it.end(); ++i)  {
00635                                 (*i)->reset();
00636                               }
00637                               return S_OK;
00638                             }
00639               }
00640             }
00641           }
00642         }
00643       }
00644     }
00645   }
00646   return S_FAIL;
00647 }
00648 
00649 StatusCode PoolDbNTupleCnv::bindRead(INTuple* nt,
00650                                      PoolDbTupleCallback* cb)
00651 {
00652   typedef INTuple::ItemContainer Cont;
00653   int cnt = 0;
00654   //pool::DbBlob&                  s       = cb->stream();
00655   std::vector<void*>&            addr    = cb->addresses();
00656   std::vector<PoolDbTokenWrap*>& links   = cb->links();
00657   const std::vector<int>&        mapping = cb->mapping();
00658   Cont&                          items   = nt->items();
00659   for (Cont::iterator i = items.begin(); i != items.end(); ++i, ++cnt )   {
00660     int count = mapping[cnt];
00661     if ( count >= 0 )  {
00662       char* buf = (char*)(*i)->buffer();
00663       switch( (*i)->type() )   {
00664         case DataTypeInfo::OBJECT_ADDR:
00665           addr[count] = &links[cnt];
00666           break;
00667         default:
00668           addr[count] = buf;
00669           break;
00670       }
00671     }
00672   }
00673   return S_OK;
00674 }
00675 
00676 StatusCode PoolDbNTupleCnv::readData(INTuple* nt,
00677                                      PoolDbTupleCallback* cb)
00678 {
00679   typedef INTuple::ItemContainer Cont;
00680   int cnt = 0;
00681   pool::DbBlob&                  s       = cb->stream();
00682   std::vector<PoolDbTokenWrap*>& links   = cb->links();
00683   const std::vector<int>&        mapping = cb->mapping();
00684   INTuple::ItemContainer&        items   = nt->items();
00685   for (Cont::iterator i = items.begin(); i != items.end(); ++i, ++cnt )   {
00686     int count = mapping[cnt];
00687     int typ   = (*i)->type();
00688     if(count < 0 || typ == DataTypeInfo::OBJECT_ADDR || typ == DataTypeInfo::POINTER)  {
00689       char* buf = (char*)(*i)->buffer();
00690       int sc = 11;
00691       switch( (*i)->type() )   {
00692       case DataTypeInfo::UCHAR:       sc=load<unsigned char> (s,buf); break;
00693       case DataTypeInfo::USHORT:      sc=load<unsigned short>(s,buf); break;
00694       case DataTypeInfo::UINT:        sc=load<unsigned int>  (s,buf); break;
00695       case DataTypeInfo::ULONG:       sc=load<unsigned long> (s,buf); break;
00696       case DataTypeInfo::CHAR:        sc=load<char>          (s,buf); break;
00697       case DataTypeInfo::SHORT:       sc=load<short>         (s,buf); break;
00698       case DataTypeInfo::INT:         sc=load<int>           (s,buf); break;
00699       case DataTypeInfo::LONG:        sc=load<long>          (s,buf); break;
00700       case DataTypeInfo::BOOL:        sc=load<bool>          (s,buf); break;
00701       case DataTypeInfo::FLOAT:       sc=load<float>         (s,buf); break;
00702       case DataTypeInfo::DOUBLE:      sc=load<double>        (s,buf); break;
00703       case DataTypeInfo::STRING:      sc=load<std::string>   (s,buf); break;
00704       case DataTypeInfo::NTCHAR:      sc=load<char*>         (s,buf); break;
00705       case DataTypeInfo::OBJECT_ADDR: sc=load(buf,links[count]);      break;
00706       case DataTypeInfo::POINTER:                                     break;
00707       case DataTypeInfo::UNKNOWN:                                     break;
00708       default:                                                        break;
00709       }
00710       if ( 0 != sc )  {
00711         MsgStream log(msgSvc(), "PoolDbNTupleCnv");
00712         log << MSG::DEBUG;
00713         switch (sc)  {
00714           case 10:
00715             log << "CANNOT Set Ntuple token: dynamic_cast<GenericAddress*> is NULL";
00716           break;
00717           case 11:
00718               log << "CANNOT Set Ntuple token: invalid address buffer";
00719           break;
00720         }
00721         log << endmsg;
00722       }
00723     }
00724   }
00725   return S_OK;
00726 }
00727 
00729 StatusCode PoolDbNTupleCnv::bindWrite(INTuple* nt, PoolDbTupleCallback* cb)
00730 {
00731   int cnt = 0;
00732   pool::DbBlob&                  s       = cb->stream();
00733   std::vector<void*>&            addr    = cb->addresses();
00734   std::vector<PoolDbTokenWrap*>& links   = cb->links();
00735   const std::vector<int>&        mapping = cb->mapping();
00736   const INTuple::ItemContainer&  items   = nt->items();
00737   INTuple::ItemContainer::const_iterator i;
00738 
00739   s.setMode(pool::DbBlob::WRITING);
00740   for(i = items.begin(); i != items.end(); ++i, ++cnt )   {
00741     char* b     = (char*)(*i)->buffer();
00742     int   len   = (*i)->filled();
00743     long  ndim  = (*i)->ndim();
00744     int   count = mapping[cnt];
00745     void* ptr = 0;
00746     switch( (*i)->type() )  {
00747     case DataTypeInfo::UCHAR:       ptr=save<unsigned char >(s,b,len,ndim>0); break;
00748     case DataTypeInfo::USHORT:      ptr=save<unsigned short>(s,b,len,ndim>0); break;
00749     case DataTypeInfo::UINT:        ptr=save<unsigned int  >(s,b,len,ndim>0); break;
00750     case DataTypeInfo::ULONG:       ptr=save<unsigned long >(s,b,len,ndim>0); break;
00751     case DataTypeInfo::CHAR:        ptr=save<char          >(s,b,len,ndim>0); break;
00752     case DataTypeInfo::SHORT:       ptr=save<short         >(s,b,len,ndim>0); break;
00753     case DataTypeInfo::INT:         ptr=save<int           >(s,b,len,ndim>0); break;
00754     case DataTypeInfo::LONG:        ptr=save<long          >(s,b,len,ndim>0); break;
00755     case DataTypeInfo::BOOL:        ptr=save<bool          >(s,b,len,ndim>0); break;
00756     case DataTypeInfo::FLOAT:       ptr=save<float         >(s,b,len,ndim>0); break;
00757     case DataTypeInfo::DOUBLE:      ptr=save<double        >(s,b,len,ndim>0); break;
00758     case DataTypeInfo::STRING:      ptr=save<std::string   >(s,b,len,ndim>0); break;
00759     case DataTypeInfo::NTCHAR:      ptr=save<char*         >(s,b,len,ndim>0); break;
00760     case DataTypeInfo::POINTER:     ptr=*(void**)b;                           break;
00761     case DataTypeInfo::OBJECT_ADDR: ptr=save(b,links[count]);                 break;
00762     case DataTypeInfo::UNKNOWN:                                               break;
00763     default:                     /* Do we have to take some action here ? */  break;
00764     }
00765     if ( count >= 0 )  {
00766       addr[count] = ptr;
00767     }
00768   }
00769   return S_OK;
00770 }

Generated at Wed Mar 17 18:06:38 2010 for Gaudi Framework, version v21r8 by Doxygen version 1.5.6 written by Dimitri van Heesch, © 1997-2004