Mangrove
The C++ Object Document Mapper for MongoDB
model.hpp
1 // Copyright 2016 MongoDB Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #pragma once
16 
17 #include <cereal/cereal.hpp>
18 
19 #include <bsoncxx/oid.hpp>
20 #include <mangrove/collection_wrapper.hpp>
21 #include <mangrove/config/prelude.hpp>
22 #include <mangrove/util.hpp>
23 #include <mongocxx/collection.hpp>
24 
25 namespace mangrove {
26 MANGROVE_INLINE_NAMESPACE_BEGIN
27 
28 template <typename T, typename IdType = bsoncxx::oid>
29 class model {
30  private:
31 // TODO: When XCode 8 is released, this can always be thread_local. Until then, the model class
32 // will not be thread-safe on OS X.
33 #ifdef __APPLE__
34  static collection_wrapper<T> _coll;
35 #else
36  static thread_local collection_wrapper<T> _coll;
37 #endif
38 
39  public:
49  template <typename... Ts,
50  typename = std::enable_if_t<!first_two_types_are_same<model, Ts...>::value>>
51  model(Ts&&... ts) : _id(std::forward<Ts>(ts)...) {
52  }
53 
54  model() = default;
55 
71  static std::int64_t count(
72  bsoncxx::document::view_or_value filter = bsoncxx::document::view_or_value{},
73  const mongocxx::options::count& options = mongocxx::options::count()) {
74  return _coll.collection().count(filter, options);
75  }
76 
83  static const mongocxx::collection collection() {
84  return _coll.collection();
85  }
86 
100  static mongocxx::stdx::optional<mongocxx::result::delete_result> delete_many(
101  bsoncxx::document::view_or_value filter,
102  const mongocxx::options::delete_options& options = mongocxx::options::delete_options()) {
103  return _coll.collection().delete_many(filter, options);
104  }
105 
119  static mongocxx::stdx::optional<mongocxx::result::delete_result> delete_one(
120  bsoncxx::document::view_or_value filter,
121  const mongocxx::options::delete_options& options = mongocxx::options::delete_options()) {
122  return _coll.collection().delete_one(filter, options);
123  }
124 
132  static void drop() {
133  _coll.collection().drop();
134  }
135 
152  bsoncxx::document::view_or_value filter,
153  const mongocxx::options::find& options = mongocxx::options::find()) {
154  return _coll.find(std::move(filter), options);
155  }
156 
170  static mongocxx::stdx::optional<T> find_one(
171  bsoncxx::document::view_or_value filter,
172  const mongocxx::options::find& options = mongocxx::options::find()) {
173  return _coll.find_one(std::move(filter), options);
174  }
175 
196  template <typename container_type,
197  typename = std::enable_if_t<container_of_v<container_type, T>>>
198  static mongocxx::stdx::optional<mongocxx::result::insert_many> insert_many(
199  const container_type& container,
200  const mongocxx::options::insert& options = mongocxx::options::insert()) {
201  return insert_many(container.begin(), container.end(), options);
202  }
203 
228  template <typename object_iterator_type,
229  typename = std::enable_if_t<iterator_of_v<object_iterator_type, T>>>
230  static mongocxx::stdx::optional<mongocxx::result::insert_many> insert_many(
231  object_iterator_type begin, object_iterator_type end,
232  const mongocxx::options::insert& options = mongocxx::options::insert()) {
233  return _coll.insert_many(begin, end, options);
234  }
235 
249  static mongocxx::stdx::optional<mongocxx::result::insert_one> insert_one(
250  T obj, const mongocxx::options::insert& options = mongocxx::options::insert()) {
251  return _coll.insert_one(obj, options);
252  }
253 
262  void remove() {
263  auto id_match_filter = bsoncxx::builder::stream::document{}
264  << "_id" << this->_id << bsoncxx::builder::stream::finalize;
265 
266  _coll.collection().delete_one(id_match_filter.view());
267  }
268 
281  static void setCollection(const mongocxx::collection& coll) {
282  _coll = collection_wrapper<T>(coll);
283  }
284  static void setCollection(mongocxx::collection&& coll) {
285  _coll = collection_wrapper<T>(std::move(coll));
286  }
287 
299  void save() {
300  auto id_match_filter = bsoncxx::builder::stream::document{}
301  << "_id" << this->_id << bsoncxx::builder::stream::finalize;
302 
303  auto update = bsoncxx::builder::stream::document{}
304  << "$set" << boson::to_dotted_notation_document(*static_cast<T*>(this))
305  << bsoncxx::builder::stream::finalize;
306 
307  mongocxx::options::update opts{};
308 
309  opts.upsert(true);
310 
311  _coll.collection().update_one(id_match_filter.view(), update.view(), opts);
312  };
313 
329  static mongocxx::stdx::optional<mongocxx::result::update> update_many(
330  bsoncxx::document::view_or_value filter, bsoncxx::document::view_or_value update,
331  const mongocxx::options::update& options = mongocxx::options::update()) {
332  return _coll.collection().update_many(filter, update, options);
333  }
334 
350  static mongocxx::stdx::optional<mongocxx::result::update> update_one(
351  bsoncxx::document::view_or_value filter, bsoncxx::document::view_or_value update,
352  const mongocxx::options::update& options = mongocxx::options::update()) {
353  return _coll.collection().update_many(filter, update, options);
354  }
355 
356  protected:
357  IdType _id;
358 };
359 
360 #ifdef __APPLE__
361 template <typename T, typename IdType>
363 #else
364 template <typename T, typename IdType>
365 thread_local collection_wrapper<T> model<T, IdType>::_coll;
366 #endif
367 
368 MANGROVE_INLINE_NAMESPACE_END
369 } // namespace mangrove
static mongocxx::stdx::optional< mongocxx::result::insert_one > insert_one(T obj, const mongocxx::options::insert &options=mongocxx::options::insert())
Inserts a single object of the model into the collection.
Definition: model.hpp:249
static mongocxx::stdx::optional< mongocxx::result::update > update_many(bsoncxx::document::view_or_value filter, bsoncxx::document::view_or_value update, const mongocxx::options::update &options=mongocxx::options::update())
Updates multiple documents matching the provided filter in this collection.
Definition: model.hpp:329
static void drop()
Drops the underlying collection and all its contained documents from the database.
Definition: model.hpp:132
A class that wraps a mongocxx::cursor.
Definition: deserializing_cursor.hpp:37
static mongocxx::stdx::optional< T > find_one(bsoncxx::document::view_or_value filter, const mongocxx::options::find &options=mongocxx::options::find())
Finds a single document in this collection that matches the provided filter.
Definition: model.hpp:170
static mongocxx::stdx::optional< mongocxx::result::delete_result > delete_one(bsoncxx::document::view_or_value filter, const mongocxx::options::delete_options &options=mongocxx::options::delete_options())
Deletes a single matching document from the collection.
Definition: model.hpp:119
static const mongocxx::collection collection()
Returns a copy of the underlying collection.
Definition: model.hpp:83
static mongocxx::stdx::optional< mongocxx::result::insert_many > insert_many(const container_type &container, const mongocxx::options::insert &options=mongocxx::options::insert())
Inserts multiple object of the model into the collection.
Definition: model.hpp:198
Definition: collection_wrapper.hpp:28
static void setCollection(const mongocxx::collection &coll)
Sets the underlying mongocxx::collection used to store and load instances of T.
Definition: model.hpp:281
static mongocxx::stdx::optional< mongocxx::result::update > update_one(bsoncxx::document::view_or_value filter, bsoncxx::document::view_or_value update, const mongocxx::options::update &options=mongocxx::options::update())
Updates a single document matching the provided filter in this collection.
Definition: model.hpp:350
Definition: collection_wrapper.hpp:32
static mongocxx::stdx::optional< mongocxx::result::insert_many > insert_many(object_iterator_type begin, object_iterator_type end, const mongocxx::options::insert &options=mongocxx::options::insert())
Inserts multiple objects of the model into the collection.
Definition: model.hpp:230
static deserializing_cursor< T > find(bsoncxx::document::view_or_value filter, const mongocxx::options::find &options=mongocxx::options::find())
Finds the documents in this collection which match the provided filter.
Definition: model.hpp:151
Definition: model.hpp:29
void save()
Performs an update in the database that saves the current T object instance to the collection mapped ...
Definition: model.hpp:299
model(Ts &&...ts)
Forward the arguments to the constructor of IdType.
Definition: model.hpp:51
static std::int64_t count(bsoncxx::document::view_or_value filter=bsoncxx::document::view_or_value{}, const mongocxx::options::count &options=mongocxx::options::count())
Counts the number of documents matching the provided filter.
Definition: model.hpp:71
Helper type trait widget that helps properly forward arguments to _id constructor in mangrove::model...
Definition: util.hpp:187
static mongocxx::stdx::optional< mongocxx::result::delete_result > delete_many(bsoncxx::document::view_or_value filter, const mongocxx::options::delete_options &options=mongocxx::options::delete_options())
Deletes all matching documents from the collection.
Definition: model.hpp:100