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

DbNTupleCnv.cpp

Go to the documentation of this file.
00001 //------------------------------------------------------------------------------
00002 //
00003 // Implementation of class :  DbNTupleCnv
00004 //
00005 // Author :                   Markus Frank
00006 //
00007 //------------------------------------------------------------------------------
00008 
00009 // $Header: /nfs/slac/g/glast/ground/cvs/GaudiDb/src/NTuples/DbNTupleCnv.cpp,v 1.1.1.1 2001/04/18 21:13:35 tlindner Exp $
00010 #define DBCNV_NTUPLES_DBTUPLECNV_CPP
00011 
00012 
00013 #define ALLOW_ALL_TYPES
00014 // Include files
00015 #include "DbNTupleCnv.h"
00016 #include "GaudiDb/DbColumn.h"
00017 #include "GaudiDb/DbContainer.h"
00018 #include "GaudiDb/IDataBaseMgr.h"
00019 #include "GaudiDb/DbPersistent.h"
00020 #include "GaudiDb/DbCnvFactory.h"
00021 #include "GaudiDb/DbVArray.h"
00022 #include "GaudiDb/DbAddress.h"
00023 #include "GaudiDb/DbFactory.h"
00024 
00025 #include "GaudiKernel/xtoa.h"
00026 #include "GaudiKernel/SmartIF.h"
00027 #include "GaudiKernel/SmartRef.h"
00028 #include "GaudiKernel/GenericAddress.h"
00029 #include "GaudiKernel/NTuple.h"
00030 #include "GaudiKernel/IDataDirectory.h"
00031 #include "GaudiKernel/INTupleSvc.h"
00032 #include "GaudiKernel/ISelectStatement.h"
00033 #include "GaudiKernel/ContainedObject.h"
00034 
00035 #include "GaudiKernel/MsgStream.h"
00036 
00037 class GenericLinkIO   {
00038 public:
00039   inline static void writeLink(StreamBuffer &R__b, const GenericLinkBase& link)   {
00040     R__b << link.m_clID << link.m_svcType << link.m_gene.m_info[0] << link.m_gene.m_info[1];
00041   }
00042   inline static void readLink(StreamBuffer &R__b, GenericLinkBase& link)   {
00043     R__b >> link.m_clID >> link.m_svcType >> link.m_gene.m_info[0] >> link.m_gene.m_info[1];
00044   }
00045 };
00046 
00047 // Instantiation of a static factory class used by clients to create
00048 // instances of this service
00049 static DbOOMsCnvFactory<DbRWNTupleCnv>          s_RWNTfactory;
00050 const ICnvFactory& DbOOMsDbRWNTupleCnvFactory = s_RWNTfactory;
00051 static DbOOMsCnvFactory<DbCWNTupleCnv>          s_CWNTfactory;
00052 const ICnvFactory& DbOOMsDbCWNTupleCnvFactory = s_CWNTfactory;
00053 
00054 static inline std::istream& loadLong(std::istream& is)    {
00055   long i;
00056   is >> i;
00057   return is;
00058 }
00059 static inline std::istream& operator>>(std::istream& is, SmartRef<DataObject>& /*pObj*/)    {
00060   return loadLong(is);
00061 }
00062 static inline std::istream& operator>>(std::istream& is, SmartRef<ContainedObject>& /*pObj*/)    {
00063   return loadLong(is);
00064 }
00065 static inline std::istream& operator>>(std::istream& is, IOpaqueAddress*& /*pObj*/)    {
00066   return loadLong(is);
00067 }
00068 static inline std::istream& operator>>(std::istream& is, std::string& /*pObj*/)    {
00069   return loadLong(is);
00070 }
00071 
00072 template<class TYP>
00073 static StatusCode createItem (INTuple* tuple, std::istream& is, 
00074                        const std::string& name, const DbTypeInfo* info, const TYP& null)
00075 {
00076   std::string idxName;
00077   long len, ndim, dim[4], hasIdx, idxLow, idxLen;
00078   long dim1 = 1, dim2 = 1;
00079   INTupleItem* it = 0;
00080   char c;
00081   is >> len    >> c
00082      >> ndim   >> c
00083      >> hasIdx >> c;
00084   if ( hasIdx )   {
00085     std::getline(is, idxName, ';') >> idxLow >> c >> idxLen >> c;
00086   }
00087   for ( int i = 0; i < ndim; i++ ) 
00088     is >> dim[i] >> c;
00089 
00090   TYP low = null, high = null;
00091   is >> low >> c >> high >> c;
00092   is >> c;
00093   switch( ndim )   {
00094   case 0:
00095     it = NTuple::_Item<TYP>::create (tuple, name, low, high, null);
00096     break;
00097   case 1:
00098     dim1 = (hasIdx) ? idxLen : dim[0];
00099     it = NTuple::_Array<TYP>::create (tuple, name, idxName, dim1, low, high, null);
00100     break;
00101   case 2:
00102     dim1 = (hasIdx) ? idxLen : dim[0];
00103     dim2 = (hasIdx) ? dim[0] : dim[1];
00104     it = NTuple::_Matrix<TYP>::create (tuple, name, idxName, dim1, dim2, low, high, null);
00105     break;
00106   default:  
00107     return StatusCode::FAILURE;
00108   }
00109   DbColumn* col = const_cast<DbColumn*>(info->column(name));
00110   if ( col )    {
00111     col->setAddress((char*)it->buffer());
00112   }
00113   return tuple->add(it);
00114 }
00115 
00116 template <class T> static inline
00117 void putRange(std::ostream& os, NTuple::_Data<T>* it)   { 
00118   const NTuple::Range<T>& x = it->range();
00119   os << x.lower() << ';' << x.upper() << ';';
00120 }
00121 
00122 // Helper to read
00123 template <class T> static inline
00124 int readItem(StreamBuffer& s, T* buff, const DbColumn* col)   {
00125   if ( col )  {
00126     DbColumn* c = const_cast<DbColumn*>(col);
00127     char* d = c->data();
00128     *buff = *(T*)d;
00129     return 0;
00130   }
00131   else    {
00132     long len;
00133     s >> len;
00134     s.swapFromBuffer(buff, len*sizeof(T));
00135   }
00136   return 0;
00137 }
00138 
00139 // Helper to read specialized for strings
00140 template <> static inline
00141 int readItem(StreamBuffer& s, std::string* buff, const DbColumn* /*col*/)   {
00142   s >> (*buff);
00143   return 0;
00144 }
00145 
00146 template <class T> static inline
00147 int saveItem(StreamBuffer& s, const T* buff, int len)   {
00148   if ( len > 1 )   {
00149     s << len;
00150     s.swapToBuffer(buff, len*sizeof(T));
00151     return 0;
00152   }
00153   return 0;
00154 }
00155 
00156 template <> static inline
00157 int saveItem(StreamBuffer& s, const std::string* buff, int /*len*/)   {
00158   s << (*buff);
00159   return 0;
00160 }
00161 /*
00162 template <> inline
00163 int saveItem(StreamBuffer& s, DbNTupleItem& it, const char* t)   {
00164   char** src = (char**)it.buffer();
00165   s << it.length();
00166   for ( int i = 0; i < it.length(); i++ )   {
00167     s << *(src++);
00168   }
00169   return 0;
00170 }
00171 */
00172 template int saveItem<unsigned char>(StreamBuffer& s, const unsigned char* buff, int len);
00173 template int saveItem<unsigned short>(StreamBuffer& s, const unsigned short* buff, int len );
00174 template int saveItem<unsigned int>(StreamBuffer& s, const unsigned int* buff, int len );
00175 template int saveItem<unsigned long>(StreamBuffer& s, const unsigned long* buff, int len );
00176 template int saveItem<char>(StreamBuffer& s, const char* buff, int len );
00177 template int saveItem<short>(StreamBuffer& s, const short* buff, int len );
00178 template int saveItem<int>(StreamBuffer& s, const int* buff, int len );
00179 template int saveItem<long>(StreamBuffer& s, const long* buff, int len );
00180 template int saveItem<float>(StreamBuffer& s, const float* buff, int len );
00181 template int saveItem<double>(StreamBuffer& s, const double* buff, int len );
00182 
00183 // Standard constructor
00184 DbNTupleCnv::DbNTupleCnv(const CLID& clid, IOODataBase* db, ISvcLocator* svc)    
00185 : DbUserDataBaseCnv(clid, db, svc)
00186 {
00187 }
00188 
00189 // Standard destructor
00190 DbNTupleCnv::~DbNTupleCnv()    
00191 {
00192 }
00193 
00194 // Initialize the converter
00195 StatusCode DbNTupleCnv::initialize()   {
00196   StatusCode status = DbUserDataBaseCnv::initialize();
00197   if ( status.isSuccess() )   {
00198     status = serviceLocator()->getService(m_cnvSvcName, IID_IDataProviderSvc, (IInterface*&)m_helperServices.DataSvc);
00199   }
00200   return status;
00201 }
00202 
00203 // Finalize the converter
00204 StatusCode DbNTupleCnv::finalize()     {
00205   return DbUserDataBaseCnv::finalize();
00206 }
00207 
00208 // DbUserDataBaseCnv overrides: Update the references of an updated transient object.
00209 StatusCode DbNTupleCnv::createObj(IOpaqueAddress* pAddress, DataObject*& refpObject)    {
00210   StatusCode status = StatusCode::FAILURE;
00211   DbAddress* pdbA = dynamic_cast<DbAddress*>(pAddress);
00212   if ( 0 != pdbA )    {
00213     SmartIF<INTupleSvc> ntupleSvc(IID_INTupleSvc, m_helperServices.DataSvc);
00214     dbHandle<DbContainer>& cntH = pdbA->containerHdl();
00215     m_type = cntH.typeInfo();
00216     pAddress->genericLink()->genericInfo()->m_info[1] = 0;
00217     if ( 0 != m_type && ntupleSvc.isValid() )    {
00218       char c;
00219       size_t siz;
00220       int typ;
00221       CLID clid;
00222       std::string title;
00223       NTuple::Tuple* nt = 0;
00224       std::istrstream is(m_type->userDescription().c_str());
00225       std::getline(is, title, ';') >> clid >> c >> siz >> c;
00226       status = ntupleSvc->create(clid, title, nt);
00227       for ( size_t j = 0; j < siz && status.isSuccess(); j++ )   {
00228         is >> c;
00229         std::getline(is, title, ';') >> typ >> c;
00230         switch ( typ )    {
00231         case DataTypeInfo::UCHAR:
00232           status = createItem(nt, is, title, m_type, (unsigned char)0);
00233           break;
00234         case DataTypeInfo::USHORT:
00235           status = createItem(nt, is, title, m_type, (unsigned short)0);
00236           break;
00237         case DataTypeInfo::UINT:
00238           status = createItem(nt, is, title, m_type, (unsigned int)0);
00239           break;
00240         case DataTypeInfo::ULONG:
00241           status = createItem(nt, is, title, m_type, (unsigned long)0);
00242           break; 
00243         case DataTypeInfo::CHAR:
00244           status = createItem(nt, is, title, m_type, char(0));
00245           break;
00246         case DataTypeInfo::SHORT:
00247           status = createItem(nt, is, title, m_type, short(0));
00248           break;
00249         case DataTypeInfo::INT:
00250           status = createItem(nt, is, title, m_type, int(0));
00251           break;
00252         case DataTypeInfo::LONG:
00253           status = createItem(nt, is, title, m_type, long(0));
00254           break;
00255         case DataTypeInfo::BOOL:
00256           status = createItem(nt, is, title, m_type, false);
00257           break;
00258         case DataTypeInfo::FLOAT:
00259           status = createItem(nt, is, title, m_type, float(0.0));
00260           break;
00261         case DataTypeInfo::DOUBLE:
00262           status = createItem(nt, is, title, m_type, double(0.0));
00263           break;
00264         /*
00265         case DataTypeInfo::NTCHAR:
00266           status = createItem(nt, is, title, m_type, (char*)0);
00267           break;
00268         case DataTypeInfo::STRING:
00269           status = createItem(nt, is, title, m_type, std::string(""));
00270           break;
00271         case DataTypeInfo::OBJECT_REF: 
00272           status = createItem(nt, is, title, m_type, SmartRef<DataObject>());
00273           break;
00274         case DataTypeInfo::CONTAINED_REF:
00275           status = createItem(nt, is, title, m_type, SmartRef<ContainedObject>());
00276           break;
00277         */
00278         case DataTypeInfo::OBJECT_ADDR:
00279           status = createItem(nt, is, title, m_type, (IOpaqueAddress*)0);
00280           break;
00281         case DataTypeInfo::UNKNOWN:
00282         default:
00283           status = StatusCode::FAILURE;
00284           break;
00285         }
00286       }
00287       if ( status.isSuccess() )   {
00288         refpObject = nt;
00289       }
00290       else  {
00291         refpObject = 0;
00292         if ( nt ) nt->release();
00293       }
00294     }
00295   }
00296   return status;
00297 }
00298 
00299 // Update the references of an updated transient object: Nothing to do for N-tuples
00300 StatusCode DbNTupleCnv::fillObjRefs(IOpaqueAddress* /*pAddress*/, DataObject* /*pObject*/)   {
00301   return StatusCode::SUCCESS;
00302 }
00303 
00304 // Update the transient object: NTuples end here when reading records
00305 StatusCode DbNTupleCnv::updateObj(IOpaqueAddress* pAddress, DataObject* pObject)   {
00306   INTuple*   tuple = dynamic_cast<INTuple*>(pObject);
00307   if ( 0 != tuple )   {
00308     ISelectStatement* sel = tuple->selector();
00309     if ( 0 != sel )   {
00310       if ( !sel->isActive() )   {
00311         DbAddress* pdbA = dynamic_cast<DbAddress*>(pAddress);
00312         if ( 0 != pdbA )    {
00313           dbHandle<DbContainer>& cntH = pdbA->containerHdl();
00314           DbResult res = cntH.select(sel);
00315           if ( res )   {
00316             return DbUserDataBaseCnv::updateObj(pAddress, pObject);
00317           }
00318         }
00319         return StatusCode::FAILURE;
00320       }
00321     }
00322     return DbUserDataBaseCnv::updateObj(pAddress, pObject);
00323   }
00324   return StatusCode::FAILURE;
00325 }
00326 
00327 // Update the references of an updated transient object: NTuples end here when reading records
00328 StatusCode DbNTupleCnv::updateObjRefs(IOpaqueAddress* pAddress, DataObject* pObject)   {
00329   DbAddress* pdbA = dynamic_cast<DbAddress*>(pObject->address());
00330   if ( 0 != pdbA )    {
00331     dbHandle<DbContainer>& cntH = pdbA->containerHdl();
00332     m_type = cntH.typeInfo();
00333     if ( 0 != m_type )    {
00334       StatusCode status = DbUserDataBaseCnv::updateObjRefs(pAddress, pObject);
00335       pdbA->genericInfo()->m_info[1] += 1;
00336       return status;
00337     }
00338   }
00339   return StatusCode::FAILURE;
00340 }
00341 
00342 // Overridable callback when actually updating the transient data
00343 StatusCode DbNTupleCnv::doTransientUpdate( dbHandle<DbDefObject>& objH, DataObject* pObject)    {
00344   const dbHandle<DbContainer>& cntH = objH.containedIn();
00345   INTuple*                       nt = dynamic_cast<INTuple*>(pObject);
00346   StreamBuffer&                   s = objH->streamBuffer();
00347   const DbTypeInfo*            info = cntH.typeInfo();
00348   if ( info )   {
00349     const INTuple::ItemContainer& items = nt->items();
00350     for ( INTuple::ItemContainer::const_iterator i = items.begin(); i != items.end(); i++ )   {
00351       char* buf = (char*)(*i)->buffer();
00352       const DbColumn* col = info->column((*i)->name());
00353       switch( (*i)->type() )   {
00354       case DataTypeInfo::UCHAR:
00355         readItem(s, (unsigned char*)buf, col);
00356         break;
00357       case DataTypeInfo::USHORT:
00358         readItem(s, (unsigned short*)buf, col);
00359         break;
00360       case DataTypeInfo::UINT:
00361         readItem(s, (unsigned int*)buf, col);
00362         break;
00363       case DataTypeInfo::ULONG:
00364         readItem(s, (unsigned long*)buf, col);
00365         break;
00366       case DataTypeInfo::CHAR:
00367         readItem(s, (char*)buf, col);
00368         break;
00369       case DataTypeInfo::SHORT:
00370         readItem(s, (short*)buf, col);
00371         break;
00372       case DataTypeInfo::INT:
00373         readItem(s, (int*)buf, col);
00374         break;
00375       case DataTypeInfo::LONG:
00376         readItem(s, (long*)buf, col);
00377         break;
00378       case DataTypeInfo::BOOL:
00379         readItem(s, (bool*)buf, col);
00380         break;
00381       case DataTypeInfo::FLOAT:
00382         readItem(s, (float*)buf, col);
00383         break;
00384       case DataTypeInfo::DOUBLE:
00385         readItem(s, (double*)buf, col);
00386         break;
00387       /*
00388       case DataTypeInfo::STRING:
00389         readItem(s, (std::string*)buf, col);
00390         break;
00391       case DataTypeInfo::NTCHAR:
00392         readItem(s, (char*)buf, col);
00393         break;
00394       case DataTypeInfo::OBJECT_REF:      {
00395         SmartRef<DataObject>& objRef = *(SmartRef<DataObject>*)buf;
00396         s >> objRef(pObject);
00397         break;
00398       }
00399       case DataTypeInfo::CONTAINED_REF:      {
00400         SmartRef<ContainedObject>& objRef = *(SmartRef<ContainedObject>*)buf;
00401         s >> objRef(pObject);
00402         break;
00403       }
00404       */
00405       case DataTypeInfo::OBJECT_ADDR:      {
00406         dbHandle<DbLink> lnk;
00407         std::string db, cnt, obj;
00408         StatusCode status = StatusCode::FAILURE;
00409         IOpaqueAddress* pA = *(IOpaqueAddress**)buf;
00410         GenericAddress* pAddr = dynamic_cast<GenericAddress*>(pA);
00411         unsigned char valid;
00412         s >> valid;
00413         if ( valid )    {
00414           GenericLinkIO::readLink(s, lnk);
00415           if ( 0 != pAddr )   {
00416             status = objH.validateAssoc(lnk, db, cnt, obj);
00417           }
00418         }
00419         if ( 0 != pAddr )   {
00420           *(pAddr->genericLink()) = lnk;
00421           pAddr->setDbName(db);
00422           pAddr->setContainerName(cnt);
00423           pAddr->setObjectName(obj);
00424         }
00425         break;
00426       }
00427       case DataTypeInfo::UNKNOWN:
00428       default:
00429         break;
00430       }
00431     }
00432   }
00433   return StatusCode::SUCCESS;
00434 }
00435 
00437 dbHandle<DbObject> DbNTupleCnv::createPersistent(dbHandle<DbContainer>& cntH)  {
00438   dbHandle<DbObject> handle = new(cntH, *m_type) DbDefObject();
00439   return handle;
00440 }
00441 
00443 StatusCode DbNTupleCnv::createRep(DataObject* pObject, IOpaqueAddress*& pAddr)  {
00444   DbAddress* pdbA = dynamic_cast<DbAddress*>(pObject->address());
00445   if ( 0 == pdbA )    {
00446     const INTuple* nt     = dynamic_cast<const INTuple*>(pObject);
00447     const INTuple::ItemContainer& items = nt->items();
00448     std::string loc       = containerName(pObject->directory());
00449     const DbTypeInfo* typ = m_db->typeInfo(loc);
00450     if ( 0 != nt )   {
00451       std::vector<DbColumn*> cols;
00452       char txt[4096];
00453       std::ostrstream os(txt,sizeof(txt));
00454       os << nt->title() << ';' << pObject->clID()  << ';' << items.size() << ';';
00455       for ( INTuple::ItemContainer::const_iterator i = items.begin(); i != items.end(); i++ )   {
00456         os << '{' 
00457            << (*i)->name()      << ';' 
00458            << (*i)->type()      << ';' 
00459            << (*i)->length()    << ';'
00460            << (*i)->ndim()      << ';' 
00461            << (*i)->hasIndex()  << ';';
00462         if ( (*i)->hasIndex() )   {
00463           os << (*i)->index() << ';';
00464           INTupleItem* idxItem = (*i)->indexItem();
00465           switch( idxItem->type() )    {
00466           case DataTypeInfo::UCHAR:
00467             putRange(os, dynamic_cast<NTuple::_Data<unsigned char>*>(idxItem));   break;
00468           case DataTypeInfo::USHORT:
00469             putRange(os, dynamic_cast<NTuple::_Data<unsigned short>*>(idxItem));  break;
00470           case DataTypeInfo::UINT:
00471             putRange(os, dynamic_cast<NTuple::_Data<unsigned int>*>(idxItem));    break;
00472           case DataTypeInfo::ULONG:
00473             putRange(os, dynamic_cast<NTuple::_Data<unsigned long>*>(idxItem));   break;
00474           case DataTypeInfo::CHAR:
00475             putRange(os, dynamic_cast<NTuple::_Data<char>*>(idxItem));            break;
00476           case DataTypeInfo::SHORT:
00477             putRange(os, dynamic_cast<NTuple::_Data<short>*>(idxItem));           break;
00478           case DataTypeInfo::INT:
00479             putRange(os, dynamic_cast<NTuple::_Data<int>*>(idxItem));             break;
00480           case DataTypeInfo::LONG:
00481             putRange(os, dynamic_cast<NTuple::_Data<long>*>(idxItem));            break;
00482           default: {
00483             MsgStream err(msgSvc(), pObject->fullpath());
00484             err << MSG::ERROR << "Column " << (*i)->index() 
00485                 << " is not a valid index column!" << endreq;
00486             return StatusCode::FAILURE;
00487             }
00488           }
00489         }
00490         for ( long k = 0; k < (*i)->ndim(); k++ )  os << (*i)->dim(k) << ';';
00491         switch((*i)->type())   {
00492           case DataTypeInfo::STRING:
00493           case DataTypeInfo::NTCHAR:
00494           case DataTypeInfo::OBJECT_REF:
00495           case DataTypeInfo::OBJECT_ADDR:
00496           case DataTypeInfo::CONTAINED_REF:
00497             os << 0 << ';' << 0 << ';';
00498             break;
00499           case DataTypeInfo::UCHAR:
00500             putRange(os, dynamic_cast<NTuple::_Data<unsigned char>*>(*i));    goto MakeCol;
00501           case DataTypeInfo::USHORT:
00502             putRange(os, dynamic_cast<NTuple::_Data<unsigned short>*>(*i));   goto MakeCol;
00503           case DataTypeInfo::UINT:
00504             putRange(os, dynamic_cast<NTuple::_Data<unsigned int>*>(*i));     goto MakeCol;
00505           case DataTypeInfo::ULONG:
00506             putRange(os, dynamic_cast<NTuple::_Data<unsigned long>*>(*i));    goto MakeCol;
00507           case DataTypeInfo::CHAR:
00508             putRange(os, dynamic_cast<NTuple::_Data<char>*>(*i));             goto MakeCol;
00509           case DataTypeInfo::SHORT:
00510             putRange(os, dynamic_cast<NTuple::_Data<short>*>(*i));            goto MakeCol;
00511           case DataTypeInfo::INT:
00512             putRange(os, dynamic_cast<NTuple::_Data<int>*>(*i));              goto MakeCol;
00513           case DataTypeInfo::LONG:
00514             putRange(os, dynamic_cast<NTuple::_Data<long>*>(*i));             goto MakeCol;
00515           case DataTypeInfo::BOOL:
00516             putRange(os, dynamic_cast<NTuple::_Data<bool>*>(*i));             goto MakeCol;
00517           case DataTypeInfo::FLOAT:
00518             putRange(os, dynamic_cast<NTuple::_Data<float>*>(*i));            goto MakeCol;
00519           case DataTypeInfo::DOUBLE:  
00520             putRange(os, dynamic_cast<NTuple::_Data<double>*>(*i));           goto MakeCol;
00521 MakeCol:
00522             if ( (*i)->length() == 1 )   {
00523               DbColumn* col = (0==typ) ? new DbColumn((*i)->name(), 0, (*i)->type()) 
00524                                        : (DbColumn*)typ->column((*i)->name());
00525               col->setAddress((char*)(*i)->buffer());
00526               cols.push_back(col);
00527             }
00528           break;
00529           // Everything else CANNOT be identified using SQL
00530           default:
00531             break;
00532         }
00533         os << '}';
00534       }
00535       if ( 0 == typ )   {
00536         os << '\0';
00537         typ = m_db->addTypeInfo(loc,"DbDefObject","",txt,cols);
00538       }
00539     }
00540     m_type = typ;
00541   }
00542   else  {
00543     dbHandle<DbContainer>& cntH = pdbA->containerHdl();
00544     m_type = cntH.typeInfo();
00545     if ( m_type == 0 )    {
00546       return StatusCode::FAILURE;
00547     }
00548   }
00549   StatusCode status = StatusCode::SUCCESS;
00550   if ( 0 == pdbA || !pdbA->objectHdl().isValid() )    {
00551     status = DbUserDataBaseCnv::createRep(pObject, pAddr);
00552   }
00553   if ( status.isSuccess() )   {
00554     status = DbUserDataBaseCnv::updateRep(pAddr, pObject);
00555   }
00556   return status;
00557 }
00558 
00560 StatusCode DbNTupleCnv::updateRep(IOpaqueAddress* /* pAddress */, DataObject* /* pObject */ )     {
00561   return StatusCode::SUCCESS;
00562 }
00563 
00565 StatusCode DbNTupleCnv::updateRepRefs(IOpaqueAddress* /* pAddress */, DataObject* /* pObject */)     {
00566   return StatusCode::SUCCESS;
00567 }
00568 
00569 // Overridable callback when actually updating the persistent data
00570 StatusCode DbNTupleCnv::doPersistentUpdate( dbHandle<DbDefObject>& objH, const DataObject* pObject)    {
00571   const dbHandle<DbContainer>& cntH = objH.containedIn();
00572   const INTuple*                 nt = dynamic_cast<const INTuple*>(pObject);
00573   StreamBuffer&                   s = objH->streamBuffer();
00574   clearBuffers(objH);
00575 //  s << pObject->clID();
00576 //  pObject->DataObject::serialize(s);
00577   if ( nt != 0 )   {
00578     const INTuple::ItemContainer& items = nt->items();
00579     m_type = cntH.typeInfo();
00580     for ( INTuple::ItemContainer::const_iterator i = items.begin(); i != items.end(); i++ )   {
00581       char* buf = (char*)(*i)->buffer();
00582       int len = (*i)->filled();
00583       switch( (*i)->type() )   {
00584       case DataTypeInfo::UCHAR:
00585         saveItem(s, (const unsigned char*)buf, len);
00586         break;
00587       case DataTypeInfo::USHORT:
00588         saveItem(s, (const unsigned short*)buf, len);
00589         break;
00590       case DataTypeInfo::UINT:
00591         saveItem(s, (const unsigned int*)buf, len);
00592         break;
00593       case DataTypeInfo::ULONG:
00594         saveItem(s, (const unsigned long*)buf, len);
00595         break;
00596       case DataTypeInfo::CHAR:
00597         saveItem(s, (const char*)buf, len);
00598         break;
00599       case DataTypeInfo::SHORT:
00600         saveItem(s, (const short*)buf, len);
00601         break;
00602       case DataTypeInfo::INT:
00603         saveItem(s, (const int*)buf, len);
00604         break;
00605       case DataTypeInfo::LONG:
00606         saveItem(s, (const long*)buf, len);
00607         break;
00608       case DataTypeInfo::BOOL:
00609         saveItem(s, (const bool*)buf, len);
00610         break;
00611       case DataTypeInfo::FLOAT:
00612         saveItem(s, (const float*)buf, len);
00613         break;
00614       case DataTypeInfo::DOUBLE:
00615         saveItem(s, (const double*)buf, len);
00616         break;
00617       /*
00618       case DataTypeInfo::STRING:
00619         saveItem(s, (const std::string*)buf, len);
00620         break;
00621       case DataTypeInfo::NTCHAR:
00622         saveItem(s, (const char*)buf, len);
00623         break;
00624       case DataTypeInfo::OBJECT_REF:      {
00625         SmartRef<DataObject>& objRef = *(SmartRef<DataObject>*)buf;
00626         s << objRef(pObject);
00627         break;
00628       }
00629       case DataTypeInfo::CONTAINED_REF:      {
00630         SmartRef<ContainedObject>& objRef = *(SmartRef<ContainedObject>*)buf;
00631         s << objRef(pObject);
00632         break;
00633       }
00634       */
00635       case DataTypeInfo::OBJECT_ADDR:      {
00636         IOpaqueAddress* pA = *(IOpaqueAddress**)buf;
00637         if ( 0 != pA )   {    
00638           dbHandle<DbLink> to2(*pA->genericLink());
00639           dbHandle<DbLink> to(*pA->genericLink());
00640           dbHandle<DbDataBase> dbH = objH.containedIn().containedIn();
00641           if ( dbH.addAssocEntry(pA->dbName(), pA->containerName(), pA->objectName(), to) )  {
00642             s << (unsigned char)1;
00643             GenericLinkIO::writeLink(s, to);
00644             break;
00645           }
00646         }
00647         s << (unsigned char)0;
00648         break;
00649       }
00650       case DataTypeInfo::UNKNOWN:
00651       default:
00652         break;
00653       }
00654     }
00655   }
00656   return StatusCode::SUCCESS;
00657 }
00658 
00660 StatusCode DbNTupleCnv::afterPersistentUpdate(dbHandle<DbDefObject>& /* objH */ , const DataObject* pObject)   {
00661   const INTuple* tup = dynamic_cast<const INTuple*>(pObject);
00662   if ( 0 != tup )   {
00663     INTuple::ItemContainer& items = const_cast<INTuple::ItemContainer&>(tup->items());
00664     for ( INTuple::ItemContainer::iterator i = items.begin(); i != items.end(); i++ )   {
00665       (*i)->reset();
00666     }
00667     return StatusCode::SUCCESS;
00668   }
00669   return StatusCode::FAILURE;
00670 }

Generated at Wed Nov 21 12:22:19 2001 by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000