Line data Source code
1 : //
2 : // DUNE DAQ modification notice:
3 : // This file has been modified from the original ATLAS oks_utils source for the DUNE DAQ project.
4 : // Fork baseline commit: c2e7dfc7 (2022-03-30).
5 : // Renamed since fork: yes (from src/bin/oks_merge.cpp to apps/oks_merge.cxx).
6 : //
7 :
8 : /**
9 : * \file oks_merge.cpp
10 : *
11 : * This file is part of the OKS package.
12 : * https://gitlab.cern.ch/atlas-tdaq-software/oks
13 : *
14 : * This file contains the implementation of the OKS application to merge several data files into a single data files.
15 : */
16 :
17 : #include "oks/kernel.hpp"
18 :
19 : using namespace dunedaq;
20 : using namespace dunedaq::oks;
21 :
22 : ////////////////////////////////////////////////////////////////////////////////////////////////////
23 :
24 : #include "ers/ers.hpp"
25 :
26 0 : ERS_DECLARE_ISSUE(oks_merge, BadCommandLine, "Bad command line: \"" << what << '\"', ((const char*)what))
27 :
28 0 : ERS_DECLARE_ISSUE(oks_merge,
29 : BadQuery,
30 : "Failed to parse query \"" << query << "\" in class \"" << class_name << '\"',
31 : ((const char*)query)((const char*)class_name))
32 :
33 0 : ERS_DECLARE_ISSUE(oks_merge, BadClass, "Cannot find class \"" << class_name << '\"', ((const char*)class_name))
34 :
35 : /** Failed to read OKS database file. */
36 :
37 0 : ERS_DECLARE_ISSUE(oks_merge,
38 : CaughtException,
39 : "Caught " << what << " exception: \'" << text << '\'',
40 : ((const char*)what)((const char*)text))
41 :
42 : ////////////////////////////////////////////////////////////////////////////////////////////////////
43 :
44 : std::string appTitle;
45 :
46 : void
47 0 : printUsage(const char* appName, std::ostream& s)
48 : {
49 0 : s << appTitle
50 : << "\n"
51 : "Usage: "
52 : << appName
53 : << "\n"
54 : " [--class name-of-class [--query query [--print-references recursion-depth [class-name*] [--]]]\n"
55 : " [--version]\n"
56 : " [--help]\n"
57 : " [--out-data-file data_file] [--out-data-file schema_file] inputfiles*\n"
58 : "\n"
59 : " Options:\n"
60 : " -o | --out-data-file datafilename the out filename to store oks objects from input files\n"
61 : " -s | --out-schema-file schemafilename the out filename to store oks classes from input files\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 class)\n"
64 : " -r | --print-references N C1 C2 ... CX print objects referenced by found objects (can only be used with "
65 : "query), where:\n"
66 : " * the parameter N defines recursion depth for referenced objects "
67 : "(> 0)\n"
68 : " * the optional set of names {C1 .. CX} defines [sub-]classes for "
69 : "above objects\n"
70 : " -v | --version print version\n"
71 : " -h | --help print this text\n"
72 : "\n"
73 : " Description:\n"
74 : " Merges several oks files into single schema and data files.\n"
75 0 : "\n";
76 0 : }
77 :
78 : enum __OksMergeExitStatus__
79 : {
80 : __Success__ = 0,
81 : __NoDataFilesLoaded__,
82 : __NoSchemaFilesLoaded__,
83 : __BadCommandLine__,
84 : __NoOutputSchemaFile__,
85 : __BadQuery__,
86 : __NoSuchClass__,
87 : __ExceptionCaught__
88 : };
89 :
90 : static void
91 0 : no_param(const char* s)
92 : {
93 0 : Oks::error_msg("oks_merge") << "no parameter(s) for command line argument \'" << s << "\' provided\n\n";
94 0 : exit(__BadCommandLine__);
95 : }
96 :
97 : int
98 0 : main(int argc, char* argv[])
99 : {
100 0 : appTitle = "OKS merge. OKS kernel version ";
101 0 : appTitle += OksKernel::GetVersion();
102 :
103 0 : const char* appName = "oks_merge";
104 :
105 0 : std::string out_data_file;
106 0 : std::string out_schema_file;
107 :
108 0 : const char* class_name = nullptr;
109 0 : const char* query = nullptr;
110 0 : long recursion_depth = 0;
111 0 : std::vector<std::string> ref_classes;
112 :
113 0 : if (argc == 1) {
114 0 : printUsage(appName, std::cerr);
115 : return __BadCommandLine__;
116 : }
117 :
118 0 : OksKernel kernel;
119 0 : kernel.set_use_strict_repository_paths(false);
120 :
121 0 : try {
122 :
123 0 : for (int i = 1; i < argc; i++) {
124 0 : const char* cp = argv[i];
125 :
126 0 : if (!strcmp(cp, "-h") || !strcmp(cp, "--help")) {
127 0 : printUsage(appName, std::cout);
128 : return __Success__;
129 0 : } else if (!strcmp(cp, "-v") || !strcmp(cp, "--version")) {
130 0 : std::cout << appTitle << std::endl;
131 : return __Success__;
132 0 : } else if (!strcmp(cp, "-o") || !strcmp(cp, "--out-data-file")) {
133 0 : if (++i == argc) {
134 0 : no_param(cp);
135 : } else {
136 0 : out_data_file = argv[i];
137 : }
138 0 : } else if (!strcmp(cp, "-s") || !strcmp(cp, "--out-schema-file")) {
139 0 : if (++i == argc) {
140 0 : no_param(cp);
141 : } else {
142 0 : out_schema_file = argv[i];
143 : }
144 0 : } else if (!strcmp(cp, "-c") || !strcmp(cp, "--class")) {
145 0 : if (++i == argc) {
146 0 : no_param(cp);
147 : } else {
148 0 : class_name = argv[i];
149 : }
150 0 : } else if (!strcmp(cp, "-q") || !strcmp(cp, "--query")) {
151 0 : if (++i == argc) {
152 0 : no_param(cp);
153 : } else {
154 0 : query = argv[i];
155 : }
156 0 : } else if (!strcmp(cp, "-r") || !strcmp(cp, "--print-references")) {
157 0 : if (++i == argc) {
158 0 : no_param(cp);
159 : } else {
160 0 : recursion_depth = atol(argv[i]);
161 : }
162 0 : int j = 0;
163 0 : for (; j < argc - i - 1; ++j) {
164 0 : if (argv[i + 1 + j][0] != '-') {
165 0 : ref_classes.push_back(argv[i + 1 + j]);
166 : } else {
167 : break;
168 : }
169 : }
170 0 : i += j;
171 0 : } else if (strcmp(cp, "--")) {
172 0 : kernel.load_file(cp);
173 : }
174 : }
175 :
176 0 : if (!out_data_file.empty() && kernel.data_files().empty()) {
177 0 : ers::fatal(oks_merge::BadCommandLine(ERS_HERE, "There were no data files loaded"));
178 0 : return __NoDataFilesLoaded__;
179 : }
180 :
181 0 : if (!out_schema_file.empty() && kernel.schema_files().empty()) {
182 0 : ers::fatal(oks_merge::BadCommandLine(ERS_HERE, "There were no schema files loaded"));
183 0 : return __NoSchemaFilesLoaded__;
184 : }
185 :
186 0 : if (query && !class_name) {
187 0 : ers::fatal(
188 0 : oks_merge::BadCommandLine(ERS_HERE, "Query can only be executed when class name is provided (use -c option)"));
189 0 : return __BadCommandLine__;
190 : }
191 :
192 0 : OksFile* data_file_h = 0;
193 0 : OksFile* schema_file_h = 0;
194 :
195 0 : if (!out_data_file.empty()) {
196 0 : data_file_h = kernel.new_data(out_data_file);
197 0 : kernel.set_active_data(data_file_h);
198 : }
199 :
200 0 : if (!out_schema_file.empty()) {
201 0 : schema_file_h = kernel.new_schema(out_schema_file);
202 0 : kernel.set_active_schema(schema_file_h);
203 : }
204 :
205 0 : if (!data_file_h && !schema_file_h) {
206 0 : ers::fatal(oks_merge::BadCommandLine(ERS_HERE, "There is no out schema file name defined"));
207 0 : return __NoOutputSchemaFile__;
208 : }
209 :
210 0 : if (schema_file_h) {
211 0 : for (OksClass::Map::const_iterator j = kernel.classes().begin(); j != kernel.classes().end(); ++j) {
212 0 : j->second->set_file(schema_file_h, false);
213 : }
214 :
215 0 : kernel.save_schema(schema_file_h);
216 : }
217 :
218 0 : if (data_file_h) {
219 0 : if (schema_file_h) {
220 0 : data_file_h->add_include_file(out_schema_file);
221 : }
222 :
223 0 : if (class_name && *class_name) {
224 0 : if (OksClass* c = kernel.find_class(class_name)) {
225 0 : if (query && *query) {
226 0 : OksQuery* q = new OksQuery(c, query);
227 0 : if (q->good()) {
228 0 : OksObject::List* objs = c->execute_query(q);
229 0 : size_t num = (objs ? objs->size() : 0);
230 0 : std::cout << "Found " << num << " matching query \"" << query << "\" in class \"" << class_name << "\"";
231 0 : if (num) {
232 0 : OksObject::FSet refs;
233 0 : std::cout << ':' << std::endl;
234 0 : while (!objs->empty()) {
235 0 : OksObject* o = objs->front();
236 0 : objs->pop_front();
237 0 : if (recursion_depth > 0) {
238 0 : oks::ClassSet all_ref_classes;
239 0 : kernel.get_all_classes(ref_classes, all_ref_classes);
240 0 : o->references(refs, recursion_depth, true, &all_ref_classes);
241 0 : std::cout << " - " << o << " references " << refs.size() << " objects" << std::endl;
242 0 : } else {
243 0 : refs.insert(o);
244 : }
245 : }
246 0 : delete objs;
247 0 : for (OksObject::FSet::iterator i = refs.begin(); i != refs.end(); ++i) {
248 0 : const_cast<OksObject*>(*i)->set_file(data_file_h, false);
249 : }
250 0 : } else {
251 0 : std::cout << std::endl;
252 : }
253 : } else {
254 0 : ers::fatal(oks_merge::BadQuery(ERS_HERE, query, class_name));
255 0 : return __BadQuery__;
256 : }
257 0 : delete q;
258 : } else {
259 0 : std::cout << *c << std::endl;
260 : }
261 : } else {
262 0 : ers::fatal(oks_merge::BadClass(ERS_HERE, class_name));
263 0 : return __NoSuchClass__;
264 : }
265 : } else {
266 0 : for (OksObject::Set::const_iterator j = kernel.objects().begin(); j != kernel.objects().end(); ++j) {
267 0 : (*j)->set_file(data_file_h, false);
268 : }
269 : }
270 :
271 0 : kernel.save_data(data_file_h);
272 : }
273 :
274 : }
275 :
276 0 : catch (oks::exception& ex) {
277 0 : ers::fatal(oks_merge::CaughtException(ERS_HERE, "OKS", ex.what()));
278 0 : return __ExceptionCaught__;
279 0 : }
280 :
281 0 : catch (std::exception& ex) {
282 0 : ers::fatal(oks_merge::CaughtException(ERS_HERE, "Standard C++", ex.what()));
283 0 : return __ExceptionCaught__;
284 0 : }
285 :
286 0 : catch (...) {
287 0 : ers::fatal(oks_merge::CaughtException(ERS_HERE, "unknown", ""));
288 0 : return __ExceptionCaught__;
289 0 : }
290 :
291 : return __Success__;
292 0 : }
|