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 : /// Including QT Headers
7 : #include "dbe/Sorting.hpp"
8 : #include "dbe/Exceptions.hpp"
9 : #include "dbe/dbaccessor.hpp"
10 : #include "dbe/confaccessor.hpp"
11 : #include "dbe/messenger.hpp"
12 :
13 : #include "dbe/change_attribute.hpp"
14 : #include "dbe/change_enum.hpp"
15 : #include "dbe/config_api.hpp"
16 : #include "dbe/config_ui_info.hpp"
17 : #include "dbe/version.hpp"
18 :
19 : #include "conffwk/Configuration.hpp"
20 :
21 : #include <QFileInfo>
22 : #include <QStringList>
23 : #include <QVector>
24 :
25 : #include <unordered_set>
26 : #include <functional>
27 : #include <memory>
28 : #include <vector>
29 : #include <stack>
30 :
31 : using namespace dunedaq::conffwk;
32 :
33 : char const * const dbe_lib_internal_version = dbe_compiled_version;
34 :
35 : //------------------------------------------------------------------------------------------
36 21 : dbe::confaccessor & dbe::confaccessor::ref()
37 : {
38 24 : static confaccessor me;
39 21 : return me;
40 : }
41 :
42 : //------------------------------------------------------------------------------------------
43 :
44 : //------------------------------------------------------------------------------------------
45 3 : dbe::confaccessor::confaccessor()
46 3 : : CallId ( nullptr ),
47 3 : internal_change_stack ( new t_internal_changes_stack
48 3 : { } ),
49 3 : sequenced_command_stack ( new QUndoStack() ),
50 3 : editconfig ( new datahandler() ),
51 3 : coreconfig ( nullptr ),
52 3 : this_change_enabled ( false ),
53 9 : this_total_objects ( 0 )
54 3 : {}
55 :
56 3 : dbe::confaccessor::~confaccessor()
57 : {
58 3 : delete editconfig;
59 3 : delete coreconfig;
60 3 : {
61 3 : dbholder::t_lock l ( dbholder::database_lock );
62 3 : delete dbholder::database;
63 3 : }
64 3 : }
65 :
66 : //------------------------------------------------------------------------------------------
67 :
68 : //------------------------------------------------------------------------------------------
69 0 : bool dbe::confaccessor::enabled()
70 : {
71 0 : t_lock l ( ref().this_change_enabled_mutex );
72 0 : return ref().this_change_enabled;
73 0 : }
74 :
75 9 : void dbe::confaccessor::setenabled()
76 : {
77 9 : t_lock l ( this_change_enabled_mutex );
78 9 : this_change_enabled = true;
79 9 : }
80 :
81 0 : void dbe::confaccessor::setdisabled()
82 : {
83 0 : t_lock l ( this_change_enabled_mutex );
84 0 : this_change_enabled = false;
85 0 : }
86 :
87 : //------------------------------------------------------------------------------------------
88 :
89 : //------------------------------------------------------------------------------------------
90 0 : void dbe::confaccessor::force_emit_object_created ( QString const & src, dref const obj )
91 : {
92 0 : t_lock l ( force_mut );
93 0 : emit object_created ( src, obj );
94 0 : }
95 :
96 0 : void dbe::confaccessor::force_emit_object_renamed ( QString const & src, dref const obj )
97 : {
98 0 : t_lock l ( force_mut );
99 0 : emit object_renamed ( src, obj );
100 0 : }
101 :
102 0 : void dbe::confaccessor::force_emit_object_deleted ( QString const & src, dref const obj )
103 : {
104 0 : t_lock l ( force_mut );
105 0 : emit object_deleted ( src, obj );
106 0 : }
107 :
108 0 : void dbe::confaccessor::force_emit_object_changed ( QString const & src, dref const obj )
109 : {
110 0 : t_lock l ( force_mut );
111 0 : emit object_changed ( src, obj );
112 0 : }
113 :
114 : //------------------------------------------------------------------------------------------
115 :
116 : //------------------------------------------------------------------------------------------
117 0 : void dbe::confaccessor::GetFileCache ( QList<QStringList> & FileCache )
118 : {
119 0 : IncludedFileCache = FileCache;
120 0 : }
121 :
122 : //------------------------------------------------------------------------------------------
123 :
124 : //------------------------------------------------------------------------------------------
125 0 : QString dbe::confaccessor::dbfullname()
126 : {
127 0 : return ref().this_dblocation;
128 : }
129 :
130 0 : QString dbe::confaccessor::db_implementation_name()
131 : {
132 0 : return ref().this_resource_location;
133 : }
134 :
135 : //------------------------------------------------------------------------------------------
136 :
137 : //------------------------------------------------------------------------------------------
138 0 : cptr<dbe::datahandler> dbe::confaccessor::gethandler()
139 : {
140 0 : static cptr<datahandler> r ( ref().editconfig );
141 0 : return r;
142 : }
143 :
144 0 : cptr<dbe::ui::config::info> dbe::confaccessor::guiconfig()
145 : {
146 0 : static cptr<dbe::ui::config::info> r ( confaccessor::ref().coreconfig );
147 0 : return r;
148 : }
149 :
150 0 : dbe::confaccessor::t_undo_stack_cptr dbe::confaccessor::get_commands()
151 : {
152 0 : static t_undo_stack_cptr rp ( ref().sequenced_command_stack );
153 0 : return rp;
154 : }
155 :
156 : //------------------------------------------------------------------------------------------
157 :
158 : //------------------------------------------------------------------------------------------
159 0 : int dbe::confaccessor::get_total_objects()
160 : {
161 0 : return ref().this_total_objects;
162 : }
163 :
164 0 : void dbe::confaccessor::increase_total_objects ( int const i )
165 : {
166 0 : ref().this_total_objects += i;
167 0 : }
168 :
169 0 : void dbe::confaccessor::set_total_objects ( int const i )
170 : {
171 0 : ref().this_total_objects = i;
172 0 : }
173 :
174 : //------------------------------------------------------------------------------------------
175 :
176 : //------------------------------------------------------------------------------------------
177 :
178 : template<>
179 9 : void dbe::confaccessor::set_dbinfo<dbe::dbinfo::oks> ( QString const & location )
180 : {
181 12 : static QString const implementation ( "oksconflibs" );
182 :
183 9 : this_dblocation = location;
184 9 : this_resource_location = implementation + ":" + location;
185 :
186 9 : setenabled();
187 9 : }
188 :
189 : template<>
190 0 : void dbe::confaccessor::set_dbinfo<dbe::dbinfo::roks> ( QString const & location )
191 : {
192 0 : this_dblocation = location;
193 0 : static QString const implementation ( "roksconflibs" );
194 0 : this_resource_location = implementation + ":" + location;
195 0 : t_lock l ( this_change_enabled_mutex );
196 0 : this_change_enabled = true;
197 0 : }
198 :
199 : template<>
200 0 : void dbe::confaccessor::set_dbinfo<dbe::dbinfo::rdb> ( QString const & location )
201 : {
202 0 : static QString const implementation ( "rdbconfig" );
203 0 : this_resource_location = implementation + ":" + location;
204 0 : this_dblocation = this_resource_location;
205 0 : t_lock l ( this_change_enabled_mutex );
206 0 : this_change_enabled = true;
207 0 : }
208 :
209 9 : void dbe::confaccessor::setdbinfo ( QString const & location, dbinfo const itype )
210 : {
211 9 : switch ( itype )
212 : {
213 :
214 9 : case dbinfo::oks:
215 9 : ref().set_dbinfo<dbinfo::oks> ( location );
216 9 : break;
217 :
218 0 : case dbinfo::roks:
219 0 : ref().set_dbinfo<dbinfo::roks> ( location );
220 0 : break;
221 :
222 0 : case dbinfo::rdb:
223 0 : ref().set_dbinfo<dbinfo::rdb> ( location );
224 0 : break;
225 :
226 0 : default:
227 0 : ref().setenabled();
228 0 : break;
229 : }
230 9 : }
231 :
232 0 : void dbe::confaccessor::setdblocation ( QString const & Implementation )
233 : {
234 0 : ref().this_resource_location = Implementation;
235 0 : }
236 :
237 7 : bool dbe::confaccessor::is_database_loaded()
238 : {
239 7 : return dbaccessor::dbptr().get() != nullptr;
240 : }
241 :
242 : //------------------------------------------------------------------------------------------
243 :
244 : //------------------------------------------------------------------------------------------
245 0 : bool dbe::confaccessor::check_file_rw ( QString const & fn )
246 : {
247 0 : try
248 : {
249 0 : if ( not fn.endsWith ( ".schema.xml" ) )
250 : {
251 0 : return dbaccessor::dbptr()->is_writable ( fn.toStdString() );
252 : }
253 : }
254 0 : catch ( dunedaq::conffwk::Generic const & ex )
255 : {
256 0 : ERROR ( "Not possible to operate on file", dbe::config::errors::parse ( ex ),
257 0 : "\n\nCheck filename:", fn.toStdString() );
258 0 : }
259 :
260 : return false;
261 : }
262 :
263 : //------------------------------------------------------------------------------------------
264 0 : void dbe::confaccessor::clear_commands()
265 : {
266 0 : if ( ref().get_commands().get() )
267 : {
268 0 : ref().get_commands()->clear();
269 0 : t_internal_changes_stack cleared{ };
270 0 : ref().get_internal_change_stack()->swap ( cleared );
271 0 : }
272 0 : }
273 :
274 : //------------------------------------------------------------------------------------------
275 :
276 : //------------------------------------------------------------------------------------------
277 0 : void dbe::confaccessor::abort()
278 : {
279 0 : dbaccessor::dbptr()->abort();
280 0 : }
281 :
282 :
283 0 : std::list<std::string> dbe::confaccessor::uncommitted_files() {
284 0 : std::list<std::string> dbs;
285 0 : dbaccessor::dbptr()->get_updated_dbs(dbs);
286 0 : return dbs;
287 0 : }
288 : //------------------------------------------------------------------------------------------
289 :
290 : //------------------------------------------------------------------------------------------
291 9 : bool dbe::confaccessor::load(bool subscribeToChanges)
292 : {
293 9 : try
294 : {
295 9 : dbholder::t_lock l ( dbholder::database_lock );
296 :
297 9 : if ( dbholder::database == nullptr )
298 : {
299 3 : dbholder::database = new Configuration ( ref().this_resource_location.toStdString() );
300 :
301 3 : if ( subscribeToChanges == true ) {
302 3 : ref().CallId = dbholder::database->subscribe (
303 6 : ConfigurationSubscriptionCriteria(),
304 : &confaccessor::CallbackFunction,
305 : reinterpret_cast<void *> ( dbholder::database ) );
306 : }
307 : }
308 : else
309 : {
310 6 : dbe::inner::dbcontroller::flush();
311 6 : delete dbholder::database;
312 6 : dbholder::database = new Configuration ( ref().this_resource_location.toStdString() );
313 : }
314 :
315 9 : dbholder::database->prefetch_all_data();
316 :
317 9 : dbholder::database_concurrent_ptr = cptr<Configuration> ( dbholder::database );
318 9 : return true;
319 9 : }
320 0 : catch ( dunedaq::conffwk::Exception const & e )
321 : {
322 0 : FAIL ( "Database loading failed", dbe::config::errors::parse ( e ).c_str() );
323 0 : return false;
324 0 : }
325 :
326 : }
327 :
328 0 : std::list<std::string> dbe::confaccessor::save ( const QString & CommitMessage )
329 : {
330 0 : try
331 : {
332 0 : std::list<std::string> tobecommited{};
333 :
334 0 : if ( ref().is_database_loaded() )
335 : {
336 0 : dbaccessor::dbptr()->get_updated_dbs ( tobecommited );
337 0 : dbaccessor::dbptr()->commit ( CommitMessage.toStdString() );
338 0 : confaccessor::ref().db_committed(tobecommited, CommitMessage.toStdString());
339 : }
340 :
341 0 : return tobecommited;
342 0 : }
343 0 : catch ( dunedaq::conffwk::Exception const & e )
344 : {
345 : // throw daq::dbe::CouldNotCommitChanges ( ERS_HERE, dbe::config::errors::parse ( e ) );
346 0 : throw daq::dbe::CouldNotCommitChanges ( ERS_HERE, "confaccessor", e );
347 0 : }
348 : }
349 :
350 : //------------------------------------------------------------------------------------------
351 :
352 : //------------------------------------------------------------------------------------------
353 0 : void dbe::confaccessor::init()
354 : {
355 0 : QString DUNEDAQ_DB_PATH = getenv ( "DUNEDAQ_DB_PATH" );
356 0 : QString GUI_DATA = getenv ( "OKS_GUI_INIT_DATA" );
357 :
358 0 : QStringList CONFIG_DATABASE = GUI_DATA.split ( ":", Qt::SkipEmptyParts );
359 0 : QStringList DUNEDAQ_DB_PATH_SPLIT = DUNEDAQ_DB_PATH.split ( ":", Qt::SkipEmptyParts );
360 :
361 : // We need to read the current configuration ( to retrieve parameters affecting dbe )
362 :
363 0 : std::vector<std::string> full_path_names;
364 :
365 0 : for ( QString & FileName : CONFIG_DATABASE )
366 : {
367 :
368 0 : for ( QString & PATH : DUNEDAQ_DB_PATH_SPLIT )
369 : {
370 0 : QFileInfo CheckFile ( PATH + "/" + FileName );
371 :
372 0 : if ( CheckFile.exists() and CheckFile.isFile() )
373 : {
374 0 : QString fullpathname = PATH + "/" + FileName;
375 0 : full_path_names.push_back ( fullpathname.toStdString() );
376 0 : }
377 0 : }
378 : }
379 :
380 0 : confaccessor::ref().coreconfig = new ui::config::info ( full_path_names );
381 :
382 0 : }
383 :
384 0 : QList<QStringList> dbe::confaccessor::GetIncludedFileCache() const
385 : {
386 0 : return IncludedFileCache;
387 : }
388 :
389 : //------------------------------------------------------------------------------------------
390 :
391 : //------------------------------------------------------------------------------------------
392 0 : void dbe::confaccessor::addfile ( std::string const & db, std::string const & fn )
393 : {
394 0 : if ( not enabled() )
395 : {
396 0 : throw daq::dbe::ChangeNotAllowed ( ERS_HERE );
397 : }
398 :
399 0 : dbaccessor::dbptr()->add_include ( db, fn );
400 0 : emit IncludeFileDone();
401 0 : }
402 :
403 0 : void dbe::confaccessor::removefile ( std::string const & db, std::string const & fn )
404 : {
405 0 : if ( not enabled() )
406 : {
407 0 : throw daq::dbe::ChangeNotAllowed ( ERS_HERE );
408 : }
409 :
410 0 : dbaccessor::dbptr()->remove_include ( db, fn );
411 0 : emit RemoveFileDone();
412 0 : }
413 :
414 : //------------------------------------------------------------------------------------------
415 :
416 : //------------------------------------------------------------------------------------------
417 0 : void dbe::confaccessor::CallbackFunction ( std::vector<ConfigurationChange *> const &
418 : changes,
419 : void * parameter )
420 : {
421 0 : dbe::confaccessor::ref().docallback ( changes, parameter );
422 0 : }
423 :
424 0 : void dbe::confaccessor::docallback ( std::vector<ConfigurationChange *> const & changes,
425 : void * parameter )
426 : {
427 0 : Q_UNUSED ( parameter );
428 :
429 0 : t_lock l ( mut_changes );
430 0 : external_change_stack.clear();
431 :
432 0 : for ( ConfigurationChange * Change : changes )
433 : {
434 0 : const auto& cl = Change->get_class_name();
435 0 : const auto& mod = Change->get_modified_objs();
436 0 : const auto& cre = Change->get_created_objs();
437 0 : const auto& rem = Change->get_removed_objs();
438 :
439 0 : external_change_stack.push_back ( { cl, mod, cre, rem } );
440 : }
441 :
442 0 : emit ExternalChangesAccepted();
443 0 : }
444 :
445 : //------------------------------------------------------------------------------------------
446 :
447 : //------------------------------------------------------------------------------------------
448 0 : void dbe::confaccessor::unsubscribe()
449 : {
450 0 : if ( dbaccessor::dbptr().get() && ref().CallId != nullptr )
451 : {
452 0 : dbaccessor::dbptr()->unsubscribe ( ref().CallId );
453 : }
454 0 : }
455 :
456 : dbe::confaccessor::t_internal_changes_stack_cptr
457 0 : dbe::confaccessor::get_internal_change_stack()
458 : {
459 0 : static t_internal_changes_stack_cptr rp ( ref().internal_change_stack.get() );
460 0 : return rp;
461 : }
462 :
463 : //------------------------------------------------------------------------------------------
464 :
|