Create
Protocol for creating documents in a collection.
Data model that represents the payload to be submitted to the service for creating documents. Two structures are defined: `Create` that owns the document payload, and `CreateWithReference` that references instances that are owned by calling code.
//
// Created by Rakesh on 13/12/2024.
//
#pragma once
#include "action.hpp"
#include "../../options/insert.hpp"
#if defined __has_include
#if __has_include("../../../common/util/json.hpp")
#include "../../../common/util/json.hpp"
#else
#include <mongo-service/common/util/json.hpp>
#endif
#endif
#include <functional>
#include <bsoncxx/builder/stream/document.hpp>
namespace spt::mongoservice::api::model::request
{
template <util::Visitable Document, util::Visitable Metadata>
requires std::is_same_v<decltype(Document::id), bsoncxx::oid> && std::constructible_from<Document, bsoncxx::document::view>
struct Create
{
Create() = default;
~Create() = default;
Create(Create&&) = default;
Create& operator=(Create&&) = default;
Create(const Create&) = delete;
Create& operator=(const Create&) = delete;
BEGIN_VISITABLES(Create);
Document document;
VISITABLE(std::optional<Metadata>, metadata);
VISITABLE(std::optional<options::Insert>, options);
std::string database;
std::string collection;
std::string application;
std::string correlationId;
Action action{Action::create};
bool skipVersion{false};
bool skipMetric{false};
END_VISITABLES;
};
template <util::Visitable Document, util::Visitable Metadata>
requires std::is_same_v<decltype(Document::id), bsoncxx::oid> && std::constructible_from<Document, bsoncxx::document::view>
struct CreateWithReference
{
explicit CreateWithReference( const Document& doc ) : document{ std::cref( doc ) } {}
CreateWithReference( const Document& doc, const Metadata& md ) : document{ std::cref( doc ) }, metadata{ std::cref( md ) } {}
~CreateWithReference() = default;
CreateWithReference(CreateWithReference&&) = default;
CreateWithReference& operator=(CreateWithReference&&) = default;
CreateWithReference(const CreateWithReference&) = delete;
CreateWithReference& operator=(const CreateWithReference&) = delete;
BEGIN_VISITABLES(CreateWithReference);
std::reference_wrapper<const Document> document;
VISITABLE(std::optional<std::reference_wrapper<const Metadata>>, metadata);
VISITABLE(std::optional<options::Insert>, options);
std::string database;
std::string collection;
std::string application;
std::string correlationId;
Action action{Action::create};
bool skipVersion{false};
bool skipMetric{false};
END_VISITABLES;
};
}
Data model that represents the payload that the service responds with when creating a document.
//
// Created by Rakesh on 17/12/2024.
//
#pragma once
#if defined __has_include
#if __has_include("../../../common/visit_struct/visit_struct_intrusive.hpp")
#include "../../../common/visit_struct/visit_struct_intrusive.hpp"
#include "../../../common/util/serialise.hpp"
#else
#include <mongo-service/common/visit_struct/visit_struct_intrusive.hpp>
#include <mongo-service/common/util/serialise.hpp>
#endif
#endif
#include <optional>
#include <bsoncxx/oid.hpp>
namespace spt::mongoservice::api::model::response
{
struct Create
{
explicit Create( bsoncxx::document::view document ) { util::unmarshall( *this, document ); }
Create() = default;
~Create() = default;
Create(Create&&) = default;
Create& operator=(Create&&) = default;
Create(const Create&) = delete;
Create& operator=(const Create&) = delete;
BEGIN_VISITABLES(Create);
VISITABLE(std::string, database);
VISITABLE(std::string, collection);
VISITABLE(std::optional<bsoncxx::oid>, id);
VISITABLE(std::optional<bsoncxx::oid>, entity);
VISITABLE(std::optional<bool>, skipVersion);
END_VISITABLES;
};
}
Sample code illustrating the create action.
#include <mongo-service/api/repository/repository.hpp>
namespace example
{
struct Document
{
explicit Document( bsoncxx::document::view bson ) { spt::util::unmarshall( *this, bson ); }
Document() = default;
~Document() = default;
Document(Document&&) = default;
Document& operator=(Document&&) = default;
bool operator==(const Document&) const = default;
Document(const Document&) = delete;
Document& operator=(const Document&) = delete;
BEGIN_VISITABLES(Document);
VISITABLE(bsoncxx::oid, id);
VISITABLE(std::string, str);
VISITABLE_DIRECT_INIT(spt::util::DateTimeMs, created, {std::chrono::duration_cast<std::chrono::milliseconds>( std::chrono::system_clock::now().time_since_epoch() )});
VISITABLE_DIRECT_INIT(int64_t, integer, {5});
VISITABLE_DIRECT_INIT(double, floating, {10.345});
VISITABLE_DIRECT_INIT(bool, boolean, {true});
END_VISITABLES;
};
struct Metadata
{
explicit Metadata( bsoncxx::document::view bson ) { spt::util::unmarshall( *this, bson ); }
Metadata() = default;
~Metadata() = default;
Metadata(Metadata&&) = default;
Metadata& operator=(Metadata&&) = default;
bool operator==(const Metadata&) const = default;
Metadata(const Metadata&) = delete;
Metadata& operator=(const Metadata&) = delete;
BEGIN_VISITABLES(Metadata);
VISITABLE(std::string, project);
VISITABLE(std::string, product);
END_VISITABLES;
};
}
int main()
{
using namespace spt::mongoservice::api;
auto insert = model::request::Create<example::Document, example::Metadata>{};
insert.database = database;
insert.collection = collection;
insert.document.str = "value";
insert.metadata.emplace();
insert.metadata->project = "serialisation";
insert.metadata->product = "mongo-service";
insert.options.emplace();
insert.options->bypassValidation = true;
insert.options->ordered = true;
auto result = repository::create( insert );
if ( !result.has_value() )
{
LOG_WARN << "Error creating document. " << magic_enum::enum_name( result.error().cause ) << ". " << result.error().message;
}
}
Last modified: 18 February 2025