The Gaudi Framework  v30r1 (5d4f4ae2)
XMLFileCatalog.cpp
Go to the documentation of this file.
1 #include "xercesc/dom/DOM.hpp"
2 #include "xercesc/framework/LocalFileFormatTarget.hpp"
3 #include "xercesc/framework/MemBufInputSource.hpp"
4 #include "xercesc/parsers/XercesDOMParser.hpp"
5 #include "xercesc/sax/EntityResolver.hpp"
6 #include "xercesc/sax/InputSource.hpp"
7 #include "xercesc/sax/SAXParseException.hpp"
8 #include "xercesc/util/PlatformUtils.hpp"
9 #include "xercesc/util/XMLString.hpp"
10 #include "xercesc/util/XMLURL.hpp"
11 #include "xercesc/util/XMLUni.hpp"
12 #include "xercesc/util/XercesDefs.hpp"
13 
14 #include "GaudiKernel/MsgStream.h"
15 #include "GaudiKernel/Service.h"
16 #include <Gaudi/PluginService.h>
17 
18 #include "XMLFileCatalog.h"
19 #include "createGuidAsString.h"
20 
21 #include <fstream>
22 #include <iostream>
23 #include <stdexcept>
24 #include <sys/stat.h>
25 #include <sys/types.h>
26 
27 using namespace xercesc;
28 using namespace Gaudi;
29 using namespace std;
30 
31 #if _XERCES_VERSION <= 30000
32 // API change between XercesC 2 and 3
33 #define setIdAttribute( a, b ) setIdAttribute( a )
34 #endif
35 
37 
38 namespace
39 {
40 
41  typedef const string& CSTR;
42  inline string _toString( const XMLCh* toTranscode )
43  {
44  char* buff = XMLString::transcode( toTranscode );
45  string tmp( buff == 0 ? "" : buff );
46  XMLString::release( &buff );
47  return tmp;
48  }
49  struct __Init {
50  __Init()
51  {
52  try {
53  XMLPlatformUtils::Initialize();
54  } catch ( const XMLException& e ) {
55  cout << "Xerces-c error in initialization:" << _toString( e.getMessage() ) << endl;
56  }
57  }
58  ~__Init() { XMLPlatformUtils::Terminate(); }
59  };
60  __Init __In__;
61 
62  struct XMLStr {
63  XMLCh* m_xml;
64  XMLStr( CSTR c ) { m_xml = XMLString::transcode( c.c_str() ); }
65  ~XMLStr()
66  {
67  if ( m_xml ) XMLString::release( &m_xml );
68  }
69  operator const XMLCh*() const { return m_xml; }
70  };
71  struct XMLTag : public XMLStr {
72  string m_str;
73  XMLTag( CSTR s ) : XMLStr( s ), m_str( s ) {}
74  ~XMLTag() {}
75  operator CSTR() const { return m_str; }
76  };
77  // bool operator==(const XMLTag& b, CSTR c) { return c==b.m_str; }
78  bool operator==( CSTR c, const XMLTag& b ) { return c == b.m_str; }
79  struct XMLCollection {
80  DOMElement* m_node;
81  XMLCollection( DOMNode* n, bool use_children = true ) : m_node( (DOMElement*)n )
82  {
83  if ( use_children ) {
84  if ( m_node ) m_node = (DOMElement*)m_node->getFirstChild();
85  if ( m_node && m_node->getNodeType() != DOMNode::ELEMENT_NODE ) ++( *this );
86  }
87  }
88  operator bool() const { return m_node; }
89  operator DOMNode*() const { return m_node; }
90  operator DOMElement*() const { return m_node; }
91  DOMElement* operator->() const { return m_node; }
92  string attr( const XMLTag& tag ) const { return _toString( m_node->getAttribute( tag ) ); }
93  string attr( CSTR tag ) const { return attr( XMLTag( tag ) ); }
94  string tag() const { return _toString( m_node->getTagName() ); }
95  void operator++()
96  {
97  while ( m_node ) {
98  m_node = (DOMElement*)m_node->getNextSibling();
99  if ( m_node && m_node->getNodeType() == DOMNode::ELEMENT_NODE ) {
100  return;
101  }
102  }
103  }
104  };
105  struct ErrHandler : public ErrorHandler {
107  IMessageSvc* m_msg;
109  ErrHandler( IMessageSvc* m ) : m_msg( m ) {}
111  void resetErrors() override {}
113  void warning( const SAXParseException& /* e */ ) override {}
115  void error( const SAXParseException& e ) override;
117  void fatalError( const SAXParseException& e ) override;
118  };
119  struct DTDRedirect : public EntityResolver {
120  InputSource* resolveEntity( const XMLCh* const /* pubId */, const XMLCh* const /* sysId */ ) override
121  {
122  static const char* dtdID = "redirectinmem.dtd";
123  static const char* dtd = "\
124  <!ELEMENT POOLFILECATALOG (META*,File*)>\
125  <!ELEMENT META EMPTY>\
126  <!ELEMENT File (physical,logical,metadata*)>\
127  <!ATTLIST META name CDATA #REQUIRED>\
128  <!ATTLIST META type CDATA #REQUIRED>\
129  <!ELEMENT physical (pfn)+>\
130  <!ELEMENT logical (lfn)*>\
131  <!ELEMENT metadata EMPTY>\
132  <!ELEMENT lfn EMPTY>\
133  <!ELEMENT pfn EMPTY>\
134  <!ATTLIST File ID ID #REQUIRED>\
135  <!ATTLIST pfn name ID #REQUIRED>\
136  <!ATTLIST pfn filetype CDATA #IMPLIED>\
137  <!ATTLIST pfn se CDATA #IMPLIED>\
138  <!ATTLIST lfn name ID #REQUIRED>\
139  <!ATTLIST metadata att_name CDATA #REQUIRED>\
140  <!ATTLIST metadata att_value CDATA #REQUIRED>\
141  ";
142  static const size_t len = strlen( dtd );
143  return new MemBufInputSource( (const XMLByte*)dtd, len, dtdID, false );
144  }
145  };
146 
147  void ErrHandler::error( const SAXParseException& e )
148  {
149  string m( _toString( e.getMessage() ) );
150  if ( m.find( "The values for attribute 'name' must be names or name tokens" ) != string::npos ||
151  m.find( "The values for attribute 'ID' must be names or name tokens" ) != string::npos ||
152  m.find( "for attribute 'name' must be Name or Nmtoken" ) != string::npos ||
153  m.find( "for attribute 'ID' must be Name or Nmtoken" ) != string::npos ||
154  m.find( "for attribute 'name' is invalid Name or NMTOKEN value" ) != string::npos ||
155  m.find( "for attribute 'ID' is invalid Name or NMTOKEN value" ) != string::npos )
156  return;
157  string sys( _toString( e.getSystemId() ) );
158  MsgStream log( m_msg, "XMLCatalog" );
159  log << MSG::ERROR << "Error at file \"" << sys << "\", line " << e.getLineNumber() << ", column "
160  << e.getColumnNumber() << endmsg << "Message: " << m << endmsg;
161  }
162  void ErrHandler::fatalError( const SAXParseException& e )
163  {
164  MsgStream log( m_msg, "XMLCatalog" );
165  string m( _toString( e.getMessage() ) );
166  string sys( _toString( e.getSystemId() ) );
167  log << MSG::ERROR << "Fatal Error at file \"" << sys << "\", line " << e.getLineNumber() << ", column "
168  << e.getColumnNumber() << endmsg << "Message: " << m << endmsg;
169  throw runtime_error( "Standard pool exception : Fatal Error on the DOM Parser" );
170  }
171 
172  const XMLTag EmptyCatalog( "<!-- Edited By POOL -->\n"
173  "<!DOCTYPE POOLFILECATALOG SYSTEM \"InMemory\">\n"
174  "<POOLFILECATALOG>\n"
175  "</POOLFILECATALOG>\n" );
176  const XMLTag PFNCOLL( "physical" );
177  const XMLTag LFNCOLL( "logical" );
178  const XMLTag PFNNODE( "pfn" );
179  const XMLTag LFNNODE( "lfn" );
180  const XMLTag Attr_type( "type" );
181  const XMLTag Attr_ID( "ID" );
182  const XMLTag Attr_name( "name" );
183  const XMLTag Attr_ftype( "filetype" );
184  const XMLTag MetaNode( "metadata" );
185  const XMLTag Attr_metaName( "att_name" );
186  const XMLTag Attr_metaValue( "att_value" );
187 }
188 
189 // ----------------------------------------------------------------------------
190 XMLFileCatalog::XMLFileCatalog( CSTR uri, IMessageSvc* m ) : m_file( uri ), m_msgSvc( m ) {}
191 // ----------------------------------------------------------------------------
194 // ----------------------------------------------------------------------------
195 DOMDocument* XMLFileCatalog::getDoc( bool throw_if_no_exists ) const
196 {
197  if ( !m_doc && throw_if_no_exists ) printError( "The XML catalog was not started.", true );
198  return m_doc;
199 }
200 // ----------------------------------------------------------------------------
201 void XMLFileCatalog::printError( CSTR msg, bool rethrow ) const
202 {
203  MsgStream log( m_msgSvc, "XMLCatalog" );
204  log << MSG::FATAL << msg << endmsg;
205  if ( rethrow ) throw runtime_error( "XMLFileCatalog> " + msg );
206 }
207 // ----------------------------------------------------------------------------
209 {
210  string xmlFile = getfile( false );
211  try {
212  m_parser = std::make_unique<XercesDOMParser>();
213  m_parser->setValidationScheme( XercesDOMParser::Val_Auto );
214  m_parser->setDoNamespaces( false );
215  DTDRedirect dtdinmem;
216  m_parser->setEntityResolver( &dtdinmem );
217  if ( !m_errHdlr ) m_errHdlr = std::make_unique<ErrHandler>( m_msgSvc );
218  m_parser->setErrorHandler( m_errHdlr.get() );
219  if ( !xmlFile.empty() ) {
220  m_parser->parse( xmlFile.c_str() );
221  } else {
222  const std::string& s = EmptyCatalog;
223  MemBufInputSource src( (const XMLByte*)s.c_str(), s.length(), "MemCatalog" );
224  m_parser->parse( src );
225  }
226  m_doc = m_parser->getDocument();
227  } catch ( const XMLException& e ) {
228  printError( "XML parse error[" + xmlFile + "]: " + _toString( e.getMessage() ) );
229  } catch ( const DOMException& e ) {
230  printError( "XML parse error[" + xmlFile + "]: " + _toString( e.getMessage() ) );
231  } catch ( ... ) {
232  printError( "UNKNOWN XML parse error in file " + xmlFile );
233  }
234 }
235 // ----------------------------------------------------------------------------
236 string XMLFileCatalog::lookupFID( const std::string& fid ) const
237 {
238  std::string result;
239  DOMNode* e = element( fid, false );
240  e = e ? e->getParentNode() : 0; // Mode up to <logical>
241  e = e ? e->getParentNode() : 0; // Mode up to <File>
242  if ( e ) {
243  if ( e->getAttributes() ) { // Need to check this. The node may be no DOMElement
244  char* nam = XMLString::transcode( ( (DOMElement*)e )->getAttribute( Attr_ID ) );
245  if ( nam ) result = nam;
246  XMLString::release( &nam );
247  }
248  }
249  return result;
250 }
251 // ----------------------------------------------------------------------------
252 void XMLFileCatalog::getFID( Strings& fids ) const
253 {
254  fids.clear();
255  DOMNode* fde = getDoc( true )->getElementsByTagName( XMLStr( "*" ) )->item( 0 );
256  for ( XMLCollection c( child( fde, "File" ), false ); c; ++c ) fids.push_back( c.attr( Attr_ID ) );
257 }
258 // ----------------------------------------------------------------------------
259 void XMLFileCatalog::getPFN( CSTR fid, Files& files ) const
260 {
261  files.clear();
262  for ( XMLCollection c( child( child( element( fid, false ), PFNCOLL ), PFNNODE ), false ); c; ++c )
263  files.emplace_back( c.attr( Attr_name ), c.attr( Attr_ftype ) );
264 }
265 // ----------------------------------------------------------------------------
266 void XMLFileCatalog::getLFN( CSTR fid, Files& files ) const
267 {
268  files.clear();
269  for ( XMLCollection c( child( child( element( fid, false ), LFNCOLL ), LFNNODE ), false ); c; ++c )
270  files.emplace_back( c.attr( Attr_name ), fid );
271 }
272 // ----------------------------------------------------------------------------
273 void XMLFileCatalog::getMetaData( CSTR fid, Attributes& attr ) const
274 {
275  attr.clear();
276  for ( XMLCollection c( child( element( fid ), MetaNode ), false ); c; ++c )
277  attr.emplace_back( c.attr( Attr_metaName ), c.attr( Attr_metaValue ) );
278  if ( attr.size() > 0 ) attr.emplace_back( "guid", fid );
279 }
280 // ----------------------------------------------------------------------------
281 DOMNode* XMLFileCatalog::child( DOMNode* par, CSTR tag, CSTR attr, CSTR val ) const
282 {
283  for ( XMLCollection c( par ); c; ++c ) {
284  if ( c.tag() == tag ) {
285  if ( !attr.empty() && c.attr( attr ) != val ) continue;
286  return c;
287  }
288  }
289  return 0;
290 }
291 // ----------------------------------------------------------------------------
292 void XMLFileCatalog::setMetaData( CSTR fid, CSTR attr, CSTR val ) const
293 {
294  if ( !readOnly() ) {
295  DOMNode* node = element( fid );
296  DOMElement* mnod = (DOMElement*)child( node, MetaNode, Attr_metaName, attr );
297  if ( !mnod ) {
298  mnod = getDoc( true )->createElement( MetaNode );
299  node->appendChild( mnod );
300  mnod->setAttribute( Attr_metaName, XMLStr( attr ) );
301  }
302  mnod->setAttribute( Attr_metaValue, XMLStr( val ) );
303  m_update = true;
304  return;
305  }
306  printError( "Cannot update readonly catalog!" );
307 }
308 // ----------------------------------------------------------------------------
309 string XMLFileCatalog::getMetaDataItem( CSTR fid, CSTR attr ) const
310 {
311  XMLCollection c( child( getDoc( true )->getElementById( XMLStr( fid ) ), MetaNode, Attr_metaName, attr ) );
312  return c ? c.attr( attr ) : string( "" );
313 }
314 // ----------------------------------------------------------------------------
315 void XMLFileCatalog::dropMetaData( CSTR fid, CSTR attr ) const
316 {
317  vector<DOMNode*> gbc;
318  DOMNode* fn = getDoc( true )->getElementById( XMLStr( fid ) );
319  for ( XMLCollection c{child( fn, MetaNode )}; c; ++c )
320  if ( attr[0] == '*' || !c.attr( attr ).empty() ) gbc.push_back( c );
321  for ( const auto& i : gbc ) fn->removeChild( i );
322 }
323 // ----------------------------------------------------------------------------
324 DOMNode* XMLFileCatalog::element( CSTR element_name, bool print_err ) const
325 {
326  DOMNode* node = getDoc( true )->getElementById( XMLStr( element_name ) );
327  if ( !node && print_err ) printError( "Cannot find element:" + element_name );
328  return node;
329 }
330 // ----------------------------------------------------------------------------
332 {
333  DOMNode *pn = nullptr, *fn = element( fid );
334  if ( fn ) pn = fn->getParentNode();
335  if ( pn ) pn->removeChild( fn );
336 }
337 // ----------------------------------------------------------------------------
339 {
340  if ( !fid.empty() ) {
342  if ( res.first == 0 || res.second == 0 ) {
343  printError( "Failed to register FID:" + fid );
344  }
345  return;
346  }
347  throw runtime_error( "XMLFileCatalog> Cannot register LFN for invalid FID:" + fid );
348 }
349 // ----------------------------------------------------------------------------
351 {
352  if ( readOnly() ) {
353  printError( "Cannot update readonly catalog!" );
354  return {nullptr, nullptr};
355  }
356 
358  DOMElement *file = (DOMElement *)element( fid, false ), *phyelem = 0, *logelem = 0;
359  DOMDocument* doc = getDoc( true );
360  if ( !file ) {
361  DOMNode* fde = doc->getElementsByTagName( XMLStr( "*" ) )->item( 0 );
362  file = m_doc->createElement( XMLStr( "File" ) );
363  file->setAttribute( Attr_ID, XMLStr( fid ) );
364  file->setIdAttribute( Attr_ID, true );
365  fde->appendChild( file );
366  m_update = true;
367  }
368  for ( XMLCollection c1( file ); c1; ++c1 ) {
369  char* nam = XMLString::transcode( c1->getNodeName() );
370  if ( nam == PFNCOLL ) phyelem = c1;
371  if ( nam == LFNCOLL ) logelem = c1;
372  XMLString::release( &nam );
373  }
374  if ( !phyelem ) {
375  phyelem = doc->createElement( PFNCOLL );
376  file->appendChild( phyelem );
377  m_update = true;
378  }
379  if ( !logelem ) {
380  logelem = doc->createElement( LFNCOLL );
381  file->appendChild( logelem );
382  m_update = true;
383  }
384  return {logelem, phyelem};
385 }
386 // ----------------------------------------------------------------------------
387 void XMLFileCatalog::registerPFN( CSTR fid, CSTR pfn, CSTR ftype ) const
388 {
389  if ( !fid.empty() ) {
391  DOMElement *phyelem = res.second, *fnelem = 0;
392  for ( XMLCollection c( phyelem ); c; ++c ) {
393  char* nam = XMLString::transcode( c->getNodeName() );
394  if ( nam == PFNNODE ) {
395  XMLString::release( &nam );
396  nam = XMLString::transcode( c->getAttribute( Attr_name ) );
397  if ( nam == pfn ) {
398  XMLString::release( &nam );
399  fnelem = c;
400  break;
401  }
402  }
403  XMLString::release( &nam );
404  }
405  if ( !fnelem ) {
406  fnelem = getDoc( true )->createElement( PFNNODE );
407  phyelem->appendChild( fnelem );
408  fnelem->setAttribute( Attr_ftype, XMLStr( ftype ) );
409  fnelem->setAttribute( Attr_name, XMLStr( pfn ) );
410  fnelem->setIdAttribute( Attr_name, true );
411  m_update = true;
412  }
413  return;
414  }
415  throw runtime_error( "XMLFileCatalog> Cannot register PFN for invalid FID:" + fid );
416 }
417 // ----------------------------------------------------------------------------
418 void XMLFileCatalog::registerLFN( CSTR fid, CSTR lfn ) const
419 {
420  if ( !fid.empty() ) {
422  DOMElement *logelem = res.first, *fnelem = 0;
423  for ( XMLCollection c( logelem ); c; ++c ) {
424  char* nam = XMLString::transcode( c->getNodeName() );
425  if ( nam == LFNNODE ) {
426  XMLString::release( &nam );
427  nam = XMLString::transcode( c->getAttribute( Attr_name ) );
428  if ( nam == lfn ) {
429  XMLString::release( &nam );
430  fnelem = c;
431  break;
432  }
433  }
434  }
435  if ( !fnelem ) {
436  fnelem = getDoc( true )->createElement( LFNNODE );
437  logelem->appendChild( fnelem );
438  fnelem->setAttribute( Attr_name, XMLStr( lfn ) );
439  fnelem->setIdAttribute( Attr_name, true );
440  m_update = true;
441  }
442  return;
443  }
444  throw runtime_error( "XMLFileCatalog> Cannot register LFN for invalid FID:" + fid );
445 }
446 // ----------------------------------------------------------------------------
448 {
449  try {
450  if ( dirty() && !readOnly() ) {
451  string xmlfile = getfile( true );
452  XMLStr ii( "LS" );
453  DOMImplementation* imp = DOMImplementationRegistry::getDOMImplementation( ii );
454  auto tar = std::make_unique<LocalFileFormatTarget>( xmlfile.c_str() );
455 #if _XERCES_VERSION <= 30000
456  DOMWriter* wr = imp->createDOMWriter();
457  wr->setFeature( XMLUni::fgDOMWRTFormatPrettyPrint, true );
458  wr->writeNode( tar.get(), *m_doc );
459  wr->release();
460 #else
461  DOMLSOutput* output = imp->createLSOutput();
462  output->setByteStream( tar.get() );
463  DOMLSSerializer* wr = imp->createLSSerializer();
464  wr->getDomConfig()->setParameter( XMLStr( "format-pretty-print" ), true );
465  wr->write( m_doc, output );
466  output->release();
467  wr->release();
468 #endif
469  }
470  } catch ( exception& e ) {
471  printError( string( "Cannot open output file:" ) + e.what() );
472  } catch ( ... ) {
473  printError( "Unknown IO rrror." );
474  }
475 }
476 // ----------------------------------------------------------------------------
477 string XMLFileCatalog::getfile( bool create )
478 {
479  string protocol, path;
480  XMLURL xerurl;
481  try {
482  xerurl = (const XMLCh*)XMLStr( m_file );
483  protocol = _toString( xerurl.getProtocolName() );
484  path = _toString( xerurl.getPath() );
485  } catch ( const XMLException& e ) {
486  printError( _toString( e.getMessage() ) );
487  }
488  if ( protocol.empty() ) {
489  printError( "Missing protocol." );
490  } else if ( protocol == "http" || protocol == "ftp" ) {
491  m_rdOnly = true;
492  } else if ( protocol == "file" ) {
493  m_rdOnly = false;
494  struct stat buff;
495  int exist = ::stat( path.c_str(), &buff ) != -1;
496  if ( create && !exist ) {
497  MsgStream log( m_msgSvc, "XMLCatalog" );
498  log << MSG::INFO << "File '" << path << "' does not exist. New file created." << endmsg;
499  ofstream out{path};
500  if ( !m_rdOnly && out.is_open() ) {
501  out << (CSTR)EmptyCatalog << endl;
502  } else {
503  printError( "Problem creating file " + path );
504  }
505  out.close();
506  } else if ( exist ) {
507  return path;
508  } else if ( !create ) {
509  return "";
510  }
511  } else {
512  printError( protocol + ": protocol not supported." );
513  }
514  return path;
515 }
std::string getMetaDataItem(CSTR fid, CSTR name) const override
Access metadata item.
bool readOnly() const override
Check if the catalog is read-only.
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
T empty(T...args)
void registerPFN(CSTR fid, CSTR pfn, CSTR ftype) const override
Create a FileID and Node of the physical file name with all the attributes.
T endl(T...args)
std::string lookupFID(CSTR lfn) const
Gaudi::PluginService::Factory< IInterface *, const std::string &, IMessageSvc * > Factory
Definition: IFileCatalog.h:33
STL namespace.
std::string getfile(bool create)
xercesc::DOMNode * element(CSTR fid, bool print_err=true) const
std::unique_ptr< xercesc::XercesDOMParser > m_parser
STL class.
T push_back(T...args)
STL class.
const std::string & CSTR
T what(T...args)
T strlen(T...args)
xercesc::DOMNode * child(xercesc::DOMNode *par, CSTR tag, CSTR attr="", CSTR val="") const
bool operator==(const GaudiUtils::Allocator< T1 > &, const GaudiUtils::Allocator< T2 > &)
Definition: Allocator.h:246
constexpr double m
Definition: SystemOfUnits.h:94
void getMetaData(CSTR fid, Attributes &attr) const override
Dump all MetaData of the catalog for a given file ID.
void printError(CSTR msg, bool throw_exc=true) const
std::unique_ptr< xercesc::ErrorHandler > m_errHdlr
The IMessage is the interface implemented by the message service.
Definition: IMessageSvc.h:38
xercesc::DOMDocument * m_doc
xercesc::DOMDocument * getDoc(bool throw_if_no_exists=true) const
const std::string CSTR
void getLFN(CSTR fid, Files &files) const override
Dump all logical file names of the catalog associate to the FileID.
#define DECLARE_FACTORY(type, factory)
Definition: PluginService.h:24
STL class.
T get(T...args)
T find(T...args)
T length(T...args)
void setMetaData(CSTR fid, CSTR name, CSTR value) const override
Insert/update metadata item.
STL class.
std::string createGuidAsString()
Helper function creating file identifier using the UUID mechanism.
void registerLFN(CSTR fid, CSTR lfn) const override
Create a FileID and Node of the logical file name with all the attributes.
T c_str(T...args)
void commit() override
Save DOM catalog to file.
string s
Definition: gaudirun.py:253
std::pair< xercesc::DOMElement *, xercesc::DOMElement * > i_registerFID(CSTR fid) const
void init() override
Parse the DOM tree of the XML catalog.
IMessageSvc * m_msgSvc
void registerFID(CSTR fid) const override
Create a FileID and Node.
void getPFN(CSTR fid, Files &files) const override
Dump all physical file names of the catalog and their attributes associate to the FileID...
This class constitutes the core of the XML based FileCatalog API for POOL.
bool dirty() const override
Check if the catalog should be updated.
std::string createFID() const override
Catalog interface.
Helper functions to set/get the application return code.
Definition: __init__.py:1
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:209
void getFID(Strings &fids) const override
Dump all file Identifiers.
void dropMetaData(CSTR fid) const override
Drop all metadata of one FID.
void deleteFID(CSTR FileID) const override
Delete FileID Node from the catalog.