001 #include "PoolFileCatalogConnection.h"
002
003
004 #include "CollectionBase/ICollectionQuery.h"
005 #include "CollectionBase/ICollectionCursor.h"
006 #include "CollectionBase/CollectionFactory.h"
007 #include "CollectionBase/ICollection.h"
008 #include "CollectionBase/CollectionDescription.h"
009
010 #include "DataSvc/DataSvcFactory.h"
011 #include "DataSvc/IDataSvc.h"
012 #include "DataSvc/ICacheSvc.h"
013 #include "DataSvc/CacheEntry.h"
014 #include "DataSvc/AnyPtr.h"
015
016 #include "PersistencySvc/Placement.h"
017 #include "PersistencySvc/DatabaseConnectionPolicy.h"
018 #include "PersistencySvc/ITransaction.h"
019 #include "PersistencySvc/ISession.h"
020 #include "PersistencySvc/ITokenIterator.h"
021 #include "PersistencySvc/IContainer.h"
022 #include "PersistencySvc/IDatabase.h"
023 #include "PersistencySvc/IPersistencySvc.h"
024 #include "PersistencySvc/IPersistencySvcFactory.h"
025
026 #include "StorageSvc/DbType.h"
027
028 #include "FileCatalog/IFileCatalog.h"
029 #include "FileCatalog/IFCContainer.h"
030 #include "FileCatalog/URIParser.h"
031 #include "FileCatalog/FCEntry.h"
032 #include "FileCatalog/IFCAction.h"
033 #include "FileCatalog/FCLeaf.h"
034 #include "FileCatalog/FCImpl.h"
035 #include "FileCatalog/FCMetaImpl.h"
036
037 #include "DataSvc/RefBase.h"
038
039 #include "StorageSvc/DbReflex.h"
040
041 #include "AttributeList/AttributeList.h"
042 #include "POOLCore/POOLContext.h"
043
044
045 #include "PluginManager/PluginManager.h"
046 #include "SealBase/UUID.h"
047
048
049 #include "TileCalibKernel/IMainContext.h"
050
051 #include "TileCalibUtil/Timer.h"
052
053 #include "TileCalibDatasrc/IDataSourceManager.h"
054 #include "TileCalibDatasrc/DataHandle.h"
055
056 #include "PoolCatalogEntry.h"
057 #include "TileCalibPoolPlugin/AttributeListFuncs.h"
058
059 #include <iostream>
060 #include <sstream>
061 #include <ctype.h>
062
063 #include <TSystem.h>
064
065 const std::string c_empty = std::string("");
066
067 using namespace tilec::plugin::lcgpool;
068 using namespace tilec::datasrc;
069 using namespace tilec;
070
071 using ROOT::Reflex::Type;
072
073
074
075 PoolFileCatalogConnection::PoolFileCatalogConnection(const std::string &id,
076 IContext *ctx):
077 AbstractComponent(id,ctx),
078 m_isOpen(false),
079 m_writeLeaf(0),
080 m_readOnly(false),
081 m_persistSvc(0),
082 m_entryCache(0),
083 m_objectCache(0),
084 m_sealMsgLevel(4) {
085 init();
086 IDataSourceManager *dataMan = IDataSourceManager::instance();
087 if(dataMan != 0) {
088 m_entryCache = dataMan->getCache(ClassTool::getName(typeid(ICatalogEntry)), ClassTool::getName(typeid(CatalogKey)));
089 if(m_entryCache == 0) MsgError("PoolFileCatalogConnection() Error getting cache InstanceCache<ICatalogEntry,ObjectKey>");
090 m_objectCache = dataMan->getCache("tilec::datasrc::IObject","tilec::datasrc::ObjectKey");
091 if(m_objectCache == 0) MsgError("PoolFileCatalogConnection() Error getting cache InstanceCache");
092 }
093 else MsgError("PoolFileCatalogConnection() Can't get IOVObjectManager");
094
095
096
097 m_props.bind("SealMessageLevel",&m_sealMsgLevel);
098 m_props.bind("readOnly",&m_readOnly);
099 }
100
101 void
102 PoolFileCatalogConnection::init() {
103 MsgDebug("init() Initializing");
104 pool::POOLContext::loadComponent( "SEAL/Services/MessageService" );
105
106 pool::POOLContext::loadComponent( "CORAL/RelationalPlugins/mysql" );
107 pool::POOLContext::loadComponent( "CORAL/mysql/TypeConverter" );
108 pool::POOLContext::loadComponent( "CORAL/Services/EnvironmentAuthenticationService" );
109
110 pool::POOLContext::setMessageVerbosityLevel( (seal::Msg::Level)m_sealMsgLevel );
111 pool::ObjectDeletePolicy::GLOBAL_DEFAULT = pool::ObjectDeletePolicy::DONOT_DELETE;
112 }
113
114 PoolFileCatalogConnection::~PoolFileCatalogConnection() {
115 MsgDebug("Deleting");
116 }
117
118
119
120 void
121 PoolFileCatalogConnection::getData(DataHandle &pt) {
122 const std::type_info &dataType(pt.type());
123 if(pt.key() == 0) {
124 MsgError("getData() The pointer has no key!");
125 return;
126 }
127 if(dataType == typeid(ICatalogEntry)) {
128 try {
129 const CatalogKey *key(dynamic_cast<const CatalogKey*>(pt.key()));
130 if(key == 0) {
131 MsgError("getData() Can't get key "<<pt.key()<<" as CatalogKey");
132 return;
133 }
134 MsgDebug("getData() Getting data for key: "<<*key);
135 if(key->getEntryType() == CatalogKey::FID) pt.setPtr(getEntryByFID(key->getID()),typeid(ICatalogEntry));
136 else if(key->getEntryType() == CatalogKey::PFN) pt.setPtr(getEntryByPFN(key->getID()),typeid(ICatalogEntry));
137 else MsgWarning("getData() get by LFN not implemented");
138 }
139 catch(std::exception &e) {
140 MsgError("getData() Exception while getting data : "<<e.what());
141 }
142 }
143 else {
144 RawObject ro(getRawObject(pt.key()->getID()));
145 pt.setPtr(ro.ptr(),ro.type());
146 }
147 }
148
149 void
150 PoolFileCatalogConnection::eraseData(DataHandle &pt) {
151 const std::type_info &dataType(pt.type());
152 if(pt.key() == 0) {
153 MsgError("eraseData() The key is 0");
154 return;
155 }
156 if(dataType == typeid(ICatalogEntry)) {
157 try {
158 ICatalogEntry *entry = reinterpret_cast<ICatalogEntry*>(pt.ptr());
159 if(entry != 0) {
160 if(entry->getType() == ICatalogEntry::PFNEntry) {
161 MsgDebug("eraseData() Deleting PFN entry: "<<entry->getPFN()<<" with FID='"<<entry->getGUID()<<"'");
162 deleteFID(entry->getGUID());
163 }
164 else MsgWarning("eraseData() Not implemented for LFN and FID");
165 }
166 else MsgError("eraseData() Entry to delete is 0");
167 }
168 catch(std::exception &e) {
169 MsgError("eraseData() std::exception caught: "<<e.what());
170 }
171 }
172 else MsgWarning("eraseData() not implemented for type='"<<ClassTool::getName(dataType)<<"' with key='"<<pt.key()<<"'");
173 }
174
175 void
176 PoolFileCatalogConnection::writeData(DataHandle &pt) {
177 const std::type_info &dataType(pt.type());
178 if(pt.key() == 0) {
179 MsgError("writeData() The key is 0");
180 return;
181 }
182 if(dataType == typeid(ICatalogEntry)) {
183 try {
184 const CatalogKey *key(dynamic_cast<const CatalogKey*>(pt.key()));
185 if(key == 0) {
186 MsgError("writeData() The key if not a CatalogKey");
187 return;
188 }
189 MsgDebug("writeData() Writing with key: "<<*key);
190 if(key->getEntryType() == CatalogKey::PFN) {
191 std::string fid;
192
193 PoolCatalogEntry *entr = getEntryByPFN(key->getID(),true);
194 if(entr == 0) {
195 MsgDebug("writeData() Entry for PFN='"<<key->getID()<<"' not found, creating");
196 pt.setPtr(registerPFN(key->getID(),"",fid),typeid(ICatalogEntry));
197
198 }
199 else {
200
201 pt.setPtr(entr,typeid(ICatalogEntry));
202 }
203
204
205 }
206 else MsgError("writeData() Writing by FID or LFN not supported");
207 }
208 catch(std::exception &e) {
209 MsgError("writeData() Exception while writing : "<<e.what());
210 }
211 }
212 else MsgError("writeData() not implemented for "<<ClassTool::getName(dataType));
213 }
214
215 bool
216 PoolFileCatalogConnection::hasData(DataHandle &) {
217 MsgWarning("hasData() not implemented");
218 return true;
219 }
220
221 void
222 PoolFileCatalogConnection::returnData(DataHandle &pt) {
223 MsgWarning("returnData() I don't want any returned pointers, but I got "<<pt);
224 }
225
226 void
227 PoolFileCatalogConnection::newInstance(DataHandle &) {
228 MsgWarning("newInstance() Not supported");
229 }
230
231
232
233 bool
234 PoolFileCatalogConnection::listByPFN(const std::string& query, std::vector<CatalogEntry> &dst) {
235 try {
236 MsgDebug("listByPFN() Getting PFN list by query '"<<query<<"' # read cats:"<<m_catalog->nReadCatalogs());
237
238 pool::FClookup action;
239 m_catalog->setAction(action);
240 pool::PFNContainer pfnCnt(m_catalog);
241 m_catalog->start();
242 action.lookupPFNByQuery(query,pfnCnt);
243 ICatalogEntry *poolEntry(0);
244 CatalogKey key("");
245 while(pfnCnt.hasNext()) {
246 pool::PFNEntry pentry = pfnCnt.Next();
247 key = CatalogKey(pentry.guid());
248 if(m_entryCache->hasInstance(key)) poolEntry = m_entryCache->get<ICatalogEntry>(key);
249 else {
250 poolEntry = new PoolCatalogEntry(const_cast<PoolFileCatalogConnection*>(this),pentry.guid(),pentry.pfname(),pentry.filetype());
251
252 try {
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272 }
273 catch(std::exception &ex) {
274 MsgError("listByPFN() Exception: "<<ex.what());
275 }
276 }
277 MsgDebug("listByPFN() got file "<<*poolEntry);
278 dst.push_back(m_entryCache->addInstance<ICatalogEntry,CatalogKey>(poolEntry,key,this));
279 }
280 m_catalog->commit();
281 return true;
282 }
283 catch (std::exception &er) {
284 MsgError("listByPFN() Error: SEAL exception: " << er.what() );
285 try {
286 m_catalog->rollback();
287 }
288 catch(std::exception &ex) {
289 MsgError("listByPFN() Error rolling back transaction: "<<ex.what());
290 }
291 return false;
292 }
293 }
294
295 bool
296 PoolFileCatalogConnection::registerPFN(const std::string &pfn, const std::string &guid) {
297 std::string guidStr;
298 if(guid.empty()) {
299
300 seal::UUID ui = seal::UUID::generate();
301 char uuidBuff[37];
302 ui.format(uuidBuff);
303 for(int i=0;i<37;i++) uuidBuff[i] = toupper(uuidBuff[i]);
304 guidStr = uuidBuff;
305 MsgVerbose("registerPFN() GUID is empty, generating '"<<guidStr<<"'");
306 }
307 else guidStr = guid;
308 MsgDebug("registerPFN() Registering PFN='"<<pfn<<"' with UUID='"<<guidStr<<"'");
309 std::string ftype("ROOT_All");
310 return (registerPFN(pfn,ftype,guidStr) != 0);
311 }
312
313 CatalogEntry
314 PoolFileCatalogConnection::getByPFN(const std::string &pfn) {
315 PoolCatalogEntry *entry = getEntryByPFN(pfn);
316 if(entry != 0) return m_entryCache->addInstance<ICatalogEntry,CatalogKey>(entry,entry->getGUID(),this);
317 else return 0;
318 }
319
320 bool
321 PoolFileCatalogConnection::isPFNRegistered(const std::string &pfn) {
322 return getByPFN(pfn);
323 }
324
325
326 bool
327 PoolFileCatalogConnection::isOpen() {
328 return m_isOpen;
329 }
330
331 bool
332 PoolFileCatalogConnection::open() {
333 if(isOpen()) {
334 MsgWarning("open() Connection with id='"<<getID()<<"' is already open");
335 return false;
336 }
337 try {
338
339 MsgInfo("open() Opening connection with id='"<<getID()<<"'");
340
341 m_catalog = new pool::IFileCatalog;
342
343
344 g_main->setEnv("CORAL_AUTH_USER",getProperty("UserName"));
345
346 g_main->setEnv("CORAL_AUTH_PASSWORD",getProperty("Password"));
347
348
349 std::ostringstream connStrOut;
350 connStrOut<<getProperty("Technology")<<"://";
351
352 if(m_props.hasProperty("HostName")) connStrOut<<getProperty("HostName")<<"/";
353 connStrOut<<getProperty("DBName");
354
355 std::string catalogConnStr(connStrOut.str());
356 pool::URIParser p(catalogConnStr);
357 MsgDebug("open() Connecting to catalog '"<<catalogConnStr<<"' read only='"<<m_readOnly<<"'");
358 p.parse();
359
360 if(m_readOnly) m_catalog->addReadCatalog( p.contactstring() );
361 else m_catalog->setWriteCatalog( p.contactstring() );
362
363 m_writeLeaf = static_cast<pool::FCLeaf*>(m_catalog->getWriteCatalog());
364 m_catalog->connect();
365
366
367 m_dataSvc = pool::DataSvcFactory::instance(m_catalog);
368
369
370 pool::DatabaseConnectionPolicy policy;
371 policy.setWriteModeForNonExisting( pool::DatabaseConnectionPolicy::CREATE );
372 policy.setWriteModeForExisting( pool::DatabaseConnectionPolicy::UPDATE );
373 policy.setReadMode( pool::DatabaseConnectionPolicy::UPDATE );
374 m_dataSvc->session().setDefaultConnectionPolicy( policy );
375
376
377 pool::IPersistencySvcFactory *pfact = pool::IPersistencySvcFactory::get();
378 if(pfact != 0) {
379 m_persistSvc = pfact->create("PersistencySvc",*m_catalog);
380
381 if(m_persistSvc != 0) {
382 m_persistSvc->session().setDefaultConnectionPolicy( policy );
383
384
385
386
387
388
389 }
390 else MsgError("open() no IPersistencySvc created");
391 }
392 else MsgError("open() couldn't get IPersistencySvcFactory");
393 }
394 catch (std::exception &e) {
395 MsgError("open() Exception:"<< e.what());
396 throw ConnectionException(std::string("Could not make connection ")+e.what(),getID());
397 }
398 m_isOpen = true;
399 return true;
400 }
401
402 void
403 PoolFileCatalogConnection::finalize() {
404 if(m_isOpen) close();
405 }
406
407 bool
408 PoolFileCatalogConnection::close() {
409 MsgInfo("close() Closing connection with id='"<<getID()<<"'");
410 try {
411
412
413 m_dataSvc->session().disconnectAll();
414 m_catalog->disconnect();
415 }
416 catch(std::exception &e) {
417 MsgError("close() Exception while closing: "<<e.what());
418 }
419 delete m_persistSvc;
420 m_persistSvc = 0;
421 delete m_dataSvc;
422 m_dataSvc = 0;
423 delete m_catalog;
424 m_catalog = 0;
425 m_isOpen = false;
426 return true;
427 }
428
429 DataPointer
430 PoolFileCatalogConnection::getObject(const std::string &token) const {
431 MsgDebug("getObject() Getting obj with token "<<token);
432 ObjectKey tKey(token);
433 if(m_objectCache->has(tKey)) {
434 return m_objectCache->getInstance(tKey);
435 }
436 else {
437
438
439 RawObject ro(getRawObject(token));
440 return m_objectCache->registerInstance(ro.ptr(),ObjectKey(token),const_cast<PoolFileCatalogConnection*>(this));
441
442 }
443 }
444
445
446
447 RawObject
448 PoolFileCatalogConnection::getRawObject(const std::string &token) const {
449 TileCStartTimer("PoolFileCatalogConnection::getRawObject");
450 try {
451 MsgDebug("getRawObject() Getting object with token '"<<token<<"'");
452
453 pool::Token tok;
454 tok.fromString(token);
455 MsgDebug("getRawObject() classid="<<tok.classID().toString());
456
457 ROOT::Reflex::Type cltype(getClassForToken(&tok));
458 if(!cltype) {
459 MsgError("getRawObject() No class found for GUID="<<tok.classID().toString());
460 TileCStopTimer("PoolFileCatalogConnection::getRawObject");
461 return RawObject(0,typeid(void));
462 }
463
464
465 m_catalog->start();
466
467
468
469
470
471 m_persistSvc->session().transaction().start(pool::ITransaction::READ);
472 std::pair<void*,ROOT::Reflex::Type> data(m_persistSvc->readObject(cltype,tok));
473 void *obj = data.first;
474 MsgDebug("getRawObject() got object @"<<obj<<" of type "<<data.second.Name());
475 m_persistSvc->session().transaction().commit();
476
477
478 m_catalog->commit();
479
480 TileCStopTimer("PoolFileCatalogConnection::getRawObject");
481 return RawObject(obj,cltype.TypeInfo());
482 }
483 catch(std::exception &e) {
484 MsgError("getRawObject() Seal exception caught: "<<e.what());
485 try {
486 m_catalog->rollback();
487 m_dataSvc->transaction().rollback();
488 }
489 catch(std::exception &ex) {
490 MsgError("getRawObject() Error rolling back transaction: "<<ex.what());
491 }
492 }
493 TileCStopTimer("PoolFileCatalogConnection::getRawObject");
494 return RawObject(0,typeid(void));
495 }
496
497 void
498 PoolFileCatalogConnection::renamePFN(const std::string &src, const std::string &dst) {
499 try {
500 MsgVerbose("renamePFN() Renaming Src PFN='"<<src<<"' to Dst PFN='"<<dst<<"'");
501 pool::FCregister a;
502 m_catalog->setAction(a);
503 m_catalog->start();
504 a.renamePFN(src,dst);
505 m_catalog->commit();
506 MsgVerbose("renamePFN() Done renaming");
507 }
508 catch(std::exception &e) {
509 MsgError("renamePFN() Exception while renaming PFN: "<<e.what());
510 try {
511 m_catalog->rollback();
512 }
513 catch(std::exception &ex) {
514 MsgError("renamePFN() Error rolling back transaction: "<<ex.what());
515 }
516 }
517 }
518
519 PoolCatalogEntry*
520 PoolFileCatalogConnection::registerPFN(const std::string &pfn,
521 const std::string &ft,
522 std::string &fid) {
523 try {
524 std::string fileType(ft);
525 if(fileType.empty()) fileType="ROOT_All";
526
527 MsgVerbose("registerPFN() Registering PFN='"<<pfn<<"' with type='"<<fileType<<"' and FID='"<<fid<<"'");
528
529 if(fid.empty() && m_writeLeaf) {
530 pool::IFCAction a;
531 m_catalog->setAction(a);
532 m_catalog->start();
533 a.registerPFN(pfn,fileType,fid);
534 m_catalog->commit();
535 return new PoolCatalogEntry(const_cast<PoolFileCatalogConnection*>(this),fid,pfn,fileType);
536 }
537
538 else {
539 pool::FCImpl* fcImpl = m_writeLeaf->getImpl();
540
541 if(!fcImpl) {
542 MsgError("registerPFN() No FCImpl found");
543 return false;
544 }
545 m_catalog->start();
546 pool::PFNEntry pentry(pfn,fid,fileType);
547 fcImpl->insertPFN(pentry);
548 m_catalog->commit();
549 return new PoolCatalogEntry(const_cast<PoolFileCatalogConnection*>(this),fid,pfn,fileType);
550 }
551 }
552 catch(std::exception &e) {
553 MsgError("registerPFN() Exception while registering PFN: "<<e.what());
554 try {
555 m_catalog->rollback();
556 }
557 catch(std::exception &ex) {
558 MsgError("registerPFN() Error rolling back transaction: "<<ex.what());
559 }
560 return 0;
561 }
562 }
563
564 PoolCatalogEntry*
565 PoolFileCatalogConnection::getEntryByFID(const std::string &fileId) const {
566 MsgVerbose("getEntryByFID() Getting by fid '"<<fileId<<"'");
567 PoolCatalogEntry *poolEntry = 0;
568 try {
569 pool::FClookup action;
570 m_catalog->setAction(action);
571 m_catalog->start();
572 std::string pfn;
573 std::string fileType;
574 action.lookupBestPFN(fileId, pool::FileCatalog::READ,pool::FileCatalog::RANDOM, pfn,fileType);
575 m_catalog->commit();
576 poolEntry = new PoolCatalogEntry(const_cast<PoolFileCatalogConnection*>(this),fileId,pfn,fileType);
577
578
579
580
581
582
583
584
585 return poolEntry;
586 }
587 catch (std::exception &er) {
588 MsgError("getEntryByFID() Error: SEAL exception: " << er.what() );
589 try {
590 m_catalog->rollback();
591 }
592 catch(std::exception &ex) {
593 MsgError("getEntryByFID() Error rolling back transaction: "<<ex.what());
594 }
595 if(poolEntry != 0) delete poolEntry;
596 return 0;
597 }
598 }
599
600 PoolCatalogEntry*
601 PoolFileCatalogConnection::getEntryByPFN(const std::string &pfn, bool silent) const {
602 try {
603 MsgDebug("getEntryByPFN() Getting entry for PFN='"<<pfn<<"'");
604 pool::FClookup action;
605 m_catalog->setAction(action);
606 m_catalog->start();
607
608 pool::FileCatalog::FileID fid;
609 std::string ftype;
610 action.lookupFileByPFN(pfn,fid,ftype);
611
612
613
614
615
616
617
618
619
620
621
622 m_catalog->commit();
623 if(fid.empty() || ftype.empty()) {
624 if(!silent) MsgWarning("getEntryByPFN() No valid fid or ftype found for PFN='"<<pfn<<"'");
625 return 0;
626 }
627 else {
628 MsgDebug("getEntryByPFN() Got FID='"<<fid<<"' File type='"<<ftype<<"' for PFN='"<<pfn<<"'");
629
630 PoolCatalogEntry *poolEntry = new PoolCatalogEntry(const_cast<PoolFileCatalogConnection*>(this),fid,pfn,ftype);
631
632 return poolEntry;
633 }
634 }
635 catch (std::exception &er) {
636 MsgError("getEntryByPFN() Error while quering for PFN: SEAL exception: " << er.what() );
637 try {
638 m_catalog->rollback();
639 }
640 catch(std::exception &er2) {
641 MsgError("getEntryByPFN() Error committing transaction: "<<er2.what());
642 }
643 return 0;
644 }
645 }
646
647
648
649
650 bool
651 PoolFileCatalogConnection::getCollection(const PoolCatalogEntry *entr,
652 const std::string &collName,
653 std::vector<DataPointer> &dst) {
654 if(entr == 0) {
655 MsgError("getCollection() Given CatalogEntry is 0");
656 return false;
657 }
658 try {
659
660 std::string dataLoc(entr->getDataLocation());
661 MsgDebug("getCollection() Getting collection named '"<<collName<<"' with location '"<<dataLoc<<"' from entry:"<<*entr);
662 m_catalog->start();
663 m_dataSvc->transaction().start( pool::ITransaction::READ );
664
665 pool::CollectionFactory *fact = pool::CollectionFactory::get();
666 if(fact == 0) {
667 MsgError("getCollection() No CollectionFactory found");
668 return false;
669 }
670
671 pool::CollectionDescription desc( collName, "ImplicitCollection", dataLoc );
672 pool::ICollection *coll = fact->create(
673 "ImplicitCollection",
674 desc,
675 pool::ICollection::READ,
676 &m_dataSvc->session() );
677 if(coll == 0) {
678 MsgError("getCollection() No collection with name '"<<collName<<"' connection='"<<dataLoc<<"' found");
679 return false;
680 }
681 std::auto_ptr<pool::ICollectionQuery> query ( coll->newQuery() );
682 pool::ICollectionCursor &cursor = query->execute();
683 std::string token;
684 void *obj;
685
686 while( cursor.next() ) {
687 const pool::Token &ref = cursor.eventRef();
688 token = ref.toString();
689 ROOT::Reflex::Type cltype( getClassForToken( &ref ) );
690 if(cltype) {
691 pool::RefBase condObj( m_dataSvc, &ref, cltype.TypeInfo() );
692 obj = condObj.object().ptr();
693
694
695 dst.push_back(m_objectCache->registerInstance(obj,ObjectKey(token),const_cast<PoolFileCatalogConnection*>(this),cltype.TypeInfo()));
696 MsgVerbose("getCollection() Found object: @"<<obj<<" with token "<<token);
697 }
698 else MsgError("getCollection() Can't find class for GUID='"<< ref.classID().toString());
699 }
700 m_catalog->commit();
701 m_dataSvc->transaction().commit();
702 return true;
703 }
704 catch (std::exception &er) {
705 MsgError("getCollection() Error: SEAL exception: " << er.what());
706 try {
707 m_catalog->rollback();
708 m_dataSvc->transaction().rollback();
709 }
710 catch(std::exception &ex) {
711 MsgError("getCollection() Error rolling back transaction: "<<ex.what());
712 }
713 return false;
714 }
715 }
716
717 void
718 PoolFileCatalogConnection::writeObject(DataPointer obj,
719 const std::string &container,
720 const PoolCatalogEntry *entry,
721 std::string &tokenOut) {
722 if(!obj.isValid()) {
723 MsgError("writeObject() Object is invalid");
724 return;
725 }
726 if(entry == 0) {
727 MsgError("writeObject() The entry is 0");
728 return;
729 }
730 try {
731
732
733
734 ROOT::Reflex::Type ctype(ROOT::Reflex::Type::ByTypeInfo(obj.getClassType()));
735 MsgDebug("writeObject() Writing obj '"<<obj
736 <<"' into container '"<<container
737 <<"' in entry '"<<*entry
738 <<"' with class='"<<ctype.Name()<<"'");
739
740 if(!entry->fileExists()) {
741 MsgDebug("writeObject() The file '"<<*entry<<"' doesn't exist but is registered, removing");
742 deleteFID(entry->getGUID());
743 }
744
745 pool::Placement place;
746 if(entry->getType() == ICatalogEntry::PFNEntry) {
747 place.setDatabase(entry->getPFN(),pool::DatabaseSpecification::PFN);
748 }
749 else {
750 place.setDatabase(entry->getLFN(),pool::DatabaseSpecification::LFN);
751 }
752 place.setShapeID(ctype);
753 place.setContainerName(container);
754
755 place.setTechnology(pool::ROOTTREE_StorageType.type());
756
757 m_catalog->start();
758
759
760 MsgVerbose("writeObject() Placement created: dbname='"<<place.databaseName()
761 <<"' conainer='"<<place.containerName()
762 <<"' shapeID='"<<place.shapeID().Name()<<"'");
763
764
765
766
767 m_persistSvc->session().transaction().start(pool::ITransaction::UPDATE);
768 pool::Token *token = m_persistSvc->registerForWrite(place,obj.getPtr(),ctype);
769 m_persistSvc->session().transaction().commit();
770 if(token != 0) {
771 tokenOut = token->toString();
772 delete token;
773 }
774 else MsgError("writeObject() no token returned");
775
776
777 m_catalog->commit();
778
779
780 if(!token) {
781 MsgError("writeObject() No token found for new object!");
782 return;
783 }
784
785 MsgVerbose("writeObject() Written object token '"<<tokenOut<<"'");
786 m_objectCache->registerInstance(obj.getPtr(),ObjectKey(tokenOut),const_cast<PoolFileCatalogConnection*>(this));
787 }
788 catch(std::exception &e) {
789 MsgError("writeObject() SealException caught: "<<e.what());
790 try {
791 m_catalog->rollback();
792 m_dataSvc->transaction().rollback();
793 }
794 catch(std::exception &ex) {
795 MsgError("writeObject() Error rolling back transaction: "<<ex.what());
796 }
797 }
798 }
799
800 void
801 PoolFileCatalogConnection::writeObjects(std::vector<DataPointer> objVec,
802 const std::string &container,
803 const PoolCatalogEntry *entry,
804 std::vector<std::string> &tokens) {
805 if(entry == 0) {
806 MsgError("writeObjects() The entry is 0");
807 return;
808 }
809 if(objVec.empty()) {
810 MsgError("writeObjects() obj vector empty");
811 return;
812 }
813 try {
814 ROOT::Reflex::Type ctype(ROOT::Reflex::Type::ByTypeInfo(objVec[0].getClassType()));
815 MsgDebug("writeObjects() Writing #"<<objVec.size()
816 <<" objects into container '"<<container
817 <<"' in entry '"<<*entry<<"' class='"
818 <<ctype.Name()<<"'");
819
820
821 if(!entry->fileExists()) {
822 MsgDebug("writeObjects() The file '"<<*entry<<"' doesn't exist but is registered, removing");
823 deleteFID(entry->getGUID());
824 }
825
826
827 pool::Placement place;
828 if(entry->getType() == ICatalogEntry::PFNEntry) {
829 place.setDatabase(entry->getPFN(),pool::DatabaseSpecification::PFN);
830 }
831 else {
832 place.setDatabase(entry->getLFN(),pool::DatabaseSpecification::LFN);
833 }
834 place.setShapeID(ctype);
835 place.setContainerName(container);
836
837 place.setTechnology(pool::ROOTTREE_StorageType.type());
838
839 m_catalog->start();
840 m_persistSvc->session().transaction().start(pool::ITransaction::UPDATE);
841
842
843 MsgVerbose("writeObjects() Placement created: dbname='"<<place.databaseName()
844 <<"' conainer='"<<place.containerName()
845 <<"' shapeID='"<<place.shapeID().Name()<<"'");
846 unsigned int size(objVec.size());
847 tokens.resize(size);
848 for(unsigned int i=0;i<size;i++) {
849
850 if(objVec[i].isValid()) {
851 MsgVerbose("writeObjects() Writing object: "<<objVec[i]);
852
853
854
855
856
857 pool::Token *token = m_persistSvc->registerForWrite(place,objVec[i].getPtr(),ctype);
858 if(token != 0) {
859 tokens[i] = token->toString();
860 delete token;
861 MsgDebug("writeObjects() Written object '"<<objVec[i]<<"' token '"<<tokens[i]<<"'");
862 m_objectCache->registerInstance(objVec[i].getPtr(),ObjectKey(tokens[i]),const_cast<PoolFileCatalogConnection*>(this));
863 }
864 else MsgError("writeObjects() No token found for new object!");
865 }
866 else MsgError("writeObject() Object is invalid");
867 }
868
869 m_persistSvc->session().transaction().commit();
870 m_catalog->commit();
871 }
872 catch(std::exception &e) {
873 MsgError("writeObjects() SealException caught: "<<e.what());
874 try {
875 m_catalog->rollback();
876 m_dataSvc->transaction().rollback();
877 }
878 catch(std::exception &ex) {
879 MsgError("writeObjects() Error rolling back transaction: "<<ex.what());
880 }
881 }
882 }
883
884 std::string
885 PoolFileCatalogConnection::getAddress(DataPointer vec) {
886
887 const IObjectKey *key = vec.getKey();
888 if(key != 0) return key->getID();
889 else {
890 MsgError("getAddress() No key found for ptr: "<<vec);
891 return "";
892 }
893 }
894
895 void
896 PoolFileCatalogConnection::getContainers(std::vector<ICatalogEntry::IContainer> &dst,const PoolCatalogEntry *entry) {
897 try {
898 MsgDebug("getContainers() Getting for entry: "<<*entry);
899
900 m_catalog->start();
901 m_dataSvc->transaction().start(pool::ITransaction::READ);
902
903 pool::IDatabase *db(0);
904 if(entry->getType() == ICatalogEntry::PFNEntry) {
905 db = m_dataSvc->session().databaseHandle(entry->getPFN() ,pool::DatabaseSpecification::PFN);
906 }
907 else {
908 db = m_dataSvc->session().databaseHandle(entry->getLFN() ,pool::DatabaseSpecification::LFN);
909 }
910 if(db == 0) {
911 MsgError("getContainers() No database service for entry: "<<*entry);
912 return;
913 }
914 db->setTechnology( pool::DbType::getType(entry->getFileType()).type() );
915 db->connectForRead();
916
917 std::vector< std::string > cnts = db->containers();
918 dst.reserve(cnts.size());
919 std::vector< std::string >::const_iterator begin(cnts.begin());
920 std::vector< std::string >::const_iterator end(cnts.end());
921 pool::IContainer* cnt(0);
922 pool::ITokenIterator * tokenIter(0);
923 pool::Token *token(0);
924
925 for(;begin != end;++begin) {
926 cnt = db->containerHandle( *begin );
927 if(cnt != 0) {
928 MsgDebug("getContainers() Container '"<<cnt->name()<<"'");
929 dst.push_back(ICatalogEntry::IContainer(cnt->name()));
930 tokenIter = cnt->tokens( "" );
931 if(tokenIter != 0) {
932 while ((token = tokenIter->next()) != 0 ) {
933 ROOT::Reflex::Type cltype(getClassForToken(token));
934 if(cltype) {
935 dst.back().m_objects.push_back(m_objectCache->registerForFetch(ObjectKey(token->toString()),cltype.TypeInfo(),this));
936 }
937 else MsgError("getContainers() No SEAL class found for GUID '"<<token->classID().toString()<<"'");
938 token->release();
939 }
940 }
941 }
942 }
943 db->disconnect();
944 m_dataSvc->transaction().commit();
945 m_catalog->commit();
946 }
947 catch(std::exception &e) {
948 MsgError("getContainers() SealException caught: "<<e.what());
949 try {
950 m_catalog->rollback();
951 m_dataSvc->transaction().rollback();
952 }
953 catch(std::exception &ex) {
954 MsgError("getContainers() Error rolling back transaction: "<<ex.what());
955 }
956 }
957 }
958
959 void
960 PoolFileCatalogConnection::updateMeta(PoolCatalogEntry *entry) {
961 try {
962 pool::MetaDataEntry spec;
963 {
964 pool::FCAdmin adm;
965 m_catalog->setAction(adm);
966 m_catalog->start();
967 adm.getMetaDataSpec(spec);
968 AttributeListFuncs::updateAttributeSpec(entry->metaData(),spec.spec());
969 adm.updateMetaDataSpec(spec);
970 m_catalog->commit();
971 }
972 {
973 pool::FCregister reg;
974 m_catalog->setAction(reg);
975 m_catalog->start();
976 AttributeListFuncs::getAttributeList(entry->metaData(),spec.attrs());
977 reg.registerMetaData(entry->getGUID(),spec);
978 m_catalog->commit();
979 }
980 }
981 catch(std::exception &e) {
982 MsgError("updateMeta() SealException caught: "<<e.what());
983 try {
984 m_catalog->rollback();
985 }
986 catch(std::exception &ex) {
987 MsgError("updateMeta() Error rolling back transaction: "<<ex.what());
988 }
989 }
990 }
991
992 void
993 PoolFileCatalogConnection::printAttributes(const std::string &db) {
994 try {
995 m_catalog->start();
996 m_persistSvc->session().transaction().start(pool::ITransaction::READ);
997 pool::ISession &session(m_persistSvc->session());
998 pool::IDatabase *database(session.databaseHandle(db,pool::DatabaseSpecification::PFN));
999
1000 if(database == 0) {
1001 MsgError("printAttributes() no database");
1002 m_persistSvc->session().transaction().commit();
1003 return;
1004 }
1005
1006 if(database->openMode() == pool::IDatabase::CLOSED) {
1007 database->connectForRead();
1008 }
1009
1010 long tech(database->technology());
1011 pool::ITechnologySpecificAttributes &sessAttr(session.technologySpecificAttributes(tech));
1012 pool::ITechnologySpecificAttributes &dbAttrs(database->technologySpecificAttributes());
1013
1014 MsgDebug("-------------------------------------------");
1015 MsgDebug("db='"<<db<<"' technology="<<tech);
1016
1017 printTechAttr<int>("DEFAULT_COMPRESSION",sessAttr);
1018 printTechAttr<int>("DEFAULT_SPLITLEVEL",sessAttr);
1019 printTechAttr<int>("DEFAULT_AUTOSAVE",sessAttr);
1020 printTechAttr<int>("DEFAULT_BUFFERSIZE",sessAttr);
1021 printTechAttr<int>("NUM_CLASSES",sessAttr);
1022 printTechAttr<int>("NUM_TYPES",sessAttr);
1023 printTechAttr<int>("ERRNO",sessAttr);
1024 printTechAttr<int>("TREE_MAX_SIZE",sessAttr);
1025
1026 MsgDebug(">Database attributes:");
1027 printTechAttr<int>("DEFAULT_COMPRESSION", dbAttrs);
1028 printTechAttr<int>("DEFAULT_SPLITLEVEL", dbAttrs);
1029 printTechAttr<int>("DEFAULT_AUTOSAVE", dbAttrs);
1030 printTechAttr<int>("DEFAULT_BUFFERSIZE", dbAttrs);
1031 printTechAttr<int>("COMPRESSION_LEVEL", dbAttrs);
1032 printTechAttr<double>("COMPRESSION_FACTOR", dbAttrs);
1033 printTechAttr<int>("BEST_BUFFER", dbAttrs);
1034 printTechAttr<double>("BYTES_WRITTEN", dbAttrs);
1035 printTechAttr<double>("BYTES_READ", dbAttrs);
1036 printTechAttr<int>("BYTES_FREE", dbAttrs);
1037 printTechAttr<int>("BYTES_INFO", dbAttrs);
1038 printTechAttr<int>("BYTES_KEYS", dbAttrs);
1039 printTechAttr<int>("NKEYS", dbAttrs);
1040 printTechAttr<double>("FILEBYTES_WRITTEN", dbAttrs);
1041 printTechAttr<double>("FILEBYTES_READ", dbAttrs);
1042 printTechAttr<int>("FILE_DESCRIPTOR", dbAttrs);
1043 printTechAttr<int>("FILE_VERSION", dbAttrs);
1044 printTechAttr<long>("FILE_SIZE", dbAttrs);
1045 printTechAttr<int>("FILE_ERROR", dbAttrs);
1046 printTechAttr<long>("FILE_END", dbAttrs);
1047 printTechAttr<void*>("FILE_KEYS", dbAttrs);
1048 printTechAttr<void*>("TFILE", dbAttrs);
1049 printTechAttr<long>("TREE_MAX_SIZE", dbAttrs);
1050
1051 MsgDebug("-------------------------------------------");
1052
1053 std::vector<std::string> conts(database->containers());
1054 std::vector<std::string>::iterator begin(conts.begin());
1055 std::vector<std::string>::iterator end(conts.end());
1056 for(; begin != end; ++begin) {
1057 pool::IContainer *cont = database->containerHandle(*begin);
1058 pool::ITechnologySpecificAttributes &contAttrs(cont->technologySpecificAttributes());
1059
1060 MsgDebug("--- Container '"<<*begin<<"' technology="<<cont->technology());
1061 if(cont->technology() == pool::ROOTTREE_StorageType.type()) {
1062 MsgDebug("Container of type ROOTTree");
1063 printTechAttr<void*>("TREE", contAttrs);
1064 printTechAttr<int>("TREE_ENTRIES", contAttrs);
1065 printTechAttr<int>("TREE_NBRANCHES", contAttrs);
1066 printTechAttr<double>("TREE_TOTAL_BYTES", contAttrs);
1067 printTechAttr<double>("TREE_ZIP_BYTES", contAttrs);
1068 printTechAttr<int>("TREE_FILE_NUMBER", contAttrs);
1069 printTechAttr<int>("TREE_MAX_SIZE", contAttrs);
1070 printTechAttr<int>("TREE_MAX_VIRTUAL_SIZE", contAttrs);
1071
1072 unsigned int branches = cont->technologySpecificAttributes().attribute<int>("TREE_NBRANCHES");
1073 for(unsigned int iBranches = 0; iBranches < branches; ++iBranches) {
1074 std::string branch(begin->substr(begin->find('_') + 1));
1075 MsgDebug("----- Branch '"<<branch<<"'");
1076 printTechAttr<void*>("BRANCH", contAttrs, branch);
1077 printTechAttr<int>("BRANCH_ENTRIES", contAttrs, branch);
1078 printTechAttr<int>("BRANCH_MAX_BASKETS", contAttrs, branch);
1079 printTechAttr<int>("BRANCH_BASKET_SIZE", contAttrs, branch);
1080 printTechAttr<double>("BRANCH_TOTAL_SIZE", contAttrs, branch);
1081 printTechAttr<double>("BRANCH_TOTAL_BYTES", contAttrs, branch);
1082 printTechAttr<double>("BRANCH_ZIP_BYTES", contAttrs, branch);
1083 printTechAttr<int>("BRANCH_COMPRESSION_LEVEL", contAttrs, branch);
1084 printTechAttr<int>("BRANCH_NLEAVES", contAttrs, branch);
1085 printTechAttr<int>("BRANCH_SPLIT_LEVEL", contAttrs, branch);
1086 }
1087 }
1088 else if(cont->technology() == pool::ROOTKEY_StorageType.type()) {
1089 MsgDebug("Container of type ROOTKey");
1090
1091 printTechAttr<void*>("DIRECTORY", contAttrs);
1092 printTechAttr<void*>("DIR_MOTHER", contAttrs);
1093 printTechAttr<void*>("DIR_FILE", contAttrs);
1094 printTechAttr<void*>("DIR_LIST_KEYS", contAttrs);
1095 printTechAttr<int>("DIR_NKEYS", contAttrs);
1096 printTechAttr<int>("DIR_PRINT", contAttrs);
1097 printTechAttr<int>("DIR_WRITABLE", contAttrs);
1098 printTechAttr<int>("DIR_MODIFIED", contAttrs);
1099 }
1100 else {
1101 MsgWarning("Unknown technology for container");
1102 }
1103 }
1104 MsgDebug("-------------------------------------------");
1105 m_persistSvc->session().transaction().commit();
1106 m_catalog->commit();
1107 }
1108 catch(std::exception &e) {
1109 MsgError("printAttributes() Exception: "<<e.what());
1110 try {
1111 m_catalog->commit();
1112 }
1113 catch(std::exception &e) {
1114 MsgError("printAttributes() Exception: "<<e.what());
1115 }
1116 }
1117 }
1118
1119
1120
1121
1122 void
1123 PoolFileCatalogConnection::deletePFN(const CatalogKey &key) {
1124 try {
1125 MsgDebug("deletePFN() PFN="<<key.getID());
1126 pool::FCAdmin a;
1127 m_catalog->setAction(a);
1128 m_catalog->start();
1129 a.deletePFN(key.getID());
1130 m_catalog->commit();
1131
1132 m_entryCache->eraseInstance(key);
1133 }
1134 catch(std::exception &e) {
1135 MsgError("deletePFN() Exception caught: "<<e.what());
1136 }
1137 }
1138
1139 void
1140 PoolFileCatalogConnection::deleteFID(const std::string &fid) {
1141 try {
1142 MsgDebug("deleteFID() FID="<<fid);
1143 pool::FCAdmin a;
1144 m_catalog->setAction(a);
1145 m_catalog->start();
1146 a.deleteEntry(fid);
1147 m_catalog->commit();
1148
1149 m_entryCache->eraseInstance(CatalogKey(fid));
1150 }
1151 catch(std::exception &e) {
1152 MsgError("deleteFID() Exception caught: "<<e.what());
1153 }
1154 }
1155
1156
1157
1158 ROOT::Reflex::Type
1159 PoolFileCatalogConnection::getClassForToken( const pool::Token *token ) {
1160 const pool::Guid &classId(token->classID());
1161 return pool::DbReflex::forGuid(classId);
1162 }
This page was automatically generated by the
LXR engine.
|
|