11 #include "cetlib_except/exception.h"
12 #include "cetlib/search_path.h"
13 #include "messagefacility/MessageLogger/MessageLogger.h"
20 const std::string& tag,
bool usesqlite,
bool testmode)
43 cet::search_path sp(
"FW_SEARCH_PATH");
51 mf::LogInfo log(
"DBFolder");
52 log <<
"\nDBFolder test mode, will compare the following urls data." <<
"\n";
54 log <<
fURL2 <<
"\n" <<
"\n";
57 mf::LogInfo log(
"DBFolder");
58 log <<
"\nDBFolder test mode, will compare the following url and sqlite data." <<
"\n";
223 std::string
msg =
"Channel " +
std::to_string(channel) +
" is not found in database!";
244 std::string
msg =
"Column " + name +
" is not found in database!";
269 std::stringstream fullurl;
272 if (
fTag.length() > 0) fullurl <<
"&tag=" <<
fTag;
285 mf::LogInfo log(
"DBFolder");
286 log <<
"Accessing primary calibration data from http conditions database server." <<
"\n";
291 int status = getHTTPstatus(data);
293 std::string
msg =
"HTTP error from " + fullurl.str()+
": status: " +
std::to_string(status) +
": " + std::string(getHTTPmessage(data));
306 mf::LogInfo(
"DBFolder") <<
"Accessing comparison data from sqlite database " <<
fSQLitePath <<
"\n";
311 mf::LogInfo(
"DBFolder") <<
"Accessing comparison data from second database url." <<
"\n";
312 std::stringstream fullurl2;
315 if (
fTag.length() > 0) fullurl2 <<
"&tag=" <<
fTag;
316 mf::LogInfo(
"DBFolder") <<
"Full url = " << fullurl2.str() <<
"\n";
319 int status = getHTTPstatus(data);
321 std::string
msg =
"HTTP error from " + fullurl2.str()+
": status: " +
std::to_string(status) +
": " + std::string(getHTTPmessage(data));
344 std::vector<std::string> column_names;
345 std::vector<std::string> column_types;
346 std::vector<DBChannelID_t> channels;
347 std::vector<DBDataset::value_type>
values;
359 if(rc != SQLITE_OK) {
360 mf::LogError(
"DBFolder") <<
"Failed to open sqlite database " <<
fSQLitePath <<
"\n";
361 throw cet::exception(
"DBFolder") <<
"Failed to open sqlite database " <<
fSQLitePath;
367 std::string table_tag_iovs =
fFolderName +
"_tag_iovs";
368 std::ostringstream sql;
369 sql <<
"SELECT " << table_iovs <<
".iov_id," << table_iovs <<
".begin_time"
370 <<
" FROM " << table_tag_iovs <<
"," << table_iovs
371 <<
" WHERE " << table_tag_iovs <<
".tag='" <<
fTag <<
"'"
372 <<
" AND " << table_tag_iovs <<
".iov_id=" << table_iovs <<
".iov_id"
373 <<
" AND " << table_iovs <<
".begin_time <= " << t
374 <<
" ORDER BY " << table_iovs <<
".begin_time desc";
380 rc = sqlite3_prepare_v2(db, sql.str().c_str(), -1, &stmt, 0);
381 if(rc != SQLITE_OK) {
382 mf::LogError log(
"DBFolder");
383 log <<
"sqlite3_prepare_v2 failed." <<
fSQLitePath <<
"\n";
384 log <<
"Failed sql = " << sql.str() <<
"\n";
385 throw cet::exception(
"DBFolder") <<
"sqlite3_prepare_v2 error.";
392 rc = sqlite3_step(stmt);
395 if(rc == SQLITE_ROW) {
397 begin_time = sqlite3_column_int(stmt, 1);
403 mf::LogError(
"DBFolder") <<
"sqlite3_step returned error result = " << rc <<
"\n";
404 throw cet::exception(
"DBFolder") <<
"sqlite3_step error.";
409 sqlite3_finalize(stmt);
414 sql <<
"SELECT " << table_iovs <<
".begin_time"
415 <<
" FROM " << table_tag_iovs <<
"," << table_iovs
416 <<
" WHERE " << table_tag_iovs <<
".tag='" <<
fTag <<
"'"
417 <<
" AND " << table_tag_iovs <<
".iov_id=" << table_iovs <<
".iov_id"
418 <<
" AND " << table_iovs <<
".begin_time > " << t
419 <<
" ORDER BY " << table_iovs <<
".begin_time";
424 rc = sqlite3_prepare_v2(db, sql.str().c_str(), -1, &stmt, 0);
425 if(rc != SQLITE_OK) {
426 mf::LogError log(
"DBFolder");
427 log <<
"sqlite3_prepare_v2 failed." <<
fSQLitePath <<
"\n";
428 log <<
"Failed sql = " << sql.str() <<
"\n";
429 throw cet::exception(
"DBFolder") <<
"sqlite3_prepare_v2 error.";
436 rc = sqlite3_step(stmt);
438 if(rc == SQLITE_ROW) {
439 end_time = sqlite3_column_int(stmt, 0);
442 else if(rc != SQLITE_DONE) {
443 mf::LogError(
"DBFolder") <<
"sqlite3_step returned error result = " << rc <<
"\n";
444 throw cet::exception(
"DBFolder") <<
"sqlite3_step error.";
449 sqlite3_finalize(stmt);
456 sql <<
"SELECT COUNT(DISTINCT channel)"
457 <<
" FROM " << table_data <<
"," << table_iovs <<
"," << table_tag_iovs
458 <<
" WHERE " << table_tag_iovs <<
".tag='" <<
fTag <<
"'"
459 <<
" AND " << table_iovs <<
".iov_id=" << table_tag_iovs <<
".iov_id"
460 <<
" AND " << table_data <<
".__iov_id=" << table_tag_iovs <<
".iov_id"
461 <<
" AND " << table_iovs <<
".begin_time <= " << t;
466 rc = sqlite3_prepare_v2(db, sql.str().c_str(), -1, &stmt, 0);
467 if(rc != SQLITE_OK) {
468 mf::LogError log(
"DBFolder");
469 log <<
"sqlite3_prepare_v2 failed." <<
fSQLitePath <<
"\n";
470 log <<
"Failed sql = " << sql.str() <<
"\n";
471 throw cet::exception(
"DBFolder") <<
"sqlite3_prepare_v2 error.";
478 rc = sqlite3_step(stmt);
479 unsigned int nrows = 0;
480 if(rc == SQLITE_ROW) {
481 nrows = sqlite3_column_int(stmt, 0);
485 mf::LogError(
"DBFolder") <<
"sqlite3_step returned error result = " << rc <<
"\n";
486 throw cet::exception(
"DBFolder") <<
"sqlite3_step error.";
491 channels.reserve(nrows);
495 sqlite3_finalize(stmt);
511 sql <<
"SELECT " << table_data <<
".*,MAX(begin_time)"
512 <<
" FROM " << table_data <<
"," << table_iovs <<
"," << table_tag_iovs
513 <<
" WHERE " << table_tag_iovs <<
".tag='" <<
fTag <<
"'"
514 <<
" AND " << table_iovs <<
".iov_id=" << table_tag_iovs <<
".iov_id"
515 <<
" AND " << table_data <<
".__iov_id=" << table_tag_iovs <<
".iov_id"
516 <<
" AND " << table_iovs <<
".begin_time <= " << t
517 <<
" GROUP BY channel"
518 <<
" ORDER BY channel";
523 rc = sqlite3_prepare_v2(db, sql.str().c_str(), -1, &stmt, 0);
524 if(rc != SQLITE_OK) {
525 mf::LogError log(
"DBFolder");
526 log <<
"sqlite3_prepare_v2 failed." <<
fSQLitePath <<
"\n";
527 log <<
"Failed sql = " << sql.str() <<
"\n";
528 throw cet::exception(
"DBFolder") <<
"sqlite3_prepare_v2 error.";
534 int ncols = sqlite3_column_count(stmt);
535 column_names.reserve(ncols);
536 column_types.reserve(ncols);
538 rc = sqlite3_step(stmt);
539 if(rc == SQLITE_ROW) {
543 for(
int col = 0; col < ncols; ++col) {
544 std::string colname = sqlite3_column_name(stmt, col);
549 if(colname[0] !=
'_' && colname.substr(0,3) !=
"MAX") {
550 column_names.push_back(colname);
551 int dtype = sqlite3_column_type(stmt, col);
552 if(dtype == SQLITE_INTEGER)
553 column_types.push_back(
"integer");
554 else if(dtype == SQLITE_FLOAT)
555 column_types.push_back(
"real");
556 else if(dtype == SQLITE_TEXT)
557 column_types.push_back(
"text");
558 else if(dtype == SQLITE_NULL)
559 column_types.push_back(
"NULL");
561 mf::LogError(
"DBFolder") <<
"Unknown type " << dtype <<
"\n";
562 throw cet::exception(
"DBFolder") <<
"Unknown type " << dtype;
571 mf::LogError(
"DBFolder") <<
"No data rows." <<
"\n";
572 throw cet::exception(
"DBFolder") <<
"No data rows.";
577 size_t nrelcols = column_names.size();
578 values.reserve(nrows * nrelcols);
583 rc = sqlite3_reset(stmt);
584 if(rc != SQLITE_OK) {
585 mf::LogError(
"DBFolder") <<
"sqlite3_reset failed." <<
"\n";
586 throw cet::exception(
"DBFolder") <<
"sqlite3_failed.";
589 while(rc != SQLITE_DONE) {
590 rc = sqlite3_step(stmt);
591 if(rc == SQLITE_ROW) {
595 mf::LogError(
"DBFolder") <<
"Too many data rows " << irow <<
"\n";
596 throw cet::exception(
"DBFolder") <<
"Too many data rows " << irow;
603 bool firstcol =
true;
604 for(
int col = 0; col < ncols; ++col) {
605 std::string colname = sqlite3_column_name(stmt, col);
610 if(colname[0] !=
'_' && colname.substr(0,3) !=
"MAX") {
611 int dtype = sqlite3_column_type(stmt, col);
613 if(dtype == SQLITE_INTEGER) {
614 long value = sqlite3_column_int(stmt, col);
618 channels.push_back(value);
620 else if(dtype == SQLITE_FLOAT) {
621 double value = sqlite3_column_double(stmt, col);
625 mf::LogError(
"DBFolder") <<
"First column has wrong type float." <<
"\n";
626 throw cet::exception(
"DBFolder") <<
"First column has wrong type float.";
629 else if(dtype == SQLITE_TEXT) {
630 const char*
s = (
const char*)sqlite3_column_text(stmt, col);
632 values.emplace_back(std::make_unique<std::string>(s));
634 mf::LogError(
"DBFolder") <<
"First column has wrong type text." <<
"\n";
635 throw cet::exception(
"DBFolder") <<
"First column has wrong type text.";
638 else if(dtype == SQLITE_NULL) {
642 mf::LogError(
"DBFolder") <<
"First column has wrong type null." <<
"\n";
643 throw cet::exception(
"DBFolder") <<
"First column has wrong type null.";
647 mf::LogError(
"DBFolder") <<
"Unrecognized sqlite data type" <<
"\n";
648 throw cet::exception(
"DBFolder") <<
"Unrecognized sqlite data type.";
654 else if(rc != SQLITE_DONE) {
655 mf::LogError(
"DBFolder") <<
"sqlite3_step returned error result = " << rc <<
"\n";
656 throw cet::exception(
"DBFolder") <<
"sqlite3_step error.";
660 mf::LogError(
"DBFolder") <<
"Wrong number of data rows " << irow <<
"," << nrows <<
"\n";
661 throw cet::exception(
"DBFolder") <<
"Wrong number of data rows " << irow <<
"," << nrows <<
"\n";
663 if(values.size() != nrows * nrelcols) {
664 mf::LogError(
"DBFolder") <<
"Wrong number of values "
665 << values.size() <<
"," << nrows <<
"," << nrelcols <<
"\n";
666 throw cet::exception(
"DBFolder") <<
"Wrong number of values "
667 << values.size() <<
"," << nrows <<
"," << nrelcols <<
"\n";
672 sqlite3_finalize(stmt);
681 std::move(column_names),
682 std::move(column_types),
695 size_t nrows = data.
nrows();
696 size_t ncols = data.
ncols();
697 mf::LogInfo log(
"DBFolder");
698 log <<
"Dataset contains " << nrows <<
" rows and " << ncols <<
" columns." <<
"\n";
711 for (
size_t c=0; c<ncols; ++c)
712 log <<
"Column " << c <<
", name = " << names[c] <<
"\n";
717 for (
size_t c=0; c<ncols; ++c)
718 log <<
"Column " << c <<
", type = " << types[c] <<
"\n";
723 log <<
"\nRow " <<
row <<
"\n";
728 for(
size_t col=0; col<ncols; ++col) {
729 if(types[col] ==
"bigint" || types[col] ==
"integer" || types[col] ==
"boolean") {
731 log << names[col] <<
" = " << value <<
"\n";
733 else if(types[col] ==
"real") {
735 log << names[col] <<
" = " << value <<
"\n";
737 else if(types[col] ==
"text" or types[col] ==
"boolean") {
739 log << names[col] <<
" = " << value <<
"\n";
742 mf::LogError(
"DBFolder") <<
"Unknown type " << types[col] <<
"\n";
743 throw cet::exception(
"DBFolder") <<
"Unknown type.";
751 bool compare_ok =
true;
752 mf::LogInfo(
"DBFolder") <<
"\nComparing datasets." <<
"\n";
754 size_t nrows1 = data1.
nrows();
755 size_t nrows2 = data2.
nrows();
778 size_t ncols1 = data1.
ncols();
779 size_t ncols2 = data2.
ncols();
780 const std::vector<std::string>& names1 = data1.
colNames();
781 const std::vector<std::string>& names2 = data2.
colNames();
782 if(ncols1 != ncols2 || ncols1 != names1.size() || ncols2 != names2.size()) {
783 mf::LogWarning(
"DBFolder") <<
"Columns names size mismatch " << ncols1
785 <<
" vs. " << names1.size()
786 <<
" vs. " << names2.size()
791 for (
size_t c=0; c<ncols1; ++c) {
792 if(names1[c] != names2[c]) {
793 mf::LogWarning(
"DBFolder") <<
"Name mismatch " << names1[c] <<
" vs. " << names2[c] <<
"\n";
801 const std::vector<std::string>& types1 = data1.
colTypes();
802 const std::vector<std::string>& types2 = data2.
colTypes();
803 if(ncols1 != ncols2 || ncols1 != types1.size() || ncols2 != types2.size()) {
804 mf::LogWarning(
"DBFolder") <<
"Column types ize mismatch " << ncols1
806 <<
" vs. " << types1.size()
807 <<
" vs. " << types2.size()
812 for (
size_t c=0; c<ncols2; ++c) {
817 std::string type1 = types1[c];
818 std::string type2 = types2[c];
819 if(type1 ==
"bigint" || type1 ==
"boolean")
821 if(type2 ==
"bigint" || type2 ==
"boolean")
824 mf::LogWarning(
"DBFolder") <<
"Type mismatch " << type1 <<
" vs. " << type2 <<
"\n";
832 const std::vector<DBChannelID_t>& channels1 = data1.
channels();
833 const std::vector<DBChannelID_t>& channels2 = data2.
channels();
834 if(nrows1 != nrows2 || nrows1 != channels1.size() || nrows2 != channels2.size()) {
835 mf::LogWarning(
"DBFolder") <<
"Channels size mismatch " << nrows1
837 <<
" vs. " << channels1.size()
838 <<
" vs. " << channels2.size()
843 for (
size_t r=0;
r<nrows1; ++
r) {
844 if(channels1[
r] != channels2[
r]) {
845 mf::LogWarning(
"DBFolder") <<
"Channel mismatch " << channels1[
r] <<
" vs. " << channels2[
r] <<
"\n";
853 if(data1.
data().size() != data2.
data().size()) {
854 mf::LogWarning(
"DBFolder") <<
"Values size mismatch " << data1.
data().size()
855 <<
" vs. " << data2.
data().size()
870 for(
size_t col=0; col<ncols1; ++col) {
871 if(types1[col] ==
"integer" || types1[col] ==
"bigint" || types1[col] ==
"boolean") {
877 if(value1 != value2) {
878 mf::LogWarning(
"DBFolder") <<
"Value mismatch " << value1 <<
" vs. " << value2 <<
"\n";
882 else if(types1[col] ==
"real") {
888 if(value1 != value2) {
889 mf::LogWarning(
"DBFolder") <<
"Value mismatch " << value1 <<
" vs. " << value2 <<
"\n";
893 else if(types1[col] ==
"text") {
896 if(value1 != value2) {
897 mf::LogWarning(
"DBFolder") <<
"Value mismatch " << value1 <<
" vs. " << value2 <<
"\n";
902 mf::LogError(
"DBFolder") <<
"Unknown type " << types1[col] <<
"\n";
903 throw cet::exception(
"DBFolder") <<
"Unknown type.";
910 mf::LogInfo(
"DBFolder") <<
"Comparison OK.\n" <<
"\n";
913 mf::LogError(
"DBFolder") <<
"Comparison fail." <<
"\n";
914 throw cet::exception(
"DBFolder") <<
"Comparison fail.";
std::variant< long, double, std::unique_ptr< std::string > > value_type
int GetNamedChannelData(DBChannelID_t channel, const std::string &name, bool &data)
double getDoubleData(size_t col) const
bool UpdateData(DBTimeStamp_t raw_time)
std::uint32_t DBChannelID_t
void GetRow(DBChannelID_t channel)
EResult err(const char *call)
const std::vector< std::string > & colNames() const
DBDataset::DBRow fCachedRow
const std::string & DBStamp() const
const std::string & getStringData(size_t col) const
std::uint64_t DBTimeStamp_t
DBRow getRow(size_t row) const
int getRowNumber(DBChannelID_t ch) const
int GetChannelList(std::vector< DBChannelID_t > &channels) const
DBChannelID_t fCachedChannel
const std::vector< value_type > & data() const
bool IsValid(const IOVTimeStamp &time) const
then echo fcl sbnd_project sbnd_project sbnd_project sbnd_project production production end_time
std::vector< SelDef > types
const IOVTimeStamp & endTime() const
const std::vector< std::string > & colTypes() const
void DumpDataset(const DBDataset &data) const
bool CompareDataset(const DBDataset &data1, const DBDataset &data2) const
const IOVTimeStamp & beginTime() const
static const std::vector< std::string > names
const std::vector< DBChannelID_t > & channels() const
std::string to_string(WindowPattern const &pattern)
then echo File list $list not found else cat $list while read file do echo $file sed s
long getLongData(size_t col) const
size_t GetColumn(const std::string &name) const
int getColNumber(const std::string &name) const
static IOVTimeStamp MaxTimeStamp()
height to which particles are projected pnfs larsoft persistent physics cosmics Fermilab CORSIKA standard He_showers_ * db
DBFolder(const std::string &name, const std::string &url, const std::string &url2, const std::string &tag="", bool useqlite=false, bool testmode=false)
static IOVTimeStamp DecodeTimeStamp(DBTimeStamp_t ts)
Collection of exception classes for WebDBI.
void GetSQLiteData(int t, DBDataset &data) const