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