DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
oks_dump.cxx
Go to the documentation of this file.
1// DUNE DAQ modification notice:
2// This file has been modified from the original ATLAS oks source for the DUNE DAQ project.
3// Fork baseline commit: oks-08-03-04 (2022-04-14).
4// Renamed since fork: yes (from bin/oks_dump.cpp to apps/oks_dump.cxx).
5
16
17#include "oks/exceptions.hpp"
18#include "oks/kernel.hpp"
19#include "oks/query.hpp"
20
21#include <iostream>
22#include <vector>
23
24#include <stdlib.h>
25#include <string.h>
26
27using namespace dunedaq::oks;
28
39
40static void
41printUsage(std::ostream& s)
42{
43 s << "Usage: oks_dump\n"
44 " [--files-only | --files-stat-only | --schema-files-only | --schema-files-stat-only | --data-files-only | "
45 "--data-files-stat-only]\n"
46 " [--class name-of-class [--query query [--print-references recursion-depth [class-name*] [--]] "
47 "[--print-referenced_by [name] [--]]]]\n"
48 " [--path object-from object-to query]\n"
49 " [--allow-duplicated-objects-via-inheritance]\n"
50 " [--version]\n"
51 " [--help]\n"
52 " [--input-from-files] database-file [database-file(s)]\n"
53 "\n"
54 "Options:\n"
55 " -f | --files-only print list of oks files names\n"
56 " -F | --files-stat-only print list of oks files with statistic details (size, "
57 "number of items\n"
58 " -s | --schema-files-only print list of schema oks files names\n"
59 " -S | --schema-files-stat-only print list of oks schema files with statistic details\n"
60 " -d | --data-files-only print list of data oks files names\n"
61 " -D | --data-files-stat-only print list of oks data files with statistic details\n"
62 " -c | --class class_name dump given class (all objects or matching some query)\n"
63 " -q | --query query print objects matching query (can only be used with "
64 "class)\n"
65 " -r | --print-references N C1 C2 ... CX print objects referenced by found objects (can only be "
66 "used with query), where:\n"
67 " * the parameter N defines recursion depth for "
68 "referenced objects (> 0)\n"
69 " * the optional set of names {C1 .. CX} defines "
70 "[sub-]classes for above objects\n"
71 " -b | --print-referenced_by [name] print objects referencing found objects (can only be "
72 "used with query), where:\n"
73 " * the optional parameter name defines name of "
74 "relationship\n"
75 " -p | --path obj query print path from object \'obj\' to object of query "
76 "expression\n"
77 " -i | --input-from-files read oks files to be loaded from file(s) instead of "
78 "command line\n"
79 " (to avoid problems with long command line, when there is "
80 "huge number of files)\n"
81 " -a | --allow-duplicated-objects-via-inheritance do not stop if there are duplicated object via "
82 "inheritance hierarchy\n"
83 " -v | --version print version\n"
84 " -h | --help print this text\n"
85 "\n"
86 "Description:\n"
87 " Dumps contents of the OKS database.\n"
88 "\n"
89 "Return Status:\n"
90 " 0 - no problems found\n"
91 " 1 - bad command line parameter\n"
92 " 2 - bad oks file(s)\n"
93 " 3 - bad query passed via -q or -p options\n"
94 " 4 - cannot find class passed via -c option\n"
95 " 5 - loaded objects have dangling references\n"
96 " 6 - caught an exception\n"
97 "\n";
98}
99
100static void
101no_param(const char* s)
102{
103 Oks::error_msg("oks_dump") << "no parameter(s) for command line argument \'" << s << "\' provided\n\n";
104 exit(EXIT_FAILURE);
105}
106
109{
110 char* id = s;
111
112 if ((s = strchr(id, '@')) == 0)
113 return 0;
114
115 *s = '\0';
116 s++;
117
118 if (OksClass* c = k.find_class(s)) {
119 if (OksObject* o = c->get_object(id)) {
120 return o;
121 } else {
122 Oks::error_msg("oks_dump::find_object()") << "cannot find object \"" << id << '@' << s << "\"\n";
123 }
124 } else {
125 Oks::error_msg("oks_dump::find_object()") << "cannot find class \"" << s << "\"\n";
126 }
127
128 return 0;
129}
130
131int
132main(int argc, char** argv)
133{
134 if (argc == 1) {
135 printUsage(std::cerr);
136 return __BadCommandLine__;
137 }
138
139 OksKernel kernel;
141
142 try {
143
144 int dump_files_only = 0; // 0 - none, 12 - data, 1 - schema, 2 - schema & data
145 const char* class_name = 0;
146 const char* query = 0;
147 const char* object_from = 0;
148 const char* path_query = 0;
149 long recursion_depth = 0;
150 bool print_referenced_by = false;
151 const char* ref_by_rel_name = "*";
152 std::vector<std::string> ref_classes;
153 bool input_from_files = false;
154 bool print_files_stat = false;
155
156 for (int i = 1; i < argc; i++) {
157 const char* cp = argv[i];
158
159 if (!strcmp(cp, "-h") || !strcmp(cp, "--help")) {
160 printUsage(std::cout);
161 return __Success__;
162 } else if (!strcmp(cp, "-v") || !strcmp(cp, "--version")) {
163 std::cout << "OKS kernel version " << OksKernel::GetVersion() << std::endl;
164 return __Success__;
165 } else if (!strcmp(cp, "-a") || !strcmp(cp, "--allow-duplicated-objects-via-inheritance")) {
167 } else if (!strcmp(cp, "-f") || !strcmp(cp, "--files-only")) {
168 dump_files_only = 2;
169 } else if (!strcmp(cp, "-F") || !strcmp(cp, "--files-stat-only")) {
170 dump_files_only = 2;
171 print_files_stat = true;
172 } else if (!strcmp(cp, "-s") || !strcmp(cp, "--schema-files-only")) {
173 dump_files_only = 1;
174 } else if (!strcmp(cp, "-S") || !strcmp(cp, "--schema-files-stat-only")) {
175 dump_files_only = 1;
176 print_files_stat = true;
177 } else if (!strcmp(cp, "-d") || !strcmp(cp, "--data-files-only")) {
178 dump_files_only = 12;
179 } else if (!strcmp(cp, "-D") || !strcmp(cp, "--data-files-stat-only")) {
180 dump_files_only = 12;
181 print_files_stat = true;
182 } else if (!strcmp(cp, "-c") || !strcmp(cp, "--class")) {
183 if (++i == argc) {
184 no_param(cp);
185 } else {
186 class_name = argv[i];
187 }
188 } else if (!strcmp(cp, "-q") || !strcmp(cp, "--query")) {
189 if (++i == argc) {
190 no_param(cp);
191 } else {
192 query = argv[i];
193 }
194 } else if (!strcmp(cp, "-i") || !strcmp(cp, "--input-from-files")) {
195 input_from_files = true;
196 } else if (!strcmp(cp, "-r") || !strcmp(cp, "--print-references")) {
197 if (++i == argc) {
198 no_param(cp);
199 } else {
200 recursion_depth = atol(argv[i]);
201 }
202 int j = 0;
203 for (; j < argc - i - 1; ++j) {
204 if (argv[i + 1 + j][0] != '-') {
205 ref_classes.push_back(argv[i + 1 + j]);
206 } else {
207 break;
208 }
209 }
210 i += j;
211 } else if (!strcmp(cp, "-b") || !strcmp(cp, "--print-referenced_by")) {
212 print_referenced_by = true;
213 if ((i + 1) < argc && argv[i + 1][0] != '-') {
214 ref_by_rel_name = argv[++i];
215 }
216 } else if (!strcmp(cp, "-p") || !strcmp(cp, "--path")) {
217 if (++i > argc - 1) {
218 no_param(cp);
219 } else {
220 object_from = argv[i];
221 path_query = argv[++i];
222 }
223 } else if (strcmp(cp, "--")) {
224 if (input_from_files) {
225 std::ifstream f(cp);
226 if (f.good()) {
227 while (f.good() && !f.eof()) {
228 std::string file_name;
229 std::getline(f, file_name);
230 if (!file_name.empty() && kernel.load_file(file_name) == 0) {
231 Oks::error_msg("oks_dump") << "\tCan not load file \"" << file_name << "\", exiting...\n";
232 return __BadOksFile__;
233 }
234 }
235 } else {
236 Oks::error_msg("oks_dump") << "\tCan not open file \"" << cp << "\" for reading, exiting...\n";
237 return __BadCommandLine__;
238 }
239 } else {
240 if (kernel.load_file(cp) == 0) {
241 Oks::error_msg("oks_dump") << "\tCan not load file \"" << cp << "\", exiting...\n";
242 return __BadOksFile__;
243 }
244 }
245 }
246 }
247
248 if (kernel.schema_files().empty()) {
249 Oks::error_msg("oks_dump") << "\tAt least one oks file have to be provided, exiting...\n";
250 return __BadCommandLine__;
251 }
252
253 if (query && !class_name) {
254 Oks::error_msg("oks_dump")
255 << "\tQuery can only be executed when class name is provided (use -c option), exiting...\n";
256 return __BadCommandLine__;
257 }
258
259 if (dump_files_only) {
260 long total_size = 0;
261 long total_items = 0;
262 const OksFile::Map* files[2] = { &kernel.schema_files(), &kernel.data_files() };
263 for (int j = (dump_files_only / 10); j < (dump_files_only % 10); ++j) {
264 if (!files[j]->empty()) {
265 for (OksFile::Map::const_iterator i = files[j]->begin(); i != files[j]->end(); ++i) {
266 if (print_files_stat) {
267 total_size += i->second->get_size();
268 total_items += i->second->get_number_of_items();
269 std::cout << *(i->first) << " (" << i->second->get_number_of_items() << " items, "
270 << i->second->get_size() << " bytes)" << std::endl;
271 } else {
272 std::cout << *(i->first) << std::endl;
273 }
274 }
275 }
276 }
277
278 if (print_files_stat) {
279 std::cout << "Total number of items: " << total_items
280 << "\n"
281 "Total size of files: "
282 << total_size << " bytes" << std::endl;
283 }
284 } else if (class_name && *class_name) {
285 if (OksClass* c = kernel.find_class(class_name)) {
286 if (query && *query) {
287 OksQuery* q = new OksQuery(c, query);
288 if (q->good()) {
289 OksObject::List* objs = c->execute_query(q);
290 size_t num = (objs ? objs->size() : 0);
291 std::cout << "Found " << num << " matching query \"" << query << "\" in class \"" << class_name << "\"";
292 if (num) {
293 std::cout << ':' << std::endl;
294 while (!objs->empty()) {
295 OksObject* o = objs->front();
296 objs->pop_front();
297
298 if (recursion_depth > 0 || print_referenced_by) {
299 if (recursion_depth) {
300 ClassSet all_ref_classes;
301 kernel.get_all_classes(ref_classes, all_ref_classes);
302 OksObject::FSet refs;
303 o->references(refs, recursion_depth, false, &all_ref_classes);
304 std::cout << o << " references " << refs.size() << " object(s)" << std::endl;
305 for (OksObject::FSet::const_iterator i = refs.begin(); i != refs.end(); ++i) {
306 std::cout << " - " << *i << std::endl;
307 }
308 }
309 if (print_referenced_by) {
310 if (OksObject::FList* ref_by_objs = o->get_all_rels(ref_by_rel_name)) {
311 std::cout << o << " is referenced by " << ref_by_objs->size() << " object(s) via relationship \""
312 << ref_by_rel_name << "\":" << std::endl;
313
314 for (OksObject::FList::const_iterator i = ref_by_objs->begin(); i != ref_by_objs->end(); ++i) {
315 std::cout << " - " << *i << std::endl;
316 }
317
318 delete ref_by_objs;
319 } else {
320 std::cout << o << " is not referenced by any object via relationship \"" << ref_by_rel_name
321 << '\"' << std::endl;
322 }
323 }
324 } else {
325 std::cout << *o << std::endl;
326 }
327 }
328 delete objs;
329 } else {
330 std::cout << std::endl;
331 }
332 } else {
333 Oks::error_msg("oks_dump") << "\tFailed to parse query \"" << query << "\" in class \"" << class_name
334 << "\"\n";
335 return __BadQuery__;
336 }
337 delete q;
338 } else {
339 std::cout << *c << std::endl;
340 }
341 } else {
342 Oks::error_msg("oks_dump") << "\tCan not find class \"" << class_name << "\"\n";
343 return __NoSuchClass__;
344 }
345 } else if (object_from && *object_from && path_query && *path_query) {
346 OksObject* obj_from = find_object((char*)object_from, kernel);
347 try {
348 QueryPath q(path_query, kernel);
349 OksObject::List* objs = obj_from->find_path(q);
350
351 size_t num = (objs ? objs->size() : 0);
352 std::cout << "Found " << num << " objects in the path \"" << q << "\" from object " << obj_from << ":"
353 << std::endl;
354
355 if (num) {
356 while (!objs->empty()) {
357 OksObject* o = objs->front();
358 objs->pop_front();
359 std::cout << *o << std::endl;
360 }
361 delete objs;
362 }
363 } catch (bad_query_syntax& e) {
364 Oks::error_msg("oks_dump") << "\tFailed to parse query: " << e.what() << std::endl;
365 return __BadQuery__;
366 }
367 } else {
368 std::cout << kernel;
369 }
370
371 if (!kernel.get_bind_classes_status().empty()) {
372 Oks::error_msg("oks_dump") << "The schema contains dangling references to non-loaded classes:\n"
373 << kernel.get_bind_classes_status();
374 }
375
376 if (!kernel.get_bind_objects_status().empty()) {
377 Oks::error_msg("oks_dump") << "\tThe data contain dangling references to non-loaded objects\n";
378 }
379
380 if (!kernel.get_bind_classes_status().empty() || !kernel.get_bind_objects_status().empty()) {
382 }
383 } catch (exception& ex) {
384 std::cerr << "Caught oks exception:\n" << ex << std::endl;
385 return __ExceptionCaught__;
386 } catch (std::exception& e) {
387 std::cerr << "Caught standard C++ exception: " << e.what() << std::endl;
388 return __ExceptionCaught__;
389 } catch (...) {
390 std::cerr << "Caught unknown exception" << std::endl;
391 return __ExceptionCaught__;
392 }
393
394 return __Success__;
395}
The OKS class.
Definition class.hpp:223
std::map< const std::string *, OksFile *, SortByName > Map
Definition file.hpp:382
Provides interface to the OKS kernel.
Definition kernel.hpp:615
OksFile * load_file(const std::string &name, bool bind=true)
Load OKS database file.
Definition kernel.cpp:1625
const OksFile::Map & data_files() const
Get all data files.
Definition kernel.hpp:1472
const std::string & get_bind_classes_status() const noexcept
Return status of oks classes binding.
Definition kernel.hpp:1934
void set_test_duplicated_objects_via_inheritance_mode(const bool b)
Set status of test inherited duplicated objects mode. To switch 'On'/'Off' use the method's parameter...
Definition kernel.hpp:782
const std::string & get_bind_objects_status() const noexcept
Return status of oks objects binding.
Definition kernel.hpp:1922
static const char * GetVersion()
Get OKS version. The method returns string containing CVS tag and date of OKS build.
Definition kernel.cpp:274
OksClass * find_class(const std::string &class_name) const
Find class by name (C++ string).
Definition kernel.hpp:1754
const OksFile::Map & schema_files() const
Get all schema files.
Definition kernel.hpp:1211
void get_all_classes(const std::vector< std::string > &names_in, ClassSet &classes_out) const
The method searches all classes including subclasses for given names.
Definition kernel.cpp:4451
OksObject describes instance of OksClass.
Definition object.hpp:1144
std::unordered_set< OksObject *, oks::hash_obj_ptr, oks::equal_obj_ptr > FSet
Definition object.hpp:1171
std::list< OksObject * > List
Definition object.hpp:1179
void references(OksObject::FSet &refs, unsigned long recursion_depth, bool add_self=false, oks::ClassSet *classes=0) const
Definition object.cpp:3043
FList * get_all_rels(const std::string &name="*") const
Return objects referencing this one via relationship with given name.
Definition object.cpp:3062
std::list< OksObject *, boost::fast_pool_allocator< OksObject * > > FList
Definition object.hpp:1181
OksObject::List * find_path(const oks::QueryPath &query) const
Definition query.cpp:923
OKS query class.
Definition query.hpp:40
bool good() const
Definition query.hpp:57
OksQuery(bool b, OksQueryExpression *q=0)
Definition query.hpp:42
static std::ostream & error_msg(const char *)
Definition kernel.cpp:511
virtual const char * what() const noexcept
Definition query.hpp:315
int main(int argc, char *argv[])
std::unordered_set< const OksClass *, oks::hash_class_ptr, oks::equal_class_ptr > ClassSet
Definition object.hpp:1129
@ __BadCommandLine__
@ __Success__
OksObject * find_object(char *s, OksKernel &k)
Definition oks_dump.cxx:108
static void no_param(const char *s)
Definition oks_dump.cxx:101
static void printUsage(std::ostream &s)
Definition oks_dump.cxx:41
__OksDumpExitStatus__
Definition oks_dump.cxx:30
@ __ExceptionCaught__
Definition oks_dump.cxx:37
@ __BadQuery__
Definition oks_dump.cxx:34
@ __FoundDanglingReferences__
Definition oks_dump.cxx:36
@ __BadOksFile__
Definition oks_dump.cxx:33
@ __NoSuchClass__
Definition oks_dump.cxx:35