12#include <userver/formats/bson/document.hpp> 
   13#include <userver/formats/bson/value.hpp> 
   14#include <userver/storages/mongo/bulk.hpp> 
   15#include <userver/storages/mongo/cursor.hpp> 
   16#include <userver/storages/mongo/operations.hpp> 
   17#include <userver/storages/mongo/write_result.hpp> 
   19USERVER_NAMESPACE_BEGIN
 
   38  explicit Collection(std::shared_ptr<impl::CollectionImpl>);
 
   44  template <
typename... Options>
 
   49  template <
typename... Options>
 
   53  template <
typename... Options>
 
   57  template <
typename... Options>
 
   59                                                 Options&&... options) 
const;
 
   62  template <
typename... Options>
 
   66  template <
typename... Options>
 
   68                         Options&&... options);
 
   72  template <
typename... Options>
 
   75                         Options&&... options);
 
   79  template <
typename... Options>
 
   85  template <
typename... Options>
 
   90  template <
typename... Options>
 
   94  template <
typename... Options>
 
   96                         Options&&... options);
 
  101  template <
typename... Options>
 
  104                            Options&&... options);
 
  107  template <
typename... Options>
 
  109                            Options&&... options);
 
  112  template <
typename... Options>
 
  113  void Drop(Options&&... options);
 
  116  template <
typename... Options>
 
  120  template <
typename... Options>
 
  125  template <
typename... Options>
 
  133  size_t Execute(
const operations::Count&) 
const;
 
  134  size_t Execute(
const operations::CountApprox&) 
const;
 
  148  std::shared_ptr<impl::CollectionImpl> impl_;
 
  151template <
typename... Options>
 
  155  (count_op.SetOption(std::forward<Options>(options)), ...);
 
  156  return Execute(count_op);
 
  159template <
typename... Options>
 
  162  (count_approx_op.SetOption(std::forward<Options>(options)), ...);
 
  163  return Execute(count_approx_op);
 
  168template <
typename Option, 
typename... Options>
 
  169using HasOptionHelper =
 
  170    std::disjunction<std::is_same<std::decay_t<Options>, Option>...>;
 
  172template <
typename Option, 
typename... Options>
 
  173static constexpr bool kHasOption = HasOptionHelper<Option, Options...>::value;
 
  177template <
typename... Options>
 
  179                        Options&&... options) 
const {
 
  181  (find_op.SetOption(std::forward<Options>(options)), ...);
 
  182  return Execute(find_op);
 
  185template <
typename... Options>
 
  187    formats::
bson::
Document filter, Options&&... options) 
const {
 
  189      !(std::is_same<std::decay_t<Options>, options::Limit>::value || ...),
 
  190      "Limit option cannot be used in FindOne");
 
  191  auto cursor = Find(std::move(filter), options::Limit{1},
 
  192                     std::forward<Options>(options)...);
 
  193  if (cursor.begin() == cursor.end()) 
return {};
 
  194  return *cursor.begin();
 
  197template <
typename... Options>
 
  199                                  Options&&... options) {
 
  201  (insert_op.SetOption(std::forward<Options>(options)), ...);
 
  202  return Execute(insert_op);
 
  205template <
typename... Options>
 
  207    std::vector<formats::bson::Document> documents, Options&&... options) {
 
  209  (insert_op.SetOption(std::forward<Options>(options)), ...);
 
  210  return Execute(insert_op);
 
  213template <
typename... Options>
 
  216                                   Options&&... options) {
 
  218                                    std::move(replacement));
 
  219  (replace_op.SetOption(std::forward<Options>(options)), ...);
 
  220  return Execute(replace_op);
 
  223template <
typename... Options>
 
  226                                  Options&&... options) {
 
  228                               std::move(selector), std::move(update));
 
  229  (update_op.SetOption(std::forward<Options>(options)), ...);
 
  230  return Execute(update_op);
 
  233template <
typename... Options>
 
  236                                   Options&&... options) {
 
  238                               std::move(selector), std::move(update));
 
  239  (update_op.SetOption(std::forward<Options>(options)), ...);
 
  240  return Execute(update_op);
 
  243template <
typename... Options>
 
  245                                  Options&&... options) {
 
  247                               std::move(selector));
 
  248  (delete_op.SetOption(std::forward<Options>(options)), ...);
 
  249  return Execute(delete_op);
 
  252template <
typename... Options>
 
  254                                   Options&&... options) {
 
  256                               std::move(selector));
 
  257  (delete_op.SetOption(std::forward<Options>(options)), ...);
 
  258  return Execute(delete_op);
 
  261template <
typename... Options>
 
  264                                      Options&&... options) {
 
  266  (fam_op.SetOption(std::forward<Options>(options)), ...);
 
  267  return Execute(fam_op);
 
  270template <
typename... Options>
 
  272                                      Options&&... options) {
 
  274  (fam_op.SetOption(std::forward<Options>(options)), ...);
 
  275  return Execute(fam_op);
 
  278template <
typename... Options>
 
  281  (drop_op.SetOption(std::forward<Options>(options)), ...);
 
  282  return Execute(drop_op);
 
  285template <
typename... Options>
 
  288  (bulk.SetOption(std::forward<Options>(options)), ...);
 
  292template <
typename... Options>
 
  295  (bulk.SetOption(std::forward<Options>(options)), ...);
 
  299template <
typename... Options>
 
  301                             Options&&... options) {
 
  303  (aggregate.SetOption(std::forward<Options>(options)), ...);
 
  304  return Execute(aggregate);