HCE project C++ developers source code library  1.1.1
HCE project developer library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
SphinxInputJsonMessageSearch.cpp
Go to the documentation of this file.
1 #include <Poco/JSON/Object.h>
2 #include <Poco/JSON/Array.h>
3 #include <Poco/JSON/JSON.h>
4 #include <Poco/JSON/Stringifier.h>
5 #include <Poco/JSON/Parser.h>
6 #include <Poco/JSON/JSONException.h>
7 
8 #include "EncodeDecodeBase64.hpp"
9 #include "SphinxError.hpp"
12 
13 namespace HCE
14 {
15 namespace sphinx
16 {
17 //-----------------------------------------------------------------------------
19 :inherited(), queryString(""),
20  queryParams(), orderParams(), filtersArray(), externalFields(), orderFields()
21 {
22  if (!json.empty())
23  unserialize(json);
24 }
25 //----------------------------------------------------------------------------
26 void SphinxInputJsonMessageSearch::addQueryParameters(const std::string& paramName, const std::string& paramValue)
27 {
28  queryParams.push_back(std::make_pair(paramName, paramValue));
29 }
30 //-----------------------------------------------------------------------------
31 void SphinxInputJsonMessageSearch::addOrderParameters(const std::string& paramName, const std::string& paramValue)
32 {
33  orderParams.push_back(std::make_pair(paramName, paramValue));
34 }
35 //-----------------------------------------------------------------------------
36 void SphinxInputJsonMessageSearch::addFilter(Poco::SharedPtr<SphinxFilter> pFilter)
37 {
38  filtersArray.addFilter(pFilter);
39 }
40 //-----------------------------------------------------------------------------
42  std::vector<std::string> attributeValues, SphinxFilter::ExcludeType exclude)
43 {
44  Poco::SharedPtr<SphinxFilter> pFilter(new SphinxFilter());
45  pFilter->setFilterType(filterType);
46  pFilter->setAttributeName(attributeName);
47  pFilter->setAttributeValues(attributeValues);
48  pFilter->setExcludeValue(exclude);
49  filtersArray.addFilter(pFilter);
50 }
51 //-----------------------------------------------------------------------------
52 void SphinxInputJsonMessageSearch::addExternalFields(const std::string& fieldName)
53 {
54  externalFields.push_back(fieldName);
55 }
56 //-----------------------------------------------------------------------------
57 void SphinxInputJsonMessageSearch::addOrderFields(const std::string& fieldName)
58 {
59  orderFields.push_back(fieldName);
60 }
61 //-----------------------------------------------------------------------------
62 std::string SphinxInputJsonMessageSearch::convertVarToString(Poco::Dynamic::Var& var) throw (std::exception)
63 {
64  std::string result;
65  if (var.isString())
66  result = var.convert<std::string>();
67  else if(var.isNumeric())
68  {
69  if(var.isInteger())
70  {
71  if(var.isSigned())
72  result = std::to_string(var.convert<long>());
73  else
74  result = std::to_string(var.convert<unsigned long>());
75  }
76  else
77  {
78  result = std::to_string(var.convert<double>());
79  }
80  }
81  return result;
82 }
83 //-----------------------------------------------------------------------------
85 {
86  _isError = false;
87  errorMsg.clear();
88  try
89  {
90  Poco::JSON::Object::Ptr obj = new Poco::JSON::Object();
92 
93  // serialize query parameters
94  Poco::JSON::Array::Ptr queryParameters = new Poco::JSON::Array();
95  obj->set(input_json_message_const::queryParameters, queryParameters);
96  Poco::JSON::Object::Ptr elem = new Poco::JSON::Object();
97  queryParameters->add(elem);
98  for (size_t i=0;i<queryParams.size();++i)
99  elem->set(queryParams[i].first, queryParams[i].second);
100  // add ext fields array to query parameters
101  Poco::JSON::Array::Ptr extArray = new Poco::JSON::Array();
103  for (size_t i=0;i<externalFields.size();++i)
104  extArray->add(externalFields[i]);
105 
106  // serialize order param
107  Poco::JSON::Array::Ptr orderParameters = new Poco::JSON::Array();
108  obj->set(input_json_message_const::orderParameters, orderParameters);
109  Poco::JSON::Object::Ptr elemOrder = new Poco::JSON::Object();
110  orderParameters->add(elemOrder);
111  for (size_t i=0;i<orderParams.size();++i)
112  elemOrder->set(orderParams[i].first, orderParams[i].second);
113  // add order ext fields to order param
114  Poco::JSON::Array::Ptr orderArray = new Poco::JSON::Array();
115  elemOrder->set(input_json_message_const::orderFieldsNames, orderArray);
116  for (size_t i=0;i<orderFields.size();++i)
117  orderArray->add(orderFields[i]);
118 
119  std::string filterString;
120  if (!filtersArray.serialize(filterString))
121  throw Poco::Exception(filtersArray.getErrorMsg());
123 
124  std::stringstream ostr;
125  Poco::JSON::Stringifier::stringify(obj, ostr);
126  json = ostr.str();
127  }
128  catch(std::exception& e)
129  {
130  errorMsg = e.what();
132  _isError = true;
133  }
134  return !_isError;
135 }
136 //-----------------------------------------------------------------------------
137 bool SphinxInputJsonMessageSearch::unserialize(const std::string& json)
138 {
139  queryString.clear();
140  queryParams.clear();
141  orderParams.clear();
142  filtersArray.clear();
143  externalFields.clear();
144  errorMsg.clear();
145  _isError = false;
146  try
147  {
148  Poco::JSON::Parser parser;
149  Poco::Dynamic::Var res = parser.parse(json);
150  Poco::JSON::Object::Ptr obj = res.extract<Poco::JSON::Object::Ptr>();
151 
152 // std::vector<std::string> keys;
153 // obj->getNames(keys);
154 // for (size_t i=0;i<keys.size();++i)
155 // std::cout << "[" << i << "]= " << keys[i] << std::endl << std::endl;
156 
157  Poco::Dynamic::Var tmp = obj->get(input_json_message_const::queryString);
158  if (tmp.isString())
159  queryString = decodeBase64(tmp.convert<std::string>());
160 
161  Poco::JSON::Array::Ptr queryParameters = obj->getArray(input_json_message_const::queryParameters);
162  if (queryParameters.isNull())
163  throw Poco::JSON::JSONException (std::string("array '").append(input_json_message_const::queryParameters).append("' not found"));
164 
165  for (size_t j = 0;j <queryParameters->size();++j)
166  {
167  tmp = queryParameters->get(j);
168  if (tmp.type() == typeid(Poco::JSON::Object::Ptr))
169  {
170  Poco::JSON::Object::Ptr elem = tmp.extract<Poco::JSON::Object::Ptr>();
171  std::vector<std::string> vecNames;
172  elem->getNames(vecNames);
173  for (size_t i=0;i<vecNames.size();++i)
174  {
175  tmp = elem->get(vecNames[i]);
176  if(tmp.isEmpty()) // check exists content
177  continue;
178 
180  {
181 
182  Poco::JSON::Array::Ptr extArray = elem->getArray(input_json_message_const::externalFieldsNames);
183  if (extArray.isNull())
184  throw Poco::JSON::JSONException (std::string("array '").append(input_json_message_const::externalFieldsNames).append("' not found"));
185 
186  for (size_t k=0;k<extArray->size();++k)
187  {
188  tmp = extArray->get(k);
189  if (tmp.isString())
190  externalFields.push_back(tmp.convert<std::string>());
191  }
192  }
193  else
194  queryParams.push_back(std::make_pair(vecNames[i], convertVarToString(tmp))); // analyze type and convert if input type Numeric or String
195  }
196  }
197  }
198 
199  Poco::JSON::Array::Ptr orderParameters = obj->getArray(input_json_message_const::orderParameters);
200  if (!orderParameters.isNull())
201  {
202  for (size_t j = 0;j <orderParameters->size();++j)
203  {
204  tmp = orderParameters->get(j);
205  if (tmp.type() == typeid(Poco::JSON::Object::Ptr))
206  {
207  Poco::JSON::Object::Ptr elem = tmp.extract<Poco::JSON::Object::Ptr>();
208  std::vector<std::string> vecNames;
209  elem->getNames(vecNames);
210  for (size_t i=0;i<vecNames.size();++i)
211  {
212  tmp = elem->get(vecNames[i]);
213  if(tmp.isEmpty()) // check exists content
214  continue;
215 
217  {
218 
219  Poco::JSON::Array::Ptr extArray = elem->getArray(input_json_message_const::orderFieldsNames);
220  if (extArray.isNull())
221  throw Poco::JSON::JSONException (std::string("array '").append(input_json_message_const::orderFieldsNames).append("' not found"));
222 
223  for (size_t k=0;k<extArray->size();++k)
224  {
225  tmp = extArray->get(k);
226  if (tmp.isString())
227  orderFields.push_back(tmp.convert<std::string>());
228  }
229  }
230  else
231  orderParams.push_back(std::make_pair(vecNames[i], convertVarToString(tmp))); // analyze type and convert if input type Numeric or String
232 
233  }
234  }
235  }
236  }
237 
239  if (tmp.isString())
240  {
241  std::string filterString = decodeBase64(tmp.convert<std::string>());
242  if (!filtersArray.unserialize(filterString))
243  throw Poco::Exception(filtersArray.getErrorMsg());
244  }
245 
246  }
247  catch(Poco::JSON::JSONException& e)
248  {
249  errorMsg = e.message();
251  _isError = true;
252  }
253  catch(std::exception& e)
254  {
255  errorMsg = e.what();
257  _isError = true;
258  }
259  return !_isError;
260 }
261 //-----------------------------------------------------------------------------
262 std::istream& operator>>(std::istream& is, SphinxInputJsonMessageSearch& messageSearch)
263 {
264  std::string json;
265  is.seekg(0, std::ios::end);
266  json.resize(is.tellg());
267  is.seekg(0, std::ios::beg);
268  is.read(const_cast<char*>(json.c_str()), json.size());
269  messageSearch.unserialize(json);
270  return is;
271 }
272 //-----------------------------------------------------------------------------
273 std::ostream& operator<<(std::ostream& os, const SphinxInputJsonMessageSearch& messageSearch)
274 {
275  std::string json;
276  const_cast<SphinxInputJsonMessageSearch&>(messageSearch).serialize(json);
277  return os << json;
278 }
279 //-----------------------------------------------------------------------------
280 //-----------------------------------------------------------------------------
281 } // end namespace sphinx
282 } // end namespace HCE