Gaudi Framework, version v23r5

Home   Generated: Wed Nov 28 2012
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
PersistencySvc.cpp
Go to the documentation of this file.
1 //====================================================================
2 // PersistencySvc.cpp
3 //--------------------------------------------------------------------
4 //
5 // Package : System ( The LHCb Offline System)
6 //
7 // Description: implementation of the PersistencySvc
8 //
9 // Author : M.Frank
10 // History :
11 // +---------+----------------------------------------------+---------
12 // | Date | Comment | Who
13 // +---------+----------------------------------------------+---------
14 // | 29/10/98| Initial version | MF
15 // +---------+----------------------------------------------+---------
16 //
17 //====================================================================
18 #define PERSISTENCYSVC_PERSISTENCYSVC_CPP
19 
20 // Interface defintions
21 #include "GaudiKernel/SmartIF.h"
22 #include "GaudiKernel/SvcFactory.h"
23 #include "GaudiKernel/CnvFactory.h"
24 #include "GaudiKernel/DataObject.h"
25 #include "GaudiKernel/IConverter.h"
29 #include "GaudiKernel/MsgStream.h"
30 #include "GaudiKernel/strcasecmp.h"
33 
34 // Implementation specific definitions
35 #include "PersistencySvc.h"
36 
37 #define ON_DEBUG if (UNLIKELY(outputLevel() <= MSG::DEBUG))
38 #define ON_VERBOSE if (UNLIKELY(outputLevel() <= MSG::VERBOSE))
39 
40 #define DEBMSG ON_DEBUG debug()
41 #define VERMSG ON_VERBOSE verbose()
42 
43 // Instantiation of a static factory class used by clients to create
44 // instances of this service
46 
56 };
57 
59  IOpaqueAddress*& pAddress,
60  DataObject*& pObject) {
61  if ( m_enable ) {
62  IConversionSvc* svc = 0;
63  switch(typ) {
64  case CREATE_REP:
65  case FILL_REP_REFS:
66  case UPDATE_REP:
67  case UPDATE_REP_REFS:
68  svc = m_cnvDefault;
69  break;
70  default:
71  if ( 0 != pAddress ) {
72  long svc_type = pAddress->svcType();
73  svc = service(svc_type);
74  if ( 0 == svc ) {
75  return BAD_STORAGE_TYPE;
76  }
77  }
78  else {
79  return INVALID_ADDRESS;
80  }
81  break;
82  }
83 
84  StatusCode status(StatusCode::FAILURE,true);
85  switch( typ ) {
86  case CREATE_OBJ:
87  pObject = 0;
88  status = svc->createObj(pAddress, pObject);
89  break;
90  case FILL_OBJ_REFS:
91  status = svc->fillObjRefs(pAddress, pObject);
92  break;
93  case UPDATE_OBJ:
94  status = svc->updateObj(pAddress, pObject);
95  break;
96  case UPDATE_OBJ_REFS:
97  status = svc->updateObjRefs(pAddress, pObject);
98  break;
99  case CREATE_REP:
100  status = svc->createRep(pObject, pAddress);
101  break;
102  case FILL_REP_REFS:
103  status = svc->fillRepRefs(pAddress, pObject);
104  break;
105  case UPDATE_REP:
106  status = svc->updateRep(pAddress, pObject);
107  break;
108  case UPDATE_REP_REFS:
109  status = svc->updateRepRefs(pAddress, pObject);
110  break;
111  default:
112  status = StatusCode::FAILURE;
113  break;
114  }
115  status.ignore();
116  return status;
117  }
118  return StatusCode::SUCCESS;
119 }
120 
123  return makeCall(CREATE_OBJ, pAddr, refpObj);
124 }
125 
128  return makeCall(FILL_OBJ_REFS, pAddr, pObj);
129 }
130 
133  return makeCall(UPDATE_OBJ, pAddr, pObj);
134 }
135 
138  return makeCall(UPDATE_OBJ_REFS, pAddr, pObj);
139 }
140 
143  return makeCall(CREATE_REP, refpAddr, pObj);
144 }
145 
148  return makeCall(FILL_REP_REFS, pAddr, pObj);
149 }
150 
153  return makeCall(UPDATE_REP, pAddr, pObj);
154 }
155 
158  return makeCall(UPDATE_REP_REFS, pAddr, pObj);
159 }
160 
163  long typ = type;
165  if( it == m_cnvServices.end() ) {
166  IConversionSvc* s = service(type);
167  if ( s ) {
168  it = m_cnvServices.find( typ );
169  if ( it != m_cnvServices.end() ) {
170  return (*it).second.addrCreator();
171  }
172  }
173  static SmartIF<IAddressCreator> no_creator;
174  return no_creator;
175  }
176  return (*it).second.addrCreator();
177 }
178 
181  m_dataSvc = pDataSvc;
182  for ( Services::iterator i = m_cnvServices.begin(); i != m_cnvServices.end(); i++ ) {
183  (*i).second.conversionSvc()->setDataProvider(m_dataSvc).ignore();
184  }
185  return StatusCode(StatusCode::SUCCESS,true);
186 }
187 
190  return m_dataSvc;
191 }
192 
195  m_cnvDefault = svc;
196  return StatusCode(StatusCode::SUCCESS,true);
197 }
198 
201  return m_cnvDefault;
202 }
203 
206  return StatusCode::FAILURE;
207 }
208 
211  if ( 0 != pConverter ) {
212  long typ = pConverter->repSvcType();
213  IConversionSvc* svc = service(typ);
214  if ( 0 != svc ) {
215  return svc->addConverter(pConverter);
216  }
217  return BAD_STORAGE_TYPE;
218  }
219  return NO_CONVERTER;
220 }
221 
224  // Remove converter type from all services
225  StatusCode status = NO_CONVERTER, iret = StatusCode::SUCCESS;
226  for ( Services::iterator i = m_cnvServices.begin(); i != m_cnvServices.end(); i++ ) {
227  iret = (*i).second.conversionSvc()->removeConverter(clid);
228  if ( iret.isSuccess() ) {
229  status = iret;
230  }
231  }
232  return status;
233 }
234 
237  return 0;
238 }
239 
242  Gaudi::Utils::TypeNameString tn(nam);
243  IConversionSvc* svc = 0;
244  for ( Services::iterator it = m_cnvServices.begin(); it != m_cnvServices.end(); it++ ) {
245  if ( (*it).second.service()->name() == tn.name() ) {
246  return (*it).second.conversionSvc();
247  }
248  }
249  StatusCode status = Service::service(nam, svc, true);
250  if ( status.isSuccess() ) {
251  if ( addCnvService(svc).isSuccess() ) {
252  svc->release(); // Do not double-reference count
253  return service(nam); // now it is in the list
254  }
255  }
256  info() << "Cannot access Conversion service:" << nam << endmsg;
257  static SmartIF<IConversionSvc> no_svc;
258  return no_svc;
259 }
260 
263  typedef std::vector<std::string> SvcNames;
264  // Check wether this is already an active service
266  if( it != m_cnvServices.end() ) {
267  return (*it).second.conversionSvc();
268  }
269  // if not, check if the service is in the list and may be requested
270  const SvcNames& theNames = m_svcNames.value();
271  for ( SvcNames::const_iterator i = theNames.begin(); i != theNames.end(); i++ ) {
273  if ( svc != 0 ) {
274  long typ = svc->repSvcType();
275  if ( typ == type ) {
276  return svc;
277  }
278  }
279  }
280  static SmartIF<IConversionSvc> no_svc;
281  return no_svc;
282 }
283 
286  if ( 0 != servc ) {
287  long type = servc->repSvcType();
288  long def_typ = (m_cnvDefault) ? m_cnvDefault->repSvcType() : 0;
290  IConversionSvc* cnv_svc = 0;
291  if ( it != m_cnvServices.end() ) {
292  cnv_svc = (*it).second.conversionSvc();
293  }
294  if ( type == def_typ ) {
295  m_cnvDefault = servc;
296  }
297  if ( cnv_svc != servc ) {
298  IAddressCreator* icr = 0;
299  StatusCode status = servc->queryInterface(IAddressCreator::interfaceID(), pp_cast<void>(&icr));
300  if ( status.isSuccess() ) {
301  IService* isvc = 0;
302  status = servc->queryInterface(IService::interfaceID(), pp_cast<void>(&isvc));
303  if ( status.isSuccess() ) {
304  if ( 0 != cnv_svc ) {
305  removeCnvService (type).ignore();
306  }
308  m_cnvServices.insert( Services::value_type( type, ServiceEntry(type, isvc, servc, icr)));
309  if( p.second ) {
310  info() << "Added successfully Conversion service:" << isvc->name() << endmsg;
311  servc->addRef();
312  servc->setAddressCreator(this).ignore();
313  servc->setDataProvider(m_dataSvc).ignore();
314  return StatusCode::SUCCESS;
315  }
316  info() << "Cannot add Conversion service of type " << isvc->name() << endmsg;
317  isvc->release();
318  icr->release();
319  return StatusCode::FAILURE;
320  }
321  icr->release();
322  }
323  info() << "Cannot add Conversion service of type " << type << endmsg;
324  return StatusCode::FAILURE;
325  }
326  else {
327  return StatusCode::SUCCESS;
328  }
329  }
330  return BAD_STORAGE_TYPE;
331 }
332 
335  Services::iterator it = m_cnvServices.find( svctype );
336  if( it != m_cnvServices.end() ) {
337  (*it).second.service()->release();
338  (*it).second.addrCreator()->release();
339  m_cnvServices.erase(it);
340  return StatusCode::SUCCESS;
341  }
342  return BAD_STORAGE_TYPE;
343 }
344 
347  long typ = (m_cnvDefault) ? m_cnvDefault->repSvcType() : 0;
348  return typ;
349 }
350 
353  m_cnvDefault = service(type);
354  return StatusCode::SUCCESS;
355 }
356 
359  const std::string& /* openMode */) {
360  return connectOutput(outputFile);
361 }
362 
365  return StatusCode::SUCCESS;
366 }
367 
370  return StatusCode::SUCCESS;
371 }
372 
375  const CLID& clid,
376  const std::string* pars,
377  const unsigned long* ipars,
378  IOpaqueAddress*& refpAddress) {
379  IAddressCreator* svc = addressCreator(svc_type);
380  StatusCode status = BAD_STORAGE_TYPE; // Preset error
381  refpAddress = 0;
382  if ( 0 != svc ) {
383  status = svc->createAddress(svc_type, clid, pars, ipars, refpAddress);
384  }
385  return status;
386 }
387 
390  std::string& refAddress)
391 {
392  // Assumuption is that the Persistency service prepends a header
393  // and requests the conversion service refered to by the service
394  // type to encode the rest
395  long svc_type = 0;
396  CLID clid = 0;
397  if ( 0 != pAddress ) {
398  svc_type = pAddress->svcType();
399  clid = pAddress->clID();
400  }
401  IAddressCreator* svc = addressCreator(svc_type);
402  StatusCode status = BAD_STORAGE_TYPE; // Preset error
403  refAddress = "";
404 
405  if ( 0 != svc ) {
406  // Found service, set header
407  encodeAddrHdr(svc_type, clid, refAddress);
408  std::string address;
409  // Get rest of address from conversion service
410  status = svc->convertAddress(pAddress, address);
411  refAddress += address;
412  }
413  return status;
414 }
415 
418  const CLID& /* clid */,
419  const std::string& refAddress,
420  IOpaqueAddress*& refpAddress)
421 {
422  // Assumption is that the Persistency service decodes that header
423  // and requests the conversion service referred to by the service
424  // type to decode the rest
425  long new_svc_type = 0;
426  CLID new_clid = 0;
427  std::string address_trailer;
428  decodeAddrHdr(refAddress, new_svc_type, new_clid, address_trailer);
429  IAddressCreator* svc = addressCreator(new_svc_type);
430  StatusCode status = BAD_STORAGE_TYPE; // Preset error
431  if ( 0 != svc ) {
432  status = svc->createAddress( new_svc_type, new_clid, address_trailer, refpAddress);
433  }
434  return status;
435 }
436 
438 void PersistencySvc::encodeAddrHdr( long service_type,
439  const CLID& clid,
440  std::string& address) const
441 {
442  // For address header, use xml-style format of
443  // <addrhdr service_type="xxx" clid="yyy" />
444  std::stringstream stream;
445  int svctyp = service_type; // must put int into stream, not char
446  stream << "<address_header service_type=\"" << svctyp << "\" clid=\"" << clid << "\" /> ";
447  address = stream.str();
448 }
449 
452  long& service_type,
453  CLID& clid,
454  std::string& address_trailer) const
455 {
456  // For address header, use xml-style format of
457  // <address_header service_type="xxx" clid="yyy" />
458  service_type = 0;
459  clid = 0;
460  address_trailer = "";
461 
462  // Check for address_header tag
463  size_t pos = address.find("<address_header");
464  if (std::string::npos != pos) {
465  // Get service_type
466  pos = address.find("service_type=\"");
467  if (std::string::npos != pos) {
468  pos += 14;
469  size_t end = address.find('"', pos);
470  if (std::string::npos != end) {
471  std::istringstream str(address.substr(pos, end-pos));
472  str >> service_type;
473  // Get clid
474  pos = address.find("clid=\"");
475  if (std::string::npos != pos) {
476  pos += 6;
477  end = address.find('\"', pos);
478  if (std::string::npos != end) {
479  str.clear(); // reuse the istringstream (the error flags must be explicitly cleared)
480  str.str(address.substr(pos, end-pos));
481  str >> clid;
482  // Get trailer_address
483  pos = address.find('>');
484  if (pos < (address.size()-2)) { // this means that '>' was found (pos != npos)
485  // it is before the last char
486  address_trailer = address.substr(pos+1);
487  }
488  }
489  }
490  }
491  }
492  }
493 }
494 
497  // The persistency service is a address creation dispatcher istelf.
498  // The persistency service can NEVER create addresses itself.
499  // The entry point must only be provided in order to fulfill the needs of the
500  // implementing interfaces.
501  return StatusCode::FAILURE;
502 }
503 
506  return m_addrCreator;
507 }
508 
510 StatusCode PersistencySvc::getService(long service_type, IConversionSvc*& refpSvc) {
511  refpSvc = service(service_type);
512  return (0==refpSvc) ? StatusCode::FAILURE : StatusCode::SUCCESS;
513 }
514 
517  const char* imp = service_type.c_str();
518  long len = service_type.length();
519  if ( ::strncasecmp(imp,"SICB", len) == 0 )
520  return getService(SICB_StorageType, refpSvc);
521  else if ( ::strncasecmp(imp,"ZEBRA", len) == 0 )
522  return getService(SICB_StorageType, refpSvc);
523  else if ( ::strncasecmp(imp,"MS Access", len) == 0 )
524  return getService(ACCESS_StorageType, refpSvc);
525  else if ( ::strncasecmp(imp,"Microsoft Access", strlen("Microsoft Access")) == 0 )
526  return getService(ACCESS_StorageType, refpSvc);
527  else if ( ::strncasecmp(imp,"SQL Server", len) == 0 )
528  return getService(SQLSERVER_StorageType, refpSvc);
529  else if ( ::strncasecmp(imp,"Microsoft ODBC for Oracle", len) == 0 )
530  return getService(ORACLE_StorageType, refpSvc);
531  else if ( ::strncasecmp(imp,"Oracle ODBC", strlen("Oracle ODBC")) == 0 )
532  return getService(ORACLE_StorageType, refpSvc);
533  else if ( ::strncasecmp(imp,"Oracle OCI", strlen("Oracle OCI")) == 0 )
534  return getService(ORACLE_StorageType, refpSvc);
535  else if ( ::strncasecmp(imp,"MySQL", len) == 0 )
536  return getService(MYSQL_StorageType, refpSvc);
537  else if ( ::strncasecmp(imp,"ROOT", len) == 0 )
538  return getService(ROOT_StorageType, refpSvc);
539  else if ( ::strncasecmp(imp,"OBJY", len) == 0 )
540  return getService(OBJY_StorageType, refpSvc);
541  else if ( ::strncasecmp(imp,"OBJYECTI", 7) == 0 )
542  return getService(OBJY_StorageType, refpSvc);
543  else if ( ::strncasecmp(imp,"POOL_ROOTKEY", 12) == 0 )
544  return getService(POOL_ROOTKEY_StorageType, refpSvc);
545  else if ( ::strncasecmp(imp,"POOL_ROOTTREE", 12) == 0 )
546  return getService(POOL_ROOTTREE_StorageType, refpSvc);
547  else if ( ::strncasecmp(imp,"POOL_ROOT", 9) == 0 )
548  return getService(POOL_ROOT_StorageType, refpSvc);
549  else if ( ::strncasecmp(imp,"POOL_MySQL", 8) == 0 )
550  return getService(POOL_MYSQL_StorageType, refpSvc);
551  else if ( ::strncasecmp(imp,"POOL_ORACLE", 8) == 0 )
552  return getService(POOL_ORACLE_StorageType, refpSvc);
553  else if ( ::strncasecmp(imp,"POOL_ACCESS", 8) == 0 )
554  return getService(POOL_ACCESS_StorageType, refpSvc);
555  else if ( ::strncasecmp(imp,"POOL", 4) == 0 )
556  return getService(POOL_StorageType, refpSvc);
557 
559  SmartIF<IService> svc((*i).second.conversionSvc());
560  if ( svc ) {
561  // Check wether this is already an active service: first check by service name
562  if ( svc->name() == service_type ) {
563  refpSvc = (*i).second.conversionSvc();
564  return StatusCode::SUCCESS;
565  }
566  // Check wether this is already an active service: now check by service type
567  if ( System::typeinfoName(typeid(*(svc.get()))) == service_type ) {
568  refpSvc = (*i).second.conversionSvc();
569  return StatusCode::SUCCESS;
570  }
571  }
572  }
574  // if not, check if the service is in the list and may be requested
575  for(std::vector<std::string>::const_iterator i=names.begin(); i != names.end(); i++) {
576  Gaudi::Utils::TypeNameString itm(*i);
577  if ( itm.name() == service_type || itm.type() == service_type ) {
578  IConversionSvc* svc = service(*i);
579  if ( svc ) {
580  refpSvc = svc;
581  return StatusCode::SUCCESS;
582  }
583  }
584  }
585  return StatusCode::FAILURE;
586 }
587 
590  return CLID_NULL;
591 }
592 
595  m_addrCreator = this; // initialize internal pointer to IAddressCreator interface
596  // Initialize basic service
597  StatusCode status = Service::initialize();
598  if ( UNLIKELY(!status.isSuccess()) ) {
599  error() << "Error initializing Service base class." << endmsg;
600  }
601  return status;
602 }
603 
606  // Release all workers
608  // Release references to this to avoid loops
609  m_addrCreator = 0;
610  return StatusCode::SUCCESS;
611 }
612 
614  DEBMSG << p << endmsg;
615 }
616 
618 bool PersistencySvc::enable(bool value)
619 {
620  bool old = m_enable;
621  m_enable = value;
622  return old;
623 }
624 
627 : base_class(name, svc),
628  m_cnvDefType(TEST_StorageType),
629  m_enable(true)
630 {
631  declareProperty("CnvServices", m_svcNames);
633 }
634 
637 }

Generated at Wed Nov 28 2012 12:17:11 for Gaudi Framework, version v23r5 by Doxygen version 1.8.2 written by Dimitri van Heesch, © 1997-2004