| # Gaudi Framework, version v20r2
Generated: 18 Jul 2008

- Main Page
- Namespaces
- Classes
- Files
- Directories
- Related Pages

- Search for |

- File List
- File Members

# PoolDbNTupleCnv.cpp

Go to the documentation of this file.

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