knowrob  2.1.0
A Knowledge Base System for Cognition-enabled Robots
BindingsCursor.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/Logger.h"
7 #include "knowrob/storage/mongo/BindingsCursor.h"
8 #include "knowrob/terms/Numeric.h"
9 #include "knowrob/terms/IRIAtom.h"
10 #include "knowrob/terms/Blank.h"
11 #include "knowrob/storage/mongo/bson-helper.h"
12 #include "knowrob/terms/String.h"
13 
14 using namespace knowrob;
15 using namespace knowrob::mongo;
16 
17 BindingsCursor::BindingsCursor(const std::shared_ptr<Collection> &collection)
18  : Cursor(collection),
19  resultDocument_(nullptr),
20  resultIter_(),
21  varIter_(),
22  valIter_() {
23 }
24 
25 void BindingsCursor::setSubstitution(const std::shared_ptr<Bindings> &bindings) {
26  while (bson_iter_next(&varIter_)) {
27  auto var = std::make_shared<Variable>(bson_iter_key(&varIter_));
28 
29  if (!bson_iter_recurse(&varIter_, &valIter_)) continue;
30  if (!bson_iter_find(&valIter_, "val")) continue;
31 
32  // read the value of the variable
33  switch (bson_iter_type(&valIter_)) {
34  case BSON_TYPE_UTF8: {
35  auto utf8 = bson_iter_utf8(&valIter_, nullptr);
36  // note: currently mongo KG does not store the type of the literal,
37  // so we cannot trivially distinguish between IRI and literal and need to guess here.
38  // note: we need to copy the string data here, as the bson_iter_utf8() returns a pointer
39  // to the internal buffer of the bson document, which is not guaranteed to be valid
40  // after the cursor is advanced.
41  switch (rdfNodeTypeGuess(utf8)) {
42  case RDFNodeType::BLANK:
43  bindings->set(var, Blank::Tabled(utf8));
44  break;
45  case RDFNodeType::IRI:
46  bindings->set(var, IRIAtom::Tabled(utf8));
47  break;
49  bindings->set(var, std::make_shared<String>(utf8));
50  break;
51  }
52  break;
53  }
54  case BSON_TYPE_INT32:
55  bindings->set(var, std::make_shared<Integer>(bson_iter_int32(&valIter_)));
56  break;
57  case BSON_TYPE_INT64:
58  bindings->set(var, std::make_shared<Long>(bson_iter_int64(&valIter_)));
59  break;
60  case BSON_TYPE_BOOL:
61  bindings->set(var, std::make_shared<Boolean>(bson_iter_bool(&valIter_)));
62  break;
63  case BSON_TYPE_DOUBLE:
64  bindings->set(var, std::make_shared<Double>(bson_iter_double(&valIter_)));
65  break;
66  default:
67  KB_WARN("unsupported type {} for predicate arguments.", bson_iter_type(&valIter_));
68  break;
69  }
70  }
71 }
72 
73 bool BindingsCursor::nextBindings(const std::shared_ptr<Bindings> &bindings) {
74  if (!next(&resultDocument_)) return false;
75  if (!bson_iter_init(&resultIter_, resultDocument_)) return false;
76 
77  while (bson_iter_next(&resultIter_)) {
78  std::string_view resultKey(bson_iter_key(&resultIter_));
79  // read variables from "v_VARS". each sub-field is named according to the field of
80  // a variable.
81  if (resultKey == "v_VARS" && bson_iter_recurse(&resultIter_, &varIter_)) {
82  setSubstitution(bindings);
83  }
84  }
85 
86  return true;
87 }
#define KB_WARN
Definition: Logger.h:27
static std::shared_ptr< Blank > Tabled(std::string_view stringForm)
Definition: Blank.cpp:12
static std::shared_ptr< IRIAtom > Tabled(std::string_view stringForm)
Definition: IRIAtom.cpp:25
BindingsCursor(const std::shared_ptr< Collection > &collection)
bool nextBindings(const std::shared_ptr< Bindings > &bindings)
void setSubstitution(const std::shared_ptr< Bindings > &bindings)
bool next(const bson_t **doc, bool ignore_empty=false)
Definition: Cursor.cpp:67
VariableRule & var()
Definition: terms.cpp:91
RDFNodeType rdfNodeTypeGuess(std::string_view str)
Definition: RDFNode.cpp:11