167int main(
int argc,
char *argv[])
172 int verbose_level = 1;
173 std::string connect_string;
174 std::string working_schema;
175 int schema_version = -1;
176 bool ls_base_versions_only =
false;
177 bool ls_get_size =
false;
178 bool ls_usage =
false;
179 bool ls_description =
false;
180 bool list_db =
false;
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);
191 boost::local_time::time_zone_ptr tz_ptr;
193 for(
int i = 1; i < argc; i++) {
194 const char * cp = argv[i];
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; }
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]; }
206 else if(!strcmp(cp,
"-r") || !strcmp(cp,
"--release")) {
207 if(++i == argc) {
no_param(cp);
return (EXIT_FAILURE); }
else { release = argv[i]; }
209 else if(!strcmp(cp,
"-e") || !strcmp(cp,
"--user")) {
210 if(++i == argc) {
no_param(cp);
return (EXIT_FAILURE); }
else { user = argv[i]; }
212 else if(!strcmp(cp,
"-o") || !strcmp(cp,
"--host")) {
213 if(++i == argc) {
no_param(cp);
return (EXIT_FAILURE); }
else { host = argv[i]; }
215 else if(!strcmp(cp,
"-p") || !strcmp(cp,
"--partition")) {
216 if(++i == argc) {
no_param(cp);
return (EXIT_FAILURE); }
else { partition = argv[i]; }
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]); }
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]);}
224 else if(!strcmp(cp,
"-c") || !strcmp(cp,
"--connect-string")) {
225 if(++i == argc) {
no_param(cp);
return (1); }
else { connect_string = argv[i]; }
227 else if(!strcmp(cp,
"-w") || !strcmp(cp,
"--working-schema")) {
228 if(++i == argc) {
no_param(cp);
return (1); }
else { working_schema = argv[i]; }
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]; }
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]; }
236 else if(!strcmp(cp,
"-Z") || !strcmp(cp,
"--time-zone")) {
237 if(++i == argc) {
no_param(cp);
return 1; }
else { tz = argv[i]; }
240 std::cerr <<
"ERROR: Unexpected parameter: \"" << cp <<
"\"\n\n";
242 return (EXIT_FAILURE);
252 if (!strcmp(tz,
"list-regions"))
256 std::cout << i << std::endl;
263 catch (
const std::exception& ex)
265 std::cerr <<
"ERROR: time-zone db access failed: " << ex.what() << std::endl;
270 if(connect_string.empty()) {
271 std::cerr <<
"ERROR: the connect string is required\n";
276 if(working_schema.empty()) {
277 std::cerr <<
"ERROR: the working schema is required\n";
284 if (tmp_acrhived_since)
291 if (tmp_acrhived_till)
298 catch (
const std::exception& ex)
300 std::cerr <<
"ERROR: " << ex.what() << std::endl;
306 std::unique_ptr<coral::ConnectionService> connection;
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();
319 std::set<std::string> names;
321 while(cursor.next()) {
322 names.insert(cursor.currentRow().begin()->data<std::string>());
325 std::cout <<
"Found configuration archives for " << names.size() <<
" releases:\n";
327 for(std::set<std::string>::const_iterator i = names.begin(); i != names.end(); ++i) {
328 std::cout <<
" - \'" << *i <<
'\'' << std::endl;
332 if(schema_version == 0) {
334 if(schema_version == 0) {
335 throw std::runtime_error(
"Cannot get HEAD schema version." );
339 coral::ITable& archive_table =
session->schema(working_schema).tableHandle(
"OKSARCHIVE" );
341 std::list<std::string> conditions_list;
342 coral::AttributeList conditions;
345 std::unique_ptr< coral::IQuery > query (
session->schema(working_schema).newQuery());
346 query->setRowCacheSize( 1000 );
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" );
357 query->addToOutputList(
"A.DESCRIPTION" );
360 coral::IQueryDefinition& subQuery1 = query->defineSubQuery(
"A" );
361 subQuery1.addToTableList(
"OKSDATA" );
362 query->addToTableList(
"A" );
364 coral::IQueryDefinition& subQuery2 = query->defineSubQuery(
"B" );
365 subQuery2.addToTableList(
"OKSSCHEMA" );
366 query->addToTableList(
"B" );
368 conditions_list.push_back(
"A.SCHEMAVERSION = B.VERSION");
399 if(schema_version != -1) {
400 conditions.extend<
int>(
"ver" );
401 conditions[
"ver"].data<
int>() = schema_version;
403 if(ls_base_versions_only) {
404 conditions_list.push_back(
"A.SCHEMAVERSION = :ver AND A.VERSION = A.BASEVERSION");
407 conditions_list.push_back(
"A.SCHEMAVERSION = :ver");
410 else if(ls_base_versions_only) {
411 conditions_list.push_back(
"A.VERSION = A.BASEVERSION");
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");
420 if(!partition.empty()) {
422 if(ls_description ==
false) {
423 throw std::runtime_error(
"cannot search by partition without \"-d\" or \"-u\" command line option" );
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");
431 if(!acrhived_since.empty()) {
432 conditions.extend<std::string>(
"ars" );
433 conditions[
"ars"].data<std::string>() = acrhived_since;
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");
445 conditions_list.push_back(condition);
448 conditions_list.push_back(
"A.TIME >= :ars");
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");
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");
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");
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" );
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;
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() );
498 std::string conditions_str;
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;
505 query->setCondition( conditions_str, conditions );
507 coral::ICursor& cursor = query->execute();
510 std::vector<TableRow> rows;
515 rows.push_back(
TableRow(
' ',
'|',
"Version",
"Release",(tz_ptr ?
"Date (local time)" :
"Date (UTC)"),
"User",
"Host",
"Size",
"Description"));
520 coral::ITable& table;
522 {0,
session->schema(working_schema).tableHandle(
"OKSOBJECT" )},
523 {0,
session->schema(working_schema).tableHandle(
"OKSDATAVAL" )},
524 {0,
session->schema(working_schema).tableHandle(
"OKSDATAREL" )}
527 while(cursor.next()) {
528 const coral::AttributeList& row = cursor.currentRow();
530 std::string time, host, user;
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;
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;
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 );
552 coral::ICursor& c = query->execute();
555 nums[i].num = (int)c.currentRow().begin()->data<
long>();
562 sv, dv, row[
"A.BASEVERSION"].data<int>(),
563 r, time, user, host, description,
564 nums[0].num, nums[1].num, nums[2].num
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");
582 if(!sorted_by.empty()) {
583 for(
const char * p = sorted_by.c_str(); *p != 0; ++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;
600 std::string condition(
"SCHEMAVERSION = :sv AND DATAVERSION = :dv");
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";
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";
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");
620 query->setCondition( condition, archive_query_conditions );
622 coral::ICursor& c = query->execute();
625 const coral::AttributeList& ar_row = c.currentRow();
626 std::string ar_time, ar_host, ar_user;
628 std::string p;
if(!ar_row[
"PARTITION"].isNull()) p = ar_row[
"PARTITION"].data<std::string>();
630 std::ostringstream s;
631 s <<
"partition: " << p <<
" run: " << ar_row[
"RUNNUMBER"].data<
int>();
633 rows.push_back(
TableRow(
' ',
'|', 0, 0, 0, r, ar_time, ar_user, ar_host, s.str()));
642 unsigned short cw[] = {1,1,1,1,1,1,1};
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;
656 bool align_left[] = {
false,
true,
true,
true,
true,
false,
true};
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;
666 std::cout << (*i).m_separator << std::endl;
672 session->transaction().commit();
680 catch ( coral::Exception& e ) {
681 std::cerr <<
"CORAL exception: " << e.what() << std::endl;
685 catch ( std::exception& e ) {
686 std::cerr <<
"Standard C++ exception : " << e.what() << std::endl;
691 std::cerr <<
"Exception caught (...)" << std::endl;