DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
dbcontroller.cpp
Go to the documentation of this file.
1// DUNE DAQ modification notice:
2// This file has been modified from the original ATLAS dbe source for the DUNE DAQ project.
3// Fork baseline commit: dbe-02-12-17 (2022-05-12).
4// Renamed since fork: no.
5
6/*
7 * dbcontroller.cpp
8 *
9 * Created on: Oct 30, 2015
10 * Author: lgeorgop
11 */
12
13#include "dbe/dbcontroller.hpp"
15#include "dbe/messenger.hpp"
16#include "dbe/msghandler.hpp"
17
18#include <utility>
19
20using namespace dunedaq::conffwk;
21
22namespace dbe {
23namespace inner {
24
25namespace configobject {
26//------------------------------------------------------------------------------------------
27// NAMESPACE
28// DBE::INNER::CONFIGOBJECT
29//------------------------------------------------------------------------------------------
30
31//------------------------------------------------------------------------------------------
32template<typename T>
33std::vector<T>
34ref_interface<T>::referenced_by(std::string const& name, bool check_composite_only) const
35{
36 std::vector<ConfigObject> referees;
37 std::vector<tref> result;
38
39 static_cast<ConfigObject&>(*this).referenced_by(referees, name, check_composite_only);
40
41 for (ConfigObject const& x : referees) {
42 try {
43 result.push_back(inner::dbcontroller::get({ x.UID(), x.class_name() }));
44 } catch (daq::dbe::config_object_retrieval_result_is_null const& e) {
45 // Nothing needed to do here, this is normal, just the query has resulted in null
46 }
47 }
48
49 return result;
50}
51
52template std::vector<tref>
53ref_interface<tref>::referenced_by(std::string const&, bool) const;
54
55//------------------------------------------------------------------------------------------
56
57//------------------------------------------------------------------------------------------
58template<typename T>
59void
61{
63 for (auto const& linked : obj.relations) {
64 for (auto const& candidate : linked.second) {
65 record(candidate.ref());
66 }
67 }
68 this_remove_stack.push_back(obj);
69}
70
71template<typename T>
72void
74{
76 std::swap(acopy, this_remove_stack);
77
78 while (not acopy.empty()) {
79 t_extractor candidate = acopy.front();
80 // Keep only objects that have been deleted
81 if (not dbe::config::api::info::has_obj(candidate.ref.class_name(), candidate.ref.UID())) {
82 this_remove_stack.push_back(candidate);
83 }
84 acopy.pop_front();
85 }
86}
87
88template<typename T>
89void
91{
92 if (this_notify_stack.empty()) {
93 for (typename type_extractor_stack::value_type const& val : this_remove_stack) {
94 tele(val.ref);
95 }
96 } else {
97 for (typename type_ref_container::value_type const& val : this_notify_stack) {
98 tele(val);
99 }
100 }
101}
102
103template<typename T>
104tref
106{
107 if (not this_remove_stack.empty()) {
108 for (;;) {
111 this_remove_stack.pop_front();
112 if (not last.is_null()) {
113 this_notify_stack.push_back(last);
114 }
115 if (this_remove_stack.empty()) {
116 return last;
117 }
118 }
119 }
120 throw daq::dbe::gref_empty_internal_queue_is_invalid_state(ERS_HERE);
121}
122
123template<typename T>
124bool
126{
127 return this_remove_stack.front().is_null();
128}
129//------------------------------------------------------------------------------------------
130
131//------------------------------------------------------------------------------------------
132template<typename T>
133tref
134authorized_getter<T, tref>::operator()(std::string const& key)
135{
136 ConfigObject voisin{ this->that->template getdirect<ConfigObject>(key) };
137
138 if (voisin.is_null()) {
139 throw daq::dbe::config_object_retrieval_result_is_null(ERS_HERE, key);
140 }
141
142 // There is no need to catch the resulting exception from get because the object
143 // has just been retrieved from the database, and the call to get just generates
144 // the tref and adds the object to the internal lookup table.
145 return dbcontroller::get({ voisin.UID(), voisin.class_name() });
146}
147
148template<typename T>
149std::vector<tref>
150authorized_getter<T, std::vector<tref>>::operator()(std::string const& key)
151{
152 std::vector<ConfigObject> voisins{ this->that->template getdirect<std::vector<ConfigObject>>(key) };
153
154 std::vector<tref> references;
155
156 for (ConfigObject const& voisin : voisins) {
157 try {
158 references.push_back(dbcontroller::get({ voisin.UID(), voisin.class_name() }));
159 } catch (daq::dbe::config_object_retrieval_result_is_null const& ex) {
160 // Actually there is no need to handle this error here ,
161 // since the object will not be added to the result list of references,
162 // and can be safely ignored
163 }
164 }
165
166 return references;
167}
168
169template class authorized_getter<tref, tref>;
171//------------------------------------------------------------------------------------------
172
173} // end namespace configobject
174
175//------------------------------------------------------------------------------------------
176// NAMESPACE
177// DBE::INNER
178//------------------------------------------------------------------------------------------
179
181
182//------------------------------------------------------------------------------------------
184//------------------------------------------------------------------------------------------
185
186//------------------------------------------------------------------------------------------
189{
190 static dbcontroller self;
191 return self;
192}
193//------------------------------------------------------------------------------------------
194
195//------------------------------------------------------------------------------------------
196void
198{
200 locker l(me.this_lock);
201 me.this_allobjects.clear();
202}
203//------------------------------------------------------------------------------------------
204
205//------------------------------------------------------------------------------------------
206std::vector<tref>
207dbcontroller::referenced_by(configobject::tref objref, std::string const& name, bool check_composite_only)
208{
209 std::vector<ConfigObject> linked;
210 objref.ref().referenced_by(linked, name, check_composite_only);
211
212 std::vector<configobject::tref> references;
213
214 for (ConfigObject const& anobj : linked) {
215 try {
216 references.push_back(get({ anobj.UID(), anobj.class_name() }));
217 } catch (daq::dbe::config_object_retrieval_result_is_null const& e) {
218 // nothing needed to do here, since this just signal that
219 // some of the relation results are null
220 }
221 }
222
223 return references;
224}
225//------------------------------------------------------------------------------------------
226
227//------------------------------------------------------------------------------------------
228template<typename T>
229configobject::gref<T>
232{
234 subgraph.notify(notice);
235 return subgraph;
236}
237
240 configobject::tref const&,
242
243//------------------------------------------------------------------------------------------
244
245//------------------------------------------------------------------------------------------
246/*
247 * Create an object in the database.
248 *
249 * If the object cannot be created an exception will be thrown
250 * by the underlying database access layer, as it cannot be handled here.
251 *
252 * If the object is already in the underlying container the object reference will be updated
253 * to point to the new object reference, transparently to user classes of the controller
254 */
257{
259
260 tref el = dbcontroller::ref().insert(result);
261 try {
263 } catch (dunedaq::conffwk::Exception const& e) {
264 // just need to remove the object from the underlying database
266 throw;
267 } catch (daq::dbe::Exception const& e) {
268 // just need to remove the object from the underlying database
270 throw;
271 }
272}
273
274template<typename T>
280
281template<typename T>
284{
285 return obj.rebuild();
286}
287
288template<typename T>
292{
293 tref ret = obj.rebuild();
294 obj.notify(notice);
295 return ret;
296}
297
302//------------------------------------------------------------------------------------------
303
304//------------------------------------------------------------------------------------------
306dbcontroller::move_object_request(configobject::tref objref, std::string const& destfile)
307{
308 if (not objref.is_null()) {
309 static_cast<ConfigObject&>(*(objref.refered)).move(destfile);
310 }
311
312 return objref;
313}
314//------------------------------------------------------------------------------------------
315
316//------------------------------------------------------------------------------------------
319{
320 return dbcontroller::ref().rename(objref, newname);
321}
322//------------------------------------------------------------------------------------------
323
324//------------------------------------------------------------------------------------------
326dbcontroller::rename(configobject::tref objref, std::string const& aname)
327{
328 if (not objref.is_null()) {
329 // pick up the pointer
330 std::shared_ptr<configobject::oref> current_ptr = objref.refered;
331
332 // remove the current reference from the internal map
333 this_allobjects.erase(*current_ptr);
334 try {
335 // rename the refered object
336 dbe::config::api::rwdacc::rename_object(static_cast<ConfigObject&>(*current_ptr), aname);
337 } catch (dunedaq::conffwk::Generic const& e) {
338 // Logging the error but this may not affect program execution per-se
339 FAIL("Object rename failure", dbe::config::errors::parse(e).c_str());
340 }
341 // position it in its proper place
342 bool nofail;
343 t_object_map::iterator position;
344 std::tie(position, nofail) = this_allobjects.emplace(*current_ptr, current_ptr);
345
346 if (not nofail) {
347 throw daq::dbe::dbcontroller_internal_cache_failure(ERS_HERE);
348 }
349 return position->second;
350 }
351 return objref;
352}
353//------------------------------------------------------------------------------------------
354
355//------------------------------------------------------------------------------------------
358{
359 return dbcontroller::ref().lookup(key);
360}
361
362std::vector<configobject::tref>
363dbcontroller::gets(std::string const& cname, std::string const& query)
364{
365 std::vector<ConfigObject> database_objects = config::api::rwdacc::query_class(cname, query);
366 std::vector<configobject::tref> result;
367
368 for (ConfigObject const& keyin : database_objects) {
369 try {
370 result.push_back(dbcontroller::ref().lookup({ keyin.UID(), keyin.class_name() }));
371 } catch (daq::dbe::config_object_retrieval_result_is_null const& e) {
372 // nothing needs be done to specifically handle this case, it just that in some
373 // cases the underlying database does not contain initialized objects
374 }
375 }
376 return result;
377}
378//------------------------------------------------------------------------------------------
379
380//------------------------------------------------------------------------------------------
383{
384 // Find the object in the database
385 t_object_map::iterator position = this_allobjects.find(key);
386
387 if (position == this_allobjects.end()) {
388 // if it is not in the cache we need to add it
390 if (not toinsert.is_null()) {
391 return insert(static_cast<ConfigObject>(toinsert));
392 }
393 } else {
394 return position->second;
395 }
396
397 throw daq::dbe::config_object_retrieval_result_is_null(ERS_HERE, key.this_name + "@" + key.this_class);
398}
399//------------------------------------------------------------------------------------------
400
401//------------------------------------------------------------------------------------------
404{
405 // Construct the oref to add in the internal map
406 std::shared_ptr<configobject::oref> element(new configobject::oref(obj));
407
408 bool object_inserted;
409 t_object_map::iterator position;
410
411 locker l(this_lock);
412 std::tie(position, object_inserted) = this_allobjects.emplace(*element, element);
413
414 if (not object_inserted) {
415 // Object is already defined in the database and we replace the old reference with the new.
416 // A case is if there have been external modification and we try to replay changes
417 static_cast<ConfigObject&>(*position->second) = obj;
418 }
419
420 return position->second;
421}
422//------------------------------------------------------------------------------------------
423
424//------------------------------------------------------------------------------------------
425template<typename T>
428{
429 configobject::gref<T> subgraph;
430
431 {
432 locker l(this_lock);
433 // Record the associated subgraph
434 if (not ref.is_null()) {
435 subgraph.record(ref);
436 }
437
438 // Need to remove from the internal map all candidates, they will be added at post processing
439 for (T const& key : subgraph.this_remove_stack) {
440 // Remove from the internal map
441 this_allobjects.erase({ key.ref.UID(), key.ref.class_name() });
442 }
443 }
444
445 // Delete the object from the database
447 // Post-process the object recorded subgraph
448 subgraph.post();
449
450 return subgraph;
451}
452//------------------------------------------------------------------------------------------
453
454}
455// namespace inner
456
457template<typename S>
466
467} // namespace dbe
#define ERS_HERE
static tref set_object(tref newobj, dbe::t_config_object_preimage::type_attrmap const &attributes, dbe::t_config_object_preimage::type_relmap const &relations)
Definition rwdacc.cpp:83
static void destroy_object(dunedaq::conffwk::ConfigObject &)
Definition rwdacc.cpp:285
static dunedaq::conffwk::ConfigObject get_object(std::string const &, std::string const &)
Definition rwdacc.cpp:299
static std::vector< dunedaq::conffwk::ConfigObject > query_class(std::string const &classname, std::string const &query)
Definition rwdacc.cpp:322
static dunedaq::conffwk::ConfigObject create_object(std::string const &fn, std::string const &cn, std::string const &name)
Definition rwdacc.cpp:45
static void rename_object(dunedaq::conffwk::ConfigObject &object, std::string const &newname)
Definition rwdacc.cpp:344
inner::configobject::tref this_referenced_object
inner::configobject::tref ref() const
std::function< void(dref const)> config_action_notifiable
std::deque< t_extractor > type_extractor_stack
std::vector< T > referenced_by(std::string const &name="*", bool check_composite_only=true) const
dunedaq::conffwk::ConfigObject & ref(bool check_null=true) const
std::shared_ptr< oref > refered
friend class configobject::tref
configobject::tref rename(configobject::tref objref, std::string const &aname)
static dbcontroller & ref()
configobject::gref< T > remove(dbe::tref ref)
static configobject::gref< T > delete_object_request(configobject::tref const &obj)
std::lock_guard< t_mutex > locker
static std::vector< configobject::tref > gets(std::string const &cname, std::string const &query="")
configobject::tref insert(dunedaq::conffwk::ConfigObject const &)
std::vector< configobject::tref > referenced_by(configobject::tref objref, std::string const &name="*", bool check_composite_only=true)
std::recursive_mutex t_mutex
static configobject::tref move_object_request(configobject::tref objref, std::string const &destfile)
configobject::tref lookup(dbe::cokey const &desc)
static configobject::tref get(dbe::cokey const &desc)
static configobject::tref rename_object_request(configobject::tref objref, std::string const &newname)
static configobject::tref create_object_request(dbe::t_config_object_preimage const &rep)
Represents database objects.
const std::string & UID() const noexcept
Return object identity.
void referenced_by(std::vector< ConfigObject > &value, const std::string &relationship_name="*", bool check_composite_only=true, unsigned long rlevel=0, const std::vector< std::string > *rclasses=nullptr) const
Get objects which have references to given object.
bool is_null() const noexcept
Check if object's implementation points to null.
const std::string & class_name() const noexcept
Return object's class name.
#define FAIL(...)
bool has_obj(std::string const &classname, std::string const &object_uid)
std::string const parse(ers::Issue const &)
Include QT Headers.
config_object_aggregates config_object_aggregator
inner::configobject::tref tref
Definition tref.hpp:36
config_object_preimage< std::string > t_config_object_preimage
config_object_key cokey
msgpack::object obj