knowrob  2.1.0
A Knowledge Base System for Cognition-enabled Robots
Cursor.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/Cursor.h"
7 #include "knowrob/storage/mongo/MongoException.h"
8 #include "knowrob/reasoner/mongolog/bson_pl.h"
9 
10 #include <sstream>
11 #include <iostream>
12 
13 using namespace knowrob::mongo;
14 
15 Cursor::Cursor(const std::shared_ptr<Collection> &collection)
16  : collection_(collection),
17  cursor_(nullptr),
18  isAggregateQuery_(false),
19  limit_(0) {
20  query_ = bson_new();
21  opts_ = bson_new();
22  collection_->appendSession(opts_);
23  // use pointer as id
24  std::stringstream ss;
25  ss << static_cast<const void *>(this);
26  id_ = ss.str();
27 }
28 
30  if (cursor_ != nullptr) {
31  mongoc_cursor_destroy(cursor_);
32  cursor_ = nullptr;
33  }
34  if (query_ != nullptr) {
35  bson_destroy(query_);
36  query_ = nullptr;
37  }
38  if (opts_ != nullptr) {
39  bson_destroy(opts_);
40  opts_ = nullptr;
41  }
42 }
43 
44 void Cursor::limit(unsigned int limit) {
45  limit_ = limit;
46 }
47 
48 void Cursor::ascending(const char *key) {
49  static bson_t *doc = BCON_NEW("sort", "{", key, BCON_INT32(1), "}");
50  bson_concat(opts_, doc);
51 }
52 
53 void Cursor::descending(const char *key) {
54  static bson_t *doc = BCON_NEW("sort", "{", key, BCON_INT32(-1), "}");
55  bson_concat(opts_, doc);
56 }
57 
58 void Cursor::filter(const bson_t *query_doc) {
59  bson_concat(query_, query_doc);
60 }
61 
62 void Cursor::aggregate(const bson_t *query_doc) {
63  isAggregateQuery_ = true;
64  bson_concat(query_, query_doc);
65 }
66 
67 bool Cursor::next(const bson_t **doc, bool ignore_empty) {
68  if (cursor_ == nullptr) {
69  if (isAggregateQuery_) {
70  cursor_ = mongoc_collection_aggregate(
71  collection_->coll(), MONGOC_QUERY_NONE, query_, opts_, nullptr /* read_prefs */ );
72  } else {
73  cursor_ = mongoc_collection_find_with_opts(
74  collection_->coll(), query_, opts_, nullptr /* read_prefs */ );
75  }
76  if (limit_ > 0) {
77  mongoc_cursor_set_limit(cursor_, limit_);
78  }
79  }
80  // make sure cursor has no error
81  bson_error_t err1;
82  if (mongoc_cursor_error(cursor_, &err1)) {
83  throw MongoException("cursor_error", err1);
84  }
85  // get next document
86  if (!mongoc_cursor_next(cursor_, doc)) {
87  // make sure cursor has no error after next has been called
88  bson_error_t err2;
89  if (mongoc_cursor_error(cursor_, &err2)) {
90  throw MongoException("cursor_error", err2);
91  }
92  return ignore_empty;
93  } else {
94  return true;
95  }
96 }
97 
98 bool Cursor::erase() {
99  bson_error_t err;
100  bool success = mongoc_collection_delete_many(
101  collection_->coll(), query_, opts_, nullptr /* reply */, &err);
102  if (!success) {
103  throw MongoException("erase_error", err);
104  }
105  return true;
106 }
Cursor(const std::shared_ptr< Collection > &collection)
Definition: Cursor.cpp:15
void filter(const bson_t *query_doc)
Definition: Cursor.cpp:58
void limit(unsigned int limit)
Definition: Cursor.cpp:44
bool next(const bson_t **doc, bool ignore_empty=false)
Definition: Cursor.cpp:67
void aggregate(const bson_t *query_doc)
Definition: Cursor.cpp:62
void ascending(const char *key)
Definition: Cursor.cpp:48
void descending(const char *key)
Definition: Cursor.cpp:53