DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
oks_get_data.cxx
Go to the documentation of this file.
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_get_data.cpp to apps/oks_get_data.cxx).
6//
7
8#include <unistd.h>
9#include <iostream>
10#include <stdexcept>
11
12#include "CoralBase/Exception.h"
13#include "CoralKernel/Context.h"
14#include "RelationalAccess/ITransaction.h"
15#include "RelationalAccess/ConnectionService.h"
16#include "RelationalAccess/ISessionProxy.h"
17
18#include "oks/kernel.hpp"
19#include "oks/ral.hpp"
20
21static void
23{
24 std::cout <<
25 "usage: oks_get_data\n"
26 " -c | --connect-string connect_string\n"
27 " -w | --working-schema schema_name\n"
28 " [-t | --tag data_tag]\n"
29 " [-e | --head-data-version [release-name]]\n"
30 " [-s | --schema-version schema_version]\n"
31 " [-n | --data-version data_version]\n"
32 " [-m | --out-schema-file schema_file]\n"
33 " [-f | --out-data-file data_file]\n"
34 " [-q | --query class oks-query [-r | --reference-level ref-level]]\n"
35 " [-v | --verbose-level verbosity_level]\n"
36 " [-h | --help]\n"
37 "\n"
38 "Options/Arguments:\n"
39 " -c connect_string database connection string\n"
40 " -w schema_name name of working schema\n"
41 " -t data_tag get data by tag\n"
42 " -e [release-name] get HEAD data version (cannot be used with -n);\n"
43 " if there is no -s, then for schema HEAD version of \'" TDAQ_CMT_RELEASE "\' or the explicit release\n"
44 " -s schema_version get data for given schema version (extra -n or -e to get HEAD data version is required)\n"
45 " -n data_version get data by version (extra -s is required, but cannot be used with -e)\n"
46 " -m out_schema_file name for output schema file\n"
47 " -f out_data_file name for output data file\n"
48 " -q class query only get objects of given class satisfying query\n"
49 " -r ref-level also get objects referencing above objects with given recursion level\n"
50 " -v verbosity_level set verbose output level (0 - silent, 1 - normal, 2 - extended, 3 - debug, ...)\n"
51 " -h print this message\n"
52 "\n"
53 "Description:\n"
54 " The utility creates oks files for given version of data stored in relational database.\n\n";
55}
56
57static void
58no_param(const char * s)
59{
60 std::cerr << "ERROR: no parameter for " << s << " provided\n\n";
61}
62
63
64int main(int argc, char *argv[])
65{
66
67 // parse and check command line
68
69 int verbose_level = 1;
70 std::string connect_string;
71 std::string release;
72 std::string tag;
73 std::string working_schema;
74 std::string schema_file;
75 std::string data_file;
76 std::string query;
77 std::string class_name;
78 long ref_level = 0;
79 int schema_version = -1;
80 int data_version = -1;
81 bool remove_schema_file = false;
82 bool remove_data_file = false;
83
84 for(int i = 1; i < argc; i++) {
85 const char * cp = argv[i];
86
87 if(!strcmp(cp, "-h") || !strcmp(cp, "--help")) {
88 usage();
89 return (EXIT_SUCCESS);
90 }
91 else if(!strcmp(cp, "-v") || !strcmp(cp, "--verbose-level")) {
92 if(++i == argc) { no_param(cp); return (EXIT_FAILURE); } else { verbose_level = atoi(argv[i]); }
93 }
94 else if(!strcmp(cp, "-e") || !strcmp(cp, "--head-data-version")) {
95 if(data_version > 0) {
96 std::cerr << "ERROR: use either explicit data version (parameter -n) or HEAD version for provided release name (parameter -e ...)\n";
97 usage();
98 return EXIT_FAILURE;
99 }
100 data_version = 0;
101 if(argc > (i+1) && argv[i+1][0] != '-') {++i; release = argv[i]; }
102 }
103 else if(!strcmp(cp, "-t") || !strcmp(cp, "--tag")) {
104 if(++i == argc) { no_param(cp); return (EXIT_FAILURE); } else { tag = argv[i];}
105 }
106 else if(!strcmp(cp, "-s") || !strcmp(cp, "--schema-version")) {
107 if(++i == argc) { no_param(cp); return (EXIT_FAILURE); } else { schema_version = atoi(argv[i]); }
108 }
109 else if(!strcmp(cp, "-n") || !strcmp(cp, "--data-version")) {
110 if(++i == argc) { no_param(cp); return (EXIT_FAILURE); } else {
111 if(!release.empty()) {
112 std::cerr << "ERROR: use either explicit data version (parameter -n) or HEAD version for provided release name (parameter -e ...)\n";
113 usage();
114 return EXIT_FAILURE;
115 }
116 data_version = atoi(argv[i]);
117 }
118 }
119 else if(!strcmp(cp, "-c") || !strcmp(cp, "--connect-string")) {
120 if(++i == argc) { no_param(cp); return (EXIT_FAILURE); } else { connect_string = argv[i]; }
121 }
122 else if(!strcmp(cp, "-w") || !strcmp(cp, "--working-schema")) {
123 if(++i == argc) { no_param(cp); return (EXIT_FAILURE); } else { working_schema = argv[i]; }
124 }
125 else if(!strcmp(cp, "-m") || !strcmp(cp, "--out-schema-file")) {
126 if(++i == argc) { no_param(cp); return (EXIT_FAILURE); } else { schema_file = argv[i]; }
127 }
128 else if(!strcmp(cp, "-f") || !strcmp(cp, "--out-data-file")) {
129 if(++i == argc) { no_param(cp); return (EXIT_FAILURE); } else { data_file = argv[i]; }
130 }
131 else if(!strcmp(cp, "-q") || !strcmp(cp, "--query")) {
132 if(i >= argc-2) { no_param(cp); return (EXIT_FAILURE); } else { class_name = argv[++i]; query = argv[++i];}
133 }
134 else if(!strcmp(cp, "-r") || !strcmp(cp, "--reference-level")) {
135 if(++i == argc) { no_param(cp); return (EXIT_FAILURE); } else { ref_level = atoi(argv[i]); }
136 }
137 else {
138 std::cerr << "ERROR: Unexpected parameter: \"" << cp << "\"\n\n";
139 usage();
140 return (EXIT_FAILURE);
141 }
142 }
143
144 if(data_version == -1 && tag.empty()) {
145 std::cerr << "ERROR: the data version or tag is required\n";
146 usage();
147 return EXIT_FAILURE;
148 }
149 else if(data_version > 0 && schema_version <= 0) {
150 std::cerr << "ERROR: an explicit data version cannot be used without schema version\n";
151 usage();
152 return EXIT_FAILURE;
153 }
154 else if(data_version != -1 && !tag.empty()) {
155 std::cerr << "ERROR: both schema version and tag are defined; only one can be used\n";
156 usage();
157 return EXIT_FAILURE;
158 }
159
160 if(connect_string.empty()) {
161 std::cerr << "ERROR: the connect string is required\n";
162 usage();
163 return EXIT_FAILURE;
164 }
165
166 if(working_schema.empty()) {
167 std::cerr << "ERROR: the working schema is required\n";
168 usage();
169 return EXIT_FAILURE;
170 }
171
172
173 // create oks kernel
174
175 VerboseMsg2("Creating OKS kernel...");
176 ::OksKernel kernel;
177
178
179 try {
180
181 // create oks schema file
182
183 if(schema_file.empty()) {
184 schema_file = kernel.get_tmp_file("/tmp/unknown.schema.xml");
185 VerboseMsg2("The name of output schema file was not provided.\n * use file \'" << schema_file << '\'');
186 remove_schema_file = true;
187 }
188
189 VerboseMsg3("Creating OKS schema file...");
190 ::OksFile * fh1 = kernel.new_schema(schema_file);
191
192
193 // create oks data file
194
195 if(data_file.empty()) {
196 data_file = kernel.get_tmp_file("/tmp/unknown.data.xml");
197 VerboseMsg2("The name of output data file was not provided.\n * use file \'" << data_file << '\'');
198 remove_data_file = true;
199 }
200
201 VerboseMsg3("Creating OKS data file...");
202 ::OksFile * fh2 = kernel.new_data(data_file);
203
204 {
205 std::unique_ptr<coral::ConnectionService> connection;
206 {
207 std::unique_ptr<coral::ISessionProxy> session (oks::ral::start_coral_session(connect_string, coral::ReadOnly, connection, verbose_level));
208
209 if(!tag.empty() || data_version <= 0 || schema_version < 0) {
210 oks::ral::get_data_version(session.get(), working_schema, tag, schema_version, data_version, release.c_str(), verbose_level);
211 if(data_version <= 0 || schema_version < 0) {
212 throw std::runtime_error( (data_version == 0) ? "Cannot get head data" : "Cannot get given data" );
213 }
214 }
215
216 oks::ral::get_data(kernel, session.get(), working_schema, schema_version, data_version, verbose_level);
217
218 VerboseMsg2("Committing...");
219 session->transaction().commit();
220
221 VerboseMsg2("Ending user session..."); // delete session by unique_ptr<>
222 }
223
224 VerboseMsg2("Disconnecting..."); // delete connection by unique_ptr<>
225 }
226
227 if(!query.empty()) {
228
229 // compute data, if there is an explicit query
230
231 OksObject::FSet objects;
232
233 if(OksClass * c = kernel.find_class(class_name)) {
234 OksQuery q(c, query);
235
236 if(q.good()) {
237 OksObject::List * l = c->execute_query(&q);
238 if(l && !l->empty()) {
239 for(OksObject::List::iterator i = l->begin(); i != l->end(); ++i) {
240 objects.insert(*i);
241 if(ref_level > 0) {
242 (*i)->references(objects, static_cast<unsigned long>(ref_level));
243 }
244 }
245 }
246 else {
247 std::cerr << "ERROR: failed to find any object of class \"" << class_name << "\" satisfying query \"" << query << "\", exiting...\n";
248 unlink(schema_file.c_str());
249 unlink(data_file.c_str());
250 return (EXIT_FAILURE);
251 }
252 }
253 else {
254 std::cerr << "ERROR: failed to parse query \"" << query << "\" for class class \"" << class_name << "\", exiting...\n";
255 unlink(schema_file.c_str());
256 unlink(data_file.c_str());
257 return (EXIT_FAILURE);
258 }
259 }
260 else {
261 std::cerr << "ERROR: cannot find class \"" << class_name << "\", exiting...\n";
262 unlink(schema_file.c_str());
263 unlink(data_file.c_str());
264 return (EXIT_FAILURE);
265 }
266
267 if(verbose_level > 2) {
268 std::cout << objects.size() << " objects to be saved as defined by query and reference-level parameters:\n";
269
270 for(OksObject::FSet::const_iterator i = objects.begin(); i != objects.end(); ++i) {
271 std::cout << " " << *i << std::endl;
272 }
273 }
274
275 std::string trash_data_file = kernel.get_tmp_file("/tmp/trash.data.xml");
276 OksFile * fh3 = kernel.new_data(trash_data_file);
277
278 if(!fh3) {
279 std::cerr << "ERROR: failed to create oks data file \'" << trash_data_file << "\'\n";
280 unlink(schema_file.c_str());
281 unlink(data_file.c_str());
282 return (EXIT_FAILURE);
283 }
284
285 VerboseMsg3("Filter out objects not satisfying query...");
286 for(OksObject::Set::const_iterator i = kernel.objects().begin(); i != kernel.objects().end(); ++i) {
287 if(objects.find(*i) == objects.end()) {
288 (*i)->set_file(fh3);
289 VerboseMsg3(" - filter out object " << *i);
290 }
291 }
292
293 unlink(trash_data_file.c_str());
294 }
295
296 VerboseMsg5("Dump data:\n" << kernel);
297
298 if(remove_schema_file) {
299 VerboseMsg2("Removing temporal schema file \'" << schema_file << "\'...");
300 unlink(schema_file.c_str());
301 }
302 else {
303 VerboseMsg2("Saving oks schema...");
304 kernel.save_schema(fh1);
305 fh2->add_include_file(schema_file);
306 }
307
308 if(remove_data_file) {
309 VerboseMsg2("Removing temporal data file \'" << data_file << "\'...");
310 unlink(data_file.c_str());
311 }
312 else {
313 VerboseMsg2("Saving oks data...");
314 kernel.save_data(fh2, true);
315 }
316
317 VerboseMsg2("Exiting...");
318 }
319
320 catch ( coral::Exception& e ) {
321 std::cerr << "CORAL exception: " << e.what() << std::endl;
322 return 1;
323 }
324
325 catch ( oks::exception & ex) {
326 std::cerr << "OKS exception:\n" << ex << std::endl;
327 return 2;
328 }
329
330 catch ( std::exception& e ) {
331 std::cerr << "Standard C++ exception : " << e.what() << std::endl;
332 return 3;
333 }
334
335 catch ( ... ) {
336 std::cerr << "Exception caught (...)" << std::endl;
337 return 4;
338 }
339
340 return 0;
341}
coral::ISessionProxy * start_coral_session(const std::string &connect_string, int mode, std::unique_ptr< coral::ConnectionService > &connection, int verbose_level)
Start coral session.
void get_data_version(coral::ISessionProxy *session, const std::string &schema, const std::string &tag, int &schema_version, int &data_version, const char *release=0, int verbose_level=1, const char *dx="")
Get data version by tag.
unsigned long get_data(OksKernel &kernel, coral::ISessionProxy *session, const std::string &schema, int schema_version, int data_version, int verbose_level, const OksClass::Map *pattern=0)
Get data by version numbers.
int main(int argc, char *argv[])
static void usage()
static void no_param(const char *s)
#define VerboseMsg2(MSG)
Definition ral.hpp:20
#define VerboseMsg5(MSG)
Definition ral.hpp:23
#define VerboseMsg3(MSG)
Definition ral.hpp:21