DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
oks_ls_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_ls_data.cpp to apps/oks_ls_data.cxx).
6//
7
8#include <list>
9
10#include "CoralBase/Exception.h"
11#include "CoralKernel/Context.h"
12#include <CoralBase/Attribute.h>
13#include <CoralBase/AttributeList.h>
14#include <CoralBase/AttributeSpecification.h>
15
16#include "RelationalAccess/ConnectionService.h"
17#include "RelationalAccess/ISessionProxy.h"
18#include "RelationalAccess/ITransaction.h"
19#include <RelationalAccess/ICursor.h>
20#include <RelationalAccess/IQuery.h>
21#include <RelationalAccess/ISchema.h>
22#include <RelationalAccess/ITable.h>
23#include <RelationalAccess/ITransaction.h>
24#include <RelationalAccess/SchemaException.h>
25
26#include <iostream>
27#include <stdexcept>
28#include <stdlib.h>
29#include <unistd.h>
30
31#include "ers/ers.hpp"
32
33#include "oks/ral.hpp"
34#include "oks/tz.hpp"
35
37
38// The struct describes table's row with 5 items, separator and fill chars.
39// It is used to print separator line, title row and application parameters
40
42{
43 char m_fill;
45 std::string m_items[7];
46 TableRow(const char fill, const char separator)
47 : m_fill(fill)
48 , m_separator(separator)
49 {
50 ;
51 }
52 TableRow(const char fill,
53 const char separator,
54 int sv,
55 int dv,
56 int bv,
57 const std::string& release,
58 const std::string& date,
59 const std::string& user,
60 const std::string& host,
61 const std::string& description,
62 long num_of_obj = 0,
63 long num_of_attr = 0,
64 long num_of_rel = 0)
65 : m_fill(fill)
66 , m_separator(separator)
67 {
68 if (sv || dv || bv) {
69 std::ostringstream s;
70 s << sv << '.' << dv;
71 if (bv != dv)
72 s << '.' << bv;
73 m_items[0] = s.str();
74 }
75 m_items[1] = release;
76 m_items[2] = date;
77 m_items[3] = user;
78 m_items[4] = host;
79 if (num_of_obj || num_of_attr || num_of_rel) {
80 std::ostringstream s2;
81 s2 << num_of_obj << ':' << num_of_attr << ':' << num_of_rel;
82 m_items[5] = s2.str();
83 }
84 m_items[6] = description;
85 }
86 TableRow(const char fill,
87 const char separator,
88 const std::string& s1,
89 const std::string& s2,
90 const std::string& s3,
91 const std::string& s4,
92 const std::string& s5,
93 const std::string& s6,
94 const std::string& s7)
95 : m_fill(fill)
96 , m_separator(separator)
97 {
98 m_items[0] = s1;
99 m_items[1] = s2;
100 m_items[2] = s3;
101 m_items[3] = s4;
102 m_items[4] = s5;
103 m_items[5] = s6;
104 m_items[6] = s7;
105 }
106};
107
109
110static void
112{
113 std::cout
114 << "usage: oks_ls_data\n"
115 " -c | --connect-string connect_string\n"
116 " -w | --working-schema schema_name\n"
117 " [-l | --list-releases]\n"
118 " [-s | --schema-version schema_version]\n"
119 " [-b | --base-data-only]\n"
120 " [-z | --show-size]\n"
121 " [-u | --show-usage]\n"
122 " [-d | --show-description]\n"
123 " [-t | --sorted-by parameters]\n"
124 " [-r | --release release_name]\n"
125 " [-e | --user user_name_pattern]\n"
126 " [-o | --host hostname_pattern]\n"
127 " [-p | --partition partition_name_pattern]\n"
128 " [-S | --archived-since timestamp]\n"
129 " [-T | --archived-till timestamp]\n"
130 " [-Z | --time-zone name]\n"
131 " [-v | --verbose-level verbosity_level]\n"
132 " [-h | --help]\n"
133 "\n"
134 "Options/Arguments:\n"
135 " -c connect_string database connection string\n"
136 " -w schema_name name of working schema\n"
137 " -l list releases\n"
138 " -s schema_version print out data of this particular version (0 = HEAD version)\n"
139 " -b print out base data versions only\n"
140 " -z print size of version (i.e. number of relational rows to store it)\n"
141 " -u show who, when, where and how used given version\n"
142 " -d show description\n"
143 " -t parameters sort output by several columns; the parameters may contain the following\n"
144 " items (where first symbol is for ascending and second for descending order):\n"
145 " v | V - sort by versions (run-number for usage [-u option]);\n"
146 " t | T - sort by time;\n"
147 " u | U - sort by user names;\n"
148 " h | H - sort by hostnames;\n"
149 " p | P - sort by partition names (i.e. by descriptions);\n"
150 // " s | S - sort by sizes of archive, requires -u option.\n" // disabled because of
151 // Oracle bug
152 " -r release_name show configurations for given release name\n"
153 " -e user_name_pattern show configurations for user names satisfying pattern (see syntax description below)\n"
154 " -o hostname_pattern show configurations for hostnames satisfying pattern (see syntax description below)\n"
155 " -p partition_pattern show configurations or usage for partition names satisfying pattern (see syntax "
156 "description below)\n"
157 " -S since_timestamp show configurations archived or used since given moment (see timestamp format "
158 "description below)\n"
159 " -T till_timestamp show configurations archived before given moment (see timestamp format description "
160 "below)\n"
161 " -Z name time zone name (run \"-Z list-regions\" to see all supported time zones)\n"
162 " -v verbosity_level set verbose output level (0 - silent, 1 - normal, 2 - extended, 3 - debug, ...)\n"
163 " -h print this message\n"
164 "\n"
165 "Description:\n"
166 " The utility prints out details of oks data versions archived in relational database.\n"
167 " The Version is shown as sv.dv[.bv], where:\n"
168 " * sv = schema version;\n"
169 " * dv = data version;\n"
170 " * bv = base version (optional, only appears for incremental data versions).\n"
171 " The Size (numbers of relational rows) is reported in form x:y:z, where the:\n"
172 " * x = number of new[/deleted/updated] objects;\n"
173 " * y = number of new[/deleted/updated] attribute values;\n"
174 " * z = number of new[/deleted/updated] relationship values.\n"
175 " By default the input timestamps are expected and the results are printed in UTC.\n"
176 " To use specific local time run program with -Z option (e.g. \"-Z \'Europe/Zurich\'\" for CERN local time).\n"
177 " The timestamps to be provided in ISO 8601 format: \"YYYY-MM-DD HH:MM:SS\".\n"
178 " The allowed wildcard characters used to select by user, host and partition names are:\n"
179 " % (i.e. percent symbol) - any string of zero or more characters;\n"
180 " _ (i.e. underscore symbol) - any single character.\n\n";
181 // " [ ] - any single character within the specified range ([a.f]) or set ([abcdef]);\n"
182 // " [^] - any single character not within the specified range ([^a.d]) or set ([^abcd]).\n\n";
183}
184
185static void
186no_param(const char* s)
187{
188 std::cerr << "ERROR: no parameter for " << s << " provided\n\n";
189}
190
191static bool
192has_a_pattern(const std::string& s)
193{
194 return ((s.find("%") != std::string::npos) || (s.find("_") != std::string::npos) ||
195 (s.find("[") != std::string::npos && s.find("]") != std::string::npos)
196 ? true
197 : false);
198}
199
200int
201main(int argc, char* argv[])
202{
203
204 // parse and check command line
205
206 int verbose_level = 1;
207 std::string connect_string;
208 std::string working_schema;
209 int schema_version = -1; // -1 -> ALL, 0 -> HEAD, >0 -> exact version
210 bool ls_base_versions_only = false; // -b
211 bool ls_get_size = false; // -z
212 bool ls_usage = false; // -u
213 bool ls_description = false; // -d
214 bool list_db = false; // -l
215 std::string release;
216 std::string user;
217 std::string host;
218 std::string partition;
219 std::string acrhived_since;
220 std::string acrhived_till;
221 std::string sorted_by;
222 const char* tmp_acrhived_since(0);
223 const char* tmp_acrhived_till(0);
224 const char* tz(0);
225 boost::local_time::time_zone_ptr tz_ptr;
226
227 for (int i = 1; i < argc; i++) {
228 const char* cp = argv[i];
229
230 if (!strcmp(cp, "-h") || !strcmp(cp, "--help")) {
231 usage();
232 return (EXIT_SUCCESS);
233 } else if (!strcmp(cp, "-b") || !strcmp(cp, "--base-data-only")) {
234 ls_base_versions_only = true;
235 } else if (!strcmp(cp, "-l") || !strcmp(cp, "--list-releases")) {
236 list_db = true;
237 } else if (!strcmp(cp, "-z") || !strcmp(cp, "--show-size")) {
238 ls_get_size = true;
239 } else if (!strcmp(cp, "-u") || !strcmp(cp, "--show-usage")) {
240 ls_usage = true;
241 } else if (!strcmp(cp, "-d") || !strcmp(cp, "--show-description")) {
242 ls_description = true;
243 }
244
245 else if (!strcmp(cp, "-t") || !strcmp(cp, "--sorted-by")) {
246 if (++i == argc) {
247 no_param(cp);
248 return (EXIT_FAILURE);
249 } else {
250 sorted_by = argv[i];
251 }
252 } else if (!strcmp(cp, "-r") || !strcmp(cp, "--release")) {
253 if (++i == argc) {
254 no_param(cp);
255 return (EXIT_FAILURE);
256 } else {
257 release = argv[i];
258 }
259 } else if (!strcmp(cp, "-e") || !strcmp(cp, "--user")) {
260 if (++i == argc) {
261 no_param(cp);
262 return (EXIT_FAILURE);
263 } else {
264 user = argv[i];
265 }
266 } else if (!strcmp(cp, "-o") || !strcmp(cp, "--host")) {
267 if (++i == argc) {
268 no_param(cp);
269 return (EXIT_FAILURE);
270 } else {
271 host = argv[i];
272 }
273 } else if (!strcmp(cp, "-p") || !strcmp(cp, "--partition")) {
274 if (++i == argc) {
275 no_param(cp);
276 return (EXIT_FAILURE);
277 } else {
278 partition = argv[i];
279 }
280 } else if (!strcmp(cp, "-v") || !strcmp(cp, "--verbose-level")) {
281 if (++i == argc) {
282 no_param(cp);
283 return (EXIT_FAILURE);
284 } else {
285 verbose_level = atoi(argv[i]);
286 }
287 } else if (!strcmp(cp, "-s") || !strcmp(cp, "--schema-version")) {
288 if (++i == argc) {
289 no_param(cp);
290 return (1);
291 } else {
292 schema_version = atoi(argv[i]);
293 }
294 } else if (!strcmp(cp, "-c") || !strcmp(cp, "--connect-string")) {
295 if (++i == argc) {
296 no_param(cp);
297 return (1);
298 } else {
299 connect_string = argv[i];
300 }
301 } else if (!strcmp(cp, "-w") || !strcmp(cp, "--working-schema")) {
302 if (++i == argc) {
303 no_param(cp);
304 return (1);
305 } else {
306 working_schema = argv[i];
307 }
308 } else if (!strcmp(cp, "-S") || !strcmp(cp, "--archived-since")) {
309 if (++i == argc) {
310 no_param(cp);
311 return 1;
312 } else {
313 tmp_acrhived_since = argv[i];
314 }
315 } else if (!strcmp(cp, "-T") || !strcmp(cp, "--archived-till")) {
316 if (++i == argc) {
317 no_param(cp);
318 return 1;
319 } else {
320 tmp_acrhived_till = argv[i];
321 }
322 } else if (!strcmp(cp, "-Z") || !strcmp(cp, "--time-zone")) {
323 if (++i == argc) {
324 no_param(cp);
325 return 1;
326 } else {
327 tz = argv[i];
328 }
329 } else {
330 std::cerr << "ERROR: Unexpected parameter: \"" << cp << "\"\n\n";
331 usage();
332 return (EXIT_FAILURE);
333 }
334 }
335
336 if (tz) {
337 try {
338 oks::tz::DB tz_db;
339
340 if (!strcmp(tz, "list-regions")) {
341 for (auto& i : tz_db.get_regions()) {
342 std::cout << i << std::endl;
343 }
344 return 0;
345 }
346
347 tz_ptr = tz_db.get_tz_ptr(tz);
348 } catch (const std::exception& ex) {
349 std::cerr << "ERROR: time-zone db access failed: " << ex.what() << std::endl;
350 return 2;
351 }
352 }
353
354 if (connect_string.empty()) {
355 std::cerr << "ERROR: the connect string is required\n";
356 usage();
357 return EXIT_FAILURE;
358 }
359
360 if (working_schema.empty()) {
361 std::cerr << "ERROR: the working schema is required\n";
362 usage();
363 return EXIT_FAILURE;
364 }
365
366 try {
367 if (tmp_acrhived_since) {
368 acrhived_since =
369 oks::tz::posix_time_2_iso_string(oks::tz::str_2_posix_time(tmp_acrhived_since, tz_ptr, "archived-since"));
370 }
371
372 if (tmp_acrhived_till) {
373 acrhived_till =
374 oks::tz::posix_time_2_iso_string(oks::tz::str_2_posix_time(tmp_acrhived_till, tz_ptr, "archived-till"));
375 }
376 } catch (const std::exception& ex) {
377 std::cerr << "ERROR: " << ex.what() << std::endl;
378 return 2;
379 }
380
381 try {
382
383 std::unique_ptr<coral::ConnectionService> connection;
384
385 {
386 std::unique_ptr<coral::ISessionProxy> session(
387 oks::ral::start_coral_session(connect_string, coral::ReadOnly, connection, verbose_level));
388
389 if (list_db) {
390 coral::ITable& schema_table = session->schema(working_schema).tableHandle("OKSSCHEMA");
391 std::unique_ptr<coral::IQuery> query(schema_table.newQuery());
392 query->setRowCacheSize(10);
393 query->setDistinct();
394 query->addToOutputList("RELEASE");
395 coral::ICursor& cursor = query->execute();
396
397 std::set<std::string> names;
398
399 while (cursor.next()) {
400 names.insert(cursor.currentRow().begin()->data<std::string>());
401 }
402
403 std::cout << "Found configuration archives for " << names.size() << " releases:\n";
404
405 for (std::set<std::string>::const_iterator i = names.begin(); i != names.end(); ++i) {
406 std::cout << " - \'" << *i << '\'' << std::endl;
407 }
408 } else {
409 if (schema_version == 0) {
410 schema_version =
411 oks::ral::get_head_schema_version(session.get(), working_schema, release.c_str(), verbose_level, " ");
412 if (schema_version == 0) {
413 throw std::runtime_error("Cannot get HEAD schema version.");
414 }
415 }
416
417 coral::ITable& archive_table = session->schema(working_schema).tableHandle("OKSARCHIVE");
418
419 std::list<std::string> conditions_list;
420 coral::AttributeList conditions;
421
422 std::unique_ptr<coral::IQuery> query(session->schema(working_schema).newQuery());
423 query->setRowCacheSize(1000);
424
425 query->addToOutputList("A.SCHEMAVERSION");
426 query->addToOutputList("A.BASEVERSION");
427 query->addToOutputList("A.VERSION");
428 query->addToOutputList("B.RELEASE");
429 query->addToOutputList("A.TIME");
430 query->addToOutputList("A.CREATEDBY");
431 query->addToOutputList("A.HOST");
432
433 if (ls_description) {
434 query->addToOutputList("A.DESCRIPTION");
435 }
436
437 coral::IQueryDefinition& subQuery1 = query->defineSubQuery("A");
438 subQuery1.addToTableList("OKSDATA");
439 query->addToTableList("A");
440
441 coral::IQueryDefinition& subQuery2 = query->defineSubQuery("B");
442 subQuery2.addToTableList("OKSSCHEMA");
443 query->addToTableList("B");
444
445 conditions_list.push_back("A.SCHEMAVERSION = B.VERSION");
446
447 /*if(ls_get_size) {
448 struct {
449 const char * var;
450 const char * table;
451 } ts[] = {
452 {"X", "OKSOBJECT" },
453 {"Y", "OKSDATAVAL" },
454 {"Z", "OKSDATAREL" }
455 };
456
457 for(unsigned int i = 0; i < 1 ; ++i) {
458 std::string p = std::string(ts[i].var) + ".S";
459
460 query->addToOutputList(p);
461 query->addToTableList( ts[i].var );
462 query->defineOutputType( p, "long");
463
464 coral::IQueryDefinition& subQuery = query->defineSubQuery( ts[i].var );
465 subQuery.addToOutputList( "count(*)", "S" );
466 subQuery.addToOutputList( "SCHEMAVERSION" );
467 subQuery.addToOutputList( "DATAVERSION");
468 subQuery.addToTableList( ts[i].table );
469 subQuery.setCondition( "SCHEMAVERSION > 0 group by SCHEMAVERSION, DATAVERSION" , coral::AttributeList());
470
471 conditions_list.push_back(std::string("A.SCHEMAVERSION = ") + ts[i].var + ".SCHEMAVERSION");
472 conditions_list.push_back(std::string("A.VERSION = ") + ts[i].var + ".DATAVERSION");
473 }
474 }*/
475
476 if (schema_version != -1) {
477 conditions.extend<int>("ver");
478 conditions["ver"].data<int>() = schema_version;
479
480 if (ls_base_versions_only) {
481 conditions_list.push_back("A.SCHEMAVERSION = :ver AND A.VERSION = A.BASEVERSION");
482 } else {
483 conditions_list.push_back("A.SCHEMAVERSION = :ver");
484 }
485 } else if (ls_base_versions_only) {
486 conditions_list.push_back("A.VERSION = A.BASEVERSION");
487 }
488
489 if (!release.empty()) {
490 conditions.extend<std::string>("rel");
491 conditions["rel"].data<std::string>() = release;
492 conditions_list.push_back("B.RELEASE = :rel");
493 }
494
495 if (!partition.empty()) {
496 if (!ls_usage) {
497 if (ls_description == false) {
498 throw std::runtime_error("cannot search by partition without \"-d\" or \"-u\" command line option");
499 }
500 conditions.extend<std::string>("prt1");
501 conditions["prt1"].data<std::string>() = std::string("%partition ") + partition + '%';
502 conditions_list.push_back("A.DESCRIPTION like :prt1");
503 }
504 }
505
506 if (!acrhived_since.empty()) {
507 conditions.extend<std::string>("ars");
508 conditions["ars"].data<std::string>() = acrhived_since;
509 if (ls_usage) {
510 query->setDistinct();
511 coral::IQueryDefinition& subQuery3 = query->defineSubQuery("C");
512 subQuery3.addToTableList("OKSARCHIVE");
513 query->addToTableList("C");
514 std::string condition("C.TIME >= :ars AND A.SCHEMAVERSION = C.SCHEMAVERSION AND A.VERSION = C.DATAVERSION");
515 if (!partition.empty()) {
516 conditions.extend<std::string>("prt2");
517 conditions["prt2"].data<std::string>() = partition;
518 condition += (has_a_pattern(partition) ? " AND C.PARTITION like :prt2" : " AND C.PARTITION = :prt2");
519 }
520 conditions_list.push_back(condition);
521 } else {
522 conditions_list.push_back("A.TIME >= :ars");
523 }
524 }
525
526 if (!acrhived_till.empty()) {
527 conditions.extend<std::string>("art");
528 conditions["art"].data<std::string>() = acrhived_till;
529 conditions_list.push_back("A.TIME <= :art");
530 }
531
532 if (!user.empty()) {
533 conditions.extend<std::string>("usr");
534 conditions["usr"].data<std::string>() = user;
535 conditions_list.push_back(has_a_pattern(user) ? "A.CREATEDBY like :usr" : "A.CREATEDBY = :usr");
536 }
537
538 if (!host.empty()) {
539 conditions.extend<std::string>("hst");
540 conditions["hst"].data<std::string>() = host;
541 conditions_list.push_back(has_a_pattern(host) ? "A.HOST like :hst" : "A.HOST = :hst");
542 }
543
544 if (!sorted_by.empty()) {
545 for (const char* p = sorted_by.c_str(); *p != 0; ++p) {
546 if (ls_description == false && (*p == 'p' || *p == 'P')) {
547 throw std::runtime_error("cannot sort by partition without \"-d\" command line option");
548 }
549
550 switch (*p) {
551 case 'v':
552 query->addToOrderList("A.SCHEMAVERSION");
553 query->addToOrderList("A.VERSION");
554 break;
555 case 'V':
556 query->addToOrderList("A.SCHEMAVERSION DESC");
557 query->addToOrderList("A.VERSION DESC");
558 break;
559 case 't':
560 query->addToOrderList("A.TIME");
561 break;
562 case 'T':
563 query->addToOrderList("A.TIME DESC");
564 break;
565 case 'u':
566 query->addToOrderList("A.CREATEDBY");
567 break;
568 case 'U':
569 query->addToOrderList("A.CREATEDBY DESC");
570 break;
571 case 'h':
572 query->addToOrderList("A.HOST");
573 break;
574 case 'H':
575 query->addToOrderList("A.HOST DESC");
576 break;
577 case 'p':
578 query->addToOrderList("A.DESCRIPTION");
579 break;
580 case 'P':
581 query->addToOrderList("A.DESCRIPTION DESC");
582 break;
583 // case 's': query->addToOrderList("X.S"); break;
584 // case 'S': query->addToOrderList("X.S DESC"); break;
585 default:
586 std::stringstream text;
587 text << "ERROR: wrong value \'" << *p << "\' in the command line parameter: \"--sorted-by\" or \"-t\"";
588 throw std::runtime_error(text.str().c_str());
589 }
590 }
591 }
592
593 std::string conditions_str;
594
595 for (std::list<std::string>::const_iterator i = conditions_list.begin(); i != conditions_list.end(); ++i) {
596 if (i != conditions_list.begin())
597 conditions_str += " AND ";
598 conditions_str += *i;
599 }
600
601 query->setCondition(conditions_str, conditions);
602
603 coral::ICursor& cursor = query->execute();
604
605 std::vector<TableRow> rows;
606
607 // fill the table
608
609 rows.push_back(TableRow('=', '='));
610 rows.push_back(TableRow(' ',
611 '|',
612 "Version",
613 "Release",
614 (tz_ptr ? "Date (local time)" : "Date (UTC)"),
615 "User",
616 "Host",
617 "Size",
618 "Description"));
619 rows.push_back(TableRow('=', '='));
620
621 struct
622 {
623 long num;
624 coral::ITable& table;
625 } nums[] = { { 0, session->schema(working_schema).tableHandle("OKSOBJECT") },
626 { 0, session->schema(working_schema).tableHandle("OKSDATAVAL") },
627 { 0, session->schema(working_schema).tableHandle("OKSDATAREL") } };
628
629 while (cursor.next()) {
630 const coral::AttributeList& row = cursor.currentRow();
631
632 std::string time, host, user;
633 oks::ral::get_time_host_user(row, time, host, user, tz_ptr, "A.");
634 std::string description;
635 if (ls_description && !row["A.DESCRIPTION"].isNull())
636 description = row["A.DESCRIPTION"].data<std::string>();
637 std::string r;
638 if (!row["B.RELEASE"].isNull())
639 r = row["B.RELEASE"].data<std::string>();
640 int sv = row["A.SCHEMAVERSION"].data<int>();
641 int dv = row["A.VERSION"].data<int>();
642 nums[0].num = nums[1].num = nums[2].num = 0;
643
644 if (ls_get_size) {
645 coral::AttributeList sizes_query_conditions;
646 sizes_query_conditions.extend<int>("sv");
647 sizes_query_conditions["sv"].data<int>() = sv;
648 sizes_query_conditions.extend<int>("dv");
649 sizes_query_conditions["dv"].data<int>() = dv;
650
651 for (unsigned int i = 0; i < 3; ++i) {
652 std::unique_ptr<coral::IQuery> query(nums[i].table.newQuery());
653 query->setRowCacheSize(1);
654 query->addToOutputList("COUNT(*)");
655 query->defineOutputType("COUNT(*)", "long");
656 query->setCondition("SCHEMAVERSION = :sv AND DATAVERSION = :dv", sizes_query_conditions);
657
658 coral::ICursor& c = query->execute();
659
660 if (c.next()) {
661 nums[i].num = (int)c.currentRow().begin()->data<long>();
662 }
663 }
664 }
665
666 rows.push_back(TableRow(' ',
667 '|',
668 sv,
669 dv,
670 row["A.BASEVERSION"].data<int>(),
671 r,
672 time,
673 user,
674 host,
675 description,
676 nums[0].num,
677 nums[1].num,
678 nums[2].num));
679
680 if (ls_usage) {
681 std::unique_ptr<coral::IQuery> query(archive_table.newQuery());
682 coral::AttributeList archive_query_conditions;
683 archive_query_conditions.extend<int>("sv");
684 archive_query_conditions["sv"].data<int>() = sv;
685 archive_query_conditions.extend<int>("dv");
686 archive_query_conditions["dv"].data<int>() = dv;
687 query->setRowCacheSize(10);
688 query->addToOutputList("TIME");
689 query->addToOutputList("PARTITION");
690 query->addToOutputList("CREATEDBY");
691 query->addToOutputList("HOST");
692 query->addToOutputList("RUNNUMBER");
693
694 if (!sorted_by.empty()) {
695 for (const char* p = sorted_by.c_str(); *p != 0; ++p) {
696
697 switch (*p) {
698 case 'v':
699 query->addToOrderList("RUNNUMBER");
700 break;
701 case 'V':
702 query->addToOrderList("RUNNUMBER DESC");
703 break;
704 case 't':
705 query->addToOrderList("TIME");
706 break;
707 case 'T':
708 query->addToOrderList("TIME DESC");
709 break;
710 case 'u':
711 query->addToOrderList("CREATEDBY");
712 break;
713 case 'U':
714 query->addToOrderList("CREATEDBY DESC");
715 break;
716 case 'h':
717 query->addToOrderList("HOST");
718 break;
719 case 'H':
720 query->addToOrderList("HOST DESC");
721 break;
722 case 'p':
723 query->addToOrderList("PARTITION");
724 break;
725 case 'P':
726 query->addToOrderList("PARTITION DESC");
727 break;
728 }
729 }
730 }
731
732 std::string condition("SCHEMAVERSION = :sv AND DATAVERSION = :dv");
733
734 if (!acrhived_since.empty()) {
735 archive_query_conditions.extend<std::string>("ars");
736 archive_query_conditions["ars"].data<std::string>() = acrhived_since;
737 condition += " AND TIME >= :ars";
738 }
739
740 if (!acrhived_till.empty()) {
741 archive_query_conditions.extend<std::string>("art");
742 archive_query_conditions["art"].data<std::string>() = acrhived_till;
743 condition += " AND TIME <= :art";
744 }
745
746 if (!partition.empty()) {
747 archive_query_conditions.extend<std::string>("prt");
748 archive_query_conditions["prt"].data<std::string>() = partition;
749 condition += (has_a_pattern(partition) ? " AND PARTITION like :prt" : " AND PARTITION = :prt");
750 }
751
752 query->setCondition(condition, archive_query_conditions);
753
754 coral::ICursor& c = query->execute();
755
756 while (c.next()) {
757 const coral::AttributeList& ar_row = c.currentRow();
758 std::string ar_time, ar_host, ar_user;
759 oks::ral::get_time_host_user(ar_row, ar_time, ar_host, ar_user, tz_ptr);
760 std::string p;
761 if (!ar_row["PARTITION"].isNull())
762 p = ar_row["PARTITION"].data<std::string>();
763
764 std::ostringstream s;
765 s << "partition: " << p << " run: " << ar_row["RUNNUMBER"].data<int>();
766
767 rows.push_back(TableRow(' ', '|', 0, 0, 0, r, ar_time, ar_user, ar_host, s.str()));
768 }
769 }
770 }
771
772 rows.push_back(TableRow('=', '='));
773
774 // detect columns widths
775
776 unsigned short cw[] = { 1, 1, 1, 1, 1, 1, 1 };
777 {
778 for (auto& i : rows) {
779 for (unsigned short j = 0; j < sizeof(cw) / sizeof(unsigned short); ++j) {
780 unsigned short len = i.m_items[j].size();
781 if (len > cw[j])
782 cw[j] = len;
783 }
784 }
785 }
786
787 // print table
788
789 {
790 bool align_left[] = { false, true, true, true, true, false, true };
791
792 for (std::vector<TableRow>::const_iterator i = rows.begin(); i != rows.end(); ++i) {
793 std::cout.fill((*i).m_fill);
794 for (unsigned short j = 0; j < sizeof(cw) / sizeof(unsigned short); ++j) {
795 std::cout << (*i).m_separator << (*i).m_fill;
796 std::cout.setf((align_left[j] ? std::ios::left : std::ios::right), std::ios::adjustfield);
797 std::cout.width(cw[j]);
798 std::cout << (*i).m_items[j] << (*i).m_fill;
799 }
800 std::cout << (*i).m_separator << std::endl;
801 }
802 }
803 }
804
805 session->transaction().commit();
806
807 VerboseMsg2("Ending user session..."); // delete session by unique_ptr<>
808 }
809
810 VerboseMsg2("Disconnecting..."); // delete connection by unique_ptr<>
811 }
812
813 catch (coral::Exception& e) {
814 std::cerr << "CORAL exception: " << e.what() << std::endl;
815 return 1;
816 }
817
818 catch (std::exception& e) {
819 std::cerr << "Standard C++ exception : " << e.what() << std::endl;
820 return 2;
821 }
822
823 catch (...) {
824 std::cerr << "Exception caught (...)" << std::endl;
825 return 3;
826 }
827
828 VerboseMsg2("Exiting...");
829
830 return 0;
831}
std::vector< std::string > get_regions()
Get known time zone regions.
Definition oks_tz.cpp:55
boost::local_time::time_zone_ptr get_tz_ptr(const std::string &region)
Get boost time-zone pointer from string.
Definition oks_tz.cpp:41
static void usage(const char *s)
static void no_param(const char *s)
int main(int argc, char *argv[])
coral::ISessionProxy * start_coral_session(const std::string &connect_string, int mode, std::unique_ptr< coral::ConnectionService > &connection, int verbose_level)
Start coral session.
int get_head_schema_version(coral::ISessionProxy *session, const std::string &schema, const char *release=0, int verbose_level=1, const char *dx="")
Get HEAD schema version number.
void get_time_host_user(const coral::AttributeList &data, std::string &time, std::string &host, std::string &user, boost::local_time::time_zone_ptr tz_ptr, const char *prefix=0)
boost::posix_time::ptime str_2_posix_time(const std::string &in, boost::local_time::time_zone_ptr tz_ptr, const char *value)
Definition oks_tz.cpp:61
std::string posix_time_2_iso_string(boost::posix_time::ptime t)
Definition oks_tz.cpp:105
static bool has_a_pattern(const std::string &s)
#define VerboseMsg2(MSG)
Definition ral.hpp:25
char m_separator
std::string m_items[7]
TableRow(const char fill, const char separator)
TableRow(const char fill, const char separator, int sv, int dv, int bv, const std::string &release, const std::string &date, const std::string &user, const std::string &host, const std::string &description, long num_of_obj=0, long num_of_attr=0, long num_of_rel=0)
TableRow(const char fill, const char separator, const std::string &s1, const std::string &s2, const std::string &s3, const std::string &s4, const std::string &s5, const std::string &s6, const std::string &s7)