knowrob  2.1.0
A Knowledge Base System for Cognition-enabled Robots
MongoTerm.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of KnowRob, please consult
3  * https://github.com/knowrob/knowrob for license details.
4  */
5 
6 #include "knowrob/storage/mongo/MongoTerm.h"
7 #include "knowrob/terms/ListTerm.h"
8 #include "knowrob/terms/Numeric.h"
9 #include "knowrob/terms/Variable.h"
10 
11 using namespace knowrob::mongo;
12 
13 void MongoTerm::append( //NOLINT(misc-no-recursion)
14  bson_t *doc,
15  const char *key,
16  const TermPtr &term,
17  const char *queryOperator,
18  bool matchNullValues,
19  bool includeVariables) {
20  bson_t queryOperatorDoc;
21  bson_t orArray, orCase1, orCase2;
22  bson_t *valueDocument;
23  const char *valueKey;
24 
25  if (matchNullValues) {
26  // allow to pass through if key is undefined. e.g. important for time scope etc.
27  // e.g. {$or: [ { b: null }, { b: {$gt: 10.0} } ]}
28  BSON_APPEND_ARRAY_BEGIN(doc, "$or", &orArray);
29 
30  BSON_APPEND_DOCUMENT_BEGIN(&orArray, "0", &orCase1);
31  BSON_APPEND_NULL(&orCase1, key);
32  bson_append_document_end(&orArray, &orCase1);
33 
34  BSON_APPEND_DOCUMENT_BEGIN(&orArray, "1", &orCase2);
35  }
36 
37  if (queryOperator) {
38  BSON_APPEND_DOCUMENT_BEGIN(matchNullValues ? &orCase2 : doc, key, &queryOperatorDoc);
39  valueDocument = &queryOperatorDoc;
40  valueKey = queryOperator;
41  } else {
42  valueDocument = (matchNullValues ? &orCase2 : doc);
43  valueKey = key;
44  }
45 
46  if (term->termType() == TermType::ATOMIC) {
47  auto atomic = std::static_pointer_cast<Atomic>(term);
48  switch (atomic->atomicType()) {
49  case AtomicType::STRING:
50  case AtomicType::ATOM:
51  BSON_APPEND_UTF8(valueDocument, valueKey, atomic->stringForm().data());
52  break;
53  case AtomicType::NUMERIC: {
54  auto numeric = std::static_pointer_cast<Numeric>(atomic);
55  switch (numeric->xsdType()) {
56  case XSDType::FLOAT:
57  case XSDType::DOUBLE:
58  BSON_APPEND_DOUBLE(valueDocument, valueKey, numeric->asDouble());
59  break;
62  case XSDType::INTEGER:
63  BSON_APPEND_INT32(valueDocument, valueKey, numeric->asInteger());
64  break;
66  case XSDType::LONG:
67  BSON_APPEND_INT64(valueDocument, valueKey, numeric->asLong());
68  break;
70  case XSDType::SHORT:
71  BSON_APPEND_INT32(valueDocument, valueKey, numeric->asShort());
72  break;
73  case XSDType::BOOLEAN:
74  BSON_APPEND_BOOL(valueDocument, valueKey, numeric->asBoolean());
75  break;
76  case XSDType::STRING:
77  case XSDType::LAST:
78  break;
79  }
80  break;
81  }
82  }
83  } else if (term->termType() == TermType::FUNCTION) {
84  append(valueDocument, valueKey,
85  ((ListTerm *) term.get())->elements());
86  } else if (includeVariables && term->termType() == TermType::VARIABLE) {
87  static const std::string varPrefix("$");
88  auto varKey = MongoTerm::variableKey(std::static_pointer_cast<Variable>(term)->name());
89  BSON_APPEND_UTF8(valueDocument, valueKey, (varPrefix + varKey).data());
90  }
91 
92  if (queryOperator) {
93  bson_append_document_end(matchNullValues ? &orCase2 : doc, &queryOperatorDoc);
94  }
95  if (matchNullValues) {
96  bson_append_document_end(&orArray, &orCase2);
97  bson_append_array_end(doc, &orArray);
98  }
99 }
100 
101 void MongoTerm::appendWithVars(bson_t *doc, const char *key, const TermPtr &term, const char *queryOperator,
102  bool matchNullValue) {
103  append(doc, key, term, queryOperator, matchNullValue, true);
104 }
105 
106 void MongoTerm::append( // NOLINT(misc-no-recursion)
107  bson_t *doc,
108  const char *key,
109  const std::vector<TermPtr> &terms,
110  const char *arrayOperator) {
111  bson_t orOperator, orArray;
112  char arrIndexStr[16];
113  const char *arrIndexKey;
114  uint32_t arrIndex = 0;
115 
116  BSON_APPEND_DOCUMENT_BEGIN(doc, key, &orOperator);
117  BSON_APPEND_ARRAY_BEGIN(&orOperator, arrayOperator, &orArray);
118  for (auto &term: terms) {
119  bson_uint32_to_string(arrIndex++,
120  &arrIndexKey, arrIndexStr, sizeof arrIndexStr);
121  append(&orArray, arrIndexKey, term);
122  }
123  bson_append_array_end(&orOperator, &orArray);
124  bson_append_document_end(doc, &orOperator);
125 }
126 
127 std::string MongoTerm::variableKey(const std::string_view &varName) {
128  std::stringstream ss;
129  ss << "v_VARS." << varName << ".val";
130  return ss.str();
131 }
static void append(bson_t *doc, const char *key, const TermPtr &term, const char *queryOperator=nullptr, bool matchNullValue=false, bool includeVariables=false)
Definition: MongoTerm.cpp:13
static void appendWithVars(bson_t *doc, const char *key, const TermPtr &term, const char *queryOperator=nullptr, bool matchNullValue=false)
Definition: MongoTerm.cpp:101
static std::string variableKey(const std::string_view &varName)
Definition: MongoTerm.cpp:127
TermRule & string()
Definition: terms.cpp:63
TermRule & atomic()
Definition: terms.cpp:79
TermRule & term()
Definition: terms.cpp:136
std::shared_ptr< Term > TermPtr
Definition: Term.h:117