LCOV - code coverage report
Current view: top level - dbe/src/internal - dbcontroller.cpp (source / functions) Coverage Total Hit
Test: code.result Lines: 21.2 % 184 39
Test Date: 2026-07-12 15:23:06 Functions: 30.4 % 23 7

            Line data    Source code
       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"
      14              : #include "dbe/config_reference_copy.hpp"
      15              : #include "dbe/messenger.hpp"
      16              : #include "dbe/msghandler.hpp"
      17              : 
      18              : #include <utility>
      19              : 
      20              : using namespace dunedaq::conffwk;
      21              : 
      22              : namespace dbe
      23              : {
      24              : namespace inner
      25              : {
      26              : 
      27              : namespace configobject
      28              : {
      29              : //------------------------------------------------------------------------------------------
      30              : //                                                                                                                                      NAMESPACE DBE::INNER::CONFIGOBJECT
      31              : //------------------------------------------------------------------------------------------
      32              : 
      33              : //------------------------------------------------------------------------------------------
      34              : template<typename T>
      35            0 : std::vector<T> ref_interface<T>::referenced_by(std::string const & name,
      36              :     bool check_composite_only) const
      37              : {
      38            0 :   std::vector<ConfigObject> referees;
      39            0 :   std::vector<tref> result;
      40              : 
      41            0 :   static_cast<ConfigObject &>(*this).referenced_by(referees, name, check_composite_only);
      42              : 
      43            0 :   for (ConfigObject const & x : referees)
      44              :   {
      45              :     try
      46              :     {
      47            0 :       result.push_back(inner::dbcontroller::get(
      48            0 :                          { x.UID(), x.class_name() }));
      49              :     }
      50            0 :     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            0 :   return result;
      57            0 : }
      58              : 
      59              : template
      60              : std::vector<tref> ref_interface<tref>::referenced_by(std::string const &, bool) const;
      61              : 
      62              : //------------------------------------------------------------------------------------------
      63              : 
      64              : //------------------------------------------------------------------------------------------
      65            0 : template<typename T> void gref<T>::record(tref const & o)
      66              : {
      67            0 :   t_extractor obj(o);
      68            0 :   for (auto const & linked : obj.relations)
      69              :   {
      70            0 :     for (auto const & candidate : linked.second)
      71              :     {
      72            0 :       record(candidate.ref());
      73              :     }
      74              :   }
      75            0 :   this_remove_stack.push_back(obj);
      76            0 : }
      77              : 
      78            0 : template<typename T> void gref<T>::post()
      79              : {
      80            0 :   type_extractor_stack acopy;
      81            0 :   std::swap(acopy, this_remove_stack);
      82              : 
      83            0 :   while (not acopy.empty())
      84              :   {
      85            0 :     t_extractor candidate = acopy.front();
      86              :     // Keep only objects that have been deleted
      87            0 :     if (not dbe::config::api::info::has_obj(candidate.ref.class_name(),
      88            0 :                                             candidate.ref.UID()))
      89              :     {
      90            0 :       this_remove_stack.push_back(candidate);
      91              :     }
      92            0 :     acopy.pop_front();
      93              :   }
      94            0 : }
      95              : 
      96            0 : template<typename T> void gref<T>::notify(config_action_notifiable tele)
      97              : {
      98            0 :   if (this_notify_stack.empty())
      99              :   {
     100            0 :     for (typename type_extractor_stack::value_type const & val : this_remove_stack)
     101              :     {
     102            0 :       tele(val.ref);
     103              :     }
     104              :   }
     105              :   else
     106              :   {
     107            0 :     for (typename type_ref_container::value_type const & val : this_notify_stack)
     108              :     {
     109            0 :       tele(val);
     110              :     }
     111              :   }
     112            0 : }
     113              : 
     114            0 : template<typename T> tref gref<T>::rebuild()
     115              : {
     116            0 :   if (not this_remove_stack.empty())
     117              :   {
     118            0 :     for (;;)
     119              :     {
     120            0 :       t_extractor record = this_remove_stack.front();
     121            0 :       tref last = dbcontroller::create_object_request(record.toimage());
     122            0 :       this_remove_stack.pop_front();
     123            0 :       if (not last.is_null())
     124              :       {
     125            0 :         this_notify_stack.push_back(last);
     126              :       }
     127            0 :       if (this_remove_stack.empty())
     128              :       {
     129            0 :         return last;
     130              :       }
     131              :     }
     132              :   }
     133            0 :   throw daq::dbe::gref_empty_internal_queue_is_invalid_state(ERS_HERE);
     134              : }
     135              : 
     136              : template<typename T> bool gref<T>::is_null() const
     137              : {
     138              :   return this_remove_stack.front().is_null();
     139              : }
     140              : //------------------------------------------------------------------------------------------
     141              : 
     142              : //------------------------------------------------------------------------------------------
     143              : template<typename T>
     144            0 : tref authorized_getter<T, tref>::operator()(std::string const & key)
     145              : {
     146            0 :   ConfigObject voisin
     147            0 :   { this->that->template getdirect<ConfigObject>(key) };
     148              : 
     149            0 :   if (voisin.is_null())
     150              :   {
     151            0 :     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            0 :   return dbcontroller::get({ voisin.UID(), voisin.class_name() });
     158            0 : }
     159              : 
     160              : template<typename T>
     161            0 : std::vector<tref> authorized_getter<T, std::vector<tref>>::operator()(
     162              :   std::string const & key)
     163              : {
     164            0 :   std::vector<ConfigObject> voisins
     165            0 :   { this->that->template getdirect<std::vector<ConfigObject>>(key) };
     166              : 
     167            0 :   std::vector<tref> references;
     168              : 
     169            0 :   for (ConfigObject const & voisin : voisins)
     170              :   {
     171              :     try
     172              :     {
     173            0 :       references.push_back(dbcontroller::get(
     174            0 :                              { voisin.UID(), voisin.class_name() }));
     175              :     }
     176            0 :     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            0 :   return references;
     185            0 : }
     186              : 
     187              : template class authorized_getter<tref, tref> ;
     188              : template class authorized_getter<tref, std::vector<tref>> ;
     189              : //------------------------------------------------------------------------------------------
     190              : 
     191              : }// end namespace configobject
     192              : 
     193              : //------------------------------------------------------------------------------------------
     194              : //                                                                                                                                                      NAMESPACE DBE::INNER
     195              : //------------------------------------------------------------------------------------------
     196              : 
     197              : dbcontroller::t_mutex dbcontroller::this_lock;
     198              : 
     199              : //------------------------------------------------------------------------------------------
     200            2 : dbcontroller::dbcontroller() = default;
     201              : //------------------------------------------------------------------------------------------
     202              : 
     203              : //------------------------------------------------------------------------------------------
     204           14 : dbcontroller & dbcontroller::ref()
     205              : {
     206           14 :   static dbcontroller self;
     207           14 :   return self;
     208              : }
     209              : //------------------------------------------------------------------------------------------
     210              : 
     211              : //------------------------------------------------------------------------------------------
     212            6 : void dbcontroller::flush()
     213              : {
     214            6 :   dbcontroller & me = dbcontroller::ref();
     215            6 :   locker l(me.this_lock);
     216            6 :   me.this_allobjects.clear();
     217            6 : }
     218              : //------------------------------------------------------------------------------------------
     219              : 
     220              : //------------------------------------------------------------------------------------------
     221            0 : std::vector<tref> dbcontroller::referenced_by(configobject::tref objref,
     222              :     std::string const & name,
     223              :     bool check_composite_only)
     224              : {
     225            0 :   std::vector<ConfigObject> linked;
     226            0 :   objref.ref().referenced_by(linked, name, check_composite_only);
     227              : 
     228            0 :   std::vector<configobject::tref> references;
     229              : 
     230            0 :   for (ConfigObject const & anobj : linked)
     231              :   {
     232            0 :     try
     233              :     {
     234            0 :       references.push_back(get(
     235            0 :                              { anobj.UID(), anobj.class_name() }));
     236              :     }
     237            0 :     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            0 :     }
     242              :   }
     243              : 
     244            0 :   return references;
     245            0 : }
     246              : //------------------------------------------------------------------------------------------
     247              : 
     248              : //------------------------------------------------------------------------------------------
     249            0 : template<typename T> configobject::gref<T> dbcontroller::delete_object_request(
     250              :   configobject::tref const & obj,
     251              :   typename configobject::gref<T>::config_action_notifiable notice)
     252              : {
     253            0 :   configobject::gref<T> subgraph = dbcontroller::ref().remove<T>(obj);
     254            0 :   subgraph.notify(notice);
     255            0 :   return subgraph;
     256            0 : }
     257              : 
     258              : template
     259              : configobject::gref<dbe::config_object_aggregates<std::string>>
     260              : dbcontroller::delete_object_request (
     261              :   configobject::tref const &,
     262              :   configobject::gref<dbe::config_object_aggregates<std::string>>::config_action_notifiable);
     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              :  */
     276            0 : configobject::tref dbcontroller::create_object_request(
     277              :   dbe::t_config_object_preimage const & image)
     278              : {
     279            0 :   ConfigObject result = config::api::rwdacc::create_object(image.fn,
     280            0 :       image.ref.this_class,
     281            0 :       image.ref.this_name);
     282              : 
     283            0 :   tref el = dbcontroller::ref().insert(result);
     284            0 :   try
     285              :   {
     286            0 :     return dbe::config::api::rwdacc::set_object(el,image.attributes, image.relations);
     287              :   }
     288            0 :   catch (dunedaq::conffwk::Exception const & e)
     289              :   {
     290              :     // just need to remove the object from the underlying database
     291            0 :     dbcontroller::ref().remove<config_object_aggregator>(el);
     292            0 :     throw;
     293            0 :   }
     294            0 :   catch (daq::dbe::Exception const & e)
     295              :   {
     296              :     // just need to remove the object from the underlying database
     297            0 :     dbcontroller::ref().remove<config_object_aggregator>(el);
     298            0 :     throw;
     299            0 :   }
     300            0 : }
     301              : 
     302              : template<typename T> configobject::tref dbcontroller::create_object_request(
     303              :   configobject::aref<T> const & obj)
     304              : {
     305              :   return dbcontroller::create_object_request(obj.this_object_image);
     306              : }
     307              : 
     308              : template<typename T> configobject::tref dbcontroller::create_object_request(
     309              :   configobject::gref<T> const & obj)
     310              : {
     311              :   return obj.rebuild();
     312              : }
     313              : 
     314            0 : template<typename T> configobject::tref dbcontroller::create_object_request(
     315              :   configobject::gref<T> & obj,
     316              :   typename configobject::gref<T>::config_action_notifiable notice)
     317              : {
     318            0 :   tref ret = obj.rebuild();
     319            0 :   obj.notify(notice);
     320            0 :   return ret;
     321            0 : }
     322              : 
     323              : template dbe::inner::configobject::tref dbe::inner::dbcontroller::create_object_request<
     324              : dbe::config_object_aggregates<std::string> >(
     325              :   dbe::inner::configobject::gref<dbe::config_object_aggregates<std::string> > &,
     326              :   dbe::inner::configobject::gref<dbe::config_object_aggregates<std::string> >::config_action_notifiable);
     327              : //------------------------------------------------------------------------------------------
     328              : 
     329              : //------------------------------------------------------------------------------------------
     330            0 : configobject::tref dbcontroller::move_object_request(configobject::tref objref,
     331              :     std::string const & destfile)
     332              : {
     333            0 :   if (not objref.is_null())
     334              :   {
     335            0 :     static_cast<ConfigObject &>(*(objref.refered)).move(destfile);
     336              :   }
     337              : 
     338            0 :   return objref;
     339              : }
     340              : //------------------------------------------------------------------------------------------
     341              : 
     342              : //------------------------------------------------------------------------------------------
     343            0 : configobject::tref dbcontroller::rename_object_request(configobject::tref objref,
     344              :     std::string const & newname)
     345              : {
     346            0 :   return dbcontroller::ref().rename(objref, newname);
     347              : }
     348              : //------------------------------------------------------------------------------------------
     349              : 
     350              : //------------------------------------------------------------------------------------------
     351            0 : configobject::tref dbcontroller::rename(configobject::tref objref,
     352              :                                         std::string const & aname)
     353              : {
     354            0 :   if (not objref.is_null())
     355              :   {
     356              :     // pick up the pointer
     357            0 :     std::shared_ptr<configobject::oref> current_ptr = objref.refered;
     358              : 
     359              :     // remove the current reference from the internal map
     360            0 :     this_allobjects.erase(*current_ptr);
     361            0 :     try
     362              :     {
     363              :       // rename the refered object
     364            0 :       dbe::config::api::rwdacc::rename_object(static_cast<ConfigObject &>(*current_ptr),
     365              :                                               aname);
     366              :     }
     367            0 :     catch (dunedaq::conffwk::Generic const & e)
     368              :     {
     369              :       // Logging the error but this may not affect program execution per-se
     370            0 :       FAIL("Object rename failure", dbe::config::errors::parse(e).c_str());
     371            0 :     }
     372              :     // position it in its proper place
     373            0 :     bool nofail;
     374            0 :     t_object_map::iterator position;
     375            0 :     std::tie(position, nofail) = this_allobjects.emplace(*current_ptr, current_ptr);
     376              : 
     377            0 :     if (not nofail)
     378              :     {
     379            0 :       throw daq::dbe::dbcontroller_internal_cache_failure(ERS_HERE);
     380              :     }
     381            0 :     return position->second;
     382            0 :   }
     383            0 :   return objref;
     384              : }
     385              : //------------------------------------------------------------------------------------------
     386              : 
     387              : //------------------------------------------------------------------------------------------
     388            2 : configobject::tref dbcontroller::get(dbe::cokey const & key)
     389              : {
     390            2 :   return dbcontroller::ref().lookup(key);
     391              : }
     392              : 
     393            2 : std::vector<configobject::tref> dbcontroller::gets(std::string const & cname,
     394              :     std::string const & query)
     395              : {
     396            2 :   std::vector<ConfigObject> database_objects = config::api::rwdacc::query_class(cname,
     397            2 :       query);
     398            2 :   std::vector<configobject::tref> result;
     399              : 
     400            8 :   for (ConfigObject const & keyin : database_objects)
     401              :   {
     402            6 :     try
     403              :     {
     404           12 :       result.push_back(dbcontroller::ref().lookup(
     405            6 :                          { keyin.UID(), keyin.class_name() }));
     406              :     }
     407            0 :     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            0 :     }
     412              :   }
     413            2 :   return result;
     414            2 : }
     415              : //------------------------------------------------------------------------------------------
     416              : 
     417              : //------------------------------------------------------------------------------------------
     418            8 : configobject::tref dbcontroller::lookup(dbe::cokey const & key)
     419              : {
     420              :   // Find the object in the database
     421            8 :   t_object_map::iterator position = this_allobjects.find(key);
     422              : 
     423            8 :   if (position == this_allobjects.end())
     424              :   {
     425              :     // if it is not in the cache we need to add it
     426            5 :     ConfigObject toinsert = dbe::config::api::rwdacc::get_object(key.this_class,
     427            5 :         key.this_name);
     428            5 :     if (not toinsert.is_null())
     429              :     {
     430            5 :       return insert(static_cast<ConfigObject>(toinsert));
     431              :     }
     432            5 :   }
     433              :   else
     434              :   {
     435            3 :     return position->second;
     436              :   }
     437              : 
     438            0 :   throw daq::dbe::config_object_retrieval_result_is_null ( ERS_HERE,
     439            0 :                                                            key.this_name + "@" + key.this_class );
     440              : }
     441              : //------------------------------------------------------------------------------------------
     442              : 
     443              : //------------------------------------------------------------------------------------------
     444            5 : configobject::tref dbcontroller::insert(ConfigObject const & obj)
     445              : {
     446              :   // Construct the oref to add in the internal map
     447            5 :   std::shared_ptr<configobject::oref> element(new configobject::oref(obj));
     448              : 
     449            5 :   bool object_inserted;
     450            5 :   t_object_map::iterator position;
     451              : 
     452            5 :   locker l(this_lock);
     453            5 :   std::tie(position, object_inserted) = this_allobjects.emplace(*element, element);
     454              : 
     455            5 :   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            0 :     static_cast<ConfigObject &>(*position->second) = obj;
     460              :   }
     461              : 
     462           10 :   return position->second;
     463            5 : }
     464              : //------------------------------------------------------------------------------------------
     465              : 
     466              : //------------------------------------------------------------------------------------------
     467            0 : template<typename T> configobject::gref<T> dbcontroller::remove(dbe::tref ref)
     468              : {
     469            0 :   configobject::gref<T> subgraph;
     470              : 
     471              :   {
     472            0 :     locker l(this_lock);
     473              :     // Record the associated subgraph
     474            0 :     if (not ref.is_null())
     475              :     {
     476            0 :       subgraph.record(ref);
     477              :     }
     478              : 
     479              :     // Need to remove from the internal map all candidates, they will be added at post processing
     480            0 :     for (T const & key : subgraph.this_remove_stack)
     481              :     {
     482              :       // Remove from the internal map
     483            0 :       this_allobjects.erase({ key.ref.UID(), key.ref.class_name() });
     484              :     }
     485            0 :   }
     486              : 
     487              :   // Delete the object from the database
     488            0 :   dbe::config::api::rwdacc::destroy_object(ref.ref());
     489              :   // Post-process the object recorded subgraph
     490            0 :   subgraph.post();
     491              : 
     492            0 :   return subgraph;
     493            0 : }
     494              : //------------------------------------------------------------------------------------------
     495              : 
     496              : }
     497              : // namespace inner
     498              : 
     499              : template<typename S>
     500            0 : inner::configobject::tref config_object_description<S>::ref() const
     501              : {
     502            0 :   if (this_referenced_object.is_null())
     503              :   {
     504            0 :     this_referenced_object = dbe::inner::dbcontroller::get(
     505            0 :       { this->this_name, this->this_class });
     506              :   }
     507            0 :   return this_referenced_object;
     508              : }
     509              : 
     510              : }                       // namespace dbe
        

Generated by: LCOV version 2.0-1