@@ -803,14 +803,14 @@ class collection_impl : public std::enable_shared_from_this<collection_impl>
803803 }
804804
805805 void upsert (std::string document_key,
806- codec::encoded_value encoded ,
806+ std::variant< codec::encoded_value, std::function<codec::encoded_value()>> value ,
807807 upsert_options::built options,
808808 upsert_handler&& handler) const
809809 {
810810 auto span = create_kv_span (
811811 core::tracing::operation::mcbp_upsert, options.parent_span , options.durability_level );
812812
813- auto value = std::move (encoded );
813+ auto [data, flags] = get_encoded_value ( std::move (value), span );
814814 auto id = core::document_id{
815815 bucket_name_,
816816 scope_name_,
@@ -820,10 +820,10 @@ class collection_impl : public std::enable_shared_from_this<collection_impl>
820820 if (options.persist_to == persist_to::none && options.replicate_to == replicate_to::none) {
821821 core::operations::upsert_request request{
822822 std::move (id),
823- std::move (value. data ),
823+ std::move (data),
824824 {},
825825 {},
826- value. flags ,
826+ flags,
827827 options.expiry ,
828828 options.durability_level ,
829829 options.timeout ,
@@ -845,10 +845,10 @@ class collection_impl : public std::enable_shared_from_this<collection_impl>
845845
846846 core::operations::upsert_request request{
847847 id,
848- std::move (value. data ),
848+ std::move (data),
849849 {},
850850 {},
851- value. flags ,
851+ flags,
852852 options.expiry ,
853853 durability_level::none,
854854 options.timeout ,
@@ -893,14 +893,14 @@ class collection_impl : public std::enable_shared_from_this<collection_impl>
893893 }
894894
895895 void insert (std::string document_key,
896- codec::encoded_value encoded ,
896+ std::variant< codec::encoded_value, std::function<codec::encoded_value()>> value ,
897897 insert_options::built options,
898898 insert_handler&& handler) const
899899 {
900900 auto span = create_kv_span (
901901 core::tracing::operation::mcbp_insert, options.parent_span , options.durability_level );
902902
903- auto value = std::move (encoded );
903+ auto [data, flags] = get_encoded_value ( std::move (value), span );
904904 auto id = core::document_id{
905905 bucket_name_,
906906 scope_name_,
@@ -910,10 +910,10 @@ class collection_impl : public std::enable_shared_from_this<collection_impl>
910910 if (options.persist_to == persist_to::none && options.replicate_to == replicate_to::none) {
911911 core::operations::insert_request request{
912912 std::move (id),
913- std::move (value. data ),
913+ std::move (data),
914914 {},
915915 {},
916- value. flags ,
916+ flags,
917917 options.expiry ,
918918 options.durability_level ,
919919 options.timeout ,
@@ -937,10 +937,10 @@ class collection_impl : public std::enable_shared_from_this<collection_impl>
937937
938938 core::operations::insert_request request{
939939 id,
940- std::move (value. data ),
940+ std::move (data),
941941 {},
942942 {},
943- value. flags ,
943+ flags,
944944 options.expiry ,
945945 durability_level::none,
946946 options.timeout ,
@@ -982,15 +982,17 @@ class collection_impl : public std::enable_shared_from_this<collection_impl>
982982 });
983983 });
984984 }
985+
985986 void replace (std::string document_key,
986- codec::encoded_value encoded ,
987+ std::variant< codec::encoded_value, std::function<codec::encoded_value()>> value ,
987988 replace_options::built options,
988989 replace_handler&& handler) const
989990 {
990991 auto span = create_kv_span (
991992 core::tracing::operation::mcbp_replace, options.parent_span , options.durability_level );
992993
993- auto value = std::move (encoded);
994+ auto [data, flags] = get_encoded_value (std::move (value), span);
995+
994996 auto id = core::document_id{
995997 bucket_name_,
996998 scope_name_,
@@ -1000,10 +1002,10 @@ class collection_impl : public std::enable_shared_from_this<collection_impl>
10001002 if (options.persist_to == persist_to::none && options.replicate_to == replicate_to::none) {
10011003 core::operations::replace_request request{
10021004 std::move (id),
1003- std::move (value. data ),
1005+ std::move (data),
10041006 {},
10051007 {},
1006- value. flags ,
1008+ flags,
10071009 options.expiry ,
10081010 options.cas ,
10091011 options.durability_level ,
@@ -1029,10 +1031,10 @@ class collection_impl : public std::enable_shared_from_this<collection_impl>
10291031
10301032 core::operations::replace_request request{
10311033 id,
1032- std::move (value. data ),
1034+ std::move (data),
10331035 {},
10341036 {},
1035- value. flags ,
1037+ flags,
10361038 options.expiry ,
10371039 options.cas ,
10381040 durability_level::none,
@@ -1216,6 +1218,20 @@ class collection_impl : public std::enable_shared_from_this<collection_impl>
12161218 }
12171219
12181220private:
1221+ auto get_encoded_value (
1222+ std::variant<codec::encoded_value, std::function<codec::encoded_value()>> value,
1223+ const std::shared_ptr<tracing::request_span>& operation_span) const -> codec::encoded_value
1224+ {
1225+ if (std::holds_alternative<codec::encoded_value>(value)) {
1226+ return std::get<codec::encoded_value>(value);
1227+ }
1228+ const auto request_encoding_span =
1229+ tracer ()->create_span (core::tracing::operation::step_request_encoding, operation_span);
1230+ auto encoded = std::get<std::function<codec::encoded_value ()>>(value)();
1231+ request_encoding_span->end ();
1232+ return encoded;
1233+ }
1234+
12191235 auto create_kv_span (const std::string& operation_name,
12201236 const std::shared_ptr<tracing::request_span>& parent_span,
12211237 const std::optional<durability_level> durability = {}) const
@@ -1656,6 +1672,30 @@ collection::upsert(std::string document_id,
16561672 return future;
16571673}
16581674
1675+ auto
1676+ collection::upsert (std::string document_id,
1677+ std::function<codec::encoded_value()> document_fn,
1678+ const upsert_options& options,
1679+ upsert_handler&& handler) const -> void
1680+ {
1681+ impl_->upsert (
1682+ std::move (document_id), std::move (document_fn), options.build (), std::move (handler));
1683+ }
1684+
1685+ auto
1686+ collection::upsert (std::string document_id,
1687+ std::function<codec::encoded_value()> document_fn,
1688+ const upsert_options& options) const
1689+ -> std::future<std::pair<error, mutation_result>>
1690+ {
1691+ auto barrier = std::make_shared<std::promise<std::pair<error, mutation_result>>>();
1692+ auto future = barrier->get_future ();
1693+ upsert (std::move (document_id), std::move (document_fn), options, [barrier](auto err, auto result) {
1694+ barrier->set_value ({ std::move (err), std::move (result) });
1695+ });
1696+ return future;
1697+ }
1698+
16591699void
16601700collection::insert (std::string document_id,
16611701 codec::encoded_value document,
@@ -1680,6 +1720,30 @@ collection::insert(std::string document_id,
16801720 return future;
16811721}
16821722
1723+ auto
1724+ collection::insert (std::string document_id,
1725+ std::function<codec::encoded_value()> document_fn,
1726+ const insert_options& options,
1727+ insert_handler&& handler) const -> void
1728+ {
1729+ impl_->insert (
1730+ std::move (document_id), std::move (document_fn), options.build (), std::move (handler));
1731+ }
1732+
1733+ auto
1734+ collection::insert (std::string document_id,
1735+ std::function<codec::encoded_value()> document_fn,
1736+ const insert_options& options) const
1737+ -> std::future<std::pair<error, mutation_result>>
1738+ {
1739+ auto barrier = std::make_shared<std::promise<std::pair<error, mutation_result>>>();
1740+ auto future = barrier->get_future ();
1741+ insert (std::move (document_id), std::move (document_fn), options, [barrier](auto err, auto result) {
1742+ barrier->set_value ({ std::move (err), std::move (result) });
1743+ });
1744+ return future;
1745+ }
1746+
16831747void
16841748collection::replace (std::string document_id,
16851749 codec::encoded_value document,
@@ -1704,6 +1768,31 @@ collection::replace(std::string document_id,
17041768 return future;
17051769}
17061770
1771+ void
1772+ collection::replace (std::string document_id,
1773+ std::function<codec::encoded_value()> document_fn,
1774+ const replace_options& options,
1775+ replace_handler&& handler) const
1776+ {
1777+ impl_->replace (
1778+ std::move (document_id), std::move (document_fn), options.build (), std::move (handler));
1779+ }
1780+
1781+ auto
1782+ collection::replace (std::string document_id,
1783+ std::function<codec::encoded_value()> document_fn,
1784+ const replace_options& options) const
1785+ -> std::future<std::pair<error, mutation_result>>
1786+ {
1787+ auto barrier = std::make_shared<std::promise<std::pair<error, mutation_result>>>();
1788+ auto future = barrier->get_future ();
1789+ replace (
1790+ std::move (document_id), std::move (document_fn), options, [barrier](auto err, auto result) {
1791+ barrier->set_value ({ std::move (err), std::move (result) });
1792+ });
1793+ return future;
1794+ }
1795+
17071796void
17081797collection::scan (const couchbase::scan_type& scan_type,
17091798 const couchbase::scan_options& options,
0 commit comments