mongodb.cpp
Go to the documentation of this file.
1#include "mongodb.h"
2
3// Simox
4#include <SimoxUtility/algorithm/string/string_tools.h>
5#include <SimoxUtility/json.h>
6
10
12{
13 namespace bbuilder = bsoncxx::builder;
14 namespace bdoc = bsoncxx::document;
15
16 namespace detail
17 {
18 std::string
19 escapeName(const std::string& segmentName)
20 {
21 std::string ret = segmentName;
22 //simox::alg::replace_all(ret, Prefix, PrefixEscaped);
23 for (const auto& [s, r] : EscapeTable)
24 {
25 ret = simox::alg::replace_all(ret, s, r);
26 }
27 return ret;
28 }
29
30 std::string
31 unescapeName(const std::string& escapedName)
32 {
33 std::string ret = escapedName;
34 for (
35 const auto& [s, r] :
36 EscapeTable) // Here we assume that noone uses the replaced char usually in the segment name... TODO
37 {
38 ret = simox::alg::replace_all(ret, r, s);
39 }
40 return ret;
41 }
42
43 bool
44 insert(mongocxx::collection& coll, const nlohmann::json& value)
45 {
46 std::string v = value.dump();
47 auto q = bsoncxx::from_json(v);
48 auto res = coll.insert_one(q.view());
49
50 return (bool)res;
51 }
52
53 std::optional<nlohmann::json>
54 contains(mongocxx::collection& coll, const nlohmann::json& value)
55 {
56 // check mongodb
57 std::string v = value.dump();
58 auto q = bsoncxx::from_json(v);
59 auto res = coll.find_one(q.view());
60 if (res)
61 {
62 return nlohmann::json::parse(bsoncxx::to_json(*res));
63 }
64 return std::nullopt;
65 }
66
67 bool
68 update(mongocxx::collection& coll,
69 const nlohmann::json& query,
70 const nlohmann::json& update)
71 {
72 // check mongodb
73 auto q = bsoncxx::from_json(query.dump());
74 auto udoc = bsoncxx::from_json(update.dump());
75 auto u = bbuilder::basic::make_document(bbuilder::basic::kvp("$set", udoc));
76
77 auto res = coll.update_one(q.view(), u.view());
78
79 return (bool)res;
80 }
81 } // namespace detail
82
83 std::optional<mongocxx::database>
84 databaseExists(mongocxx::client& client, const std::string& databaseName)
85 {
86 //auto names = client.list_databases();
87 //if (auto it = std::find(names.begin(), names.end(), databaseName); it != names.end())
88 //{
89 // return client[databaseName];
90 //}
91 return std::nullopt;
92 }
93
94 mongocxx::database
95 ensureDatabaseExists(mongocxx::client& client,
96 const std::string& databaseName,
97 bool createIfNotExistent)
98 {
99 auto db = databaseExists(client, databaseName);
100 if (!db)
101 {
102 if (!createIfNotExistent)
103 {
104 throw armarx::LocalException("Database existence can not be ensured: " +
105 databaseName);
106 }
107 }
108 return client[databaseName];
109 }
110
111 std::optional<mongocxx::collection>
112 collectionExists(mongocxx::database& db, const std::string& collectionName)
113 {
114 if (db.has_collection(collectionName))
115 {
116 return db[collectionName];
117 }
118 return std::nullopt;
119 }
120
121 mongocxx::collection
122 ensureCollectionExists(mongocxx::database& db,
123 const std::string& collectionName,
124 bool createIfNotExistent)
125 {
126 auto coll = collectionExists(db, collectionName);
127 if (!coll)
128 {
129 if (!createIfNotExistent)
130 {
131 throw armarx::LocalException("Collection existence can not be ensured: " +
132 collectionName);
133 }
134 }
135 return db[collectionName];
136 }
137
138 std::string
140 {
141 if (id.hasTimestamp())
142 {
143 return id.timestampStr();
144 }
145
146 // fallback
147 throw armarx::LocalException("Called toDocumentName() on non-snapshot id: " + id.str());
148 }
149
150 std::string
152 {
153 ARMARX_CHECK(id.isWellDefined());
154 std::stringstream ss;
155 if (id.hasMemoryName())
156 {
157 ss << detail::escapeName(id.memoryName);
158 }
159 if (id.hasCoreSegmentName())
160 {
161 ss << "." << detail::escapeName(id.coreSegmentName);
162 }
163 if (id.hasProviderSegmentName())
164 {
165 ss << "." << detail::escapeName(id.providerSegmentName);
166 }
167 if (id.hasEntityName())
168 {
169 ss << "." << detail::escapeName(id.entityName);
170 }
171
172 return ss.str();
173 }
174
175 std::optional<nlohmann::json>
176 documentExists(mongocxx::collection& collection, const nlohmann::json& json)
177 {
178 return detail::contains(collection, json);
179 }
180
181 nlohmann::json
182 ensureDocumentExists(mongocxx::collection& collection,
183 const nlohmann::json& json,
184 bool createIfNotExistent)
185 {
186 auto op = documentExists(collection, json);
187 if (!op)
188 {
189 if (!createIfNotExistent)
190 {
191 throw armarx::LocalException("Document existence can not be ensured: " +
192 json.dump());
193 }
194 }
195
196 if (!op)
197 {
198 detail::insert(collection, json);
199 }
200
201 auto find = detail::contains(collection, json);
202 if (!find)
203 {
204 throw armarx::LocalException(
205 "Even after creating the docuemnt it wasnt found.. error: " + json.dump());
206 }
207 return *find;
208 }
209
210 nlohmann::json
211 readDataFromDocument(mongocxx::collection& collection, const nlohmann::json& json)
212 {
213 auto doc = detail::contains(collection, json);
214
215 ARMARX_CHECK((bool)doc) << " Could not find document matching: " << json.dump()
216 << " in collection " << collection.name();
217
218 return *doc;
219 }
220
221 void
222 writeDataToDocument(mongocxx::collection& collection,
223 const nlohmann::json& query,
224 const nlohmann::json& update)
225 {
226 if (documentExists(collection, query))
227 {
228 detail::update(collection, query, update);
229 }
230 else
231 {
232 nlohmann::json full;
233 full.update(query);
234 full.update(update);
235 detail::insert(collection, full);
236 }
237 }
238
239 std::vector<nlohmann::json>
240 getAllDocuments(mongocxx::collection& collection)
241 {
242 std::vector<nlohmann::json> ret;
243 mongocxx::cursor cursor = collection.find({});
244 for (const auto& doc : cursor)
245 {
246 ret.push_back(
247 nlohmann::json::parse(bsoncxx::to_json(doc, bsoncxx::ExtendedJsonMode::k_relaxed)));
248 }
249 return ret;
250 }
251
252} // namespace armarx::armem::server::ltm::util::mongodb
std::string str(const T &t)
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
#define q
This file is part of ArmarX.
std::string unescapeName(const std::string &escapedName)
Definition mongodb.cpp:31
std::string escapeName(const std::string &segmentName)
Definition mongodb.cpp:19
std::optional< nlohmann::json > contains(mongocxx::collection &coll, const nlohmann::json &value)
Definition mongodb.cpp:54
bool insert(mongocxx::collection &coll, const nlohmann::json &value)
Definition mongodb.cpp:44
bool update(mongocxx::collection &coll, const nlohmann::json &query, const nlohmann::json &update)
Definition mongodb.cpp:68
const std::map< std::string, std::string > EscapeTable
Definition mongodb.h:26
std::optional< mongocxx::database > databaseExists(mongocxx::client &client, const std::string &databaseName)
Definition mongodb.cpp:84
mongocxx::collection ensureCollectionExists(mongocxx::database &db, const std::string &collectionName, bool createIfNotExistent)
Definition mongodb.cpp:122
std::optional< nlohmann::json > documentExists(mongocxx::collection &collection, const nlohmann::json &json)
Definition mongodb.cpp:176
std::vector< nlohmann::json > getAllDocuments(mongocxx::collection &collection)
Definition mongodb.cpp:240
void writeDataToDocument(mongocxx::collection &collection, const nlohmann::json &query, const nlohmann::json &update)
Definition mongodb.cpp:222
nlohmann::json ensureDocumentExists(mongocxx::collection &collection, const nlohmann::json &json, bool createIfNotExistent)
Definition mongodb.cpp:182
mongocxx::database ensureDatabaseExists(mongocxx::client &client, const std::string &databaseName, bool createIfNotExistent)
Definition mongodb.cpp:95
std::optional< mongocxx::collection > collectionExists(mongocxx::database &db, const std::string &collectionName)
Definition mongodb.cpp:112
nlohmann::json readDataFromDocument(mongocxx::collection &collection, const nlohmann::json &json)
Definition mongodb.cpp:211
std::string toCollectionName(const armem::MemoryID &id)
Definition mongodb.cpp:151
std::string toDocumentID(const armem::MemoryID &id)
Definition mongodb.cpp:139