Google Cloud Spanner C++ Client 2.13.0
A C++ Client Library for Google Cloud Spanner
Loading...
Searching...
No Matches
mutations.h
1// Copyright 2019 Google LLC
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// https://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#ifndef GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_SPANNER_MUTATIONS_H
16#define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_SPANNER_MUTATIONS_H
17
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>
22#include <string>
23#include <vector>
24
25namespace google {
26namespace cloud {
27namespace spanner_internal {
28GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
29template <typename Op>
30class WriteMutationBuilder;
31class DeleteMutationBuilder;
32GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
33} // namespace spanner_internal
34
35namespace spanner {
36GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
37
38/**
39 * A wrapper for Cloud Spanner mutations.
40 *
41 * In addition to the Data Manipulation Language (DML) based APIs, Cloud Spanner
42 * supports the mutation API, where the application describes data modification
43 * using a data structure instead of a SQL statement.
44 *
45 * This class serves as a wrapper for all mutations types. Use the builders,
46 * such as `InsertMutationBuilder` or `UpdateMutationBuilder` to create objects
47 * of this class.
48 *
49 * @see https://cloud.google.com/spanner/docs/modify-mutation-api
50 * for more information about the Cloud Spanner mutation API.
51 */
52class Mutation {
53 public:
54 /**
55 * Creates an empty mutation.
56 *
57 * @note Empty mutations are not usable with the Cloud Spanner mutation API.
58 */
59 Mutation() = default;
60
61 Mutation(Mutation&&) = default;
62 Mutation& operator=(Mutation&&) = default;
63 Mutation(Mutation const&) = default;
64 Mutation& operator=(Mutation const&) = default;
65
66 friend bool operator==(Mutation const& lhs, Mutation const& rhs);
67 friend bool operator!=(Mutation const& lhs, Mutation const& rhs) {
68 return !(lhs == rhs);
69 }
70
71 /// Convert the mutation to the underlying proto.
72 google::spanner::v1::Mutation as_proto() && { return std::move(m_); }
73 google::spanner::v1::Mutation as_proto() const& { return m_; }
74
75 /**
76 * Allows Google Test to print internal debugging information when test
77 * assertions fail.
78 *
79 * @warning This is intended for debugging and human consumption only, not
80 * machine consumption as the output format may change without notice.
81 */
82 friend void PrintTo(Mutation const& m, std::ostream* os);
83
84 private:
85 google::spanner::v1::Mutation& proto() & { return m_; }
86
87 template <typename Op>
88 friend class spanner_internal::WriteMutationBuilder;
89 friend class spanner_internal::DeleteMutationBuilder;
90 explicit Mutation(google::spanner::v1::Mutation m) : m_(std::move(m)) {}
91
92 google::spanner::v1::Mutation m_;
93};
94
95/**
96 * An ordered sequence of mutations to pass to `Client::Commit()` or return
97 * from the `Client::Commit()` mutator.
98 */
99using Mutations = std::vector<Mutation>;
100
101GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
102} // namespace spanner
103
104// This namespace contains implementation details. It is not part of the public
105// API, and subject to change without notice.
106namespace spanner_internal {
107GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
108
109template <typename Op>
110class WriteMutationBuilder {
111 public:
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));
119 }
120 }
121
122 spanner::Mutation Build() const& { return m_; }
123 spanner::Mutation&& Build() && { return std::move(m_); }
124
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));
130 }
131 return *this;
132 }
133
134 WriteMutationBuilder&& AddRow(std::vector<spanner::Value> values) && {
135 return std::move(AddRow(std::move(values)));
136 }
137
138 template <typename... Ts>
139 WriteMutationBuilder& EmplaceRow(Ts&&... values) & {
140 return AddRow({spanner::Value(std::forward<Ts>(values))...});
141 }
142
143 template <typename... Ts>
144 WriteMutationBuilder&& EmplaceRow(Ts&&... values) && {
145 return std::move(EmplaceRow(std::forward<Ts>(values)...));
146 }
147
148 private:
149 spanner::Mutation m_;
150};
151
152struct InsertOp {
153 static google::spanner::v1::Mutation::Write& mutable_field(
154 google::spanner::v1::Mutation& m) {
155 return *m.mutable_insert();
156 }
157};
158
159struct UpdateOp {
160 static google::spanner::v1::Mutation::Write& mutable_field(
161 google::spanner::v1::Mutation& m) {
162 return *m.mutable_update();
163 }
164};
165
166struct InsertOrUpdateOp {
167 static google::spanner::v1::Mutation::Write& mutable_field(
168 google::spanner::v1::Mutation& m) {
169 return *m.mutable_insert_or_update();
170 }
171};
172
173struct ReplaceOp {
174 static google::spanner::v1::Mutation::Write& mutable_field(
175 google::spanner::v1::Mutation& m) {
176 return *m.mutable_replace();
177 }
178};
179
180class DeleteMutationBuilder {
181 public:
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));
186 }
187
188 spanner::Mutation Build() const& { return m_; }
189 spanner::Mutation&& Build() && { return std::move(m_); }
190
191 private:
192 spanner::Mutation m_;
193};
194
195GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
196} // namespace spanner_internal
197
198namespace spanner {
199GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
200
201/**
202 * A helper class to construct "insert" mutations.
203 *
204 * @par Example
205 * @snippet samples.cc insert-mutation-builder
206 *
207 * @see The Mutation class documentation for an overview of the Cloud Spanner
208 * mutation API
209 *
210 * @see https://cloud.google.com/spanner/docs/modify-mutation-api
211 * for more information about the Cloud Spanner mutation API.
212 */
213using InsertMutationBuilder =
214 spanner_internal::WriteMutationBuilder<spanner_internal::InsertOp>;
215
216/**
217 * Creates a simple insert mutation for the values in @p values.
218 *
219 * @par Example
220 * @snippet samples.cc make-insert-mutation
221 *
222 * @see The Mutation class documentation for an overview of the Cloud Spanner
223 * mutation API
224 *
225 * @see https://cloud.google.com/spanner/docs/modify-mutation-api
226 * for more information about the Cloud Spanner mutation API.
227 */
228template <typename... Ts>
229Mutation MakeInsertMutation(std::string table_name,
230 std::vector<std::string> columns, Ts&&... values) {
231 return InsertMutationBuilder(std::move(table_name), std::move(columns))
232 .EmplaceRow(std::forward<Ts>(values)...)
233 .Build();
234}
235
236/**
237 * A helper class to construct "update" mutations.
238 *
239 * @par Example
240 * @snippet samples.cc update-mutation-builder
241 *
242 * @see The Mutation class documentation for an overview of the Cloud Spanner
243 * mutation API
244 *
245 * @see https://cloud.google.com/spanner/docs/modify-mutation-api
246 * for more information about the Cloud Spanner mutation API.
247 */
248using UpdateMutationBuilder =
249 spanner_internal::WriteMutationBuilder<spanner_internal::UpdateOp>;
250
251/**
252 * Creates a simple update mutation for the values in @p values.
253 *
254 * @par Example
255 * @snippet samples.cc make-update-mutation
256 *
257 * @see The Mutation class documentation for an overview of the Cloud Spanner
258 * mutation API
259 *
260 * @see https://cloud.google.com/spanner/docs/modify-mutation-api
261 * for more information about the Cloud Spanner mutation API.
262 */
263template <typename... Ts>
264Mutation MakeUpdateMutation(std::string table_name,
265 std::vector<std::string> columns, Ts&&... values) {
266 return UpdateMutationBuilder(std::move(table_name), std::move(columns))
267 .EmplaceRow(std::forward<Ts>(values)...)
268 .Build();
269}
270
271/**
272 * A helper class to construct "insert_or_update" mutations.
273 *
274 * @par Example
275 * @snippet samples.cc insert-or-update-mutation-builder
276 *
277 * @see The Mutation class documentation for an overview of the Cloud Spanner
278 * mutation API
279 *
280 * @see https://cloud.google.com/spanner/docs/modify-mutation-api
281 * for more information about the Cloud Spanner mutation API.
282 */
283using InsertOrUpdateMutationBuilder =
284 spanner_internal::WriteMutationBuilder<spanner_internal::InsertOrUpdateOp>;
285
286/**
287 * Creates a simple "insert or update" mutation for the values in @p values.
288 *
289 * @par Example
290 * @snippet samples.cc make-insert-or-update-mutation
291 *
292 * @see The Mutation class documentation for an overview of the Cloud Spanner
293 * mutation API
294 *
295 * @see https://cloud.google.com/spanner/docs/modify-mutation-api
296 * for more information about the Cloud Spanner mutation API.
297 */
298template <typename... Ts>
299Mutation MakeInsertOrUpdateMutation(std::string table_name,
300 std::vector<std::string> columns,
301 Ts&&... values) {
302 return InsertOrUpdateMutationBuilder(std::move(table_name),
303 std::move(columns))
304 .EmplaceRow(std::forward<Ts>(values)...)
305 .Build();
306}
307
308/**
309 * A helper class to construct "replace" mutations.
310 *
311 * @par Example
312 * @snippet samples.cc replace-mutation-builder
313 *
314 * @see The Mutation class documentation for an overview of the Cloud Spanner
315 * mutation API
316 *
317 * @see https://cloud.google.com/spanner/docs/modify-mutation-api
318 * for more information about the Cloud Spanner mutation API.
319 */
320using ReplaceMutationBuilder =
321 spanner_internal::WriteMutationBuilder<spanner_internal::ReplaceOp>;
322
323/**
324 * Creates a simple "replace" mutation for the values in @p values.
325 *
326 * @par Example
327 * @snippet samples.cc make-replace-mutation
328 *
329 * @see The Mutation class documentation for an overview of the Cloud Spanner
330 * mutation API
331 *
332 * @see https://cloud.google.com/spanner/docs/modify-mutation-api
333 * for more information about the Cloud Spanner mutation API.
334 */
335template <typename... Ts>
336Mutation MakeReplaceMutation(std::string table_name,
337 std::vector<std::string> columns, Ts&&... values) {
338 return ReplaceMutationBuilder(std::move(table_name), std::move(columns))
339 .EmplaceRow(std::forward<Ts>(values)...)
340 .Build();
341}
342
343/**
344 * A helper class to construct "delete" mutations.
345 *
346 * @par Example
347 * @snippet samples.cc delete-mutation-builder
348 *
349 * @see The Mutation class documentation for an overview of the Cloud Spanner
350 * mutation API
351 *
352 * @see https://cloud.google.com/spanner/docs/modify-mutation-api
353 * for more information about the Cloud Spanner mutation API.
354 */
355using DeleteMutationBuilder = spanner_internal::DeleteMutationBuilder;
356
357/**
358 * Creates a simple "delete" mutation for the values in @p keys.
359 *
360 * @par Example
361 * @snippet samples.cc make-delete-mutation
362 *
363 * @see The Mutation class documentation for an overview of the Cloud Spanner
364 * mutation API
365 *
366 * @see https://cloud.google.com/spanner/docs/modify-mutation-api
367 * for more information about the Cloud Spanner mutation API.
368 */
369inline Mutation MakeDeleteMutation(std::string table_name, KeySet keys) {
370 return DeleteMutationBuilder(std::move(table_name), std::move(keys)).Build();
371}
372
373GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
374} // namespace spanner
375} // namespace cloud
376} // namespace google
377
378#endif // GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_SPANNER_MUTATIONS_H
The KeySet class is a regular type that represents a collection of Keys.
Definition: keys.h:157
A wrapper for Cloud Spanner mutations.
Definition: mutations.h:52
Mutation(Mutation const &)=default
google::spanner::v1::Mutation as_proto() const &
Definition: mutations.h:73
Mutation(Mutation &&)=default
Mutation()=default
Creates an empty mutation.
friend bool operator!=(Mutation const &lhs, Mutation const &rhs)
Definition: mutations.h:67
friend void PrintTo(Mutation const &m, std::ostream *os)
Allows Google Test to print internal debugging information when test assertions fail.
Mutation & operator=(Mutation const &)=default
google::spanner::v1::Mutation as_proto() &&
Convert the mutation to the underlying proto.
Definition: mutations.h:72
friend bool operator==(Mutation const &lhs, Mutation const &rhs)
Mutation & operator=(Mutation &&)=default
The Value class represents a type-safe, nullable Spanner value.
Definition: value.h:170
Contains all the Cloud Spanner C++ client types and functions.
Definition: backoff_policy.h:23
Mutation MakeInsertMutation(std::string table_name, std::vector< std::string > columns, Ts &&... values)
Creates a simple insert mutation for the values in values.
Definition: mutations.h:229
Mutation MakeUpdateMutation(std::string table_name, std::vector< std::string > columns, Ts &&... values)
Creates a simple update mutation for the values in values.
Definition: mutations.h:264
Mutation MakeInsertOrUpdateMutation(std::string table_name, std::vector< std::string > columns, Ts &&... values)
Creates a simple "insert or update" mutation for the values in values.
Definition: mutations.h:299
Mutation MakeDeleteMutation(std::string table_name, KeySet keys)
Creates a simple "delete" mutation for the values in keys.
Definition: mutations.h:369
Mutation MakeReplaceMutation(std::string table_name, std::vector< std::string > columns, Ts &&... values)
Creates a simple "replace" mutation for the values in values.
Definition: mutations.h:336