15 #ifndef GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_SPANNER_MUTATIONS_H
16 #define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_SPANNER_MUTATIONS_H
18 #include "google/cloud/spanner/keys.h"
19 #include "google/cloud/spanner/value.h"
20 #include "google/cloud/spanner/version.h"
21 #include <google/spanner/v1/mutation.pb.h>
27 namespace spanner_internal {
29 template <
typename Op>
30 class WriteMutationBuilder;
31 class DeleteMutationBuilder;
85 google::spanner::v1::Mutation& proto() & {
return m_; }
87 template <
typename Op>
90 explicit Mutation(
google::spanner::v1::Mutation m) : m_(std::move(m)) {}
92 google::spanner::v1::Mutation m_;
106 namespace spanner_internal {
109 template <
typename Op>
110 class WriteMutationBuilder {
112 WriteMutationBuilder(std::string table_name,
113 std::vector<std::string> column_names) {
114 auto& field = Op::mutable_field(m_.proto());
115 field.set_table(std::move(table_name));
116 field.mutable_columns()->Reserve(
static_cast<
int>(column_names.size()));
117 for (
auto& name : column_names) {
118 field.add_columns(std::move(name));
125 WriteMutationBuilder& AddRow(std::vector<
spanner::
Value> values) & {
126 auto& lv = *Op::mutable_field(m_.proto()).add_values();
127 for (
auto& v : values) {
128 std::tie(std::ignore, *lv.add_values()) =
129 spanner_internal::ToProto(std::move(v));
134 WriteMutationBuilder&& AddRow(std::vector<
spanner::
Value> values) && {
135 return std::move(AddRow(std::move(values)));
138 template <
typename... Ts>
139 WriteMutationBuilder& EmplaceRow(Ts&&... values) & {
140 return AddRow({
spanner::
Value(std::forward<Ts>(values))...});
143 template <
typename... Ts>
144 WriteMutationBuilder&& EmplaceRow(Ts&&... values) && {
145 return std::move(EmplaceRow(std::forward<Ts>(values)...));
153 static google::spanner::v1::Mutation::Write& mutable_field(
154 google::spanner::v1::Mutation& m) {
155 return *m.mutable_insert();
160 static google::spanner::v1::Mutation::Write& mutable_field(
161 google::spanner::v1::Mutation& m) {
162 return *m.mutable_update();
166 struct InsertOrUpdateOp {
167 static google::spanner::v1::Mutation::Write& mutable_field(
168 google::spanner::v1::Mutation& m) {
169 return *m.mutable_insert_or_update();
174 static google::spanner::v1::Mutation::Write& mutable_field(
175 google::spanner::v1::Mutation& m) {
176 return *m.mutable_replace();
180 class DeleteMutationBuilder {
182 DeleteMutationBuilder(std::string table_name,
spanner::
KeySet keys) {
183 auto& field = *m_.proto().mutable_delete_();
184 field.set_table(std::move(table_name));
185 *field.mutable_key_set() = spanner_internal::ToProto(std::move(keys));
213 using InsertMutationBuilder =
214 spanner_internal::WriteMutationBuilder<spanner_internal::InsertOp>;
228 template <
typename... Ts>
230 std::vector<std::string> columns, Ts&&... values) {
231 return InsertMutationBuilder(std::move(table_name), std::move(columns))
232 .EmplaceRow(std::forward<Ts>(values)...)
248 using UpdateMutationBuilder =
249 spanner_internal::WriteMutationBuilder<spanner_internal::UpdateOp>;
263 template <
typename... Ts>
265 std::vector<std::string> columns, Ts&&... values) {
266 return UpdateMutationBuilder(std::move(table_name), std::move(columns))
267 .EmplaceRow(std::forward<Ts>(values)...)
283 using InsertOrUpdateMutationBuilder =
284 spanner_internal::WriteMutationBuilder<spanner_internal::InsertOrUpdateOp>;
298 template <
typename... Ts>
300 std::vector<std::string> columns,
302 return InsertOrUpdateMutationBuilder(std::move(table_name),
304 .EmplaceRow(std::forward<Ts>(values)...)
320 using ReplaceMutationBuilder =
321 spanner_internal::WriteMutationBuilder<spanner_internal::ReplaceOp>;
335 template <
typename... Ts>
337 std::vector<std::string> columns, Ts&&... values) {
338 return ReplaceMutationBuilder(std::move(table_name), std::move(columns))
339 .EmplaceRow(std::forward<Ts>(values)...)
355 using DeleteMutationBuilder = spanner_internal::DeleteMutationBuilder;
370 return DeleteMutationBuilder(std::move(table_name), std::move(keys)).Build();