File indexing completed on 2022-09-08 03:21:37
0001 #ifndef CondTools_RunInfo_OMSAccess_h
0002 #define CondTools_RunInfo_OMSAccess_h
0003
0004 #include <string>
0005 #include <stdexcept>
0006 #include <boost/property_tree/ptree.hpp>
0007 #include <boost/property_tree/json_parser.hpp>
0008 #include <boost/date_time/posix_time/posix_time.hpp>
0009 #include <memory>
0010
0011 namespace cond {
0012
0013
0014 namespace impl {
0015
0016 static constexpr const char* const OMS_TIME_FMT = "%Y-%m-%dT%H:%M:%SZ";
0017
0018 template <typename T, T fun(const std::string&)>
0019 inline T from_string_impl(const std::string& attributeValue, T zero) {
0020 T ret = zero;
0021 if (not attributeValue.empty() && attributeValue != "null") {
0022 ret = fun(attributeValue);
0023 }
0024 return ret;
0025 }
0026
0027 template <typename T>
0028 inline T from_string(const std::string& attributeValue) {
0029 throw std::invalid_argument("");
0030 }
0031
0032 template <>
0033 inline std::string from_string(const std::string& attributeValue) {
0034 return std::string(attributeValue);
0035 }
0036
0037 inline float s_to_f(const std::string& val) { return std::stof(val); }
0038 template <>
0039 inline float from_string(const std::string& attributeValue) {
0040 return from_string_impl<float, &s_to_f>(attributeValue, 0.);
0041 }
0042
0043 inline int s_to_i(const std::string& val) { return std::stoi(val); }
0044 template <>
0045 inline int from_string(const std::string& attributeValue) {
0046 return from_string_impl<int, &s_to_i>(attributeValue, 0);
0047 }
0048
0049 inline unsigned long s_to_ul(const std::string& val) { return std::stoul(val); }
0050 template <>
0051 inline unsigned short from_string(const std::string& attributeValue) {
0052 unsigned long int_val = from_string_impl<unsigned long, &s_to_ul>(attributeValue, 0);
0053 return (unsigned short)int_val;
0054 }
0055
0056 inline boost::posix_time::ptime s_to_time(const std::string& val) {
0057 boost::posix_time::time_input_facet* facet = new boost::posix_time::time_input_facet(OMS_TIME_FMT);
0058 std::stringstream ss;
0059 ss.imbue(std::locale(std::locale(), facet));
0060 ss << val;
0061 boost::posix_time::ptime time;
0062 ss >> time;
0063 return time;
0064 }
0065 template <>
0066 inline boost::posix_time::ptime from_string(const std::string& attributeValue) {
0067 return from_string_impl<boost::posix_time::ptime, &s_to_time>(attributeValue, boost::posix_time::ptime());
0068 }
0069
0070 template <typename V>
0071 inline std::string to_string(const V& value) {
0072 return std::to_string(value);
0073 }
0074 template <typename V>
0075 inline std::string to_string(const V* value) {
0076 return std::to_string(*value);
0077 }
0078 template <>
0079 inline std::string to_string(const std::string& value) {
0080 return std::string(value);
0081 }
0082 template <>
0083 inline std::string to_string(const char* value) {
0084 return std::string(value);
0085 }
0086 template <>
0087 inline std::string to_string(const boost::posix_time::ptime& value) {
0088 boost::posix_time::time_facet* facet = new boost::posix_time::time_facet();
0089 facet->format(OMS_TIME_FMT);
0090 std::stringstream stream;
0091 stream.imbue(std::locale(std::locale::classic(), facet));
0092 stream << value;
0093 return stream.str();
0094 }
0095
0096 }
0097
0098
0099 class OMSServiceResultRef {
0100 public:
0101 OMSServiceResultRef() = delete;
0102 OMSServiceResultRef(const boost::property_tree::ptree* row);
0103
0104
0105 bool empty();
0106
0107 template <typename T>
0108 inline T get(const std::string& attributeName) {
0109 return impl::from_string<T>(getAttribute(attributeName));
0110 }
0111
0112 template <typename primitive>
0113 std::vector<primitive> getArray(const std::string& attributeName) {
0114 std::vector<primitive> ret;
0115 for (auto& item : m_row->get_child(attributeName)) {
0116 ret.push_back(item.second.get_value<primitive>());
0117 }
0118 return ret;
0119 }
0120
0121 private:
0122 std::string getAttribute(const std::string& attributeName);
0123 const boost::property_tree::ptree* m_row = nullptr;
0124 };
0125
0126
0127 class OMSServiceResultIterator {
0128 public:
0129 OMSServiceResultIterator() = delete;
0130 OMSServiceResultIterator(boost::property_tree::ptree::const_iterator iter);
0131
0132 OMSServiceResultRef operator*();
0133 OMSServiceResultIterator& operator++();
0134
0135 bool operator==(const OMSServiceResultIterator& rhs);
0136 bool operator!=(const OMSServiceResultIterator& rhs);
0137
0138 private:
0139 boost::property_tree::ptree::const_iterator m_iter;
0140 };
0141
0142
0143 class OMSServiceResult {
0144 public:
0145 OMSServiceResult();
0146
0147 OMSServiceResultIterator begin() const;
0148 OMSServiceResultIterator end() const;
0149
0150
0151 size_t parseData(const std::string& data);
0152
0153
0154 size_t size() const;
0155
0156
0157 bool empty() const;
0158
0159 private:
0160 boost::property_tree::ptree m_root;
0161 boost::property_tree::ptree* m_data;
0162 };
0163
0164
0165 class OMSServiceQuery {
0166 public:
0167
0168 static constexpr const char* const NEQ = "NEQ";
0169 static constexpr const char* const EQ = "EQ";
0170 static constexpr const char* const LT = "LT";
0171 static constexpr const char* const LE = "LE";
0172 static constexpr const char* const GT = "GT";
0173 static constexpr const char* const GE = "GE";
0174 static constexpr const char* const SNULL = "null";
0175
0176 public:
0177 OMSServiceQuery() = delete;
0178 OMSServiceQuery(const std::string& baseUrl, const std::string& function);
0179
0180
0181 OMSServiceQuery& addOutputVar(const std::string& varName);
0182 OMSServiceQuery& addOutputVars(const std::initializer_list<const char*>& varNames);
0183
0184
0185 template <typename T>
0186 inline OMSServiceQuery& filter(const char* cmp, const std::string& varName, const T& value) {
0187 std::stringstream filter;
0188 if (m_filter.empty()) {
0189 filter << "?";
0190 if (!m_limit.empty()) {
0191 m_limit.front() = '&';
0192 }
0193 } else {
0194 filter << m_filter << "&";
0195 }
0196 filter << "filter[" << varName << "][" << cmp << "]=" << impl::to_string(value);
0197 m_filter = filter.str();
0198 return *this;
0199 }
0200
0201 template <typename T>
0202 inline OMSServiceQuery& filterEQ(const std::string& varName, const T& value) {
0203 return filter<T>(EQ, varName, value);
0204 }
0205 template <typename T>
0206 inline OMSServiceQuery& filterNEQ(const std::string& varName, const T& value) {
0207 return filter<T>(NEQ, varName, value);
0208 }
0209 template <typename T>
0210 inline OMSServiceQuery& filterGT(const std::string& varName, const T& value) {
0211 return filter<T>(GT, varName, value);
0212 }
0213 template <typename T>
0214 inline OMSServiceQuery& filterGE(const std::string& varName, const T& value) {
0215 return filter<T>(GE, varName, value);
0216 }
0217 template <typename T>
0218 inline OMSServiceQuery& filterLT(const std::string& varName, const T& value) {
0219 return filter<T>(LT, varName, value);
0220 }
0221 template <typename T>
0222 inline OMSServiceQuery& filterLE(const std::string& varName, const T& value) {
0223 return filter<T>(LE, varName, value);
0224 }
0225
0226 inline OMSServiceQuery& filterNotNull(const std::string& varName) { return filterNEQ(varName, SNULL); }
0227
0228
0229 OMSServiceQuery& limit(int value);
0230
0231
0232 bool execute();
0233
0234
0235 unsigned long status();
0236
0237
0238 OMSServiceResult& result();
0239
0240
0241 std::string url();
0242
0243 private:
0244 void addVar(const std::string& varName);
0245
0246 private:
0247 std::string m_url;
0248 std::string m_filter;
0249 std::string m_limit;
0250 std::string m_varList;
0251 std::unique_ptr<OMSServiceResult> m_result;
0252 unsigned long m_status = 0;
0253 };
0254
0255
0256 class OMSService {
0257 public:
0258 OMSService();
0259
0260 void connect(const std::string& baseUrl);
0261 std::unique_ptr<OMSServiceQuery> query(const std::string& function) const;
0262
0263 private:
0264 std::string m_baseUrl;
0265 };
0266 }
0267
0268 #endif