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