Belle II Software  release-08-01-10
DBAccessorBase.h
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 #pragma once
9 
10 #include <framework/database/DBStore.h>
11 #include <framework/logging/Logger.h>
12 
13 #include <string>
14 #include <vector>
15 #include <functional>
16 
17 class TClass;
18 
19 namespace Belle2 {
27  public:
28 
36  DBAccessorBase(const std::string& name, const TClass* objClass, bool isArray, bool isRequired) :
37  m_type(DBStoreEntry::c_Object), m_name(name), m_objClass(objClass), m_isArray(isArray), m_isRequired(isRequired),
38  m_entry{DBStore::Instance().getEntry(name, objClass, isArray, isRequired)}, m_changed{isValid()}
39  {
40  if (m_entry) m_entry->registerAccessor(this);
41  }
42 
49  DBAccessorBase(DBStoreEntry::EPayloadType type, const std::string& name, bool isRequired):
50  m_type(type), m_name(name), m_objClass(nullptr), m_isArray(false), m_isRequired(isRequired),
51  m_entry{DBStore::Instance().getEntry(type, name, nullptr, false, isRequired)}, m_changed{isValid()}
52  {
53  if (m_entry) m_entry->registerAccessor(this);
54  }
55 
60  virtual ~DBAccessorBase()
61  {
62  if (m_entry) m_entry->removeAccessor(this);
63  }
64 
66  const std::string& getName() const { return m_name; }
67 
72  inline bool isValid() const {if (!ensureAttached()) return false; return (m_entry->getObject() != nullptr);}
73 
74  inline operator bool() const {return isValid();}
77  virtual bool operator==(const DBAccessorBase& other) const
78  {
79  return getName() == other.getName();
80  }
81 
83  virtual bool operator!=(const DBAccessorBase& other) const
84  {
85  return !(*this == other);
86  }
87 
89  bool hasChanged()
90  {
91  const bool ret = m_changed;
92  m_changed = false;
93  return ret;
94  }
95 
105  void addCallback(std::function<void(const std::string&)> callback, bool onDestruction = false)
106  {
107  m_callbacks.emplace_back(callback, onDestruction);
108  }
109 
118  void addCallback(std::function<void()> callback, bool onDestruction = false)
119  {
120  addCallback([callback](const std::string&) -> void { callback(); }, onDestruction);
121  }
122 
130  template<class T> void addCallback(T* object, void(T::*callback)())
131  {
132  addCallback([ = ](const std::string&) {(*object.*callback)();});
133  }
134 
136  const std::string& getGlobaltag() const { ensureAttached(); return m_entry->getGlobaltag(); }
137 
139  unsigned int getRevision() const { ensureAttached(); return m_entry->getRevision(); }
140 
143 
145  const std::string& getChecksum() const { ensureAttached(); return m_entry->getChecksum(); }
146 
148  const std::string& getFilename() const { ensureAttached(); return m_entry->getFilename(); }
149 
152 
157  const std::vector<unsigned int> getIntraRunBoundaries() const { ensureAttached(); return m_entry->getIntraRunBoundaries(); }
158 
160  bool isRequired() const { ensureAttached(); return m_entry->isRequired(); }
161 
162  protected:
164  template<class T = TObject> const T * getObject() const
165  {
166  if (!ensureAttached()) return nullptr;
167  return reinterpret_cast<const T*>(m_entry->getObject());
168  }
169 
171  bool ensureAttached() const
172  {
173  if (!m_entry) {
174  B2DEBUG(32, "DBAccessor " << m_name << " lost connection, reattaching");
176  m_changed = true;
177  if (!m_entry) return false;
178  m_entry->registerAccessor(const_cast<DBAccessorBase*>(this));
179  }
180  return true;
181  }
182 
184  void storeEntryChanged(bool destructed)
185  {
186  // we obviously changed
187  m_changed = true;
188  // StoreEntry is destructed, remove reference
189  if (destructed) m_entry = nullptr;
190  // Now run all registered callbacks
191  // TODO: We could guard m_callbacks against insertions during callback
192  // execution to prevent exponential growth of callbacks
193  for (const auto& cb : m_callbacks) {
194  if (destructed == cb.second) cb.first(m_name);
195  }
196  }
197 
201  const std::string m_name;
203  const TClass* m_objClass;
205  const bool m_isArray;
207  const bool m_isRequired;
211  mutable bool m_changed{false};
213  std::vector<std::pair<std::function<void(const std::string&)>, bool>> m_callbacks;
215  friend class DBStoreEntry;
216  };
218 }
Base class for DBObjPtr and DBArray for easier common treatment.
bool m_changed
Internal flag whether the object has changed since we last checked.
const std::string & getFilename() const
Get the filename this object is loaded from.
virtual bool operator!=(const DBAccessorBase &other) const
Check if two store accessors point to a different object/array.
const T * getObject() const
Return a pointer to the Object already cast to the correct type.
const TClass * m_objClass
Class of the payload if type is c_Object.
DBAccessorBase(DBStoreEntry::EPayloadType type, const std::string &name, bool isRequired)
Constructor to access an object in the DBStore which is not a ROOT Object.
virtual ~DBAccessorBase()
Destructor.
bool isIntraRunDependent() const
Check wether this conditions object has some intra-run dependencies.
std::vector< std::pair< std::function< void(const std::string &)>, bool > > m_callbacks
List of all registered callback functions.
DBAccessorBase(const std::string &name, const TClass *objClass, bool isArray, bool isRequired)
Constructor to access an object in the DBStore.
const std::string & getGlobaltag() const
Return the globaltag name (or testing payloads path) this object is loaded from.
void addCallback(std::function< void(const std::string &)> callback, bool onDestruction=false)
Add a callback method.
bool isValid() const
Check whether a valid object was obtained from the database.
const std::string m_name
Name of the payload in the database.
IntervalOfValidity getIoV() const
Return current IoV of the object.
DBStoreEntry * m_entry
Pointer to the entry in the DBStore.
const std::string & getChecksum() const
Get current checksum.
const std::string & getName() const
Return name under which the object is saved in the DBStore.
bool hasChanged()
Check whether the object has changed since the last call to hasChanged of the accessor).
unsigned int getRevision() const
Return current revision of the object.
bool ensureAttached() const
Make sure we are attached to the the DBStore.
bool isRequired() const
Check whether this conditions object is required (at least one user declared it as required)
void addCallback(std::function< void()> callback, bool onDestruction=false)
Add a callback method.
void storeEntryChanged(bool destructed)
Callback function which gets called by the DBStoreEntry object if it changes.
const bool m_isArray
True if the payload is an array of objects.
const std::vector< unsigned int > getIntraRunBoundaries() const
Get the intra-run boundaries, if any.
void addCallback(T *object, void(T::*callback)())
Add a callback method of an object.
const DBStoreEntry::EPayloadType m_type
Type of the payload.
virtual bool operator==(const DBAccessorBase &other) const
Check if two store accessors point to the same object/array.
const bool m_isRequired
True if the payload is required, otherwise no errors will be raised if it cannot be found.
Class to hold one entry from the ConditionsDB in the DBStore.
Definition: DBStoreEntry.h:47
void removeAccessor(DBAccessorBase *object)
Deregister an Accessor object and remove it from the list of registered objects.
Definition: DBStoreEntry.h:125
const std::string & getFilename() const
get the filename for this payload
Definition: DBStoreEntry.h:101
EPayloadType
Possible Store entry types.
Definition: DBStoreEntry.h:50
bool isIntraRunDependent() const
return whether or not the payload might change even during the run
Definition: DBStoreEntry.h:119
const std::string & getGlobaltag() const
get the globaltag name (or testing payloads path) from which the payload is picked.
Definition: DBStoreEntry.h:94
void registerAccessor(DBAccessorBase *object)
Register an Accessor object to be notified on changes by calling DBAccessorBase::storeEntryChanged()
Definition: DBStoreEntry.h:123
IntervalOfValidity getIoV() const
get the validity of the payload
Definition: DBStoreEntry.h:99
const std::string & getChecksum() const
get the checksum of the payload.
Definition: DBStoreEntry.h:104
unsigned int getRevision() const
get the revision of the payload, this is an abitrary number which indicates the conditions version
Definition: DBStoreEntry.h:97
bool isRequired() const
check whether this payload is required for operation
Definition: DBStoreEntry.h:115
const TObject * getObject() const
get the object for this payload, can be nullptr if the payload is not loaded or not of type c_Object
Definition: DBStoreEntry.h:107
const std::vector< unsigned int > getIntraRunBoundaries() const
return the boundaries of the intra-run changes of the payload, if any
Definition: DBStoreEntry.h:121
Singleton class to cache database objects.
Definition: DBStore.h:31
A class that describes the interval of experiments/runs for which an object in the database is valid.
static DBStore & Instance()
Instance of a singleton DBStore.
Definition: DBStore.cc:28
DBStoreEntry * getEntry(DBStoreEntry::EPayloadType payloadType, const std::string &name, const TClass *objClass, bool array, bool required=true)
Returns the entry with the requested name in the DBStore.
Definition: DBStore.cc:34
Abstract base class for different kinds of events.