6 #include "cetlib/search_path.h" 7 #include "cetlib_except/exception.h" 20 const std::string& url,
21 const std::string& url2,
22 const std::string& tag,
45 cet::search_path sp(
"FW_SEARCH_PATH");
54 log <<
"\nDBFolder test mode, will compare the following urls data." 62 log <<
"\nDBFolder test mode, will compare the following url and sqlite data." 142 const std::string& name,
236 std::string msg =
"Channel " +
std::to_string(channel) +
" is not found in database!";
257 std::string msg =
"Column " + name +
" is not found in database!";
283 std::stringstream fullurl;
285 if (
fTag.length() > 0) fullurl <<
"&tag=" <<
fTag;
297 log <<
"Accessing primary calibration data from http conditions database server." 303 int status = getHTTPstatus(data);
305 std::string msg =
"HTTP error from " + fullurl.str() +
307 std::string(getHTTPmessage(data));
325 mf::LogInfo(
"DBFolder") <<
"Accessing comparison data from second database url." 327 std::stringstream fullurl2;
329 if (
fTag.length() > 0) fullurl2 <<
"&tag=" <<
fTag;
330 mf::LogInfo(
"DBFolder") <<
"Full url = " << fullurl2.str() <<
"\n";
333 int status = getHTTPstatus(data);
335 std::string msg =
"HTTP error from " + fullurl2.str() +
337 std::string(getHTTPmessage(data));
359 std::vector<std::string> column_names;
360 std::vector<std::string> column_types;
361 std::vector<DBChannelID_t> channels;
362 std::vector<DBDataset::value_type>
values;
374 if (rc != SQLITE_OK) {
382 std::string table_tag_iovs =
fFolderName +
"_tag_iovs";
383 std::ostringstream sql;
384 sql <<
"SELECT " << table_iovs <<
".iov_id," << table_iovs <<
".begin_time" 385 <<
" FROM " << table_tag_iovs <<
"," << table_iovs <<
" WHERE " << table_tag_iovs
386 <<
".tag='" <<
fTag <<
"'" 387 <<
" AND " << table_tag_iovs <<
".iov_id=" << table_iovs <<
".iov_id" 388 <<
" AND " << table_iovs <<
".begin_time <= " << t <<
" ORDER BY " << table_iovs
389 <<
".begin_time desc";
395 rc = sqlite3_prepare_v2(db, sql.str().c_str(), -1, &stmt, 0);
396 if (rc != SQLITE_OK) {
398 log <<
"sqlite3_prepare_v2 failed." <<
fSQLitePath <<
"\n";
399 log <<
"Failed sql = " << sql.str() <<
"\n";
407 rc = sqlite3_step(stmt);
410 if (rc == SQLITE_ROW) {
412 begin_time = sqlite3_column_int(stmt, 1);
418 mf::LogError(
"DBFolder") <<
"sqlite3_step returned error result = " << rc <<
"\n";
424 sqlite3_finalize(stmt);
429 sql <<
"SELECT " << table_iovs <<
".begin_time" 430 <<
" FROM " << table_tag_iovs <<
"," << table_iovs <<
" WHERE " << table_tag_iovs
431 <<
".tag='" <<
fTag <<
"'" 432 <<
" AND " << table_tag_iovs <<
".iov_id=" << table_iovs <<
".iov_id" 433 <<
" AND " << table_iovs <<
".begin_time > " << t <<
" ORDER BY " << table_iovs
439 rc = sqlite3_prepare_v2(db, sql.str().c_str(), -1, &stmt, 0);
440 if (rc != SQLITE_OK) {
442 log <<
"sqlite3_prepare_v2 failed." <<
fSQLitePath <<
"\n";
443 log <<
"Failed sql = " << sql.str() <<
"\n";
451 rc = sqlite3_step(stmt);
453 if (rc == SQLITE_ROW) {
454 end_time = sqlite3_column_int(stmt, 0);
457 else if (rc != SQLITE_DONE) {
458 mf::LogError(
"DBFolder") <<
"sqlite3_step returned error result = " << rc <<
"\n";
464 sqlite3_finalize(stmt);
471 sql <<
"SELECT COUNT(DISTINCT channel)" 472 <<
" FROM " << table_data <<
"," << table_iovs <<
"," << table_tag_iovs <<
" WHERE " 473 << table_tag_iovs <<
".tag='" <<
fTag <<
"'" 474 <<
" AND " << table_iovs <<
".iov_id=" << table_tag_iovs <<
".iov_id" 475 <<
" AND " << table_data <<
".__iov_id=" << table_tag_iovs <<
".iov_id" 476 <<
" AND " << table_iovs <<
".begin_time <= " << t;
481 rc = sqlite3_prepare_v2(db, sql.str().c_str(), -1, &stmt, 0);
482 if (rc != SQLITE_OK) {
484 log <<
"sqlite3_prepare_v2 failed." <<
fSQLitePath <<
"\n";
485 log <<
"Failed sql = " << sql.str() <<
"\n";
493 rc = sqlite3_step(stmt);
494 unsigned int nrows = 0;
495 if (rc == SQLITE_ROW) {
496 nrows = sqlite3_column_int(stmt, 0);
500 mf::LogError(
"DBFolder") <<
"sqlite3_step returned error result = " << rc <<
"\n";
506 channels.reserve(nrows);
510 sqlite3_finalize(stmt);
526 sql <<
"SELECT " << table_data <<
".*,MAX(begin_time)" 527 <<
" FROM " << table_data <<
"," << table_iovs <<
"," << table_tag_iovs <<
" WHERE " 528 << table_tag_iovs <<
".tag='" <<
fTag <<
"'" 529 <<
" AND " << table_iovs <<
".iov_id=" << table_tag_iovs <<
".iov_id" 530 <<
" AND " << table_data <<
".__iov_id=" << table_tag_iovs <<
".iov_id" 531 <<
" AND " << table_iovs <<
".begin_time <= " << t <<
" GROUP BY channel" 532 <<
" ORDER BY channel";
537 rc = sqlite3_prepare_v2(db, sql.str().c_str(), -1, &stmt, 0);
538 if (rc != SQLITE_OK) {
540 log <<
"sqlite3_prepare_v2 failed." <<
fSQLitePath <<
"\n";
541 log <<
"Failed sql = " << sql.str() <<
"\n";
548 int ncols = sqlite3_column_count(stmt);
549 column_names.reserve(ncols);
550 column_types.reserve(ncols);
552 rc = sqlite3_step(stmt);
553 if (rc == SQLITE_ROW) {
558 std::string colname = sqlite3_column_name(stmt,
col);
563 if (colname[0] !=
'_' && colname.substr(0, 3) !=
"MAX") {
564 column_names.push_back(colname);
565 int dtype = sqlite3_column_type(stmt,
col);
566 if (dtype == SQLITE_INTEGER)
567 column_types.push_back(
"integer");
568 else if (dtype == SQLITE_FLOAT)
569 column_types.push_back(
"real");
570 else if (dtype == SQLITE_TEXT)
571 column_types.push_back(
"text");
572 else if (dtype == SQLITE_NULL)
573 column_types.push_back(
"NULL");
575 mf::LogError(
"DBFolder") <<
"Unknown type " << dtype <<
"\n";
592 size_t nrelcols = column_names.size();
593 values.reserve(nrows * nrelcols);
598 rc = sqlite3_reset(stmt);
599 if (rc != SQLITE_OK) {
605 while (rc != SQLITE_DONE) {
606 rc = sqlite3_step(stmt);
607 if (rc == SQLITE_ROW) {
611 mf::LogError(
"DBFolder") <<
"Too many data rows " << irow <<
"\n";
612 throw cet::exception(
"DBFolder") <<
"Too many data rows " << irow;
619 bool firstcol =
true;
621 std::string colname = sqlite3_column_name(stmt,
col);
626 if (colname[0] !=
'_' && colname.substr(0, 3) !=
"MAX") {
627 int dtype = sqlite3_column_type(stmt,
col);
629 if (dtype == SQLITE_INTEGER) {
630 long value = sqlite3_column_int(stmt,
col);
633 if (firstcol) channels.push_back(value);
635 else if (dtype == SQLITE_FLOAT) {
636 double value = sqlite3_column_double(stmt,
col);
640 mf::LogError(
"DBFolder") <<
"First column has wrong type float." 642 throw cet::exception(
"DBFolder") <<
"First column has wrong type float.";
645 else if (dtype == SQLITE_TEXT) {
646 const char* s = (
const char*)sqlite3_column_text(stmt,
col);
648 values.emplace_back(std::make_unique<std::string>(s));
650 mf::LogError(
"DBFolder") <<
"First column has wrong type text." 652 throw cet::exception(
"DBFolder") <<
"First column has wrong type text.";
655 else if (dtype == SQLITE_NULL) {
659 mf::LogError(
"DBFolder") <<
"First column has wrong type null." 661 throw cet::exception(
"DBFolder") <<
"First column has wrong type null.";
665 mf::LogError(
"DBFolder") <<
"Unrecognized sqlite data type" 667 throw cet::exception(
"DBFolder") <<
"Unrecognized sqlite data type.";
673 else if (rc != SQLITE_DONE) {
674 mf::LogError(
"DBFolder") <<
"sqlite3_step returned error result = " << rc <<
"\n";
679 mf::LogError(
"DBFolder") <<
"Wrong number of data rows " << irow <<
"," << nrows <<
"\n";
681 <<
"Wrong number of data rows " << irow <<
"," << nrows <<
"\n";
683 if (values.size() != nrows * nrelcols) {
684 mf::LogError(
"DBFolder") <<
"Wrong number of values " << values.size() <<
"," << nrows <<
"," 687 <<
"Wrong number of values " << values.size() <<
"," << nrows <<
"," << nrelcols <<
"\n";
692 sqlite3_finalize(stmt);
702 std::move(column_names),
703 std::move(column_types),
716 size_t nrows = data.
nrows();
719 log <<
"Dataset contains " << nrows <<
" rows and " << ncols <<
" columns." 732 const std::vector<std::string>& names = data.
colNames();
733 for (
size_t c = 0; c <
ncols; ++c)
734 log <<
"Column " << c <<
", name = " << names[c] <<
"\n";
738 const std::vector<std::string>& types = data.
colTypes();
739 for (
size_t c = 0; c <
ncols; ++c)
740 log <<
"Column " << c <<
", type = " << types[c] <<
"\n";
744 for (
size_t row = 0; row < nrows; ++row) {
745 log <<
"\nRow " << row <<
"\n";
751 if (types[
col] ==
"bigint" || types[
col] ==
"integer" || types[
col] ==
"boolean") {
753 log << names[
col] <<
" = " << value <<
"\n";
755 else if (types[
col] ==
"real") {
757 log << names[
col] <<
" = " << value <<
"\n";
759 else if (types[
col] ==
"text" or types[
col] ==
"boolean") {
761 log << names[
col] <<
" = " << value <<
"\n";
773 bool compare_ok =
true;
777 size_t nrows1 = data1.
nrows();
778 size_t nrows2 = data2.
nrows();
782 if (nrows1 != nrows2) compare_ok =
false;
788 if (begin1 != begin2) compare_ok =
false;
794 if (end1 != end2) compare_ok =
false;
798 size_t ncols1 = data1.
ncols();
799 size_t ncols2 = data2.
ncols();
800 const std::vector<std::string>& names1 = data1.
colNames();
801 const std::vector<std::string>& names2 = data2.
colNames();
802 if (ncols1 != ncols2 || ncols1 != names1.size() || ncols2 != names2.size()) {
803 mf::LogWarning(
"DBFolder") <<
"Columns names size mismatch " << ncols1 <<
" vs. " << ncols2
804 <<
" vs. " << names1.size() <<
" vs. " << names2.size() <<
"\n";
808 for (
size_t c = 0; c < ncols1; ++c) {
809 if (names1[c] != names2[c]) {
811 <<
"Name mismatch " << names1[c] <<
" vs. " << names2[c] <<
"\n";
819 const std::vector<std::string>& types1 = data1.
colTypes();
820 const std::vector<std::string>& types2 = data2.
colTypes();
821 if (ncols1 != ncols2 || ncols1 != types1.size() || ncols2 != types2.size()) {
822 mf::LogWarning(
"DBFolder") <<
"Column types ize mismatch " << ncols1 <<
" vs. " << ncols2
823 <<
" vs. " << types1.size() <<
" vs. " << types2.size() <<
"\n";
827 for (
size_t c = 0; c < ncols2; ++c) {
832 std::string type1 = types1[c];
833 std::string type2 = types2[c];
834 if (type1 ==
"bigint" || type1 ==
"boolean") type1 =
"integer";
835 if (type2 ==
"bigint" || type2 ==
"boolean") type2 =
"integer";
836 if (type1 != type2) {
837 mf::LogWarning(
"DBFolder") <<
"Type mismatch " << type1 <<
" vs. " << type2 <<
"\n";
845 const std::vector<DBChannelID_t>& channels1 = data1.
channels();
846 const std::vector<DBChannelID_t>& channels2 = data2.
channels();
847 if (nrows1 != nrows2 || nrows1 != channels1.size() || nrows2 != channels2.size()) {
848 mf::LogWarning(
"DBFolder") <<
"Channels size mismatch " << nrows1 <<
" vs. " << nrows2
849 <<
" vs. " << channels1.size() <<
" vs. " << channels2.size()
854 for (
size_t r = 0;
r < nrows1; ++
r) {
855 if (channels1[
r] != channels2[
r]) {
857 <<
"Channel mismatch " << channels1[
r] <<
" vs. " << channels2[
r] <<
"\n";
865 if (data1.
data().size() != data2.
data().size()) {
866 mf::LogWarning(
"DBFolder") <<
"Values size mismatch " << data1.
data().size() <<
" vs. " 867 << data2.
data().size() <<
"\n";
873 for (
size_t row = 0; row < nrows1; ++row) {
881 for (
size_t col = 0;
col < ncols1; ++
col) {
882 if (types1[
col] ==
"integer" || types1[
col] ==
"bigint" || types1[
col] ==
"boolean") {
888 if (value1 != value2) {
890 <<
"Value mismatch " << value1 <<
" vs. " << value2 <<
"\n";
894 else if (types1[
col] ==
"real") {
900 if (value1 != value2) {
902 <<
"Value mismatch " << value1 <<
" vs. " << value2 <<
"\n";
906 else if (types1[
col] ==
"text") {
909 if (value1 != value2) {
911 <<
"Value mismatch " << value1 <<
" vs. " << value2 <<
"\n";
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)
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
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
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
decltype(auto) constexpr to_string(T &&obj)
ADL-aware version of std::to_string.
decltype(auto) values(Coll &&coll)
Range-for loop helper iterating across the values of the specified collection.
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
Filters for channels, events, etc.
const std::vector< DBChannelID_t > & channels() const
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
long getLongData(size_t col) const
size_t GetColumn(const std::string &name) const
int getColNumber(const std::string &name) const
static IOVTimeStamp MaxTimeStamp()
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.
cet::coded_exception< error, detail::translate > exception
void GetSQLiteData(int t, DBDataset &data) const