00001
00009 #include <iostream>
00010 #include <cstdio>
00011 #include "Coverage.h"
00012 #include "facilities/Util.h"
00013 #include "calibUtil/Metadata.h"
00014 #include "rdbModel/Management/Manager.h"
00015 #include "rdbModel/Management/XercesBuilder.h"
00016
00017 #include "rdbModel/Db/MysqlConnection.h"
00018 #include "rdbModel/Db/MysqlResults.h"
00019 #include "rdbModel/Rdb.h"
00020 #include "rdbModel/RdbException.h"
00021 #include "rdbModel/Tables/Assertion.h"
00022 #include "rdbModel/Tables/Table.h"
00023 #include "rdbModel/Tables/Column.h"
00024
00025 class SelectInfo {
00026 public:
00027 SelectInfo(int ser, const facilities::Timestamp& start,
00028 const facilities::Timestamp& end) : m_ser(ser)
00029 {
00030 using facilities::Timestamp;
00031 m_vstart = Timestamp(start.getClibTime());
00032 m_vend = Timestamp(end.getClibTime());
00033 }
00034 int m_ser;
00035 facilities::Timestamp m_vstart;
00036 facilities::Timestamp m_vend;
00037 };
00038
00039 std::ostream& operator<<(std::ostream& out, const SelectInfo& info) {
00040 out << "Serial #" << info.m_ser << " validitiy interval ["
00041 << info.m_vstart.getString() << ", " << info.m_vend.getString() << "]"
00042 << std::endl;
00043 return out;
00044 }
00045
00046 Coverage::Coverage(calibUtil::Metadata* meta,
00047 const std::string& instr, const std::string& flavor,
00048 const std::string& level, const facilities::Timestamp& ts)
00049 : m_instr(instr), m_flavor(flavor), m_level(level), m_overlap(300) {
00050 m_ts = facilities::Timestamp(ts.getClibTime());
00051 m_selects.reserve(3);
00052 m_selects.push_back("ser_no");
00053 m_selects.push_back("vstart");
00054 m_selects.push_back("vend");
00055
00056 m_orderBy.reserve(1);
00057 m_orderBy.push_back("vstart asc");
00058
00059 m_rdb = meta->getRdb();
00060 m_conn = meta->getReadConnection();
00061 m_table = meta->getTable();
00062 }
00063
00064
00065
00066
00067 bool Coverage::expandTypes(std::string& nickname,
00068 std::vector<std::string>& types) {
00069 if ((nickname == "CAL") ||
00070 (nickname == "TKR") ||
00071 (nickname == "*") ) {
00072 if (!m_rdb) {
00073 std::cerr << "Unable to expand wildcard argument " << nickname
00074 << " without schema for metadata dbs " << std::endl;
00075 }
00076 else {
00077 std::cerr <<
00078 "Wildcard expansion of calib_type argument not yet supported";
00079 std::cerr << std::endl << "Have a nice day" << std::endl;
00080 }
00081 std::cerr.flush();
00082 exit(1);
00083 }
00084 types.push_back(nickname);
00085 return true;
00086 }
00087
00088 unsigned Coverage::checkType(std::string calibtype) {
00089 using namespace rdbModel;
00090 using facilities::Timestamp;
00091
00092
00093
00094
00095
00096
00097
00098 std::vector<Assertion::Operator *> conditions;
00099 conditions.reserve(6);
00100
00101 Assertion::Operator completeOp(OPTYPEequal, "completion", "OK",
00102 FIELDTYPEold, FIELDTYPElit);
00103
00104 Assertion::Operator instOp(OPTYPEequal, "instrument", m_instr,
00105 FIELDTYPEold, FIELDTYPElit);
00106
00107 Assertion::Operator calibTypeOp(OPTYPEequal, "calib_type", calibtype,
00108 FIELDTYPEold, FIELDTYPElit);
00109
00110 Assertion::Operator flavorOp(OPTYPEequal, "flavor", m_flavor,
00111 FIELDTYPEold, FIELDTYPElit);
00112
00113 Assertion::Operator levelOp(OPTYPEequal, "proc_level", m_level,
00114 FIELDTYPEold, FIELDTYPElit);
00115
00116 Assertion::Operator vstartOp(OPTYPElessThan, m_ts.getString(),
00117 "vstart",
00118 FIELDTYPElit, FIELDTYPEold);
00119
00120 conditions.push_back(&calibTypeOp);
00121 conditions.push_back(&instOp);
00122 conditions.push_back(&flavorOp);
00123 conditions.push_back(&levelOp);
00124 conditions.push_back(&vstartOp);
00125 conditions.push_back(&completeOp);
00126 Assertion::Operator* andOp = new Assertion::Operator(OPTYPEand, conditions);
00127 Assertion* whereClause = new Assertion(andOp);
00128
00129 ResultHandle* results = 0;
00130
00131 try {
00132 results = m_conn->select(m_table, m_selects, m_orderBy, whereClause);
00133 }
00134 catch (RdbException ex) {
00135 std::cerr << ex.getMsg() << std::endl;
00136 std::cerr.flush();
00137 return false;
00138 }
00139
00140 if (!results) {
00141 std::cerr << "Error making query " << std::endl;
00142 std::cerr.flush();
00143 exit(1);
00144 }
00145
00146
00147 std::vector<SelectInfo> info;
00148 unsigned nFound = results->getNRows();
00149
00150 if (!nFound) {
00151 std::cout << "No calibrations found for calib_type '" << calibtype
00152 << "'" << std::endl;
00153 return true;
00154 }
00155
00156 info.reserve(results->getNRows() );
00157
00158 unsigned iRow = 0;
00159 std::vector<std::string> fields;
00160 fields.reserve(3);
00161
00162 bool ok = true;
00163 unsigned retCode = 0;
00164
00165
00166 std::cout << std::endl
00167 << "Checking for valid timestamps, vstart < vend .. "
00168 << std::endl;
00169 for (iRow = 0; iRow < nFound; iRow++) {
00170 results->getRow(fields, iRow);
00171 int ser = facilities::Util::stringToInt(fields[0]);
00172 try {
00173 Timestamp vstart = Timestamp(fields[1]);
00174 Timestamp vend = Timestamp(fields[2]);
00175 info.push_back(SelectInfo(ser, vstart, vend));
00176
00177 if (vend.getClibTime() < vstart.getClibTime() ) {
00178 std::cerr << "vend < vstart for " << info.back();
00179 ok = false;
00180 retCode = 1;
00181 }
00182 }
00183 catch (facilities::BadTimeInput ex) {
00184 std::cerr << "Bad vstart or vend in row " << ser << std::endl;
00185 ok = false;
00186 retCode = 1;
00187 }
00188
00189 }
00190 if (!ok) return retCode;
00191
00192
00193 std::cout << std::endl << "Checking for vends monotonic.. " << std::endl;
00194 for (iRow = 0; iRow < nFound - 1; iRow++) {
00195 if (info[iRow].m_vend.getClibTime() > info[iRow+1].m_vend.getClibTime()) {
00196 std::cerr << "Validity interval for row with serial #"
00197 << info[iRow+1].m_ser
00198 << " completely contained in interval for row with serial #"
00199 << info[iRow].m_ser << std::endl;
00200 std::cerr << info[iRow];
00201 std::cerr << info[iRow+1] << std::endl;
00202 ok = false;
00203 retCode = 2;
00204 }
00205 }
00206 if (!ok) return retCode;
00207
00208
00209 std::cout << std::endl << "Checking for gaps.. " << std::endl;
00210 for (iRow = 0; iRow < nFound - 1; iRow++) {
00211 if (info[iRow].m_vend < info[iRow+1].m_vstart) {
00212 std::cerr << "Validity interval gap between calibrations with serial #"
00213 << info[iRow].m_ser << " and #" << info[iRow+1].m_ser
00214 << std::endl;
00215 std::cerr << info[iRow];
00216 std::cerr << info[iRow+1] << std::endl;
00217 ok = false;
00218 retCode = 3;
00219 }
00220 }
00221
00222 std::cout << std::endl << "Checking for overlaps.. " << std::endl;
00223 for (iRow = 0; iRow < nFound - 1; iRow++) {
00224 if ((info[iRow].m_vend).getClibTime() >
00225 (info[iRow+1].m_vstart).getClibTime() + m_overlap) {
00226 std::cerr << "Unacceptable overlap between serial #" << info[iRow].m_ser
00227 << " and #" << info[iRow+1].m_ser << std::endl;
00228 std::cerr << info[iRow];
00229 std::cerr << info[iRow+1] << std::endl;
00230 ok = false;
00231 if (!retCode) retCode = 4;
00232 }
00233 }
00234 return retCode;
00235
00236 }