Google Cloud Spanner C++ Client  2.4.0
A C++ Client Library for Google Cloud Spanner
client.h
Go to the documentation of this file.
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_CLIENT_H
16 #define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_SPANNER_CLIENT_H
17 
18 #include "google/cloud/spanner/batch_dml_result.h"
19 #include "google/cloud/spanner/client_options.h"
20 #include "google/cloud/spanner/commit_options.h"
21 #include "google/cloud/spanner/commit_result.h"
22 #include "google/cloud/spanner/connection.h"
23 #include "google/cloud/spanner/connection_options.h"
24 #include "google/cloud/spanner/database.h"
25 #include "google/cloud/spanner/internal/defaults.h"
26 #include "google/cloud/spanner/keys.h"
27 #include "google/cloud/spanner/mutations.h"
28 #include "google/cloud/spanner/partition_options.h"
29 #include "google/cloud/spanner/query_options.h"
30 #include "google/cloud/spanner/query_partition.h"
31 #include "google/cloud/spanner/read_options.h"
32 #include "google/cloud/spanner/read_partition.h"
33 #include "google/cloud/spanner/results.h"
34 #include "google/cloud/spanner/retry_policy.h"
35 #include "google/cloud/spanner/session_pool_options.h"
36 #include "google/cloud/spanner/sql_statement.h"
37 #include "google/cloud/spanner/transaction.h"
38 #include "google/cloud/spanner/version.h"
39 #include "google/cloud/backoff_policy.h"
40 #include "google/cloud/internal/non_constructible.h"
41 #include "google/cloud/options.h"
42 #include "google/cloud/status.h"
43 #include "google/cloud/status_or.h"
44 #include <google/spanner/v1/spanner.pb.h>
45 #include <grpcpp/grpcpp.h>
46 #include <functional>
47 #include <initializer_list>
48 #include <memory>
49 #include <string>
50 #include <vector>
51 
52 namespace google {
53 namespace cloud {
54 namespace spanner {
56 
57 // clang-format off
58 /**
59  * Performs database client operations on Spanner.
60  *
61  * Applications use this class to perform operations on
62  * [Spanner Databases][spanner-doc-link].
63  *
64  * @par Performance
65  *
66  * `Client` objects are relatively cheap to create, copy, and move. However,
67  * each `Client` object must be created with a `std::shared_ptr<Connection>`,
68  * which itself is relatively expensive to create. Therefore, connection
69  * instances should be shared when possible. See the `MakeConnection()` method
70  * and the `Connection` interface for more details.
71  *
72  * @par Thread Safety
73  *
74  * Instances of this class created via copy-construction or copy-assignment
75  * share the underlying pool of connections. Access to these copies via multiple
76  * threads is guaranteed to work. Two threads operating on the same instance of
77  * this class is not guaranteed to work.
78  *
79  * @par Error Handling
80  *
81  * This class uses `StatusOr<T>` to report errors. When an operation fails to
82  * perform its work the returned `StatusOr<T>` contains the error details. If
83  * the `ok()` member function in the `StatusOr<T>` returns `true` then it
84  * contains the expected result. Please consult the
85  * [`StatusOr<T>` documentation](#google::cloud::v0::StatusOr) for more details.
86  *
87  * @code
88  * namespace spanner = ::google::cloud::spanner;
89  *
90  * auto db = spanner::Database("my_project", "my_instance", "my_db_id"));
91  * auto conn = spanner::MakeConnection(db);
92  * auto client = spanner::Client(conn);
93  *
94  * auto rows = client.Read(...);
95  * using RowType = std::tuple<std::int64_t, std::string>;
96  * for (auto const& row : spanner::StreamOf<RowType>(rows)) {
97  * // ...
98  * }
99  * @endcode
100  *
101  * @par Query Options
102  *
103  * Most operations that take an `SqlStatement` may also be modified with
104  * query `Options`. These options can be set at various levels, with more
105  * specific levels taking precedence over broader ones. For example,
106  * `Options` that are passed directly to `Client::ExecuteQuery()` will
107  * take precedence over the `Client`-level defaults (if any), which will
108  * themselves take precedence over any environment variables. The following
109  * table shows the environment variables that may optionally be set and the
110  * query `Options` setting that they affect.
111  *
112  * Environment Variable | Options setting
113  * -------------------------------------- | --------------------
114  * `SPANNER_OPTIMIZER_VERSION` | `QueryOptimizerVersionOption`
115  * `SPANNER_OPTIMIZER_STATISTICS_PACKAGE` | `QueryOptimizerStatisticsPackageOption`
116  *
117  * @see https://cloud.google.com/spanner/docs/reference/rest/v1/QueryOptions
118  * @see http://cloud/spanner/docs/query-optimizer/manage-query-optimizer
119  *
120  * [spanner-doc-link]:
121  * https://cloud.google.com/spanner/docs/api-libraries-overview
122  */
123 // clang-format on
124 class Client {
125  public:
126  /**
127  * Constructs a `Client` object using the specified @p conn and @p opts.
128  *
129  * See `MakeConnection()` for how to create a connection to Spanner. To help
130  * with unit testing, callers may create fake/mock `Connection` objects that
131  * are injected into the `Client`.
132  */
133  explicit Client(std::shared_ptr<Connection> conn, Options opts = {})
134  : conn_(std::move(conn)),
135  opts_(internal::MergeOptions(std::move(opts), conn_->options())) {}
136 
137  /// @name Backwards compatibility for `ClientOptions`.
138  ///@{
139  explicit Client(std::shared_ptr<Connection> conn, ClientOptions const& opts)
140  : Client(std::move(conn), Options(opts)) {}
141  explicit Client(std::shared_ptr<Connection> conn,
142  std::initializer_list<internal::NonConstructible>)
143  : Client(std::move(conn)) {}
144  ///@}
145 
146  /// No default construction.
147  Client() = delete;
148 
149  //@{
150  // @name Copy and move support
151  Client(Client const&) = default;
152  Client& operator=(Client const&) = default;
153  Client(Client&&) = default;
154  Client& operator=(Client&&) = default;
155  //@}
156 
157  //@{
158  // @name Equality
159  friend bool operator==(Client const& a, Client const& b) {
160  return a.conn_ == b.conn_;
161  }
162  friend bool operator!=(Client const& a, Client const& b) { return !(a == b); }
163  //@}
164 
165  //@{
166  /**
167  * Reads rows from the database using key lookups and scans, as a simple
168  * key/value style alternative to `ExecuteQuery()`.
169  *
170  * Callers can optionally supply a `Transaction` or
171  * `Transaction::SingleUseOptions` used to create a single-use transaction -
172  * or neither, in which case a single-use transaction with default options
173  * is used.
174  *
175  * @param table The name of the table in the database to be read.
176  * @param keys Identifies the rows to be yielded. If `read_options.index_name`
177  * is set, names keys in that index; otherwise names keys in the primary
178  * index of `table`. It is not an error for `keys` to name rows that do
179  * not exist in the database; `Read` yields nothing for nonexistent rows.
180  * @param columns The columns of `table` to be returned for each row matching
181  * this request.
182  * @param opts `Options` used for this request.
183  *
184  * @par Example
185  * @snippet samples.cc read-data
186  *
187  * @note No individual row in the `ReadResult` can exceed 100 MiB, and no
188  * column value can exceed 10 MiB.
189  */
190  RowStream Read(std::string table, KeySet keys,
191  std::vector<std::string> columns, Options opts = {});
192 
193  /**
194  * @copydoc Read
195  *
196  * @param transaction_options Execute this read in a single-use transaction
197  * with these options.
198  */
200  std::string table, KeySet keys,
201  std::vector<std::string> columns, Options opts = {});
202 
203  /**
204  * @copydoc Read
205  *
206  * @param transaction Execute this read as part of an existing transaction.
207  */
208  RowStream Read(Transaction transaction, std::string table, KeySet keys,
209  std::vector<std::string> columns, Options opts = {});
210  //@}
211 
212  /// @name Backwards compatibility for `ReadOptions`.
213  ///@{
214  RowStream Read(std::string table, KeySet keys,
215  std::vector<std::string> columns,
216  ReadOptions const& read_options) {
217  return Read(std::move(table), std::move(keys), std::move(columns),
218  ToOptions(read_options));
219  }
220  RowStream Read(std::string table, KeySet keys,
221  std::vector<std::string> columns,
222  std::initializer_list<internal::NonConstructible>) {
223  return Read(std::move(table), std::move(keys), std::move(columns));
224  }
226  std::string table, KeySet keys,
227  std::vector<std::string> columns,
228  ReadOptions const& read_options) {
229  return Read(std::move(transaction_options), std::move(table),
230  std::move(keys), std::move(columns), ToOptions(read_options));
231  }
233  std::string table, KeySet keys,
234  std::vector<std::string> columns,
235  std::initializer_list<internal::NonConstructible>) {
236  return Read(std::move(transaction_options), std::move(table),
237  std::move(keys), std::move(columns));
238  }
239  RowStream Read(Transaction transaction, std::string table, KeySet keys,
240  std::vector<std::string> columns,
241  ReadOptions const& read_options) {
242  return Read(std::move(transaction), std::move(table), std::move(keys),
243  std::move(columns), ToOptions(read_options));
244  }
245  RowStream Read(Transaction transaction, std::string table, KeySet keys,
246  std::vector<std::string> columns,
247  std::initializer_list<internal::NonConstructible>) {
248  return Read(std::move(transaction), std::move(table), std::move(keys),
249  std::move(columns));
250  }
251  ///@}
252 
253  /**
254  * Reads rows from a subset of rows in a database. Requires a prior call
255  * to `PartitionRead` to obtain the partition information; see the
256  * documentation of that method for full details.
257  *
258  * @param partition A `ReadPartition`, obtained by calling `PartitionRead`.
259  * @param opts `Options` used for this request.
260  *
261  * @note No individual row in the `ReadResult` can exceed 100 MiB, and no
262  * column value can exceed 10 MiB.
263  *
264  * @par Example
265  * @snippet samples.cc read-read-partition
266  */
267  RowStream Read(ReadPartition const& partition, Options opts = {});
268 
269  /**
270  * Creates a set of partitions that can be used to execute a read
271  * operation in parallel. Each of the returned partitions can be passed
272  * to `Read` to specify a subset of the read result to read.
273  *
274  * There are no ordering guarantees on rows returned among the returned
275  * partition, or even within each individual `Read` call issued with a given
276  * partition.
277  *
278  * Partitions become invalid when the session used to create them is deleted,
279  * is idle for too long, begins a new transaction, or becomes too old. When
280  * any of these happen, it is not possible to resume the read, and the whole
281  * operation must be restarted from the beginning.
282  *
283  * @param transaction The transaction to execute the operation in.
284  * **Must** be a read-only snapshot transaction.
285  * @param table The name of the table in the database to be read.
286  * @param keys Identifies the rows to be yielded. If `read_options.index_name`
287  * is set, names keys in that index; otherwise names keys in the primary
288  * index of `table`. It is not an error for `keys` to name rows that do
289  * not exist in the database; `Read` yields nothing for nonexistent rows.
290  * @param columns The columns of `table` to be returned for each row matching
291  * this request.
292  * @param opts `Options` used for this request.
293  *
294  * @return A `StatusOr` containing a vector of `ReadPartition` or error
295  * status on failure.
296  *
297  * @par Example
298  * @snippet samples.cc partition-read
299  */
300  StatusOr<std::vector<ReadPartition>> PartitionRead(
301  Transaction transaction, std::string table, KeySet keys,
302  std::vector<std::string> columns, Options opts = {});
303 
304  /// @name Backwards compatibility for `ReadOptions` and `PartitionOptions`.
305  ///@{
306  StatusOr<std::vector<ReadPartition>> PartitionRead(
307  Transaction transaction, std::string table, KeySet keys,
308  std::vector<std::string> columns, ReadOptions const& read_options,
309  PartitionOptions const& partition_options) {
310  return PartitionRead(std::move(transaction), std::move(table),
311  std::move(keys), std::move(columns),
312  internal::MergeOptions(ToOptions(read_options),
313  ToOptions(partition_options)));
314  }
315  StatusOr<std::vector<ReadPartition>> PartitionRead(
316  Transaction transaction, std::string table, KeySet keys,
317  std::vector<std::string> columns,
318  std::initializer_list<internal::NonConstructible>) {
319  return PartitionRead(std::move(transaction), std::move(table),
320  std::move(keys), std::move(columns));
321  }
322  ///@}
323 
324  //@{
325  /**
326  * Executes a SQL query.
327  *
328  * Operations inside read-write transactions might return `ABORTED`. If this
329  * occurs, the application should restart the transaction from the beginning.
330  *
331  * Callers can optionally supply a `Transaction` or
332  * `Transaction::SingleUseOptions` used to create a single-use transaction -
333  * or neither, in which case a single-use transaction with default options
334  * is used.
335  *
336  * `SELECT * ...` queries are supported, but there's no guarantee about the
337  * order, nor number, of returned columns. Therefore, the caller must look up
338  * the wanted values in each row by column name. When the desired column
339  * names are known in advance, it is better to list them explicitly in the
340  * query's SELECT statement, so that unnecessary values are not
341  * returned/ignored, and the column order is known. This enables more
342  * efficient and simpler code.
343  *
344  * @par Example with explicitly selected columns.
345  * @snippet samples.cc spanner-query-data
346  *
347  * @par Example using SELECT *
348  * @snippet samples.cc spanner-query-data-select-star
349  *
350  * @param statement The SQL statement to execute.
351  * @param opts (optional) The `Options` to use for this call. If given,
352  * these will take precedence over the options set at the client and
353  * environment levels.
354  *
355  * @note No individual row in the `RowStream` can exceed 100 MiB, and no
356  * column value can exceed 10 MiB.
357  */
359 
360  /**
361  * @copydoc ExecuteQuery(SqlStatement, Options)
362  *
363  * @param transaction_options Execute this query in a single-use transaction
364  * with these options.
365  */
367  SqlStatement statement, Options opts = {});
368 
369  /**
370  * @copydoc ExecuteQuery(SqlStatement, Options)
371  *
372  * @param transaction Execute this query as part of an existing transaction.
373  */
375  Options opts = {});
376 
377  /**
378  * Executes a SQL query on a subset of rows in a database. Requires a prior
379  * call to `PartitionQuery` to obtain the partition information; see the
380  * documentation of that method for full details.
381  *
382  * @param partition A `QueryPartition`, obtained by calling `PartitionQuery`.
383  * @param opts (optional) The `Options` to use for this call. If given,
384  * these will take precedence over the options set at the client and
385  * environment levels.
386  *
387  * @note No individual row in the `RowStream` can exceed 100 MiB, and no
388  * column value can exceed 10 MiB.
389  *
390  * @par Example
391  * @snippet samples.cc execute-sql-query-partition
392  */
393  RowStream ExecuteQuery(QueryPartition const& partition, Options opts = {});
394  //@}
395 
396  /// @name Backwards compatibility for `QueryOptions`.
397  ///@{
399  return ExecuteQuery(std::move(statement), Options(opts));
400  }
402  std::initializer_list<internal::NonConstructible>) {
403  return ExecuteQuery(std::move(statement));
404  }
406  SqlStatement statement, QueryOptions const& opts) {
407  return ExecuteQuery(std::move(transaction_options), std::move(statement),
408  Options(opts));
409  }
411  SqlStatement statement,
412  std::initializer_list<internal::NonConstructible>) {
413  return ExecuteQuery(std::move(transaction_options), std::move(statement));
414  }
416  QueryOptions const& opts) {
417  return ExecuteQuery(std::move(transaction), std::move(statement),
418  Options(opts));
419  }
421  std::initializer_list<internal::NonConstructible>) {
422  return ExecuteQuery(std::move(transaction), std::move(statement));
423  }
425  QueryOptions const& opts) {
426  return ExecuteQuery(partition, Options(opts));
427  }
429  std::initializer_list<internal::NonConstructible>) {
430  return ExecuteQuery(partition);
431  }
432  ///@}
433 
434  //@{
435  /**
436  * Profiles a SQL query.
437  *
438  * Profiling executes the query, provides the resulting rows, `ExecutionPlan`,
439  * and execution statistics.
440  *
441  * Operations inside read-write transactions might return `kAborted`. If this
442  * occurs, the application should restart the transaction from the beginning.
443  *
444  * Callers can optionally supply a `Transaction` or
445  * `Transaction::SingleUseOptions` used to create a single-use transaction -
446  * or neither, in which case a single-use transaction with default options
447  * is used.
448  *
449  * @note Callers must consume all rows from the result before execution
450  * statistics and `ExecutionPlan` are available.
451  *
452  * @param statement The SQL statement to execute.
453  * @param opts (optional) The `Options` to use for this call. If given,
454  * these will take precedence over the options set at the client and
455  * environment levels.
456  *
457  * @note No individual row in the `ProfileQueryResult` can exceed 100 MiB, and
458  * no column value can exceed 10 MiB.
459  *
460  * @par Example
461  * @snippet samples.cc profile-query
462  */
464 
465  /**
466  * @copydoc ProfileQuery(SqlStatement, Options)
467  *
468  * @param transaction_options Execute this query in a single-use transaction
469  * with these options.
470  */
472  Transaction::SingleUseOptions transaction_options, SqlStatement statement,
473  Options opts = {});
474 
475  /**
476  * @copydoc ProfileQuery(SqlStatement, Options)
477  *
478  * @param transaction Execute this query as part of an existing transaction.
479  */
481  SqlStatement statement, Options opts = {});
482  //@}
483 
484  /// @name Backwards compatibility for `QueryOptions`.
485  ///@{
487  QueryOptions const& opts) {
488  return ProfileQuery(std::move(statement), Options(opts));
489  }
491  SqlStatement statement,
492  std::initializer_list<internal::NonConstructible>) {
493  return ProfileQuery(std::move(statement));
494  }
496  Transaction::SingleUseOptions transaction_options, SqlStatement statement,
497  QueryOptions const& opts) {
498  return ProfileQuery(std::move(transaction_options), std::move(statement),
499  Options(opts));
500  }
502  Transaction::SingleUseOptions transaction_options, SqlStatement statement,
503  std::initializer_list<internal::NonConstructible>) {
504  return ProfileQuery(std::move(transaction_options), std::move(statement));
505  }
507  SqlStatement statement,
508  QueryOptions const& opts) {
509  return ProfileQuery(std::move(transaction), std::move(statement),
510  Options(opts));
511  }
513  Transaction transaction, SqlStatement statement,
514  std::initializer_list<internal::NonConstructible>) {
515  return ProfileQuery(std::move(transaction), std::move(statement));
516  }
517  ///@}
518 
519  /**
520  * Creates a set of partitions that can be used to execute a query
521  * operation in parallel. Each of the returned partitions can be passed
522  * to `ExecuteQuery` to specify a subset of the query result to read.
523  *
524  * Partitions become invalid when the session used to create them is deleted,
525  * is idle for too long, begins a new transaction, or becomes too old. When
526  * any of these happen, it is not possible to resume the query, and the whole
527  * operation must be restarted from the beginning.
528  *
529  * @param transaction The transaction to execute the operation in.
530  * **Must** be a read-only snapshot transaction.
531  * @param statement The SQL statement to execute.
532  * @param opts `Options` used for this request.
533  *
534  * @return A `StatusOr` containing a vector of `QueryPartition`s or error
535  * status on failure.
536  *
537  * @par Example
538  * @snippet samples.cc partition-query
539  */
540  StatusOr<std::vector<QueryPartition>> PartitionQuery(
541  Transaction transaction, SqlStatement statement,
542  Options opts = Options{});
543 
544  /// @name Backwards compatibility for `PartitionOptions`.
545  ///@{
546  StatusOr<std::vector<QueryPartition>> PartitionQuery(
547  Transaction transaction, SqlStatement statement,
548  PartitionOptions const& partition_options) {
549  return PartitionQuery(std::move(transaction), std::move(statement),
550  ToOptions(partition_options));
551  }
552  StatusOr<std::vector<QueryPartition>> PartitionQuery(
553  Transaction transaction, SqlStatement statement,
554  std::initializer_list<internal::NonConstructible>) {
555  return PartitionQuery(std::move(transaction), std::move(statement));
556  }
557  ///@}
558 
559  /**
560  * Executes a SQL DML statement.
561  *
562  * Operations inside read-write transactions might return `ABORTED`. If this
563  * occurs, the application should restart the transaction from the beginning.
564  *
565  * @note Single-use transactions are not supported with DML statements.
566  *
567  * @param transaction Execute this query as part of an existing transaction.
568  * @param statement The SQL statement to execute.
569  * @param opts (optional) The `Options` to use for this call. If given,
570  * these will take precedence over the options set at the client and
571  * environment levels.
572  *
573  * @par Example
574  * @snippet samples.cc execute-dml
575  */
576  StatusOr<DmlResult> ExecuteDml(Transaction transaction,
577  SqlStatement statement, Options opts = {});
578 
579  /// @name Backwards compatibility for `QueryOptions`.
580  ///@{
581  StatusOr<DmlResult> ExecuteDml(Transaction transaction,
582  SqlStatement statement,
583  QueryOptions const& opts) {
584  return ExecuteDml(std::move(transaction), std::move(statement),
585  Options(opts));
586  }
588  Transaction transaction, SqlStatement statement,
589  std::initializer_list<internal::NonConstructible>) {
590  return ExecuteDml(std::move(transaction), std::move(statement));
591  }
592  ///@}
593 
594  /**
595  * Profiles a SQL DML statement.
596  *
597  * Profiling executes the DML statement, provides the modified row count,
598  * `ExecutionPlan`, and execution statistics.
599  *
600  * Operations inside read-write transactions might return `ABORTED`. If this
601  * occurs, the application should restart the transaction from the beginning.
602  *
603  * @note Single-use transactions are not supported with DML statements.
604  *
605  * @param transaction Execute this query as part of an existing transaction.
606  * @param statement The SQL statement to execute.
607  * @param opts (optional) The `Options` to use for this call. If given,
608  * these will take precedence over the options set at the client and
609  * environment levels.
610  *
611  * @par Example:
612  * @snippet samples.cc profile-dml
613  */
614  StatusOr<ProfileDmlResult> ProfileDml(Transaction transaction,
615  SqlStatement statement,
616  Options opts = {});
617 
618  /// @name Backwards compatibility for `QueryOptions`.
619  ///@{
620  StatusOr<ProfileDmlResult> ProfileDml(Transaction transaction,
621  SqlStatement statement,
622  QueryOptions const& opts) {
623  return ProfileDml(std::move(transaction), std::move(statement),
624  Options(opts));
625  }
627  Transaction transaction, SqlStatement statement,
628  std::initializer_list<internal::NonConstructible>) {
629  return ProfileDml(std::move(transaction), std::move(statement));
630  }
631  ///@}
632 
633  /**
634  * Analyzes the execution plan of a SQL statement.
635  *
636  * Analyzing provides the `ExecutionPlan`, but does not execute the SQL
637  * statement.
638  *
639  * Operations inside read-write transactions might return `ABORTED`. If this
640  * occurs, the application should restart the transaction from the beginning.
641  *
642  * @note Single-use transactions are not supported with DML statements.
643  *
644  * @param transaction Execute this query as part of an existing transaction.
645  * @param statement The SQL statement to execute.
646  * @param opts (optional) The `Options` to use for this call. If given,
647  * these will take precedence over the options set at the client and
648  * environment levels.
649  *
650  * @par Example:
651  * @snippet samples.cc analyze-query
652  */
653  StatusOr<ExecutionPlan> AnalyzeSql(Transaction transaction,
654  SqlStatement statement, Options opts = {});
655 
656  /// @name Backwards compatibility for `QueryOptions`.
657  ///@{
658  StatusOr<ExecutionPlan> AnalyzeSql(Transaction transaction,
659  SqlStatement statement,
660  QueryOptions const& opts) {
661  return AnalyzeSql(std::move(transaction), std::move(statement),
662  Options(opts));
663  }
664  StatusOr<ExecutionPlan> AnalyzeSql(
665  Transaction transaction, SqlStatement statement,
666  std::initializer_list<internal::NonConstructible>) {
667  return AnalyzeSql(std::move(transaction), std::move(statement));
668  }
669  ///@}
670 
671  /**
672  * Executes a batch of SQL DML statements. This method allows many statements
673  * to be run with lower latency than submitting them sequentially with
674  * `ExecuteDml`.
675  *
676  * Statements are executed in order, sequentially. Execution will stop at the
677  * first failed statement; the remaining statements will not run.
678  *
679  * As with all read-write transactions, the results will not be visible
680  * outside of the transaction until it is committed. For that reason, it is
681  * advisable to run this method from a `Commit` mutator.
682  *
683  * @warning A returned status of OK from this function does not imply that
684  * all the statements were executed successfully. For that, you need to
685  * inspect the `BatchDmlResult::status` field.
686  *
687  * @param transaction The read-write transaction to execute the operation in.
688  * @param statements The list of statements to execute in this batch.
689  * Statements are executed serially, such that the effects of statement i
690  * are visible to statement i+1. Each statement must be a DML statement.
691  * Execution will stop at the first failed statement; the remaining
692  * statements will not run. Must not be empty.
693  * @param opts (optional) The options to use for this call. Expected options
694  * are any of the types in the following option lists.
695  * - `google::cloud::RequestOptionList`
696  *
697  * @par Example
698  * @snippet samples.cc execute-batch-dml
699  */
701  std::vector<SqlStatement> statements,
702  Options opts = {});
703 
704  /**
705  * Commits a read-write transaction.
706  *
707  * Calls the @p mutator in the context of a new read-write transaction.
708  * The @p mutator can execute read/write operations using the transaction,
709  * and returns any additional `Mutations` to commit.
710  *
711  * If the @p mutator succeeds and the transaction commits, then `Commit()`
712  * returns the `CommitResult`.
713  *
714  * If the @p mutator returns a non-rerunnable status (according to the
715  * @p rerun_policy), the transaction is rolled back and that status is
716  * returned. Similarly, if the transaction fails to commit with a non-
717  * rerunnable status, that status is returned.
718  *
719  * Otherwise the whole process repeats (subject to @p rerun_policy and
720  * @p backoff_policy), by building a new transaction and re-running the
721  * @p mutator. The lock priority of the operation increases after each
722  * rerun, meaning that the next attempt has a slightly better chance of
723  * success.
724  *
725  * Note that the @p mutator should only return a rerunnable status when
726  * the transaction is no longer usable (e.g., it was aborted). Otherwise
727  * the transaction will be leaked.
728  *
729  * @param mutator the function called to create mutations
730  * @param rerun_policy controls for how long (or how many times) the mutator
731  * will be rerun after the transaction aborts.
732  * @param backoff_policy controls how long `Commit` waits between reruns.
733  * @param opts (optional) The options to use for this call. Expected options
734  * include any of the following types:
735  * - `google::cloud::spanner::CommitReturnStatsOption`
736  * - `google::cloud::spanner::RequestPriorityOption`
737  * - `google::cloud::spanner::TransactionTagOption`
738  *
739  * @throw Rethrows any exception thrown by @p `mutator` (after rolling back
740  * the transaction). However, a `RuntimeStatusError` exception is
741  * instead consumed and converted into a `mutator` return value of the
742  * enclosed `Status`.
743  *
744  * @par Example
745  * @snippet samples.cc commit-with-policies
746  */
747  StatusOr<CommitResult> Commit(
748  std::function<StatusOr<Mutations>(Transaction)> const& mutator,
749  std::unique_ptr<TransactionRerunPolicy> rerun_policy,
750  std::unique_ptr<BackoffPolicy> backoff_policy, Options opts = {});
751 
752  /// @name Backwards compatibility for `CommitOptions`.
753  ///@{
754  StatusOr<CommitResult> Commit(
755  std::function<StatusOr<Mutations>(Transaction)> const& mutator,
756  std::unique_ptr<TransactionRerunPolicy> rerun_policy,
757  std::unique_ptr<BackoffPolicy> backoff_policy,
758  CommitOptions const& commit_options) {
759  return Commit(mutator, std::move(rerun_policy), std::move(backoff_policy),
760  Options(commit_options));
761  }
762  StatusOr<CommitResult> Commit(
763  std::function<StatusOr<Mutations>(Transaction)> const& mutator,
764  std::unique_ptr<TransactionRerunPolicy> rerun_policy,
765  std::unique_ptr<BackoffPolicy> backoff_policy,
766  std::initializer_list<internal::NonConstructible>) {
767  return Commit(mutator, std::move(rerun_policy), std::move(backoff_policy));
768  }
769  ///@}
770 
771  /**
772  * Commits a read-write transaction.
773  *
774  * Same as above, but uses the default rerun and backoff policies.
775  *
776  * @param mutator the function called to create mutations
777  * @param opts (optional) The options to use for this call.
778  *
779  * @par Example
780  * @snippet samples.cc commit-with-mutator
781  */
782  StatusOr<CommitResult> Commit(
783  std::function<StatusOr<Mutations>(Transaction)> const& mutator,
784  Options opts = {});
785 
786  /// @name Backwards compatibility for `CommitOptions`.
787  ///@{
788  StatusOr<CommitResult> Commit(
789  std::function<StatusOr<Mutations>(Transaction)> const& mutator,
790  CommitOptions const& commit_options) {
791  return Commit(mutator, Options(commit_options));
792  }
793  StatusOr<CommitResult> Commit(
794  std::function<StatusOr<Mutations>(Transaction)> const& mutator,
795  std::initializer_list<internal::NonConstructible>) {
796  return Commit(mutator);
797  }
798  ///@}
799 
800  /**
801  * Commits the @p mutations, using the @p options, atomically in order.
802  *
803  * This function uses the re-run loop described above with the default
804  * policies.
805  *
806  * @par Example
807  * @snippet samples.cc commit-with-mutations
808  */
809  StatusOr<CommitResult> Commit(Mutations mutations, Options opts = {});
810 
811  /// @name Backwards compatibility for `CommitOptions`.
812  ///@{
813  StatusOr<CommitResult> Commit(Mutations mutations,
814  CommitOptions const& commit_options) {
815  return Commit(std::move(mutations), Options(commit_options));
816  }
817  StatusOr<CommitResult> Commit(
818  Mutations mutations, std::initializer_list<internal::NonConstructible>) {
819  return Commit(std::move(mutations));
820  }
821  ///@}
822 
823  /**
824  * Commits a read-write transaction.
825  *
826  * The commit might return a `kAborted` error. This can occur at any time.
827  * Commonly the cause is conflicts with concurrent transactions, however
828  * it can also happen for a variety of other reasons. If `Commit` returns
829  * `kAborted`, the caller may try to reapply the mutations within a new
830  * read-write transaction (which should share lock priority with the aborted
831  * transaction so that the new attempt has a slightly better chance of
832  * success).
833  *
834  * @note Prefer the previous `Commit` overloads if you want to simply reapply
835  * mutations after a `kAborted` error.
836  *
837  * @warning It is an error to call `Commit` with a read-only transaction.
838  *
839  * @param transaction The transaction to commit.
840  * @param mutations The mutations to be executed when this transaction
841  * commits. All mutations are applied atomically, in the order they appear
842  * in this list.
843  * @param opts (optional) The options to use for this call.
844  *
845  * @return A `StatusOr` containing the result of the commit or error status
846  * on failure.
847  */
848  StatusOr<CommitResult> Commit(Transaction transaction, Mutations mutations,
849  Options opts = {});
850 
851  /// @name Backwards compatibility for `CommitOptions`.
852  ///@{
853  StatusOr<CommitResult> Commit(Transaction transaction, Mutations mutations,
854  CommitOptions const& commit_options) {
855  return Commit(std::move(transaction), std::move(mutations),
856  Options(commit_options));
857  }
858  StatusOr<CommitResult> Commit(
859  Transaction transaction, Mutations mutations,
860  std::initializer_list<internal::NonConstructible>) {
861  return Commit(std::move(transaction), std::move(mutations));
862  }
863  ///@}
864 
865  /**
866  * Rolls back a read-write transaction, releasing any locks it holds.
867  *
868  * At any time before `Commit`, the client can call `Rollback` to abort the
869  * transaction. It is a good idea to call this for any read-write transaction
870  * that includes one or more `Read`, `ExecuteQuery`, or `ExecuteDml` requests
871  * and ultimately decides not to commit.
872  *
873  * @warning It is an error to call `Rollback` with a read-only transaction.
874  *
875  * @param transaction The transaction to roll back.
876  * @param opts (optional) The options to use for this call.
877  *
878  * @return The error status of the rollback.
879  */
880  Status Rollback(Transaction transaction, Options opts = {});
881 
882  /**
883  * Executes a Partitioned DML SQL query.
884  *
885  * @param statement the SQL statement to execute. Please see the
886  * [spanner documentation][dml-partitioned] for the restrictions on the
887  * SQL statements supported by this function.
888  * @param opts (optional) The `Options` to use for this call. If given,
889  * these will take precedence over the options set at the client and
890  * environment levels.
891  *
892  * @par Example
893  * @snippet samples.cc execute-sql-partitioned
894  *
895  * @see [Partitioned DML Transactions][txn-partitioned] for an overview of
896  * Partitioned DML transactions.
897  * @see [Partitioned DML][dml-partitioned] for a description of which SQL
898  * statements are supported in Partitioned DML transactions.
899  * [txn-partitioned]:
900  * https://cloud.google.com/spanner/docs/transactions#partitioned_dml_transactions
901  * [dml-partitioned]: https://cloud.google.com/spanner/docs/dml-partitioned
902  */
904  Options opts = {});
905 
906  /// @name Backwards compatibility for `QueryOptions`.
907  ///@{
909  SqlStatement statement, QueryOptions const& opts) {
910  return ExecutePartitionedDml(std::move(statement), Options(opts));
911  }
913  SqlStatement statement,
914  std::initializer_list<internal::NonConstructible>) {
915  return ExecutePartitionedDml(std::move(statement));
916  }
917  ///@}
918 
919  private:
920  std::shared_ptr<Connection> conn_;
921  Options opts_;
922 };
923 
924 /**
925  * Returns a Connection object that can be used for interacting with Spanner.
926  *
927  * The returned connection object should not be used directly; instead it
928  * should be given to a `Client` instance, and methods should be invoked on
929  * `Client`.
930  *
931  * The optional @p opts argument may be used to configure aspects of the
932  * returned `Connection`. Expected options are any of the types in the
933  * following option lists.
934  *
935  * - `google::cloud::CommonOptionList`
936  * - `google::cloud::GrpcOptionList`
937  * - `google::cloud::spanner::SpannerPolicyOptionList`
938  * - `google::cloud::spanner::SessionPoolOptionList`
939  *
940  * @note Unrecognized options will be ignored. To debug issues with options set
941  * `GOOGLE_CLOUD_CPP_ENABLE_CLOG=yes` in the environment and unexpected
942  * options will be logged.
943  *
944  * @see `Connection`
945  *
946  * @param db See `Database`.
947  * @param opts (optional) Configure the `Connection` created by this function.
948  */
949 std::shared_ptr<spanner::Connection> MakeConnection(spanner::Database const& db,
950  Options opts = {});
951 
952 /**
953  * Returns a Connection object that can be used for interacting with Spanner.
954  *
955  * The returned connection object should not be used directly, rather it should
956  * be given to a `Client` instance, and methods should be invoked on `Client`.
957  *
958  * @note Prefer using the `MakeConnection()` overload that accepts
959  * `google::cloud::Options`.
960  *
961  * @see `Connection`
962  *
963  * @param db See `Database`.
964  * @param connection_options configure the `Connection` created by this
965  * function.
966  * @param session_pool_options (optional) configure the `SessionPool` created
967  * by the `Connection`.
968  */
969 std::shared_ptr<Connection> MakeConnection(
970  Database const& db, ConnectionOptions const& connection_options,
971  SessionPoolOptions session_pool_options = SessionPoolOptions());
972 
973 /**
974  * @copydoc MakeConnection(Database const&, ConnectionOptions const&, SessionPoolOptions)
975  *
976  * @note Prefer using the `MakeConnection()` overload that accepts
977  * `google::cloud::Options`.
978  *
979  * @param retry_policy override the default `RetryPolicy`, controls how long
980  * the returned `Connection` object retries requests on transient
981  * failures.
982  * @param backoff_policy override the default `BackoffPolicy`, controls how
983  * long the `Connection` object waits before retrying a failed request.
984  *
985  * @par Example
986  * @snippet samples.cc custom-retry-policy
987  */
988 std::shared_ptr<Connection> MakeConnection(
989  Database const& db, ConnectionOptions const& connection_options,
990  SessionPoolOptions session_pool_options,
991  std::unique_ptr<RetryPolicy> retry_policy,
992  std::unique_ptr<BackoffPolicy> backoff_policy);
993 
995 } // namespace spanner
996 } // namespace cloud
997 } // namespace google
998 
999 #endif // GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_SPANNER_CLIENT_H