160int main(
int argc,
char *argv[])
165 int verbose_level = 1;
166 std::string connect_string;
167 std::string working_schema;
168 int schema_version = -1;
169 bool ls_base_versions_only =
false;
170 bool ls_get_size =
false;
171 bool ls_usage =
false;
172 bool ls_description =
false;
173 bool list_db =
false;
177 std::string partition;
178 std::string acrhived_since;
179 std::string acrhived_till;
180 std::string sorted_by;
181 const char * tmp_acrhived_since(0);
182 const char * tmp_acrhived_till(0);
184 boost::local_time::time_zone_ptr tz_ptr;
186 for(
int i = 1; i < argc; i++) {
187 const char * cp = argv[i];
189 if(!strcmp(cp,
"-h") || !strcmp(cp,
"--help")) {
usage();
return (EXIT_SUCCESS); }
190 else if(!strcmp(cp,
"-b") || !strcmp(cp,
"--base-data-only")) { ls_base_versions_only =
true; }
191 else if(!strcmp(cp,
"-l") || !strcmp(cp,
"--list-releases")) { list_db =
true; }
192 else if(!strcmp(cp,
"-z") || !strcmp(cp,
"--show-size")) { ls_get_size =
true; }
193 else if(!strcmp(cp,
"-u") || !strcmp(cp,
"--show-usage")) { ls_usage =
true; }
194 else if(!strcmp(cp,
"-d") || !strcmp(cp,
"--show-description")) { ls_description =
true; }
196 else if(!strcmp(cp,
"-t") || !strcmp(cp,
"--sorted-by")) {
197 if(++i == argc) {
no_param(cp);
return (EXIT_FAILURE); }
else { sorted_by = argv[i]; }
199 else if(!strcmp(cp,
"-r") || !strcmp(cp,
"--release")) {
200 if(++i == argc) {
no_param(cp);
return (EXIT_FAILURE); }
else { release = argv[i]; }
202 else if(!strcmp(cp,
"-e") || !strcmp(cp,
"--user")) {
203 if(++i == argc) {
no_param(cp);
return (EXIT_FAILURE); }
else { user = argv[i]; }
205 else if(!strcmp(cp,
"-o") || !strcmp(cp,
"--host")) {
206 if(++i == argc) {
no_param(cp);
return (EXIT_FAILURE); }
else { host = argv[i]; }
208 else if(!strcmp(cp,
"-p") || !strcmp(cp,
"--partition")) {
209 if(++i == argc) {
no_param(cp);
return (EXIT_FAILURE); }
else { partition = argv[i]; }
211 else if(!strcmp(cp,
"-v") || !strcmp(cp,
"--verbose-level")) {
212 if(++i == argc) {
no_param(cp);
return (EXIT_FAILURE); }
else { verbose_level = atoi(argv[i]); }
214 else if(!strcmp(cp,
"-s") || !strcmp(cp,
"--schema-version")) {
215 if(++i == argc) {
no_param(cp);
return (1); }
else { schema_version = atoi(argv[i]);}
217 else if(!strcmp(cp,
"-c") || !strcmp(cp,
"--connect-string")) {
218 if(++i == argc) {
no_param(cp);
return (1); }
else { connect_string = argv[i]; }
220 else if(!strcmp(cp,
"-w") || !strcmp(cp,
"--working-schema")) {
221 if(++i == argc) {
no_param(cp);
return (1); }
else { working_schema = argv[i]; }
223 else if(!strcmp(cp,
"-S") || !strcmp(cp,
"--archived-since")) {
224 if(++i == argc) {
no_param(cp);
return 1; }
else { tmp_acrhived_since = argv[i]; }
226 else if(!strcmp(cp,
"-T") || !strcmp(cp,
"--archived-till")) {
227 if(++i == argc) {
no_param(cp);
return 1; }
else { tmp_acrhived_till = argv[i]; }
229 else if(!strcmp(cp,
"-Z") || !strcmp(cp,
"--time-zone")) {
230 if(++i == argc) {
no_param(cp);
return 1; }
else { tz = argv[i]; }
233 std::cerr <<
"ERROR: Unexpected parameter: \"" << cp <<
"\"\n\n";
235 return (EXIT_FAILURE);
245 if (!strcmp(tz,
"list-regions"))
249 std::cout << i << std::endl;
256 catch (
const std::exception& ex)
258 std::cerr <<
"ERROR: time-zone db access failed: " << ex.what() << std::endl;
263 if(connect_string.empty()) {
264 std::cerr <<
"ERROR: the connect string is required\n";
269 if(working_schema.empty()) {
270 std::cerr <<
"ERROR: the working schema is required\n";
277 if (tmp_acrhived_since)
284 if (tmp_acrhived_till)
291 catch (
const std::exception& ex)
293 std::cerr <<
"ERROR: " << ex.what() << std::endl;
299 std::unique_ptr<coral::ConnectionService> connection;
305 coral::ITable& schema_table =
session->schema(working_schema).tableHandle(
"OKSSCHEMA" );
306 std::unique_ptr< coral::IQuery > query( schema_table.newQuery() );
307 query->setRowCacheSize( 10 );
308 query->setDistinct();
309 query->addToOutputList(
"RELEASE" );
310 coral::ICursor& cursor = query->execute();
312 std::set<std::string> names;
314 while(cursor.next()) {
315 names.insert(cursor.currentRow().begin()->data<std::string>());
318 std::cout <<
"Found configuration archives for " << names.size() <<
" releases:\n";
320 for(std::set<std::string>::const_iterator i = names.begin(); i != names.end(); ++i) {
321 std::cout <<
" - \'" << *i <<
'\'' << std::endl;
325 if(schema_version == 0) {
327 if(schema_version == 0) {
328 throw std::runtime_error(
"Cannot get HEAD schema version." );
332 coral::ITable& archive_table =
session->schema(working_schema).tableHandle(
"OKSARCHIVE" );
334 std::list<std::string> conditions_list;
335 coral::AttributeList conditions;
338 std::unique_ptr< coral::IQuery > query (
session->schema(working_schema).newQuery());
339 query->setRowCacheSize( 1000 );
341 query->addToOutputList(
"A.SCHEMAVERSION" );
342 query->addToOutputList(
"A.BASEVERSION" );
343 query->addToOutputList(
"A.VERSION" );
344 query->addToOutputList(
"B.RELEASE" );
345 query->addToOutputList(
"A.TIME" );
346 query->addToOutputList(
"A.CREATEDBY" );
347 query->addToOutputList(
"A.HOST" );
350 query->addToOutputList(
"A.DESCRIPTION" );
353 coral::IQueryDefinition& subQuery1 = query->defineSubQuery(
"A" );
354 subQuery1.addToTableList(
"OKSDATA" );
355 query->addToTableList(
"A" );
357 coral::IQueryDefinition& subQuery2 = query->defineSubQuery(
"B" );
358 subQuery2.addToTableList(
"OKSSCHEMA" );
359 query->addToTableList(
"B" );
361 conditions_list.push_back(
"A.SCHEMAVERSION = B.VERSION");
392 if(schema_version != -1) {
393 conditions.extend<
int>(
"ver" );
394 conditions[
"ver"].data<
int>() = schema_version;
396 if(ls_base_versions_only) {
397 conditions_list.push_back(
"A.SCHEMAVERSION = :ver AND A.VERSION = A.BASEVERSION");
400 conditions_list.push_back(
"A.SCHEMAVERSION = :ver");
403 else if(ls_base_versions_only) {
404 conditions_list.push_back(
"A.VERSION = A.BASEVERSION");
407 if(!release.empty()) {
408 conditions.extend<std::string>(
"rel" );
409 conditions[
"rel"].data<std::string>() = release;
410 conditions_list.push_back(
"B.RELEASE = :rel");
413 if(!partition.empty()) {
415 if(ls_description ==
false) {
416 throw std::runtime_error(
"cannot search by partition without \"-d\" or \"-u\" command line option" );
418 conditions.extend<std::string>(
"prt1" );
419 conditions[
"prt1"].data<std::string>() = std::string(
"%partition ") + partition +
'%';
420 conditions_list.push_back(
"A.DESCRIPTION like :prt1");
424 if(!acrhived_since.empty()) {
425 conditions.extend<std::string>(
"ars" );
426 conditions[
"ars"].data<std::string>() = acrhived_since;
428 query->setDistinct();
429 coral::IQueryDefinition& subQuery3 = query->defineSubQuery(
"C" );
430 subQuery3.addToTableList(
"OKSARCHIVE" );
431 query->addToTableList(
"C" );
432 std::string condition(
"C.TIME >= :ars AND A.SCHEMAVERSION = C.SCHEMAVERSION AND A.VERSION = C.DATAVERSION");
433 if(!partition.empty()) {
434 conditions.extend<std::string>(
"prt2" );
435 conditions[
"prt2"].data<std::string>() = partition;
436 condition += (
has_a_pattern(partition) ?
" AND C.PARTITION like :prt2" :
" AND C.PARTITION = :prt2");
438 conditions_list.push_back(condition);
441 conditions_list.push_back(
"A.TIME >= :ars");
445 if(!acrhived_till.empty()) {
446 conditions.extend<std::string>(
"art" );
447 conditions[
"art"].data<std::string>() = acrhived_till;
448 conditions_list.push_back(
"A.TIME <= :art");
452 conditions.extend<std::string>(
"usr" );
453 conditions[
"usr"].data<std::string>() = user;
454 conditions_list.push_back(
has_a_pattern(user) ?
"A.CREATEDBY like :usr" :
"A.CREATEDBY = :usr");
458 conditions.extend<std::string>(
"hst" );
459 conditions[
"hst"].data<std::string>() = host;
460 conditions_list.push_back(
has_a_pattern(host) ?
"A.HOST like :hst" :
"A.HOST = :hst");
463 if(!sorted_by.empty()) {
464 for(
const char * p = sorted_by.c_str(); *p != 0; ++p) {
465 if(ls_description ==
false && (*p ==
'p' || *p ==
'P')) {
466 throw std::runtime_error(
"cannot sort by partition without \"-d\" command line option" );
470 case 'v': query->addToOrderList(
"A.SCHEMAVERSION"); query->addToOrderList(
"A.VERSION");
break;
471 case 'V': query->addToOrderList(
"A.SCHEMAVERSION DESC"); query->addToOrderList(
"A.VERSION DESC");
break;
472 case 't': query->addToOrderList(
"A.TIME");
break;
473 case 'T': query->addToOrderList(
"A.TIME DESC");
break;
474 case 'u': query->addToOrderList(
"A.CREATEDBY");
break;
475 case 'U': query->addToOrderList(
"A.CREATEDBY DESC");
break;
476 case 'h': query->addToOrderList(
"A.HOST");
break;
477 case 'H': query->addToOrderList(
"A.HOST DESC");
break;
478 case 'p': query->addToOrderList(
"A.DESCRIPTION");
break;
479 case 'P': query->addToOrderList(
"A.DESCRIPTION DESC");
break;
483 std::stringstream text;
484 text <<
"ERROR: wrong value \'" << *p <<
"\' in the command line parameter: \"--sorted-by\" or \"-t\"";
485 throw std::runtime_error( text.str().c_str() );
491 std::string conditions_str;
493 for(std::list<std::string>::const_iterator i = conditions_list.begin(); i != conditions_list.end(); ++i) {
494 if(i != conditions_list.begin()) conditions_str +=
" AND ";
495 conditions_str += *i;
498 query->setCondition( conditions_str, conditions );
500 coral::ICursor& cursor = query->execute();
503 std::vector<TableRow> rows;
508 rows.push_back(
TableRow(
' ',
'|',
"Version",
"Release",(tz_ptr ?
"Date (local time)" :
"Date (UTC)"),
"User",
"Host",
"Size",
"Description"));
513 coral::ITable& table;
515 {0,
session->schema(working_schema).tableHandle(
"OKSOBJECT" )},
516 {0,
session->schema(working_schema).tableHandle(
"OKSDATAVAL" )},
517 {0,
session->schema(working_schema).tableHandle(
"OKSDATAREL" )}
520 while(cursor.next()) {
521 const coral::AttributeList& row = cursor.currentRow();
523 std::string time, host, user;
525 std::string description;
if(ls_description && !row[
"A.DESCRIPTION"].isNull()) description = row[
"A.DESCRIPTION"].data<std::string>();
526 std::string r;
if(!row[
"B.RELEASE"].isNull()) r = row[
"B.RELEASE"].data<std::string>();
527 int sv = row[
"A.SCHEMAVERSION"].data<
int>();
528 int dv = row[
"A.VERSION"].data<
int>();
529 nums[0].num = nums[1].num = nums[2].num = 0;
532 coral::AttributeList sizes_query_conditions;
533 sizes_query_conditions.extend<
int>(
"sv" );
534 sizes_query_conditions[
"sv"].data<
int>() = sv;
535 sizes_query_conditions.extend<
int>(
"dv" );
536 sizes_query_conditions[
"dv"].data<
int>() = dv;
538 for(
unsigned int i = 0; i < 3; ++i) {
539 std::unique_ptr< coral::IQuery > query( nums[i].table.newQuery() );
540 query->setRowCacheSize( 1 );
541 query->addToOutputList(
"COUNT(*)");
542 query->defineOutputType(
"COUNT(*)",
"long");
543 query->setCondition(
"SCHEMAVERSION = :sv AND DATAVERSION = :dv", sizes_query_conditions );
545 coral::ICursor& c = query->execute();
548 nums[i].num = (int)c.currentRow().begin()->data<
long>();
555 sv, dv, row[
"A.BASEVERSION"].data<int>(),
556 r, time, user, host, description,
557 nums[0].num, nums[1].num, nums[2].num
562 std::unique_ptr< coral::IQuery > query( archive_table.newQuery() );
563 coral::AttributeList archive_query_conditions;
564 archive_query_conditions.extend<
int>(
"sv" );
565 archive_query_conditions[
"sv"].data<
int>() = sv;
566 archive_query_conditions.extend<
int>(
"dv" );
567 archive_query_conditions[
"dv"].data<
int>() = dv;
568 query->setRowCacheSize( 10 );
569 query->addToOutputList(
"TIME");
570 query->addToOutputList(
"PARTITION");
571 query->addToOutputList(
"CREATEDBY");
572 query->addToOutputList(
"HOST");
573 query->addToOutputList(
"RUNNUMBER");
575 if(!sorted_by.empty()) {
576 for(
const char * p = sorted_by.c_str(); *p != 0; ++p) {
579 case 'v': query->addToOrderList(
"RUNNUMBER");
break;
580 case 'V': query->addToOrderList(
"RUNNUMBER DESC");
break;
581 case 't': query->addToOrderList(
"TIME");
break;
582 case 'T': query->addToOrderList(
"TIME DESC");
break;
583 case 'u': query->addToOrderList(
"CREATEDBY");
break;
584 case 'U': query->addToOrderList(
"CREATEDBY DESC");
break;
585 case 'h': query->addToOrderList(
"HOST");
break;
586 case 'H': query->addToOrderList(
"HOST DESC");
break;
587 case 'p': query->addToOrderList(
"PARTITION");
break;
588 case 'P': query->addToOrderList(
"PARTITION DESC");
break;
593 std::string condition(
"SCHEMAVERSION = :sv AND DATAVERSION = :dv");
595 if(!acrhived_since.empty()) {
596 archive_query_conditions.extend<std::string>(
"ars" );
597 archive_query_conditions[
"ars"].data<std::string>() = acrhived_since;
598 condition +=
" AND TIME >= :ars";
601 if(!acrhived_till.empty()) {
602 archive_query_conditions.extend<std::string>(
"art" );
603 archive_query_conditions[
"art"].data<std::string>() = acrhived_till;
604 condition +=
" AND TIME <= :art";
607 if(!partition.empty()) {
608 archive_query_conditions.extend<std::string>(
"prt" );
609 archive_query_conditions[
"prt"].data<std::string>() = partition;
610 condition += (
has_a_pattern(partition) ?
" AND PARTITION like :prt" :
" AND PARTITION = :prt");
613 query->setCondition( condition, archive_query_conditions );
615 coral::ICursor& c = query->execute();
618 const coral::AttributeList& ar_row = c.currentRow();
619 std::string ar_time, ar_host, ar_user;
621 std::string p;
if(!ar_row[
"PARTITION"].isNull()) p = ar_row[
"PARTITION"].data<std::string>();
623 std::ostringstream s;
624 s <<
"partition: " << p <<
" run: " << ar_row[
"RUNNUMBER"].data<
int>();
626 rows.push_back(
TableRow(
' ',
'|', 0, 0, 0, r, ar_time, ar_user, ar_host, s.str()));
635 unsigned short cw[] = {1,1,1,1,1,1,1};
637 for(
auto & i : rows) {
638 for(
unsigned short j = 0; j <
sizeof(cw)/
sizeof(
unsigned short); ++j) {
639 unsigned short len = i.m_items[j].size();
640 if(len > cw[j]) cw[j]=len;
649 bool align_left[] = {
false,
true,
true,
true,
true,
false,
true};
651 for(std::vector<TableRow>::const_iterator i = rows.begin(); i != rows.end(); ++i) {
652 std::cout.fill((*i).m_fill);
653 for(
unsigned short j = 0; j <
sizeof(cw)/
sizeof(
unsigned short); ++j) {
654 std::cout << (*i).m_separator << (*i).m_fill;
655 std::cout.setf((align_left[j] ? std::ios::left : std::ios::right), std::ios::adjustfield);
656 std::cout.width(cw[j]);
657 std::cout << (*i).m_items[j] << (*i).m_fill;
659 std::cout << (*i).m_separator << std::endl;
665 session->transaction().commit();
673 catch ( coral::Exception& e ) {
674 std::cerr <<
"CORAL exception: " << e.what() << std::endl;
678 catch ( std::exception& e ) {
679 std::cerr <<
"Standard C++ exception : " << e.what() << std::endl;
684 std::cerr <<
"Exception caught (...)" << std::endl;