11 #include "cetlib_except/exception.h" 52 log <<
"\nDBFolder test mode, will compare the following urls data." <<
"\n";
54 log <<
fURL2 <<
"\n" <<
"\n";
58 log <<
"\nDBFolder test mode, will compare the following url and sqlite data." <<
"\n";
244 std::string msg =
"Column " + name +
" is not found in database!";
269 std::stringstream fullurl;
272 if (
fTag.length() > 0) fullurl <<
"&tag=" <<
fTag;
286 log <<
"Accessing primary calibration data from http conditions database server." <<
"\n";
291 int status = getHTTPstatus(data);
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);
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) {
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) {
383 log <<
"sqlite3_prepare_v2 failed." <<
fSQLitePath <<
"\n";
384 log <<
"Failed sql = " << sql.str() <<
"\n";
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";
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) {
427 log <<
"sqlite3_prepare_v2 failed." <<
fSQLitePath <<
"\n";
428 log <<
"Failed sql = " << sql.str() <<
"\n";
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";
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) {
469 log <<
"sqlite3_prepare_v2 failed." <<
fSQLitePath <<
"\n";
470 log <<
"Failed sql = " << sql.str() <<
"\n";
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";
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) {
526 log <<
"sqlite3_prepare_v2 failed." <<
fSQLitePath <<
"\n";
527 log <<
"Failed sql = " << sql.str() <<
"\n";
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";
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";
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";
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) {
665 << values.size() <<
"," << nrows <<
"," << nrelcols <<
"\n";
667 << values.size() <<
"," << nrows <<
"," << nrelcols <<
"\n";
672 sqlite3_finalize(stmt);
696 size_t ncols = data.
ncols();
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";
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) {
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()) {
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()) {
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";
910 mf::LogInfo(
"DBFolder") <<
"Comparison OK.\n" <<
"\n";
std::variant< long, double, std::unique_ptr< std::string > > value_type
int GetNamedChannelData(DBChannelID_t channel, const std::string &name, bool &data)
void msg(const char *fmt,...)
double getDoubleData(size_t col) const
bool UpdateData(DBTimeStamp_t raw_time)
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
std::uint32_t DBChannelID_t
void GetRow(DBChannelID_t channel)
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
struct sqlite3_stmt sqlite3_stmt
DBRow getRow(size_t row) const
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
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
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
void err(const char *fmt,...)
Filters for channels, events, etc.
const std::vector< DBChannelID_t > & channels() const
static const char types[][NUM_HTML_LIST_TYPES]
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
long getLongData(size_t col) const
std::string find_file(std::string const &filename) const
size_t GetColumn(const std::string &name) const
int getColNumber(const std::string &name) const
static IOVTimeStamp MaxTimeStamp()
unsigned nrows(sqlite3 *db, std::string const &tablename)
static std::vector< std::string > const names
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.
std::string to_string(ModuleType const mt)
cet::coded_exception< error, detail::translate > exception
void GetSQLiteData(int t, DBDataset &data) const