DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
config_dump.cxx
Go to the documentation of this file.
1//
2// DUNE DAQ modification notice:
3// This file has been modified from the original ATLAS config source for the DUNE DAQ project.
4// Fork baseline commit: 67a24e731 (2022-10-27).
5// Renamed since fork: yes (from bin/config_dump.cpp to apps/config_dump.cxx).
6//
7
8#include <stdlib.h>
9
10#include <iostream>
11#include <string>
12
13#include <boost/program_options.hpp>
14
17#include "conffwk/Schema.hpp"
18
19using namespace dunedaq::conffwk;
20
21ERS_DECLARE_ISSUE(config_dump, BadCommandLine, "bad command line: " << reason, ((const char*)reason))
22
23ERS_DECLARE_ISSUE(config_dump, ConfigException, "caught dunedaq::conffwk::Exception exception", )
24
25struct SortByName
26{
27 bool operator()(const ConfigObject* o1, const ConfigObject* o2) const { return o1->UID() < o2->UID(); }
28};
29
30static void
31print_referenced_by(const ConfigObject& obj, const char* prefix)
32{
33 std::vector<ConfigObject> values;
34 obj.referenced_by(values, "*", false, 0, 0);
35 if (values.size() == 0) {
36 std::cout << prefix << "is not referenced by others objects\n";
37 } else {
38 std::cout << prefix << "is referenced by " << values.size() << " object" << (values.size() == 1 ? "" : "s")
39 << ":\n";
40 for (const auto& iobj : values)
41 std::cout << prefix << " * " << iobj << std::endl;
42 }
43}
44
45static void
46print_versions(const std::vector<dunedaq::conffwk::Version>& versions)
47{
48 const auto len = versions.size();
49 unsigned int idx = 1;
50 for (const auto& x : versions) {
51 char buf[50];
52 std::time_t t(x.get_timestamp());
53 std::strftime(buf, 50, "%F %T %Z", std::localtime(&t));
54 std::cout << " * version [" << idx++ << '/' << len
55 << "]\n"
56 " id: "
57 << x.get_id()
58 << "\n"
59 " user: "
60 << x.get_user()
61 << "\n"
62 " date: "
63 << buf
64 << "\n"
65 " comment: "
66 << x.get_comment()
67 << "\n"
68 " files:\n";
69
70 for (const auto& f : x.get_files())
71 std::cout << " - \"" << f << "\"\n";
72 }
73}
74
75int
76main(int argc, char* argv[])
77{
78 const std::string any("*");
79 std::string db_name, class_name, object_id, since, until;
80
81 bool changes = false;
82
83 bool skip_irrelevant = true;
85
86 bool direct_info = false;
87 bool objects_details = false;
88 bool contained_in = false;
89 bool referenced_by = false;
90
91 boost::program_options::options_description desc("Dumps class and objects descriptions using abstract conffwk API.\n"
92 "Without -c or -o options, the utility lists all classes.\n"
93 "\n"
94 "Options/Arguments");
95
96 try {
97 std::vector<std::string> vesrions_str;
98 std::string class_name2;
99
100 desc.add_options()("database,d",
101 boost::program_options::value<std::string>(&db_name)->required(),
102 "database specification in format plugin-name:parameters")(
103 "changes,a", "print details of new repository versions or modified files")(
104 "versions,v",
105 boost::program_options::value<std::vector<std::string>>(&vesrions_str)->multitoken()->zero_tokens(),
106 "print details of versions from archive providing 4 parameters \"all|skip\" \"date|id|tag\" \"since\" \"until\"")(
107 "class-direct-info,c",
108 boost::program_options::value<std::string>(&class_name)->default_value("")->implicit_value(any),
109 "print direct properties of all classes, or given class if name is provided")(
110 "class-all-info,C",
111 boost::program_options::value<std::string>(&class_name2)->default_value("")->implicit_value(any),
112 "similar to -c, but prints all properties of class (all attributes, all superclasses, etc.)")(
113 "list-objects,o", "list objects of class")("print-referenced-by,r",
114 "print objects referencing given object (only with -o option)")(
115 "dump-objects,O",
116 boost::program_options::value<std::string>(&object_id)->default_value("")->implicit_value(any),
117 "dump all objects of class or details of given object, if id is provided (-c is required)")(
118 "show-contained-in,n", "when dump an object, print out the database file it belongs to")("help,h",
119 "print help message");
120
121 boost::program_options::variables_map vm;
122 boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
123
124 if (vm.count("help")) {
125 std::cout << desc << std::endl;
126 return EXIT_SUCCESS;
127 }
128
129 boost::program_options::notify(vm);
130
131 if (!class_name.empty())
132 direct_info = true;
133
134 if (!class_name2.empty()) {
135 if (!class_name.empty())
136 throw std::runtime_error("cannot use -c and -C options simultaneously");
137 else
138 class_name = std::move(class_name2);
139 }
140
141 if (vm.count("changes"))
142 changes = true;
143
144 if (!vesrions_str.empty()) {
145 if (vesrions_str.size() != 4) {
146 throw std::runtime_error("-v option must have 4 parameters, see help");
147 } else {
148 if (vesrions_str[0] == "all")
149 skip_irrelevant = false;
150 else if (vesrions_str[0] != "skip")
151 throw std::runtime_error("first parameter of -v has to be \"all\" or \"skip\"");
152
153 if (vesrions_str[1] == "date")
155 else if (vesrions_str[1] == "id")
157 else if (vesrions_str[1] != "tag")
158 throw std::runtime_error("second versions parameter must be \"date\", \"id\" or \"tag\"");
159
160 since = vesrions_str[2];
161 until = vesrions_str[3];
162 }
163 }
164
165 if (!object_id.empty())
166 objects_details = true;
167
168 if (vm.count("list-objects")) {
169 objects_details = false;
170 object_id = any;
171 }
172
173 if (vm.count("print-referenced-by"))
174 referenced_by = true;
175
176 if (vm.count("show-contained-in"))
177 contained_in = true;
178
179 if (class_name.empty() && !object_id.empty() && object_id != any)
180 throw std::runtime_error("object id is set, but no class name given (use -c option)");
181 } catch (std::exception& ex) {
182 ers::fatal(config_dump::BadCommandLine(ERS_HERE, ex.what()));
183 return EXIT_FAILURE;
184 }
185
186 try {
187 Configuration conf(db_name);
188
189 // get versions if any
190 if (changes) {
191 std::cout << "Changes:\n";
193 return EXIT_SUCCESS;
194 }
195
196 if (!since.empty()) {
197 std::cout << "Versions:\n";
198 print_versions(conf.get_versions(since, until, query_type, skip_irrelevant));
199 return EXIT_SUCCESS;
200 }
201
202 std::set<std::string> classes;
203
204 if (!class_name.empty() && class_name != any)
205 classes.insert(class_name);
206 else
207 for (const auto& i : conf.superclasses())
208 classes.insert(*i.first);
209
210 // if there are no options, just list classes
211 if (class_name.empty() && object_id.empty()) {
212 std::cout << "The database schema has " << classes.size() << " class(es):\n";
213 for (const auto& i : classes)
214 std::cout << " - \'" << i << "\'\n";
215 return EXIT_SUCCESS;
216 }
217
218 // only print details of classes
219 if (!class_name.empty() && object_id.empty()) {
220 if (class_name == any)
221 std::cout << "The database schema has " << classes.size() << " class(es):\n";
222
223 for (const auto& i : classes)
224 conf.get_class_info(i, direct_info).print(std::cout, " ");
225
226 return EXIT_SUCCESS;
227 }
228
229 const char* prefix = "";
230 const char* prefix2 = " ";
231 const char* prefix3 = " ";
232
233 // list or print all objects of class(es)
234 if (object_id == any) {
235 if (class_name.empty() || class_name == any) {
236 std::cout << "The database schema has " << classes.size() << " class(es):\n";
237 prefix = " ";
238 prefix2 = " ";
239 prefix3 = " ";
240 }
241
242 for (std::set<std::string>::const_iterator i = classes.begin(); i != classes.end(); ++i) {
243 std::vector<ConfigObject> objects;
244 conf.get(*i, objects);
245 if (objects.empty()) {
246 std::cout << prefix << "The class \'" << *i << "\' has no objects\n";
247 } else {
248 std::cout << prefix << "The class \'" << *i << "\' has " << objects.size()
249 << " object(s) including sub-classes:\n";
250
251 // sort by ID for consistent output
252 std::set<const ConfigObject*, SortByName> sorted_by_id;
253
254 for (const auto& j : objects)
255 sorted_by_id.insert(&j);
256
257 for (const auto& j : sorted_by_id)
258 if (j->class_name() == *i) {
259 if (objects_details)
260 j->print_ref(std::cout, conf, prefix2, contained_in);
261 else
262 std::cout << prefix << " - \'" << j->UID() << "\'\n";
263
264 if (referenced_by)
265 print_referenced_by(*j, prefix3);
266 } else {
267 std::cout << prefix << " - \'" << j->UID() << "\' (database class name = \'" << j->class_name()
268 << "\')\n";
269 }
270 }
271 }
272 } else {
274 conf.get(class_name, object_id, obj);
275 obj.print_ref(std::cout, conf, "", contained_in);
276 if (referenced_by)
277 print_referenced_by(obj, prefix2);
278 }
279 } catch (dunedaq::conffwk::Exception& ex) {
280 ers::fatal(config_dump::ConfigException(ERS_HERE, ex));
281 return EXIT_FAILURE;
282 }
283
284 return EXIT_SUCCESS;
285}
#define ERS_HERE
Represents database objects.
const std::string & UID() const noexcept
Return object identity.
Defines base class for cache of template objects.
const conffwk::fmap< conffwk::fset > & superclasses() const noexcept
void get(const std::string &class_name, const std::string &id, ConfigObject &object, unsigned long rlevel=0, const std::vector< std::string > *rclasses=0)
Get object by class name and object id (multi-thread safe).
const dunedaq::conffwk::class_t & get_class_info(const std::string &class_name, bool direct_only=false)
The method provides access to description of class.
std::vector< dunedaq::conffwk::Version > get_changes()
Get new conffwk versions.
std::vector< dunedaq::conffwk::Version > get_versions(const std::string &since, const std::string &until, dunedaq::conffwk::Version::QueryType type=dunedaq::conffwk::Version::query_by_date, bool skip_irrelevant=true)
Get repository versions in interval.
conffwk entry point
static void print_versions(const std::vector< dunedaq::conffwk::Version > &versions)
static void print_referenced_by(const ConfigObject &obj, const char *prefix)
int main(int argc, char *argv[])
#define ERS_DECLARE_ISSUE(namespace_name, class_name, message_, attributes)
Definition macro.hpp:71
msgpack::object obj
void fatal(const Issue &issue)
Definition ers.hpp:111
void print(std::ostream &out, const std::string &prefix="") const