File indexing completed on 2024-04-06 12:03:17
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 inline unsigned long long s_to_ull(const std::string& val) { return std::stoull(val); }
0056 template <>
0057 inline unsigned long long from_string(const std::string& attributeValue) {
0058 unsigned long long int_val = from_string_impl<unsigned long long, &s_to_ull>(attributeValue, 0);
0059 return int_val;
0060 }
0061
0062 inline boost::posix_time::ptime s_to_time(const std::string& val) {
0063 boost::posix_time::time_input_facet* facet = new boost::posix_time::time_input_facet(OMS_TIME_FMT);
0064 std::stringstream ss;
0065 ss.imbue(std::locale(std::locale(), facet));
0066 ss << val;
0067 boost::posix_time::ptime time;
0068 ss >> time;
0069 return time;
0070 }
0071 template <>
0072 inline boost::posix_time::ptime from_string(const std::string& attributeValue) {
0073 return from_string_impl<boost::posix_time::ptime, &s_to_time>(attributeValue, boost::posix_time::ptime());
0074 }
0075
0076 template <typename V>
0077 inline std::string to_string(const V& value) {
0078 return std::to_string(value);
0079 }
0080 template <typename V>
0081 inline std::string to_string(const V* value) {
0082 return std::to_string(*value);
0083 }
0084 template <>
0085 inline std::string to_string(const std::string& value) {
0086 return std::string(value);
0087 }
0088 template <>
0089 inline std::string to_string(const char* value) {
0090 return std::string(value);
0091 }
0092 template <>
0093 inline std::string to_string(const boost::posix_time::ptime& value) {
0094 boost::posix_time::time_facet* facet = new boost::posix_time::time_facet();
0095 facet->format(OMS_TIME_FMT);
0096 std::stringstream stream;
0097 stream.imbue(std::locale(std::locale::classic(), facet));
0098 stream << value;
0099 return stream.str();
0100 }
0101
0102 }
0103
0104
0105 class OMSServiceResultRef {
0106 public:
0107 OMSServiceResultRef() = delete;
0108 OMSServiceResultRef(const boost::property_tree::ptree* row);
0109
0110
0111 bool empty();
0112
0113 template <typename T>
0114 inline T get(const std::string& attributeName) {
0115 return impl::from_string<T>(getAttribute(attributeName));
0116 }
0117
0118 template <typename primitive>
0119 std::vector<primitive> getArray(const std::string& attributeName) {
0120 std::vector<primitive> ret;
0121 for (auto& item : m_row->get_child(attributeName)) {
0122 ret.push_back(item.second.get_value<primitive>());
0123 }
0124 return ret;
0125 }
0126
0127 private:
0128 std::string getAttribute(const std::string& attributeName);
0129 const boost::property_tree::ptree* m_row = nullptr;
0130 };
0131
0132
0133 class OMSServiceResultIterator {
0134 public:
0135 OMSServiceResultIterator() = delete;
0136 OMSServiceResultIterator(boost::property_tree::ptree::const_iterator iter);
0137
0138 OMSServiceResultRef operator*();
0139 OMSServiceResultIterator& operator++();
0140
0141 bool operator==(const OMSServiceResultIterator& rhs);
0142 bool operator!=(const OMSServiceResultIterator& rhs);
0143
0144 private:
0145 boost::property_tree::ptree::const_iterator m_iter;
0146 };
0147
0148
0149 class OMSServiceResult {
0150 public:
0151 OMSServiceResult();
0152
0153 OMSServiceResultIterator begin() const;
0154 OMSServiceResultIterator end() const;
0155
0156 OMSServiceResultRef front() const;
0157 OMSServiceResultRef back() const;
0158
0159
0160 size_t parseData(const std::string& data);
0161
0162
0163 size_t size() const;
0164
0165
0166 bool empty() const;
0167
0168 private:
0169 boost::property_tree::ptree m_root;
0170 boost::property_tree::ptree* m_data;
0171 };
0172
0173
0174 class OMSServiceQuery {
0175 public:
0176
0177 static constexpr const char* const NEQ = "NEQ";
0178 static constexpr const char* const EQ = "EQ";
0179 static constexpr const char* const LT = "LT";
0180 static constexpr const char* const LE = "LE";
0181 static constexpr const char* const GT = "GT";
0182 static constexpr const char* const GE = "GE";
0183 static constexpr const char* const SNULL = "null";
0184
0185 public:
0186 OMSServiceQuery() = delete;
0187 OMSServiceQuery(const std::string& baseUrl, const std::string& function);
0188
0189
0190 OMSServiceQuery& addOutputVar(const std::string& varName);
0191 OMSServiceQuery& addOutputVars(const std::initializer_list<const char*>& varNames);
0192
0193
0194 template <typename T>
0195 inline OMSServiceQuery& filter(const char* cmp, const std::string& varName, const T& value) {
0196 std::stringstream filter;
0197 if (m_filter.empty()) {
0198 filter << "?";
0199 if (!m_limit.empty()) {
0200 m_limit.front() = '&';
0201 }
0202 } else {
0203 filter << m_filter << "&";
0204 }
0205 filter << "filter[" << varName << "][" << cmp << "]=" << impl::to_string(value);
0206 m_filter = filter.str();
0207 return *this;
0208 }
0209
0210 template <typename T>
0211 inline OMSServiceQuery& filterEQ(const std::string& varName, const T& value) {
0212 return filter<T>(EQ, varName, value);
0213 }
0214 template <typename T>
0215 inline OMSServiceQuery& filterNEQ(const std::string& varName, const T& value) {
0216 return filter<T>(NEQ, varName, value);
0217 }
0218 template <typename T>
0219 inline OMSServiceQuery& filterGT(const std::string& varName, const T& value) {
0220 return filter<T>(GT, varName, value);
0221 }
0222 template <typename T>
0223 inline OMSServiceQuery& filterGE(const std::string& varName, const T& value) {
0224 return filter<T>(GE, varName, value);
0225 }
0226 template <typename T>
0227 inline OMSServiceQuery& filterLT(const std::string& varName, const T& value) {
0228 return filter<T>(LT, varName, value);
0229 }
0230 template <typename T>
0231 inline OMSServiceQuery& filterLE(const std::string& varName, const T& value) {
0232 return filter<T>(LE, varName, value);
0233 }
0234
0235 inline OMSServiceQuery& filterNotNull(const std::string& varName) { return filterNEQ(varName, SNULL); }
0236
0237
0238 OMSServiceQuery& limit(int value);
0239
0240
0241 bool execute();
0242
0243
0244 unsigned long status();
0245
0246
0247 OMSServiceResult& result();
0248
0249
0250 std::string url();
0251
0252 private:
0253 void addVar(const std::string& varName);
0254
0255 private:
0256 std::string m_url;
0257 std::string m_filter;
0258 std::string m_limit;
0259 std::string m_varList;
0260 std::unique_ptr<OMSServiceResult> m_result;
0261 unsigned long m_status = 0;
0262 };
0263
0264
0265 class OMSService {
0266 public:
0267 OMSService();
0268
0269 void connect(const std::string& baseUrl);
0270 std::unique_ptr<OMSServiceQuery> query(const std::string& function) const;
0271
0272 private:
0273 std::string m_baseUrl;
0274 };
0275 }
0276
0277 #endif