Gaudi Framework, version v21r11

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

Generated at Thu Sep 30 09:57:36 2010 for Gaudi Framework, version v21r11 by Doxygen version 1.5.6 written by Dimitri van Heesch, © 1997-2004