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