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