Belle II Software development
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
17class TClass;
18
19namespace Belle2 {
24
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
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();}
75
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
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
142 IntervalOfValidity getIoV() const { ensureAttached(); return m_entry->getIoV(); }
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
151 bool isIntraRunDependent() const { ensureAttached(); return m_entry->isIntraRunDependent(); }
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 };
217
218}
bool m_changed
Internal flag whether the object has changed since we last checked.
virtual bool operator!=(const DBAccessorBase &other) const
Check if two store accessors point to a different object/array.
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.
const std::string & getFilename() const
Get the filename this object is loaded from.
const std::string & getName() const
Return name under which the object is saved in the DBStore.
bool isIntraRunDependent() const
Check whether 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.
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.
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.
friend class DBStoreEntry
Allow the DBStoreEntry to call the callback notifier.
const std::vector< unsigned int > getIntraRunBoundaries() const
Get the intra-run boundaries, if any.
const T * getObject() const
Return a pointer to the Object already cast to the correct type.
const std::string & getGlobaltag() const
Return the globaltag name (or testing payloads path) this object is loaded from.
const bool m_isArray
True if the payload is an array of objects.
const std::string & getChecksum() const
Get current checksum.
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.
EPayloadType
Possible Store entry types.
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:26
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:32
Abstract base class for different kinds of events.