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
23{
24namespace inner
25{
26
27namespace configobject
28{
29//------------------------------------------------------------------------------------------
30// NAMESPACE DBE::INNER::CONFIGOBJECT
31//------------------------------------------------------------------------------------------
32
33//------------------------------------------------------------------------------------------
34template<typename T>
35std::vector<T> ref_interface<T>::referenced_by(std::string const & name,
36 bool check_composite_only) const
37{
38 std::vector<ConfigObject> referees;
39 std::vector<tref> result;
40
41 static_cast<ConfigObject &>(*this).referenced_by(referees, name, check_composite_only);
42
43 for (ConfigObject const & x : referees)
44 {
45 try
46 {
47 result.push_back(inner::dbcontroller::get(
48 { x.UID(), x.class_name() }));
49 }
50 catch (daq::dbe::config_object_retrieval_result_is_null const & e)
51 {
52 // Nothing needed to do here, this is normal, just the query has resulted in null
53 }
54 }
55
56 return result;
57}
58
59template
60std::vector<tref> ref_interface<tref>::referenced_by(std::string const &, bool) const;
61
62//------------------------------------------------------------------------------------------
63
64//------------------------------------------------------------------------------------------
65template<typename T> void gref<T>::record(tref const & o)
66{
68 for (auto const & linked : obj.relations)
69 {
70 for (auto const & candidate : linked.second)
71 {
72 record(candidate.ref());
73 }
74 }
75 this_remove_stack.push_back(obj);
76}
77
78template<typename T> void gref<T>::post()
79{
81 std::swap(acopy, this_remove_stack);
82
83 while (not acopy.empty())
84 {
85 t_extractor candidate = acopy.front();
86 // Keep only objects that have been deleted
87 if (not dbe::config::api::info::has_obj(candidate.ref.class_name(),
88 candidate.ref.UID()))
89 {
90 this_remove_stack.push_back(candidate);
91 }
92 acopy.pop_front();
93 }
94}
95
96template<typename T> void gref<T>::notify(config_action_notifiable tele)
97{
98 if (this_notify_stack.empty())
99 {
100 for (typename type_extractor_stack::value_type const & val : this_remove_stack)
101 {
102 tele(val.ref);
103 }
104 }
105 else
107 for (typename type_ref_container::value_type const & val : this_notify_stack)
108 {
109 tele(val);
110 }
111 }
112}
113
114template<typename T> tref gref<T>::rebuild()
115{
116 if (not this_remove_stack.empty())
117 {
118 for (;;)
119 {
122 this_remove_stack.pop_front();
123 if (not last.is_null())
124 {
125 this_notify_stack.push_back(last);
126 }
127 if (this_remove_stack.empty())
128 {
129 return last;
130 }
131 }
132 }
133 throw daq::dbe::gref_empty_internal_queue_is_invalid_state(ERS_HERE);
134}
135
136template<typename T> bool gref<T>::is_null() const
137{
138 return this_remove_stack.front().is_null();
139}
140//------------------------------------------------------------------------------------------
141
142//------------------------------------------------------------------------------------------
143template<typename T>
144tref authorized_getter<T, tref>::operator()(std::string const & key)
145{
146 ConfigObject voisin
147 { this->that->template getdirect<ConfigObject>(key) };
148
149 if (voisin.is_null())
150 {
151 throw daq::dbe::config_object_retrieval_result_is_null(ERS_HERE,key);
152 }
153
154 // There is no need to catch the resulting exception from get because the object
155 // has just been retrieved from the database, and the call to get just generates
156 // the tref and adds the object to the internal lookup table.
157 return dbcontroller::get({ voisin.UID(), voisin.class_name() });
158}
159
160template<typename T>
161std::vector<tref> authorized_getter<T, std::vector<tref>>::operator()(
162 std::string const & key)
163{
164 std::vector<ConfigObject> voisins
165 { this->that->template getdirect<std::vector<ConfigObject>>(key) };
166
167 std::vector<tref> references;
168
169 for (ConfigObject const & voisin : voisins)
170 {
171 try
172 {
174 { voisin.UID(), voisin.class_name() }));
175 }
176 catch (daq::dbe::config_object_retrieval_result_is_null const & ex)
177 {
178 // Actually there is no need to handle this error here ,
179 // since the object will not be added to the result list of references,
180 // and can be safely ignored
181 }
182 }
183
184 return references;
185}
186
187template class authorized_getter<tref, tref> ;
189//------------------------------------------------------------------------------------------
190
191}// end namespace configobject
192
193//------------------------------------------------------------------------------------------
194// NAMESPACE DBE::INNER
195//------------------------------------------------------------------------------------------
196
198
199//------------------------------------------------------------------------------------------
201//------------------------------------------------------------------------------------------
202
203//------------------------------------------------------------------------------------------
205{
206 static dbcontroller self;
207 return self;
208}
209//------------------------------------------------------------------------------------------
210
211//------------------------------------------------------------------------------------------
213{
215 locker l(me.this_lock);
216 me.this_allobjects.clear();
217}
218//------------------------------------------------------------------------------------------
219
220//------------------------------------------------------------------------------------------
222 std::string const & name,
223 bool check_composite_only)
224{
225 std::vector<ConfigObject> linked;
226 objref.ref().referenced_by(linked, name, check_composite_only);
227
228 std::vector<configobject::tref> references;
229
230 for (ConfigObject const & anobj : linked)
231 {
232 try
233 {
234 references.push_back(get(
235 { anobj.UID(), anobj.class_name() }));
236 }
237 catch (daq::dbe::config_object_retrieval_result_is_null const & e)
238 {
239 // nothing needed to do here, since this just signal that
240 // some of the relation results are null
241 }
242 }
243
244 return references;
245}
246//------------------------------------------------------------------------------------------
247
248//------------------------------------------------------------------------------------------
250 configobject::tref const & obj,
252{
254 subgraph.notify(notice);
255 return subgraph;
256}
257
258template
261 configobject::tref const &,
263
264//------------------------------------------------------------------------------------------
265
266//------------------------------------------------------------------------------------------
267/*
268 * Create an object in the database.
269 *
270 * If the object cannot be created an exception will be thrown
271 * by the underlying database access layer, as it cannot be handled here.
272 *
273 * If the object is already in the underlying container the object reference will be updated
274 * to point to the new object reference, transparently to user classes of the controller
275 */
277 dbe::t_config_object_preimage const & image)
278{
280 image.ref.this_class,
281 image.ref.this_name);
282
283 tref el = dbcontroller::ref().insert(result);
284 try
285 {
287 }
288 catch (dunedaq::conffwk::Exception const & e)
289 {
290 // just need to remove the object from the underlying database
292 throw;
293 }
294 catch (daq::dbe::Exception const & e)
295 {
296 // just need to remove the object from the underlying database
298 throw;
299 }
300}
301
304{
305 return dbcontroller::create_object_request(obj.this_object_image);
306}
307
310{
311 return obj.rebuild();
312}
313
317{
318 tref ret = obj.rebuild();
319 obj.notify(notice);
320 return ret;
321}
322
327//------------------------------------------------------------------------------------------
328
329//------------------------------------------------------------------------------------------
331 std::string const & destfile)
332{
333 if (not objref.is_null())
334 {
335 static_cast<ConfigObject &>(*(objref.refered)).move(destfile);
336 }
337
338 return objref;
339}
340//------------------------------------------------------------------------------------------
341
342//------------------------------------------------------------------------------------------
344 std::string const & newname)
345{
346 return dbcontroller::ref().rename(objref, newname);
347}
348//------------------------------------------------------------------------------------------
349
350//------------------------------------------------------------------------------------------
352 std::string const & aname)
353{
354 if (not objref.is_null())
355 {
356 // pick up the pointer
357 std::shared_ptr<configobject::oref> current_ptr = objref.refered;
358
359 // remove the current reference from the internal map
360 this_allobjects.erase(*current_ptr);
361 try
362 {
363 // rename the refered object
364 dbe::config::api::rwdacc::rename_object(static_cast<ConfigObject &>(*current_ptr),
365 aname);
366 }
367 catch (dunedaq::conffwk::Generic const & e)
368 {
369 // Logging the error but this may not affect program execution per-se
370 FAIL("Object rename failure", dbe::config::errors::parse(e).c_str());
371 }
372 // position it in its proper place
373 bool nofail;
374 t_object_map::iterator position;
375 std::tie(position, nofail) = this_allobjects.emplace(*current_ptr, current_ptr);
376
377 if (not nofail)
378 {
379 throw daq::dbe::dbcontroller_internal_cache_failure(ERS_HERE);
380 }
381 return position->second;
382 }
383 return objref;
384}
385//------------------------------------------------------------------------------------------
386
387//------------------------------------------------------------------------------------------
392
393std::vector<configobject::tref> dbcontroller::gets(std::string const & cname,
394 std::string const & query)
395{
396 std::vector<ConfigObject> database_objects = config::api::rwdacc::query_class(cname,
397 query);
398 std::vector<configobject::tref> result;
399
400 for (ConfigObject const & keyin : database_objects)
401 {
402 try
403 {
404 result.push_back(dbcontroller::ref().lookup(
405 { keyin.UID(), keyin.class_name() }));
406 }
407 catch (daq::dbe::config_object_retrieval_result_is_null const & e)
408 {
409 // nothing needs be done to specifically handle this case, it just that in some
410 // cases the underlying database does not contain initialized objects
411 }
412 }
413 return result;
414}
415//------------------------------------------------------------------------------------------
416
417//------------------------------------------------------------------------------------------
419{
420 // Find the object in the database
421 t_object_map::iterator position = this_allobjects.find(key);
422
423 if (position == this_allobjects.end())
424 {
425 // if it is not in the cache we need to add it
427 key.this_name);
428 if (not toinsert.is_null())
429 {
430 return insert(static_cast<ConfigObject>(toinsert));
431 }
432 }
433 else
434 {
435 return position->second;
436 }
437
438 throw daq::dbe::config_object_retrieval_result_is_null ( ERS_HERE,
439 key.this_name + "@" + key.this_class );
440}
441//------------------------------------------------------------------------------------------
442
443//------------------------------------------------------------------------------------------
445{
446 // Construct the oref to add in the internal map
447 std::shared_ptr<configobject::oref> element(new configobject::oref(obj));
448
449 bool object_inserted;
450 t_object_map::iterator position;
451
452 locker l(this_lock);
453 std::tie(position, object_inserted) = this_allobjects.emplace(*element, element);
454
455 if (not object_inserted)
456 {
457 // Object is already defined in the database and we replace the old reference with the new.
458 // A case is if there have been external modification and we try to replay changes
459 static_cast<ConfigObject &>(*position->second) = obj;
460 }
461
462 return position->second;
463}
464//------------------------------------------------------------------------------------------
465
466//------------------------------------------------------------------------------------------
468{
469 configobject::gref<T> subgraph;
470
471 {
472 locker l(this_lock);
473 // Record the associated subgraph
474 if (not ref.is_null())
475 {
476 subgraph.record(ref);
477 }
478
479 // Need to remove from the internal map all candidates, they will be added at post processing
480 for (T const & key : subgraph.this_remove_stack)
481 {
482 // Remove from the internal map
483 this_allobjects.erase({ key.ref.UID(), key.ref.class_name() });
484 }
485 }
486
487 // Delete the object from the database
489 // Post-process the object recorded subgraph
490 subgraph.post();
491
492 return subgraph;
493}
494//------------------------------------------------------------------------------------------
495
496}
497// namespace inner
498
499template<typename S>
509
510} // 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:88
static void destroy_object(dunedaq::conffwk::ConfigObject &)
Definition rwdacc.cpp:343
static dunedaq::conffwk::ConfigObject get_object(std::string const &, std::string const &)
Definition rwdacc.cpp:360
static std::vector< dunedaq::conffwk::ConfigObject > query_class(std::string const &classname, std::string const &query)
Definition rwdacc.cpp:392
static dunedaq::conffwk::ConfigObject create_object(std::string const &fn, std::string const &cn, std::string const &name)
Definition rwdacc.cpp:47
static void rename_object(dunedaq::conffwk::ConfigObject &object, std::string const &newname)
Definition rwdacc.cpp:422
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(...)
Only Configuration DB opened by rdbconfig or oksconflibs plug in can be const char *message Internal DBE references cannot point to null ConfigObject references
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:35
config_object_preimage< std::string > t_config_object_preimage
config_object_key cokey
msgpack::object obj