Google Cloud Spanner C++ Client
A C++ Client Library for Google Cloud Spanner
database_admin_connection.cc
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 // http://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 
16 #include "google/cloud/spanner/internal/polling_loop.h"
17 #include "google/cloud/spanner/internal/retry_loop.h"
18 #include "google/cloud/spanner/internal/time_utils.h"
19 #include <chrono>
20 
21 namespace google {
22 namespace cloud {
23 namespace spanner {
24 inline namespace SPANNER_CLIENT_NS {
25 namespace gcsa = ::google::spanner::admin::database::v1;
26 
27 future<StatusOr<google::spanner::admin::database::v1::Backup>>
28 // NOLINTNEXTLINE(performance-unnecessary-value-param)
29 DatabaseAdminConnection::CreateBackup(CreateBackupParams) {
30  return google::cloud::make_ready_future(StatusOr<gcsa::Backup>(
31  Status(StatusCode::kUnimplemented, "not implemented")));
32 }
33 
34 future<StatusOr<google::spanner::admin::database::v1::Database>>
35 // NOLINTNEXTLINE(performance-unnecessary-value-param)
36 DatabaseAdminConnection::RestoreDatabase(RestoreDatabaseParams) {
37  return google::cloud::make_ready_future(StatusOr<gcsa::Database>(
38  Status(StatusCode::kUnimplemented, "not implemented")));
39 }
40 
41 StatusOr<google::spanner::admin::database::v1::Backup>
42 // NOLINTNEXTLINE(performance-unnecessary-value-param)
43 DatabaseAdminConnection::GetBackup(GetBackupParams) {
44  return Status(StatusCode::kUnimplemented, "not implemented");
45 }
46 
47 // NOLINTNEXTLINE(performance-unnecessary-value-param)
48 Status DatabaseAdminConnection::DeleteBackup(DeleteBackupParams) {
49  return Status(StatusCode::kUnimplemented, "not implemented");
50 }
51 
52 // NOLINTNEXTLINE(performance-unnecessary-value-param)
53 ListBackupsRange DatabaseAdminConnection::ListBackups(ListBackupsParams) {
54  return ListBackupsRange(
55  gcsa::ListBackupsRequest{},
56  [](gcsa::ListBackupsRequest const&) {
57  return StatusOr<gcsa::ListBackupsResponse>(
58  Status(StatusCode::kUnimplemented, "not implemented"));
59  },
60  [](gcsa::ListBackupsResponse const&) {
61  return std::vector<gcsa::Backup>{};
62  });
63 }
64 
65 StatusOr<google::spanner::admin::database::v1::Backup>
66 // NOLINTNEXTLINE(performance-unnecessary-value-param)
67 DatabaseAdminConnection::UpdateBackup(UpdateBackupParams) {
68  return Status(StatusCode::kUnimplemented, "not implemented");
69 }
70 
71 ListBackupOperationsRange DatabaseAdminConnection::ListBackupOperations(
72  // NOLINTNEXTLINE(performance-unnecessary-value-param)
75  gcsa::ListBackupOperationsRequest{},
76  [](gcsa::ListBackupOperationsRequest const&) {
77  return StatusOr<gcsa::ListBackupOperationsResponse>(
78  Status(StatusCode::kUnimplemented, "not implemented"));
79  },
80  [](gcsa::ListBackupOperationsResponse const&) {
81  return std::vector<google::longrunning::Operation>{};
82  });
83 }
84 
85 ListDatabaseOperationsRange DatabaseAdminConnection::ListDatabaseOperations(
86  // NOLINTNEXTLINE(performance-unnecessary-value-param)
89  gcsa::ListDatabaseOperationsRequest{},
90  [](gcsa::ListDatabaseOperationsRequest const&) {
91  return StatusOr<gcsa::ListDatabaseOperationsResponse>(
92  Status(StatusCode::kUnimplemented, "not implemented"));
93  },
94  [](gcsa::ListDatabaseOperationsResponse const&) {
95  return std::vector<google::longrunning::Operation>{};
96  });
97 }
98 
99 namespace {
100 
101 std::unique_ptr<RetryPolicy> DefaultAdminRetryPolicy() {
102  return LimitedTimeRetryPolicy(std::chrono::minutes(30)).clone();
103 }
104 
105 std::unique_ptr<BackoffPolicy> DefaultAdminBackoffPolicy() {
106  auto constexpr kBackoffScaling = 2.0;
107  return ExponentialBackoffPolicy(std::chrono::seconds(1),
108  std::chrono::minutes(5), kBackoffScaling)
109  .clone();
110 }
111 
112 std::unique_ptr<PollingPolicy> DefaultAdminPollingPolicy() {
113  auto constexpr kBackoffScaling = 2.0;
114  return GenericPollingPolicy<>(
115  LimitedTimeRetryPolicy(std::chrono::minutes(30)),
116  ExponentialBackoffPolicy(std::chrono::seconds(10),
117  std::chrono::minutes(5), kBackoffScaling))
118  .clone();
119 }
120 
121 class DatabaseAdminConnectionImpl : public DatabaseAdminConnection {
122  public:
123  explicit DatabaseAdminConnectionImpl(
124  std::shared_ptr<internal::DatabaseAdminStub> stub,
125  std::unique_ptr<RetryPolicy> retry_policy,
126  std::unique_ptr<BackoffPolicy> backoff_policy,
127  std::unique_ptr<PollingPolicy> polling_policy)
128  : stub_(std::move(stub)),
129  retry_policy_prototype_(std::move(retry_policy)),
130  backoff_policy_prototype_(std::move(backoff_policy)),
131  polling_policy_prototype_(std::move(polling_policy)) {}
132 
133  explicit DatabaseAdminConnectionImpl(
134  std::shared_ptr<internal::DatabaseAdminStub> stub)
135  : DatabaseAdminConnectionImpl(std::move(stub), DefaultAdminRetryPolicy(),
136  DefaultAdminBackoffPolicy(),
137  DefaultAdminPollingPolicy()) {}
138 
139  ~DatabaseAdminConnectionImpl() override = default;
140 
141  future<StatusOr<google::spanner::admin::database::v1::Database>>
142  CreateDatabase(CreateDatabaseParams p) override {
143  gcsa::CreateDatabaseRequest request;
144  request.set_parent(p.database.instance().FullName());
145  request.set_create_statement("CREATE DATABASE `" +
146  p.database.database_id() + "`");
147  for (auto& s : p.extra_statements) {
148  *request.add_extra_statements() = std::move(s);
149  }
150 
151  auto operation = RetryLoop(
152  retry_policy_prototype_->clone(), backoff_policy_prototype_->clone(),
153  false,
154  [this](grpc::ClientContext& context,
155  gcsa::CreateDatabaseRequest const& request) {
156  return stub_->CreateDatabase(context, request);
157  },
158  request, __func__);
159  if (!operation) {
160  return google::cloud::make_ready_future(
161  StatusOr<gcsa::Database>(operation.status()));
162  }
163 
164  return AwaitDatabase(*std::move(operation));
165  }
166 
167  StatusOr<google::spanner::admin::database::v1::Database> GetDatabase(
168  GetDatabaseParams p) override {
169  gcsa::GetDatabaseRequest request;
170  request.set_name(p.database.FullName());
171  return RetryLoop(
172  retry_policy_prototype_->clone(), backoff_policy_prototype_->clone(),
173  true,
174  [this](grpc::ClientContext& context,
175  gcsa::GetDatabaseRequest const& request) {
176  return stub_->GetDatabase(context, request);
177  },
178  request, __func__);
179  }
180 
181  StatusOr<google::spanner::admin::database::v1::GetDatabaseDdlResponse>
182  GetDatabaseDdl(GetDatabaseDdlParams p) override {
183  gcsa::GetDatabaseDdlRequest request;
184  request.set_database(p.database.FullName());
185  return RetryLoop(
186  retry_policy_prototype_->clone(), backoff_policy_prototype_->clone(),
187  true,
188  [this](grpc::ClientContext& context,
189  gcsa::GetDatabaseDdlRequest const& request) {
190  return stub_->GetDatabaseDdl(context, request);
191  },
192  request, __func__);
193  }
194 
195  future<
196  StatusOr<google::spanner::admin::database::v1::UpdateDatabaseDdlMetadata>>
197  UpdateDatabase(UpdateDatabaseParams p) override {
198  gcsa::UpdateDatabaseDdlRequest request;
199  request.set_database(p.database.FullName());
200  for (auto& s : p.statements) {
201  *request.add_statements() = std::move(s);
202  }
203  auto operation = RetryLoop(
204  retry_policy_prototype_->clone(), backoff_policy_prototype_->clone(),
205  false,
206  [this](grpc::ClientContext& context,
207  gcsa::UpdateDatabaseDdlRequest const& request) {
208  return stub_->UpdateDatabase(context, request);
209  },
210  request, __func__);
211  if (!operation) {
212  return google::cloud::make_ready_future(
213  StatusOr<gcsa::UpdateDatabaseDdlMetadata>(operation.status()));
214  }
215 
216  return AwaitUpdateDatabase(*std::move(operation));
217  }
218 
219  Status DropDatabase(DropDatabaseParams p) override {
220  google::spanner::admin::database::v1::DropDatabaseRequest request;
221  request.set_database(p.database.FullName());
222  return RetryLoop(
223  retry_policy_prototype_->clone(), backoff_policy_prototype_->clone(),
224  true,
225  [this](grpc::ClientContext& context,
226  gcsa::DropDatabaseRequest const& request) {
227  return stub_->DropDatabase(context, request);
228  },
229  request, __func__);
230  }
231 
232  ListDatabaseRange ListDatabases(ListDatabasesParams p) override {
233  gcsa::ListDatabasesRequest request;
234  request.set_parent(p.instance.FullName());
235  request.clear_page_token();
236  auto stub = stub_;
237  // Because we do not have C++14 generalized lambda captures we cannot just
238  // use the unique_ptr<> here, so convert to shared_ptr<> instead.
239  auto retry =
240  std::shared_ptr<RetryPolicy const>(retry_policy_prototype_->clone());
241  auto backoff = std::shared_ptr<BackoffPolicy const>(
242  backoff_policy_prototype_->clone());
243 
244  char const* function_name = __func__;
245  return ListDatabaseRange(
246  std::move(request),
247  [stub, retry, backoff,
248  function_name](gcsa::ListDatabasesRequest const& r) {
249  return RetryLoop(
250  retry->clone(), backoff->clone(), true,
251  [stub](grpc::ClientContext& context,
252  gcsa::ListDatabasesRequest const& request) {
253  return stub->ListDatabases(context, request);
254  },
255  r, function_name);
256  },
257  [](gcsa::ListDatabasesResponse r) {
258  std::vector<gcsa::Database> result(r.databases().size());
259  auto& dbs = *r.mutable_databases();
260  std::move(dbs.begin(), dbs.end(), result.begin());
261  return result;
262  });
263  }
264 
265  future<StatusOr<google::spanner::admin::database::v1::Database>>
266  RestoreDatabase(RestoreDatabaseParams p) override {
267  gcsa::RestoreDatabaseRequest request;
268  request.set_parent(p.database.instance().FullName());
269  request.set_database_id(p.database.database_id());
270  request.set_backup(std::move(p.backup_full_name));
271  auto operation = RetryLoop(
272  retry_policy_prototype_->clone(), backoff_policy_prototype_->clone(),
273  false,
274  [this](grpc::ClientContext& context,
275  gcsa::RestoreDatabaseRequest const& request) {
276  return stub_->RestoreDatabase(context, request);
277  },
278  request, __func__);
279  if (!operation) {
280  return google::cloud::make_ready_future(
281  StatusOr<gcsa::Database>(operation.status()));
282  }
283 
284  return AwaitDatabase(*std::move(operation));
285  }
286 
287  StatusOr<google::iam::v1::Policy> GetIamPolicy(
288  GetIamPolicyParams p) override {
289  google::iam::v1::GetIamPolicyRequest request;
290  request.set_resource(p.database.FullName());
291  return RetryLoop(
292  retry_policy_prototype_->clone(), backoff_policy_prototype_->clone(),
293  true,
294  [this](grpc::ClientContext& context,
295  google::iam::v1::GetIamPolicyRequest const& request) {
296  return stub_->GetIamPolicy(context, request);
297  },
298  request, __func__);
299  }
300 
301  StatusOr<google::iam::v1::Policy> SetIamPolicy(
302  SetIamPolicyParams p) override {
303  google::iam::v1::SetIamPolicyRequest request;
304  request.set_resource(p.database.FullName());
305  *request.mutable_policy() = std::move(p.policy);
306  bool is_idempotent = !request.policy().etag().empty();
307  return RetryLoop(
308  retry_policy_prototype_->clone(), backoff_policy_prototype_->clone(),
309  is_idempotent,
310  [this](grpc::ClientContext& context,
311  google::iam::v1::SetIamPolicyRequest const& request) {
312  return stub_->SetIamPolicy(context, request);
313  },
314  request, __func__);
315  }
316 
317  StatusOr<google::iam::v1::TestIamPermissionsResponse> TestIamPermissions(
318  TestIamPermissionsParams p) override {
319  google::iam::v1::TestIamPermissionsRequest request;
320  request.set_resource(p.database.FullName());
321  for (auto& permission : p.permissions) {
322  request.add_permissions(std::move(permission));
323  }
324  return RetryLoop(
325  retry_policy_prototype_->clone(), backoff_policy_prototype_->clone(),
326  true,
327  [this](grpc::ClientContext& context,
328  google::iam::v1::TestIamPermissionsRequest const& request) {
329  return stub_->TestIamPermissions(context, request);
330  },
331  request, __func__);
332  }
333 
334  future<StatusOr<gcsa::Backup>> CreateBackup(CreateBackupParams p) override {
335  gcsa::CreateBackupRequest request;
336  request.set_parent(p.database.instance().FullName());
337  request.set_backup_id(p.backup_id);
338  auto backup = request.mutable_backup();
339  backup->set_database(p.database.FullName());
340  auto proto_expire_time =
341  internal::ConvertTimePointToProtoTimestamp(p.expire_time);
342  if (!proto_expire_time) {
343  return google::cloud::make_ready_future(
344  StatusOr<gcsa::Backup>(proto_expire_time.status()));
345  }
346  *backup->mutable_expire_time() = *proto_expire_time;
347  auto operation = RetryLoop(
348  retry_policy_prototype_->clone(), backoff_policy_prototype_->clone(),
349  false,
350  [this](grpc::ClientContext& context,
351  gcsa::CreateBackupRequest const& request) {
352  return stub_->CreateBackup(context, request);
353  },
354  request, __func__);
355  if (!operation) {
356  return google::cloud::make_ready_future(
357  StatusOr<gcsa::Backup>(operation.status()));
358  }
359 
360  return AwaitCreateBackup(*std::move(operation));
361  }
362 
363  StatusOr<google::spanner::admin::database::v1::Backup> GetBackup(
364  GetBackupParams p) override {
365  gcsa::GetBackupRequest request;
366  request.set_name(p.backup_full_name);
367  return RetryLoop(
368  retry_policy_prototype_->clone(), backoff_policy_prototype_->clone(),
369  true,
370  [this](grpc::ClientContext& context,
371  gcsa::GetBackupRequest const& request) {
372  return stub_->GetBackup(context, request);
373  },
374  request, __func__);
375  }
376 
377  Status DeleteBackup(DeleteBackupParams p) override {
378  google::spanner::admin::database::v1::DeleteBackupRequest request;
379  request.set_name(p.backup_full_name);
380  return RetryLoop(
381  retry_policy_prototype_->clone(), backoff_policy_prototype_->clone(),
382  true,
383  [this](grpc::ClientContext& context,
384  gcsa::DeleteBackupRequest const& request) {
385  return stub_->DeleteBackup(context, request);
386  },
387  request, __func__);
388  }
389 
390  ListBackupsRange ListBackups(ListBackupsParams p) override {
391  gcsa::ListBackupsRequest request;
392  request.set_parent(p.instance.FullName());
393  request.set_filter(std::move(p.filter));
394  auto stub = stub_;
395  // Because we do not have C++14 generalized lambda captures we cannot just
396  // use the unique_ptr<> here, so convert to shared_ptr<> instead.
397  auto retry =
398  std::shared_ptr<RetryPolicy const>(retry_policy_prototype_->clone());
399  auto backoff = std::shared_ptr<BackoffPolicy const>(
400  backoff_policy_prototype_->clone());
401 
402  char const* function_name = __func__;
403  return ListBackupsRange(
404  std::move(request),
405  [stub, retry, backoff,
406  function_name](gcsa::ListBackupsRequest const& r) {
407  return RetryLoop(
408  retry->clone(), backoff->clone(), true,
409  [stub](grpc::ClientContext& context,
410  gcsa::ListBackupsRequest const& request) {
411  return stub->ListBackups(context, request);
412  },
413  r, function_name);
414  },
415  [](gcsa::ListBackupsResponse r) {
416  std::vector<gcsa::Backup> result(r.backups().size());
417  auto& backups = *r.mutable_backups();
418  std::move(backups.begin(), backups.end(), result.begin());
419  return result;
420  });
421  }
422 
423  StatusOr<google::spanner::admin::database::v1::Backup> UpdateBackup(
424  UpdateBackupParams p) override {
425  return RetryLoop(
426  retry_policy_prototype_->clone(), backoff_policy_prototype_->clone(),
427  true,
428  [this](grpc::ClientContext& context,
429  gcsa::UpdateBackupRequest const& request) {
430  return stub_->UpdateBackup(context, request);
431  },
432  p.request, __func__);
433  }
434 
435  ListBackupOperationsRange ListBackupOperations(
436  ListBackupOperationsParams p) override {
437  gcsa::ListBackupOperationsRequest request;
438  request.set_parent(p.instance.FullName());
439  request.set_filter(std::move(p.filter));
440  auto stub = stub_;
441  // Because we do not have C++14 generalized lambda captures we cannot just
442  // use the unique_ptr<> here, so convert to shared_ptr<> instead.
443  auto retry =
444  std::shared_ptr<RetryPolicy const>(retry_policy_prototype_->clone());
445  auto backoff = std::shared_ptr<BackoffPolicy const>(
446  backoff_policy_prototype_->clone());
447 
448  char const* function_name = __func__;
450  std::move(request),
451  [stub, retry, backoff,
452  function_name](gcsa::ListBackupOperationsRequest const& r) {
453  return RetryLoop(
454  retry->clone(), backoff->clone(), true,
455  [stub](grpc::ClientContext& context,
456  gcsa::ListBackupOperationsRequest const& request) {
457  return stub->ListBackupOperations(context, request);
458  },
459  r, function_name);
460  },
461  [](gcsa::ListBackupOperationsResponse r) {
462  std::vector<google::longrunning::Operation> result(
463  r.operations().size());
464  auto& operations = *r.mutable_operations();
465  std::move(operations.begin(), operations.end(), result.begin());
466  return result;
467  });
468  }
469 
470  ListDatabaseOperationsRange ListDatabaseOperations(
471  ListDatabaseOperationsParams p) override {
472  gcsa::ListDatabaseOperationsRequest request;
473  request.set_parent(p.instance.FullName());
474  request.set_filter(std::move(p.filter));
475  auto stub = stub_;
476  // Because we do not have C++14 generalized lambda captures we cannot just
477  // use the unique_ptr<> here, so convert to shared_ptr<> instead.
478  auto retry =
479  std::shared_ptr<RetryPolicy const>(retry_policy_prototype_->clone());
480  auto backoff = std::shared_ptr<BackoffPolicy const>(
481  backoff_policy_prototype_->clone());
482 
483  char const* function_name = __func__;
485  std::move(request),
486  [stub, retry, backoff,
487  function_name](gcsa::ListDatabaseOperationsRequest const& r) {
488  return RetryLoop(
489  retry->clone(), backoff->clone(), true,
490  [stub](grpc::ClientContext& context,
491  gcsa::ListDatabaseOperationsRequest const& request) {
492  return stub->ListDatabaseOperations(context, request);
493  },
494  r, function_name);
495  },
496  [](gcsa::ListDatabaseOperationsResponse r) {
497  std::vector<google::longrunning::Operation> result(
498  r.operations().size());
499  auto& operations = *r.mutable_operations();
500  std::move(operations.begin(), operations.end(), result.begin());
501  return result;
502  });
503  }
504 
505  private:
506  future<StatusOr<gcsa::Database>> AwaitDatabase(
507  google::longrunning::Operation operation) {
508  promise<StatusOr<gcsa::Database>> pr;
509  auto f = pr.get_future();
510 
511  // TODO(#127) - use the (implicit) completion queue to run this loop.
512  std::thread t(
513  [](std::shared_ptr<internal::DatabaseAdminStub> stub,
514  google::longrunning::Operation operation,
515  std::unique_ptr<PollingPolicy> polling_policy,
516  google::cloud::promise<StatusOr<gcsa::Database>> promise,
517  char const* location) mutable {
518  auto result = internal::PollingLoop<
519  internal::PollingLoopResponseExtractor<gcsa::Database>>(
520  std::move(polling_policy),
521  [stub](grpc::ClientContext& context,
522  google::longrunning::GetOperationRequest const& request) {
523  return stub->GetOperation(context, request);
524  },
525  std::move(operation), location);
526 
527  // Drop our reference to stub; ideally we'd have std::moved into the
528  // lambda. Doing this also prevents a false leak from being reported
529  // when using googlemock.
530  stub.reset();
531  promise.set_value(std::move(result));
532  },
533  stub_, std::move(operation), polling_policy_prototype_->clone(),
534  std::move(pr), __func__);
535  t.detach();
536 
537  return f;
538  }
539 
540  future<StatusOr<gcsa::UpdateDatabaseDdlMetadata>> AwaitUpdateDatabase(
541  google::longrunning::Operation operation) {
542  promise<StatusOr<gcsa::UpdateDatabaseDdlMetadata>> pr;
543  auto f = pr.get_future();
544 
545  // TODO(#127) - use the (implicit) completion queue to run this loop.
546  std::thread t(
547  [](std::shared_ptr<internal::DatabaseAdminStub> stub,
548  google::longrunning::Operation operation,
549  std::unique_ptr<PollingPolicy> polling_policy,
550  promise<StatusOr<gcsa::UpdateDatabaseDdlMetadata>> promise,
551  char const* location) mutable {
552  auto result =
553  internal::PollingLoop<internal::PollingLoopMetadataExtractor<
554  gcsa::UpdateDatabaseDdlMetadata>>(
555  std::move(polling_policy),
556  [stub](
557  grpc::ClientContext& context,
558  google::longrunning::GetOperationRequest const& request) {
559  return stub->GetOperation(context, request);
560  },
561  std::move(operation), location);
562 
563  // Drop our reference to stub; ideally we'd have std::moved into the
564  // lambda. Doing this also prevents a false leak from being reported
565  // when using googlemock.
566  stub.reset();
567  promise.set_value(std::move(result));
568  },
569  stub_, std::move(operation), polling_policy_prototype_->clone(),
570  std::move(pr), __func__);
571  t.detach();
572 
573  return f;
574  }
575 
576  future<StatusOr<gcsa::Backup>> AwaitCreateBackup(
577  google::longrunning::Operation operation) {
578  // Create a local copy of stub because `this` might get out of scope when
579  // the callback will be called.
580  std::shared_ptr<internal::DatabaseAdminStub> cancel_stub(stub_);
581  // Create a promise with a cancellation callback.
582  promise<StatusOr<gcsa::Backup>> pr([cancel_stub, operation]() {
583  grpc::ClientContext context;
584  google::longrunning::CancelOperationRequest request;
585  request.set_name(operation.name());
586  cancel_stub->CancelOperation(context, request);
587  });
588  auto f = pr.get_future();
589 
590  // TODO(#127) - use the (implicit) completion queue to run this loop.
591  std::thread t(
592  [](std::shared_ptr<internal::DatabaseAdminStub> stub,
593  google::longrunning::Operation operation,
594  std::unique_ptr<PollingPolicy> polling_policy,
595  google::cloud::promise<StatusOr<gcsa::Backup>> promise,
596  char const* location) mutable {
597  auto result = internal::PollingLoop<
598  internal::PollingLoopResponseExtractor<gcsa::Backup>>(
599  std::move(polling_policy),
600  [stub](grpc::ClientContext& context,
601  google::longrunning::GetOperationRequest const& request) {
602  return stub->GetOperation(context, request);
603  },
604  std::move(operation), location);
605 
606  // Drop our reference to stub; ideally we'd have std::moved into the
607  // lambda. Doing this also prevents a false leak from being reported
608  // when using googlemock.
609  stub.reset();
610  promise.set_value(std::move(result));
611  },
612  stub_, std::move(operation), polling_policy_prototype_->clone(),
613  std::move(pr), __func__);
614  t.detach();
615 
616  return f;
617  }
618 
619  std::shared_ptr<internal::DatabaseAdminStub> stub_;
620  std::unique_ptr<RetryPolicy const> retry_policy_prototype_;
621  std::unique_ptr<BackoffPolicy const> backoff_policy_prototype_;
622  std::unique_ptr<PollingPolicy const> polling_policy_prototype_;
623 };
624 } // namespace
625 
626 DatabaseAdminConnection::~DatabaseAdminConnection() = default;
627 
628 std::shared_ptr<DatabaseAdminConnection> MakeDatabaseAdminConnection(
629  ConnectionOptions const& options) {
630  return std::make_shared<DatabaseAdminConnectionImpl>(
631  internal::CreateDefaultDatabaseAdminStub(options));
632 }
633 
634 std::shared_ptr<DatabaseAdminConnection> MakeDatabaseAdminConnection(
635  ConnectionOptions const& options, std::unique_ptr<RetryPolicy> retry_policy,
636  std::unique_ptr<BackoffPolicy> backoff_policy,
637  std::unique_ptr<PollingPolicy> polling_policy) {
638  return std::make_shared<DatabaseAdminConnectionImpl>(
639  internal::CreateDefaultDatabaseAdminStub(options),
640  std::move(retry_policy), std::move(backoff_policy),
641  std::move(polling_policy));
642 }
643 
644 namespace internal {
645 
646 std::shared_ptr<DatabaseAdminConnection> MakeDatabaseAdminConnection(
647  std::shared_ptr<internal::DatabaseAdminStub> stub,
648  std::unique_ptr<RetryPolicy> retry_policy,
649  std::unique_ptr<BackoffPolicy> backoff_policy,
650  std::unique_ptr<PollingPolicy> polling_policy) {
651  return std::make_shared<DatabaseAdminConnectionImpl>(
652  std::move(stub), std::move(retry_policy), std::move(backoff_policy),
653  std::move(polling_policy));
654 }
655 
656 } // namespace internal
657 } // namespace SPANNER_CLIENT_NS
658 } // namespace spanner
659 } // namespace cloud
660 } // namespace google
google::cloud::internal::PaginationRange< google::spanner::admin::database::v1::Backup, google::spanner::admin::database::v1::ListBackupsRequest, google::spanner::admin::database::v1::ListBackupsResponse > ListBackupsRange
An input range to stream backups in Cloud Spanner instance.
google::cloud::internal::PaginationRange< google::longrunning::Operation, google::spanner::admin::database::v1::ListBackupOperationsRequest, google::spanner::admin::database::v1::ListBackupOperationsResponse > ListBackupOperationsRange
An input range to stream backup operations in Cloud Spanner instance.
Contains all the Cloud Spanner C++ client types and functions.
google::cloud::ConnectionOptions< ConnectionOptionsTraits > ConnectionOptions
The options for Cloud Spanner connections.
google::cloud::internal::LimitedTimeRetryPolicy< google::cloud::Status, internal::SafeGrpcRetry > LimitedTimeRetryPolicy
A retry policy that limits based on time.
Definition: retry_policy.h:65
google::cloud::internal::ExponentialBackoffPolicy ExponentialBackoffPolicy
A truncated exponential backoff policy with randomized periods.
#define SPANNER_CLIENT_NS
Definition: version.h:22
google::cloud::internal::PaginationRange< google::spanner::admin::database::v1::Database, google::spanner::admin::database::v1::ListDatabasesRequest, google::spanner::admin::database::v1::ListDatabasesResponse > ListDatabaseRange
An input range to stream all the databases in a Cloud Spanner instance.
google::cloud::internal::PaginationRange< google::longrunning::Operation, google::spanner::admin::database::v1::ListDatabaseOperationsRequest, google::spanner::admin::database::v1::ListDatabaseOperationsResponse > ListDatabaseOperationsRange
An input range to stream database operations in Cloud Spanner instance.
std::shared_ptr< DatabaseAdminConnection > MakeDatabaseAdminConnection(ConnectionOptions const &options)
Returns an DatabaseAdminConnection object that can be used for interacting with Cloud Spanner's admin...