google-cloud-spanner 1.16.1 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/AUTHENTICATION.md +1 -1
  3. data/CHANGELOG.md +58 -0
  4. data/CONTRIBUTING.md +6 -6
  5. data/TROUBLESHOOTING.md +0 -6
  6. data/lib/google-cloud-spanner.rb +11 -13
  7. data/lib/google/cloud/spanner.rb +13 -13
  8. data/lib/google/cloud/spanner/admin/database/credentials.rb +2 -2
  9. data/lib/google/cloud/spanner/admin/instance/credentials.rb +2 -2
  10. data/lib/google/cloud/spanner/backup.rb +1 -1
  11. data/lib/google/cloud/spanner/backup/job.rb +2 -2
  12. data/lib/google/cloud/spanner/backup/job/list.rb +2 -2
  13. data/lib/google/cloud/spanner/backup/list.rb +1 -2
  14. data/lib/google/cloud/spanner/backup/restore/job.rb +2 -2
  15. data/lib/google/cloud/spanner/batch_client.rb +2 -2
  16. data/lib/google/cloud/spanner/batch_snapshot.rb +120 -23
  17. data/lib/google/cloud/spanner/batch_update.rb +1 -1
  18. data/lib/google/cloud/spanner/client.rb +388 -47
  19. data/lib/google/cloud/spanner/commit.rb +14 -14
  20. data/lib/google/cloud/spanner/commit_response.rb +87 -0
  21. data/lib/google/cloud/spanner/commit_response/commit_stats.rb +51 -0
  22. data/lib/google/cloud/spanner/convert.rb +16 -7
  23. data/lib/google/cloud/spanner/credentials.rb +2 -2
  24. data/lib/google/cloud/spanner/data.rb +2 -2
  25. data/lib/google/cloud/spanner/database.rb +22 -22
  26. data/lib/google/cloud/spanner/database/backup_info.rb +1 -1
  27. data/lib/google/cloud/spanner/database/job.rb +3 -3
  28. data/lib/google/cloud/spanner/database/job/list.rb +2 -2
  29. data/lib/google/cloud/spanner/database/list.rb +1 -1
  30. data/lib/google/cloud/spanner/database/restore_info.rb +1 -1
  31. data/lib/google/cloud/spanner/fields.rb +8 -8
  32. data/lib/google/cloud/spanner/instance.rb +5 -12
  33. data/lib/google/cloud/spanner/instance/config.rb +1 -1
  34. data/lib/google/cloud/spanner/instance/config/list.rb +1 -1
  35. data/lib/google/cloud/spanner/instance/job.rb +2 -2
  36. data/lib/google/cloud/spanner/instance/list.rb +1 -1
  37. data/lib/google/cloud/spanner/partition.rb +4 -4
  38. data/lib/google/cloud/spanner/policy.rb +2 -2
  39. data/lib/google/cloud/spanner/results.rb +103 -24
  40. data/lib/google/cloud/spanner/service.rb +367 -349
  41. data/lib/google/cloud/spanner/session.rb +370 -39
  42. data/lib/google/cloud/spanner/snapshot.rb +60 -6
  43. data/lib/google/cloud/spanner/transaction.rb +116 -10
  44. data/lib/google/cloud/spanner/version.rb +1 -1
  45. metadata +20 -107
  46. data/lib/google/cloud/spanner/admin/database.rb +0 -149
  47. data/lib/google/cloud/spanner/admin/database/v1.rb +0 -147
  48. data/lib/google/cloud/spanner/admin/database/v1/credentials.rb +0 -46
  49. data/lib/google/cloud/spanner/admin/database/v1/database_admin_client.rb +0 -1513
  50. data/lib/google/cloud/spanner/admin/database/v1/database_admin_client_config.json +0 -111
  51. data/lib/google/cloud/spanner/admin/database/v1/doc/google/iam/v1/iam_policy.rb +0 -64
  52. data/lib/google/cloud/spanner/admin/database/v1/doc/google/iam/v1/options.rb +0 -33
  53. data/lib/google/cloud/spanner/admin/database/v1/doc/google/iam/v1/policy.rb +0 -151
  54. data/lib/google/cloud/spanner/admin/database/v1/doc/google/longrunning/operations.rb +0 -51
  55. data/lib/google/cloud/spanner/admin/database/v1/doc/google/protobuf/any.rb +0 -131
  56. data/lib/google/cloud/spanner/admin/database/v1/doc/google/protobuf/empty.rb +0 -29
  57. data/lib/google/cloud/spanner/admin/database/v1/doc/google/protobuf/field_mask.rb +0 -222
  58. data/lib/google/cloud/spanner/admin/database/v1/doc/google/protobuf/timestamp.rb +0 -113
  59. data/lib/google/cloud/spanner/admin/database/v1/doc/google/rpc/status.rb +0 -39
  60. data/lib/google/cloud/spanner/admin/database/v1/doc/google/spanner/admin/database/v1/backup.rb +0 -325
  61. data/lib/google/cloud/spanner/admin/database/v1/doc/google/spanner/admin/database/v1/spanner_database_admin.rb +0 -368
  62. data/lib/google/cloud/spanner/admin/database/v1/doc/google/type/expr.rb +0 -45
  63. data/lib/google/cloud/spanner/admin/instance.rb +0 -164
  64. data/lib/google/cloud/spanner/admin/instance/v1.rb +0 -162
  65. data/lib/google/cloud/spanner/admin/instance/v1/credentials.rb +0 -46
  66. data/lib/google/cloud/spanner/admin/instance/v1/doc/google/iam/v1/iam_policy.rb +0 -64
  67. data/lib/google/cloud/spanner/admin/instance/v1/doc/google/iam/v1/options.rb +0 -33
  68. data/lib/google/cloud/spanner/admin/instance/v1/doc/google/iam/v1/policy.rb +0 -151
  69. data/lib/google/cloud/spanner/admin/instance/v1/doc/google/longrunning/operations.rb +0 -51
  70. data/lib/google/cloud/spanner/admin/instance/v1/doc/google/protobuf/any.rb +0 -131
  71. data/lib/google/cloud/spanner/admin/instance/v1/doc/google/protobuf/empty.rb +0 -29
  72. data/lib/google/cloud/spanner/admin/instance/v1/doc/google/protobuf/field_mask.rb +0 -222
  73. data/lib/google/cloud/spanner/admin/instance/v1/doc/google/rpc/status.rb +0 -39
  74. data/lib/google/cloud/spanner/admin/instance/v1/doc/google/spanner/admin/instance/v1/spanner_instance_admin.rb +0 -334
  75. data/lib/google/cloud/spanner/admin/instance/v1/doc/google/type/expr.rb +0 -45
  76. data/lib/google/cloud/spanner/admin/instance/v1/instance_admin_client.rb +0 -975
  77. data/lib/google/cloud/spanner/admin/instance/v1/instance_admin_client_config.json +0 -76
  78. data/lib/google/cloud/spanner/v1.rb +0 -16
  79. data/lib/google/cloud/spanner/v1/credentials.rb +0 -42
  80. data/lib/google/cloud/spanner/v1/doc/google/protobuf/any.rb +0 -131
  81. data/lib/google/cloud/spanner/v1/doc/google/protobuf/duration.rb +0 -91
  82. data/lib/google/cloud/spanner/v1/doc/google/protobuf/empty.rb +0 -29
  83. data/lib/google/cloud/spanner/v1/doc/google/protobuf/struct.rb +0 -74
  84. data/lib/google/cloud/spanner/v1/doc/google/protobuf/timestamp.rb +0 -113
  85. data/lib/google/cloud/spanner/v1/doc/google/rpc/status.rb +0 -39
  86. data/lib/google/cloud/spanner/v1/doc/google/spanner/v1/keys.rb +0 -150
  87. data/lib/google/cloud/spanner/v1/doc/google/spanner/v1/mutation.rb +0 -95
  88. data/lib/google/cloud/spanner/v1/doc/google/spanner/v1/query_plan.rb +0 -121
  89. data/lib/google/cloud/spanner/v1/doc/google/spanner/v1/result_set.rb +0 -190
  90. data/lib/google/cloud/spanner/v1/doc/google/spanner/v1/spanner.rb +0 -570
  91. data/lib/google/cloud/spanner/v1/doc/google/spanner/v1/transaction.rb +0 -432
  92. data/lib/google/cloud/spanner/v1/doc/google/spanner/v1/type.rb +0 -112
  93. data/lib/google/cloud/spanner/v1/spanner_client.rb +0 -1485
  94. data/lib/google/cloud/spanner/v1/spanner_client_config.json +0 -121
  95. data/lib/google/spanner/admin/database/v1/backup_pb.rb +0 -98
  96. data/lib/google/spanner/admin/database/v1/common_pb.rb +0 -28
  97. data/lib/google/spanner/admin/database/v1/spanner_database_admin_pb.rb +0 -141
  98. data/lib/google/spanner/admin/database/v1/spanner_database_admin_services_pb.rb +0 -169
  99. data/lib/google/spanner/admin/instance/v1/spanner_instance_admin_pb.rb +0 -125
  100. data/lib/google/spanner/admin/instance/v1/spanner_instance_admin_services_pb.rb +0 -181
  101. data/lib/google/spanner/v1/keys_pb.rb +0 -34
  102. data/lib/google/spanner/v1/mutation_pb.rb +0 -39
  103. data/lib/google/spanner/v1/query_plan_pb.rb +0 -48
  104. data/lib/google/spanner/v1/result_set_pb.rb +0 -48
  105. data/lib/google/spanner/v1/spanner_pb.rb +0 -179
  106. data/lib/google/spanner/v1/spanner_services_pb.rb +0 -179
  107. data/lib/google/spanner/v1/transaction_pb.rb +0 -56
  108. data/lib/google/spanner/v1/type_pb.rb +0 -44
@@ -142,7 +142,7 @@ module Google
142
142
 
143
143
  ##
144
144
  # @private New Database::List from a
145
- # Google::Spanner::Admin::Database::V1::ListDatabasesResponse
145
+ # `Google::Cloud::Spanner::Admin::Database::V1::ListDatabasesResponse`
146
146
  # object.
147
147
  def self.from_grpc grpc, service, instance_id, max = nil
148
148
  databases = List.new(Array(grpc.databases).map do |database|
@@ -52,7 +52,7 @@ module Google
52
52
 
53
53
  ##
54
54
  # @private Creates a new Database::RestoreInfo instance from a
55
- # Google::Spanner::Admin::Database::V1::RestoreInfo.
55
+ # `Google::Cloud::Spanner::Admin::Database::V1::RestoreInfo`
56
56
  def self.from_grpc grpc
57
57
  new grpc
58
58
  end
@@ -372,9 +372,9 @@ module Google
372
372
  ##
373
373
  # @private
374
374
  def to_grpc_type
375
- Google::Spanner::V1::Type.new(
375
+ V1::Type.new(
376
376
  code: :STRUCT,
377
- struct_type: Google::Spanner::V1::StructType.new(
377
+ struct_type: V1::StructType.new(
378
378
  fields: @grpc_fields
379
379
  )
380
380
  )
@@ -382,7 +382,7 @@ module Google
382
382
 
383
383
  ##
384
384
  # @private Creates a new Fields instance from a
385
- # Google::Spanner::V1::Metadata::Row_type::Fields.
385
+ # V1::Metadata::Row_type::Fields.
386
386
  def self.from_grpc fields
387
387
  new([]).tap do |f|
388
388
  f.instance_variable_set :@grpc_fields, Array(fields)
@@ -412,18 +412,18 @@ module Google
412
412
  if pair.is_a?(Array)
413
413
  if pair.count == 2
414
414
  if pair.first.is_a?(Integer)
415
- Google::Spanner::V1::StructType::Field.new(
415
+ V1::StructType::Field.new(
416
416
  type: Convert.grpc_type_for_field(pair.last)
417
417
  )
418
418
  else
419
- Google::Spanner::V1::StructType::Field.new(
419
+ V1::StructType::Field.new(
420
420
  name: String(pair.first),
421
421
  type: Convert.grpc_type_for_field(pair.last)
422
422
  )
423
423
  end
424
424
  else
425
- Google::Spanner::V1::StructType::Field.new(
426
- type: Google::Spanner::V1::Type.new(
425
+ V1::StructType::Field.new(
426
+ type: V1::Type.new(
427
427
  code: :ARRAY,
428
428
  array_element_type: Convert.grpc_type_for_field(pair.last)
429
429
  )
@@ -435,7 +435,7 @@ module Google
435
435
  unless pair.is_a?(Symbol)
436
436
  raise ArgumentError, "type must be a symbol"
437
437
  end
438
- Google::Spanner::V1::StructType::Field.new(
438
+ V1::StructType::Field.new(
439
439
  type: Convert.grpc_type_for_field(pair)
440
440
  )
441
441
  end
@@ -342,10 +342,10 @@ module Google
342
342
  # response.
343
343
  #
344
344
  # The response returns a list of
345
- # {Google::Longrunning::Operation long-running operations} whose names
345
+ # `Google::Longrunning::Operation` long-running operations whose names
346
346
  # are prefixed by a database name within the specified instance.
347
347
  # The long-running operation
348
- # {Google::Longrunning::Operation#metadata metadata} field type
348
+ # `Google::Longrunning::Operation#metadata` metadata field type
349
349
  # `metadata.type_url` describes the type of the metadata.
350
350
  #
351
351
  # The filter expression must specify the field name,
@@ -603,10 +603,10 @@ module Google
603
603
  # response.
604
604
  #
605
605
  # The response returns a list of
606
- # {Google::Longrunning::Operation long-running operations} whose names
606
+ # `Google::Longrunning::Operation` long-running operations whose names
607
607
  # are prefixed by a backup name within the specified instance.
608
608
  # The long-running operation
609
- # {Google::Longrunning::Operation#metadata metadata} field type
609
+ # `Google::Longrunning::Operation#metadata` metadata field type
610
610
  # `metadata.type_url` describes the type of the metadata.
611
611
  #
612
612
  # The filter expression must specify the field name of an operation, a
@@ -856,7 +856,7 @@ module Google
856
856
 
857
857
  ##
858
858
  # @private Creates a new Instance instance from a
859
- # Google::Spanner::Admin::Instance::V1::Instance.
859
+ # `Google::Cloud::Spanner::Admin::Instance::V1::Instance`.
860
860
  def self.from_grpc grpc, service
861
861
  new grpc, service
862
862
  end
@@ -869,13 +869,6 @@ module Google
869
869
  def ensure_service!
870
870
  raise "Must have active connection to service" unless service
871
871
  end
872
-
873
- def instance_config_path name
874
- return name if name.to_s.include? "/"
875
- Admin::Instance::V1::InstanceAdminClient.instance_config_path(
876
- project, name.to_s
877
- )
878
- end
879
872
  end
880
873
  end
881
874
  end
@@ -77,7 +77,7 @@ module Google
77
77
 
78
78
  ##
79
79
  # @private Creates a new Instance::Config instance from a
80
- # Google::Spanner::Admin::Instance::V1::InstanceConfig.
80
+ # `Google::Cloud::Spanner::Admin::Instance::V1::InstanceConfig`.
81
81
  def self.from_grpc grpc
82
82
  new grpc
83
83
  end
@@ -142,7 +142,7 @@ module Google
142
142
 
143
143
  ##
144
144
  # @private New Instance::Config::List from a
145
- # Google::Spanner::Admin::Instance::V1::ListInstanceConfigsResponse
145
+ # `Google::Cloud::Spanner::Admin::Instance::V1::ListInstanceConfigsResponse`
146
146
  # object.
147
147
  def self.from_grpc grpc, service, max = nil
148
148
  configs = List.new(Array(grpc.instance_configs).map do |config|
@@ -54,7 +54,7 @@ module Google
54
54
  #
55
55
  class Job
56
56
  ##
57
- # @private The Google::Gax::Operation gRPC object.
57
+ # @private The `Gapic::Operation` gRPC object.
58
58
  attr_accessor :grpc
59
59
 
60
60
  ##
@@ -219,7 +219,7 @@ module Google
219
219
  end
220
220
 
221
221
  ##
222
- # @private New Instance::Job from a Google::Gax::Operation object.
222
+ # @private New Instance::Job from a `Gapic::Operation` object.
223
223
  def self.from_grpc grpc, service
224
224
  new.tap do |job|
225
225
  job.instance_variable_set :@grpc, grpc
@@ -139,7 +139,7 @@ module Google
139
139
 
140
140
  ##
141
141
  # @private New Instance::List from a
142
- # Google::Spanner::Admin::Instance::V1::ListInstancesResponse
142
+ # `Google::Cloud::Spanner::Admin::Instance::V1::ListInstancesResponse`
143
143
  # object.
144
144
  def self.from_grpc grpc, service, max = nil
145
145
  instances = List.new(Array(grpc.instances).map do |instance|
@@ -172,13 +172,13 @@ module Google
172
172
  new.tap do |p|
173
173
  if data[:execute]
174
174
  execute_sql_grpc = \
175
- Google::Spanner::V1::ExecuteSqlRequest.decode(
175
+ V1::ExecuteSqlRequest.decode(
176
176
  Base64.decode64(data[:execute])
177
177
  )
178
178
  p.instance_variable_set :@execute, execute_sql_grpc
179
179
  end
180
180
  if data[:read]
181
- read_grpc = Google::Spanner::V1::ReadRequest.decode \
181
+ read_grpc = V1::ReadRequest.decode \
182
182
  Base64.decode64(data[:read])
183
183
  p.instance_variable_set :@read, read_grpc
184
184
  end
@@ -194,7 +194,7 @@ module Google
194
194
  end
195
195
 
196
196
  ##
197
- # @private New Partition from a Google::Spanner::V1::ExecuteSqlRequest
197
+ # @private New Partition from a `Google::Cloud::Spanner::V1::ExecuteSqlRequest`
198
198
  # object.
199
199
  def self.from_execute_sql_grpc grpc
200
200
  new.tap do |p|
@@ -203,7 +203,7 @@ module Google
203
203
  end
204
204
 
205
205
  ##
206
- # @private New Partition from a Google::Spanner::V1::ReadRequest object.
206
+ # @private New Partition from a `Google::Cloud::Spanner::V1::ReadRequest` object.
207
207
  def self.from_read_grpc grpc
208
208
  new.tap do |p|
209
209
  p.instance_variable_set :@read, grpc
@@ -159,7 +159,7 @@ module Google
159
159
  end
160
160
 
161
161
  ##
162
- # @private Convert the Policy to a Google::Iam::V1::Policy object.
162
+ # @private Convert the Policy to a `Google::Iam::V1::Policy` object.
163
163
  def to_grpc
164
164
  Google::Iam::V1::Policy.new(
165
165
  etag: etag,
@@ -174,7 +174,7 @@ module Google
174
174
  end
175
175
 
176
176
  ##
177
- # @private New Policy from a Google::Iam::V1::Policy object.
177
+ # @private New Policy from a `Google::Iam::V1::Policy` object.
178
178
  def self.from_grpc grpc
179
179
  roles = grpc.bindings.each_with_object({}) do |binding, memo|
180
180
  memo[binding.role] = binding.members.to_a
@@ -41,6 +41,8 @@ module Google
41
41
  # end
42
42
  #
43
43
  class Results
44
+ RST_STREAM_INTERNAL_ERROR = "Received RST_STREAM".freeze
45
+ EOS_INTERNAL_ERROR = "Received unexpected EOS on DATA frame from server".freeze
44
46
  ##
45
47
  # The read timestamp chosen for single-use snapshots (read-only
46
48
  # transactions).
@@ -107,12 +109,24 @@ module Google
107
109
  buffer_upper_bound = 10
108
110
  chunked_value = nil
109
111
  resume_token = nil
112
+ should_resume_request = false
113
+ should_retry_request = false
110
114
 
111
115
  # Cannot call Enumerator#each because it won't return the first
112
116
  # value that was already identified when calling Enumerator#peek.
113
117
  # Iterate only using Enumerator#next and break on StopIteration.
114
118
  loop do
115
119
  begin
120
+ if should_resume_request
121
+ @enum = resume_request(resume_token)
122
+ buffered_responses = []
123
+ should_resume_request = false
124
+ elsif should_retry_request
125
+ @enum = retry_request()
126
+ buffered_responses = []
127
+ should_retry_request = false
128
+ end
129
+
116
130
  grpc = @enum.next
117
131
  # metadata should be set before the first iteration...
118
132
  @metadata ||= grpc.metadata
@@ -143,28 +157,36 @@ module Google
143
157
  # Flush the buffered responses now that they are all handled
144
158
  buffered_responses = []
145
159
  end
146
- rescue GRPC::Cancelled, GRPC::DeadlineExceeded, GRPC::Internal,
147
- GRPC::ResourceExhausted, GRPC::Unauthenticated,
148
- GRPC::Unavailable, GRPC::Core::CallError => err
149
- if resume_token.nil? || resume_token.empty?
150
- # Re-raise if the resume_token is not a valid value.
151
- # This can happen if the buffer was flushed.
152
- raise Google::Cloud::Error.from_error(err)
153
- end
160
+ # TODO: once the generated client throws only Google Cloud errors, remove
161
+ # the GRPC errors from the rescue block
162
+ rescue GRPC::Aborted,
163
+ GRPC::Cancelled,
164
+ GRPC::DeadlineExceeded,
165
+ GRPC::Internal,
166
+ GRPC::ResourceExhausted,
167
+ GRPC::Unauthenticated,
168
+ GRPC::Unavailable,
169
+ GRPC::Core::CallError,
170
+ Google::Cloud::AbortedError,
171
+ Google::Cloud::CanceledError,
172
+ Google::Cloud::DeadlineExceededError,
173
+ Google::Cloud::InternalError,
174
+ Google::Cloud::ResourceExhaustedError,
175
+ Google::Cloud::UnauthenticatedError,
176
+ Google::Cloud::UnavailableError => err
154
177
 
155
- # Resume the stream from the last known resume_token
156
- if @execute_query_options
157
- @enum = @service.execute_streaming_sql \
158
- @session_path, @sql,
159
- @execute_query_options.merge(resume_token: resume_token)
178
+ if resumable?(resume_token)
179
+ should_resume_request = true
180
+ elsif retryable?(err)
181
+ should_retry_request = true
182
+ elsif err.is_a?(Google::Cloud::Error)
183
+ raise err
160
184
  else
161
- @enum = @service.streaming_read_table \
162
- @session_path, @table, @columns,
163
- @read_options.merge(resume_token: resume_token)
185
+ raise Google::Cloud::Error.from_error(err)
164
186
  end
165
187
 
166
- # Flush the buffered responses to reset to the resume_token
167
- buffered_responses = []
188
+ # TODO: once the generated client throws only Google Cloud errors, remove
189
+ # this rescue block (for GRPC::BadStatus)
168
190
  rescue GRPC::BadStatus => err
169
191
  raise Google::Cloud::Error.from_error(err)
170
192
  rescue StopIteration
@@ -198,6 +220,60 @@ module Google
198
220
 
199
221
  # rubocop:enable all
200
222
 
223
+ ##
224
+ # @private
225
+ # Checks if a request can be resumed by inspecting the resume token
226
+ def resumable? resume_token
227
+ resume_token && !resume_token.empty?
228
+ end
229
+
230
+ ##
231
+ # @private
232
+ # Checks if a request can be retried. This is based on the error returned.
233
+ # Retryable errors are:
234
+ # - Unavailable error
235
+ # - Internal EOS error
236
+ # - Internal RST_STREAM error
237
+ def retryable? err
238
+ err.instance_of?(Google::Cloud::UnavailableError) ||
239
+ err.instance_of?(GRPC::Unavailable) ||
240
+ (err.instance_of?(Google::Cloud::InternalError) && err.message.include?(EOS_INTERNAL_ERROR)) ||
241
+ (err.instance_of?(GRPC::Internal) && err.details.include?(EOS_INTERNAL_ERROR)) ||
242
+ (err.instance_of?(Google::Cloud::InternalError) && err.message.include?(RST_STREAM_INTERNAL_ERROR)) ||
243
+ (err.instance_of?(GRPC::Internal) && err.details.include?(RST_STREAM_INTERNAL_ERROR))
244
+ end
245
+
246
+ ##
247
+ # @private
248
+ # Resumes a request, by re-executing it with a resume token.
249
+ def resume_request resume_token
250
+ if @execute_query_options
251
+ @service.execute_streaming_sql(
252
+ @session_path,
253
+ @sql,
254
+ @execute_query_options.merge(resume_token: resume_token)
255
+ )
256
+ else
257
+ @service.streaming_read_table(
258
+ @session_path,
259
+ @table,
260
+ @columns,
261
+ @read_options.merge(resume_token: resume_token)
262
+ )
263
+ end
264
+ end
265
+
266
+ ##
267
+ # @private
268
+ # Retries a request, by re-executing it from scratch.
269
+ def retry_request
270
+ if @execute_query_options
271
+ @service.execute_streaming_sql @session_path, @sql, @execute_query_options
272
+ else
273
+ @service.streaming_read_table @session_path, @table, @columns, @read_options
274
+ end
275
+ end
276
+
201
277
  ##
202
278
  # @private
203
279
  # Get row count from stats. This will be the exact row count for DML
@@ -243,11 +319,11 @@ module Google
243
319
  def self.execute_query service, session_path, sql, params: nil,
244
320
  types: nil, transaction: nil,
245
321
  partition_token: nil, seqno: nil,
246
- query_options: nil
322
+ query_options: nil, call_options: nil
247
323
  execute_query_options = {
248
324
  transaction: transaction, params: params, types: types,
249
325
  partition_token: partition_token, seqno: seqno,
250
- query_options: query_options
326
+ query_options: query_options, call_options: call_options
251
327
  }
252
328
  enum = service.execute_streaming_sql session_path, sql,
253
329
  execute_query_options
@@ -262,10 +338,13 @@ module Google
262
338
  # @private
263
339
  def self.read service, session_path, table, columns, keys: nil,
264
340
  index: nil, limit: nil, transaction: nil,
265
- partition_token: nil
266
- read_options = { keys: keys, index: index, limit: limit,
267
- transaction: transaction,
268
- partition_token: partition_token }
341
+ partition_token: nil, call_options: nil
342
+ read_options = {
343
+ keys: keys, index: index, limit: limit,
344
+ transaction: transaction,
345
+ partition_token: partition_token,
346
+ call_options: call_options
347
+ }
269
348
  enum = service.streaming_read_table \
270
349
  session_path, table, columns, read_options
271
350
  from_enum(enum, service).tap do |results|
@@ -20,7 +20,6 @@ require "google/cloud/spanner/v1"
20
20
  require "google/cloud/spanner/admin/instance/v1"
21
21
  require "google/cloud/spanner/admin/database/v1"
22
22
  require "google/cloud/spanner/convert"
23
- require "uri"
24
23
 
25
24
  module Google
26
25
  module Cloud
@@ -29,18 +28,17 @@ module Google
29
28
  # @private Represents the gRPC Spanner service, including all the API
30
29
  # methods.
31
30
  class Service
32
- attr_accessor :project, :credentials, :timeout, :client_config, :host,
33
- :lib_name, :lib_version
31
+ attr_accessor :project, :credentials, :timeout, :host, :lib_name,
32
+ :lib_version
34
33
 
35
34
  ##
36
35
  # Creates a new Service instance.
37
- def initialize project, credentials, host: nil, timeout: nil,
38
- client_config: nil, lib_name: nil, lib_version: nil
36
+ def initialize project, credentials,
37
+ host: nil, timeout: nil, lib_name: nil, lib_version: nil
39
38
  @project = project
40
39
  @credentials = credentials
41
- @host = host || V1::SpannerClient::SERVICE_ADDRESS
40
+ @host = host
42
41
  @timeout = timeout
43
- @client_config = client_config || {}
44
42
  @lib_name = lib_name
45
43
  @lib_version = lib_version
46
44
  end
@@ -64,45 +62,42 @@ module Google
64
62
  def service
65
63
  return mocked_service if mocked_service
66
64
  @service ||= \
67
- V1::SpannerClient.new(
68
- credentials: channel,
69
- timeout: timeout,
70
- client_config: client_config,
71
- service_address: service_address,
72
- service_port: service_port,
73
- lib_name: lib_name_with_prefix,
74
- lib_version: Google::Cloud::Spanner::VERSION
75
- )
65
+ V1::Spanner::Client.new do |config|
66
+ config.credentials = channel
67
+ config.timeout = timeout if timeout
68
+ config.endpoint = host if host
69
+ config.lib_name = lib_name_with_prefix
70
+ config.lib_version = Google::Cloud::Spanner::VERSION
71
+ config.metadata = { "google-cloud-resource-prefix" => "projects/#{@project}" }
72
+ end
76
73
  end
77
74
  attr_accessor :mocked_service
78
75
 
79
76
  def instances
80
77
  return mocked_instances if mocked_instances
81
78
  @instances ||= \
82
- Admin::Instance::V1::InstanceAdminClient.new(
83
- credentials: channel,
84
- timeout: timeout,
85
- client_config: client_config,
86
- service_address: service_address,
87
- service_port: service_port,
88
- lib_name: lib_name_with_prefix,
89
- lib_version: Google::Cloud::Spanner::VERSION
90
- )
79
+ Admin::Instance::V1::InstanceAdmin::Client.new do |config|
80
+ config.credentials = channel
81
+ config.timeout = timeout if timeout
82
+ config.endpoint = host if host
83
+ config.lib_name = lib_name_with_prefix
84
+ config.lib_version = Google::Cloud::Spanner::VERSION
85
+ config.metadata = { "google-cloud-resource-prefix" => "projects/#{@project}" }
86
+ end
91
87
  end
92
88
  attr_accessor :mocked_instances
93
89
 
94
90
  def databases
95
91
  return mocked_databases if mocked_databases
96
92
  @databases ||= \
97
- Admin::Database::V1::DatabaseAdminClient.new(
98
- credentials: channel,
99
- timeout: timeout,
100
- client_config: client_config,
101
- service_address: service_address,
102
- service_port: service_port,
103
- lib_name: lib_name_with_prefix,
104
- lib_version: Google::Cloud::Spanner::VERSION
105
- )
93
+ Admin::Database::V1::DatabaseAdmin::Client.new do |config|
94
+ config.credentials = channel
95
+ config.timeout = timeout if timeout
96
+ config.endpoint = host if host
97
+ config.lib_name = lib_name_with_prefix
98
+ config.lib_version = Google::Cloud::Spanner::VERSION
99
+ config.metadata = { "google-cloud-resource-prefix" => "projects/#{@project}" }
100
+ end
106
101
  end
107
102
  attr_accessor :mocked_databases
108
103
 
@@ -110,225 +105,239 @@ module Google
110
105
  credentials == :this_channel_is_insecure
111
106
  end
112
107
 
113
- def list_instances token: nil, max: nil
114
- call_options = nil
115
- call_options = Google::Gax::CallOptions.new page_token: token if token
116
-
117
- execute do
118
- paged_enum = instances.list_instances project_path,
119
- page_size: max,
120
- options: call_options
121
-
122
- paged_enum.page.response
123
- end
108
+ def list_instances token: nil, max: nil, call_options: nil
109
+ opts = default_options call_options: call_options
110
+ request = {
111
+ parent: project_path,
112
+ page_size: max,
113
+ page_token: token
114
+ }
115
+ paged_enum = instances.list_instances request, opts
116
+ paged_enum.response
124
117
  end
125
118
 
126
- def get_instance name
127
- execute do
128
- instances.get_instance instance_path(name)
129
- end
119
+ def get_instance name, call_options: nil
120
+ opts = default_options call_options: call_options
121
+ request = { name: instance_path(name) }
122
+ instances.get_instance request, opts
130
123
  end
131
124
 
132
125
  def create_instance instance_id, name: nil, config: nil, nodes: nil,
133
- labels: nil
126
+ labels: nil, call_options: nil
127
+ opts = default_options call_options: call_options
134
128
  labels = Hash[labels.map { |k, v| [String(k), String(v)] }] if labels
135
129
 
136
- create_obj = Google::Spanner::Admin::Instance::V1::Instance.new({
130
+ create_obj = Admin::Instance::V1::Instance.new({
137
131
  display_name: name, config: instance_config_path(config),
138
132
  node_count: nodes, labels: labels
139
133
  }.delete_if { |_, v| v.nil? })
140
134
 
141
- execute do
142
- instances.create_instance project_path, instance_id, create_obj
143
- end
135
+ request = {
136
+ parent: project_path,
137
+ instance_id: instance_id,
138
+ instance: create_obj
139
+ }
140
+ instances.create_instance request, opts
144
141
  end
145
142
 
146
- def update_instance instance_obj
143
+ def update_instance instance, call_options: nil
144
+ opts = default_options call_options: call_options
147
145
  mask = Google::Protobuf::FieldMask.new(
148
146
  paths: %w[display_name node_count labels]
149
147
  )
150
-
151
- execute do
152
- instances.update_instance instance_obj, mask
153
- end
148
+ request = { instance: instance, field_mask: mask }
149
+ instances.update_instance request, opts
154
150
  end
155
151
 
156
- def delete_instance name
157
- execute do
158
- instances.delete_instance instance_path(name)
159
- end
152
+ def delete_instance name, call_options: nil
153
+ opts = default_options call_options: call_options
154
+ request = { name: instance_path(name) }
155
+ instances.delete_instance request, opts
160
156
  end
161
157
 
162
- def get_instance_policy name
163
- execute do
164
- instances.get_iam_policy instance_path(name)
165
- end
158
+ def get_instance_policy name, call_options: nil
159
+ opts = default_options call_options: call_options
160
+ request = { resource: instance_path(name) }
161
+ instances.get_iam_policy request, opts
166
162
  end
167
163
 
168
- def set_instance_policy name, new_policy
169
- execute do
170
- instances.set_iam_policy instance_path(name), new_policy
171
- end
164
+ def set_instance_policy name, new_policy, call_options: nil
165
+ opts = default_options call_options: call_options
166
+ request = {
167
+ resource: instance_path(name),
168
+ policy: new_policy
169
+ }
170
+ instances.set_iam_policy request, opts
172
171
  end
173
172
 
174
- def test_instance_permissions name, permissions
175
- execute do
176
- instances.test_iam_permissions instance_path(name), permissions
177
- end
173
+ def test_instance_permissions name, permissions, call_options: nil
174
+ opts = default_options call_options: call_options
175
+ request = {
176
+ resource: instance_path(name),
177
+ permissions: permissions
178
+ }
179
+ instances.test_iam_permissions request, opts
178
180
  end
179
181
 
180
- def list_instance_configs token: nil, max: nil
181
- call_options = nil
182
- call_options = Google::Gax::CallOptions.new page_token: token if token
183
-
184
- execute do
185
- paged_enum = instances.list_instance_configs project_path,
186
- page_size: max,
187
- options: call_options
188
-
189
- paged_enum.page.response
190
- end
182
+ def list_instance_configs token: nil, max: nil, call_options: nil
183
+ opts = default_options call_options: call_options
184
+ request = { parent: project_path, page_size: max, page_token: token }
185
+ paged_enum = instances.list_instance_configs request, opts
186
+ paged_enum.response
191
187
  end
192
188
 
193
- def get_instance_config name
194
- execute do
195
- instances.get_instance_config instance_config_path(name)
196
- end
189
+ def get_instance_config name, call_options: nil
190
+ opts = default_options call_options: call_options
191
+ request = { name: instance_config_path(name) }
192
+ instances.get_instance_config request, opts
197
193
  end
198
194
 
199
- def list_databases instance_id, token: nil, max: nil
200
- call_options = nil
201
- call_options = Google::Gax::CallOptions.new page_token: token if token
202
-
203
- execute do
204
- paged_enum = databases.list_databases instance_path(instance_id),
205
- page_size: max,
206
- options: call_options
207
-
208
- paged_enum.page.response
209
- end
195
+ def list_databases instance_id, token: nil, max: nil, call_options: nil
196
+ opts = default_options call_options: call_options
197
+ request = {
198
+ parent: instance_path(instance_id),
199
+ page_size: max,
200
+ page_token: token
201
+ }
202
+ paged_enum = databases.list_databases request, opts
203
+ paged_enum.response
210
204
  end
211
205
 
212
- def get_database instance_id, database_id
213
- execute do
214
- databases.get_database database_path(instance_id, database_id)
215
- end
206
+ def get_database instance_id, database_id, call_options: nil
207
+ opts = default_options call_options: call_options
208
+ request = { name: database_path(instance_id, database_id) }
209
+ databases.get_database request, opts
216
210
  end
217
211
 
218
- def create_database instance_id, database_id, statements: []
219
- execute do
220
- databases.create_database \
221
- instance_path(instance_id),
222
- "CREATE DATABASE `#{database_id}`",
223
- extra_statements: Array(statements)
224
- end
212
+ def create_database instance_id, database_id, statements: [],
213
+ call_options: nil
214
+ opts = default_options call_options: call_options
215
+ request = {
216
+ parent: instance_path(instance_id),
217
+ create_statement: "CREATE DATABASE `#{database_id}`",
218
+ extra_statements: Array(statements)
219
+ }
220
+ databases.create_database request, opts
225
221
  end
226
222
 
227
- def drop_database instance_id, database_id
228
- execute do
229
- databases.drop_database database_path(instance_id, database_id)
230
- end
223
+ def drop_database instance_id, database_id, call_options: nil
224
+ opts = default_options call_options: call_options
225
+ request = { database: database_path(instance_id, database_id) }
226
+ databases.drop_database request, opts
231
227
  end
232
228
 
233
- def get_database_ddl instance_id, database_id
234
- execute do
235
- databases.get_database_ddl database_path(instance_id, database_id)
236
- end
229
+ def get_database_ddl instance_id, database_id, call_options: nil
230
+ opts = default_options call_options: call_options
231
+ request = { database: database_path(instance_id, database_id) }
232
+ databases.get_database_ddl request, opts
237
233
  end
238
234
 
239
235
  def update_database_ddl instance_id, database_id, statements: [],
240
- operation_id: nil
241
- execute do
242
- databases.update_database_ddl \
243
- database_path(instance_id, database_id),
244
- Array(statements),
245
- operation_id: operation_id
246
- end
236
+ operation_id: nil, call_options: nil
237
+ opts = default_options call_options: call_options
238
+ request = {
239
+ database: database_path(instance_id, database_id),
240
+ statements: Array(statements),
241
+ operation_id: operation_id
242
+ }
243
+ databases.update_database_ddl request, opts
247
244
  end
248
245
 
249
- def get_database_policy instance_id, database_id
250
- execute do
251
- databases.get_iam_policy database_path(instance_id, database_id)
252
- end
246
+ def get_database_policy instance_id, database_id, call_options: nil
247
+ opts = default_options call_options: call_options
248
+ request = { resource: database_path(instance_id, database_id) }
249
+ databases.get_iam_policy request, opts
253
250
  end
254
251
 
255
- def set_database_policy instance_id, database_id, new_policy
256
- execute do
257
- databases.set_iam_policy \
258
- database_path(instance_id, database_id), new_policy
259
- end
252
+ def set_database_policy instance_id, database_id, new_policy,
253
+ call_options: nil
254
+ opts = default_options call_options: call_options
255
+ request = {
256
+ resource: database_path(instance_id, database_id),
257
+ policy: new_policy
258
+ }
259
+ databases.set_iam_policy request, opts
260
260
  end
261
261
 
262
- def test_database_permissions instance_id, database_id, permissions
263
- execute do
264
- databases.test_iam_permissions \
265
- database_path(instance_id, database_id), permissions
266
- end
262
+ def test_database_permissions instance_id, database_id, permissions,
263
+ call_options: nil
264
+ opts = default_options call_options: call_options
265
+ request = {
266
+ resource: database_path(instance_id, database_id),
267
+ permissions: permissions
268
+ }
269
+ databases.test_iam_permissions request, opts
267
270
  end
268
271
 
269
- def get_session session_name
270
- opts = default_options_from_session session_name
271
- execute do
272
- service.get_session session_name, options: opts
273
- end
272
+ def get_session session_name, call_options: nil
273
+ opts = default_options session_name: session_name,
274
+ call_options: call_options
275
+ service.get_session({ name: session_name }, opts)
274
276
  end
275
277
 
276
- def create_session database_name, labels: nil
277
- opts = default_options_from_session database_name
278
- session = Google::Spanner::V1::Session.new labels: labels if labels
279
- execute do
280
- service.create_session database_name, session: session,
281
- options: opts
282
- end
278
+ def create_session database_name, labels: nil,
279
+ call_options: nil
280
+ opts = default_options session_name: database_name,
281
+ call_options: call_options
282
+ session = V1::Session.new labels: labels if labels
283
+ service.create_session(
284
+ { database: database_name, session: session }, opts
285
+ )
283
286
  end
284
287
 
285
- def batch_create_sessions database_name, session_count, labels: nil
286
- opts = default_options_from_session database_name
287
- session = Google::Spanner::V1::Session.new labels: labels if labels
288
- execute do
289
- # The response may have fewer sessions than requested in the RPC.
290
- service.batch_create_sessions database_name,
291
- session_count,
292
- session_template: session,
293
- options: opts
294
- end
288
+ def batch_create_sessions database_name, session_count, labels: nil,
289
+ call_options: nil
290
+ opts = default_options session_name: database_name,
291
+ call_options: call_options
292
+ session = V1::Session.new labels: labels if labels
293
+ # The response may have fewer sessions than requested in the RPC.
294
+ request = {
295
+ database: database_name,
296
+ session_count: session_count,
297
+ session_template: session
298
+ }
299
+ service.batch_create_sessions request, opts
295
300
  end
296
301
 
297
- def delete_session session_name
298
- opts = default_options_from_session session_name
299
- execute do
300
- service.delete_session session_name, options: opts
301
- end
302
+ def delete_session session_name, call_options: nil
303
+ opts = default_options session_name: session_name,
304
+ call_options: call_options
305
+ service.delete_session({ name: session_name }, opts)
302
306
  end
303
307
 
304
308
  def execute_streaming_sql session_name, sql, transaction: nil,
305
309
  params: nil, types: nil, resume_token: nil,
306
310
  partition_token: nil, seqno: nil,
307
- query_options: nil
308
- opts = default_options_from_session session_name
309
- execute do
310
- service.execute_streaming_sql \
311
- session_name, sql, transaction: transaction,
312
- params: params,
313
- param_types: types,
314
- resume_token: resume_token,
315
- partition_token: partition_token,
316
- seqno: seqno,
317
- query_options: query_options,
318
- options: opts
319
- end
311
+ query_options: nil, call_options: nil
312
+ opts = default_options session_name: session_name,
313
+ call_options: call_options
314
+ request = {
315
+ session: session_name,
316
+ sql: sql,
317
+ transaction: transaction,
318
+ params: params,
319
+ param_types: types,
320
+ resume_token: resume_token,
321
+ partition_token: partition_token,
322
+ seqno: seqno,
323
+ query_options: query_options
324
+ }
325
+ service.execute_streaming_sql request, opts
320
326
  end
321
327
 
322
- def execute_batch_dml session_name, transaction, statements, seqno
323
- opts = default_options_from_session session_name
328
+ def execute_batch_dml session_name, transaction, statements, seqno,
329
+ call_options: nil
330
+ opts = default_options session_name: session_name,
331
+ call_options: call_options
324
332
  statements = statements.map(&:to_grpc)
325
- results = execute do
326
- service.execute_batch_dml session_name,
327
- transaction,
328
- statements,
329
- seqno,
330
- options: opts
331
- end
333
+ request = {
334
+ session: session_name,
335
+ transaction: transaction,
336
+ statements: statements,
337
+ seqno: seqno
338
+ }
339
+ results = service.execute_batch_dml request, opts
340
+
332
341
  if results.status.code.zero?
333
342
  results.result_sets.map { |rs| rs.stats.row_count_exact }
334
343
  else
@@ -342,87 +351,94 @@ module Google
342
351
 
343
352
  def streaming_read_table session_name, table_name, columns, keys: nil,
344
353
  index: nil, transaction: nil, limit: nil,
345
- resume_token: nil, partition_token: nil
346
- opts = default_options_from_session session_name
347
- execute do
348
- service.streaming_read \
349
- session_name, table_name, columns, keys,
350
- transaction: transaction, index: index, limit: limit,
351
- resume_token: resume_token, partition_token: partition_token,
352
- options: opts
353
- end
354
+ resume_token: nil, partition_token: nil,
355
+ call_options: nil
356
+ opts = default_options session_name: session_name,
357
+ call_options: call_options
358
+ request = {
359
+ session: session_name, table: table_name, columns: columns,
360
+ key_set: keys, transaction: transaction, index: index,
361
+ limit: limit, resume_token: resume_token,
362
+ partition_token: partition_token
363
+ }
364
+ service.streaming_read request, opts
354
365
  end
355
366
 
356
367
  def partition_read session_name, table_name, columns, transaction,
357
368
  keys: nil, index: nil, partition_size_bytes: nil,
358
- max_partitions: nil
369
+ max_partitions: nil, call_options: nil
359
370
  partition_opts = partition_options partition_size_bytes,
360
371
  max_partitions
361
372
 
362
- opts = default_options_from_session session_name
363
-
364
- execute do
365
- service.partition_read \
366
- session_name, table_name, keys,
367
- transaction: transaction, index: index, columns: columns,
368
- partition_options: partition_opts, options: opts
369
- end
373
+ opts = default_options session_name: session_name,
374
+ call_options: call_options
375
+ request = {
376
+ session: session_name, table: table_name, key_set: keys,
377
+ transaction: transaction, index: index, columns: columns,
378
+ partition_options: partition_opts
379
+ }
380
+ service.partition_read request, opts
370
381
  end
371
382
 
372
383
  def partition_query session_name, sql, transaction, params: nil,
373
384
  types: nil, partition_size_bytes: nil,
374
- max_partitions: nil
385
+ max_partitions: nil, call_options: nil
375
386
  partition_opts = partition_options partition_size_bytes,
376
387
  max_partitions
377
388
 
378
- opts = default_options_from_session session_name
379
-
380
- execute do
381
- service.partition_query \
382
- session_name, sql,
383
- transaction: transaction,
384
- params: params, param_types: types,
385
- partition_options: partition_opts, options: opts
386
- end
389
+ opts = default_options session_name: session_name,
390
+ call_options: call_options
391
+ request = {
392
+ session: session_name, sql: sql, transaction: transaction,
393
+ params: params, param_types: types,
394
+ partition_options: partition_opts
395
+ }
396
+ service.partition_query request, opts
387
397
  end
388
398
 
389
- def commit session_name, mutations = [], transaction_id: nil
399
+ def commit session_name, mutations = [], transaction_id: nil,
400
+ commit_options: nil, call_options: nil
390
401
  tx_opts = nil
391
402
  if transaction_id.nil?
392
- tx_opts = Google::Spanner::V1::TransactionOptions.new(
393
- read_write: Google::Spanner::V1::TransactionOptions::ReadWrite.new
403
+ tx_opts = V1::TransactionOptions.new(
404
+ read_write: V1::TransactionOptions::ReadWrite.new
394
405
  )
395
406
  end
396
- opts = default_options_from_session session_name
397
- execute do
398
- service.commit \
399
- session_name, mutations,
400
- transaction_id: transaction_id, single_use_transaction: tx_opts,
401
- options: opts
407
+ opts = default_options session_name: session_name,
408
+ call_options: call_options
409
+ request = {
410
+ session: session_name, transaction_id: transaction_id,
411
+ single_use_transaction: tx_opts, mutations: mutations
412
+ }
413
+
414
+ if commit_options
415
+ request[:return_commit_stats] = commit_options[:return_commit_stats]
402
416
  end
417
+
418
+ service.commit request, opts
403
419
  end
404
420
 
405
- def rollback session_name, transaction_id
406
- opts = default_options_from_session session_name
407
- execute do
408
- service.rollback session_name, transaction_id, options: opts
409
- end
421
+ def rollback session_name, transaction_id, call_options: nil
422
+ opts = default_options session_name: session_name,
423
+ call_options: call_options
424
+ request = { session: session_name, transaction_id: transaction_id }
425
+ service.rollback request, opts
410
426
  end
411
427
 
412
- def begin_transaction session_name
413
- tx_opts = Google::Spanner::V1::TransactionOptions.new(
414
- read_write: Google::Spanner::V1::TransactionOptions::ReadWrite.new
428
+ def begin_transaction session_name, call_options: nil
429
+ tx_opts = V1::TransactionOptions.new(
430
+ read_write: V1::TransactionOptions::ReadWrite.new
415
431
  )
416
- opts = default_options_from_session session_name
417
- execute do
418
- service.begin_transaction session_name, tx_opts, options: opts
419
- end
432
+ opts = default_options session_name: session_name,
433
+ call_options: call_options
434
+ request = { session: session_name, options: tx_opts }
435
+ service.begin_transaction request, opts
420
436
  end
421
437
 
422
438
  def create_snapshot session_name, strong: nil, timestamp: nil,
423
- staleness: nil
424
- tx_opts = Google::Spanner::V1::TransactionOptions.new(
425
- read_only: Google::Spanner::V1::TransactionOptions::ReadOnly.new(
439
+ staleness: nil, call_options: nil
440
+ tx_opts = V1::TransactionOptions.new(
441
+ read_only: V1::TransactionOptions::ReadOnly.new(
426
442
  {
427
443
  strong: strong,
428
444
  read_timestamp: Convert.time_to_timestamp(timestamp),
@@ -431,92 +447,107 @@ module Google
431
447
  }.delete_if { |_, v| v.nil? }
432
448
  )
433
449
  )
434
- opts = default_options_from_session session_name
435
- execute do
436
- service.begin_transaction session_name, tx_opts, options: opts
437
- end
450
+ opts = default_options session_name: session_name,
451
+ call_options: call_options
452
+ request = { session: session_name, options: tx_opts }
453
+ service.begin_transaction request, opts
438
454
  end
439
455
 
440
- def create_pdml session_name
441
- tx_opts = Google::Spanner::V1::TransactionOptions.new(
442
- partitioned_dml: \
443
- Google::Spanner::V1::TransactionOptions::PartitionedDml.new
456
+ def create_pdml session_name, call_options: nil
457
+ tx_opts = V1::TransactionOptions.new(
458
+ partitioned_dml: V1::TransactionOptions::PartitionedDml.new
444
459
  )
445
- opts = default_options_from_session session_name
446
- execute do
447
- service.begin_transaction session_name, tx_opts, options: opts
448
- end
460
+ opts = default_options session_name: session_name,
461
+ call_options: call_options
462
+ request = { session: session_name, options: tx_opts }
463
+ service.begin_transaction request, opts
449
464
  end
450
465
 
451
- def create_backup instance_id, database_id, backup_id, expire_time
466
+ def create_backup instance_id, database_id, backup_id, expire_time,
467
+ call_options: nil
468
+ opts = default_options call_options: call_options
452
469
  backup = {
453
470
  database: database_path(instance_id, database_id),
454
471
  expire_time: expire_time
455
472
  }
456
- execute do
457
- databases.create_backup \
458
- instance_path(instance_id),
459
- backup_id,
460
- backup
461
- end
462
- end
463
-
464
- def get_backup instance_id, backup_id
465
- execute do
466
- databases.get_backup backup_path(instance_id, backup_id)
467
- end
468
- end
469
-
470
- def update_backup backup, update_mask
471
- execute do
472
- databases.update_backup backup, update_mask
473
- end
473
+ request = {
474
+ parent: instance_path(instance_id),
475
+ backup_id: backup_id,
476
+ backup: backup
477
+ }
478
+ databases.create_backup request, opts
474
479
  end
475
480
 
476
- def delete_backup instance_id, backup_id
477
- execute do
478
- databases.delete_backup backup_path(instance_id, backup_id)
479
- end
481
+ def get_backup instance_id, backup_id, call_options: nil
482
+ opts = default_options call_options: call_options
483
+ request = { name: backup_path(instance_id, backup_id) }
484
+ databases.get_backup request, opts
480
485
  end
481
486
 
482
- def list_backups instance_id, filter: nil, page_size: nil
483
- execute do
484
- databases.list_backups \
485
- instance_path(instance_id),
486
- filter,
487
- page_size: page_size
488
- end
487
+ def update_backup backup, update_mask, call_options: nil
488
+ opts = default_options call_options: call_options
489
+ request = { backup: backup, update_mask: update_mask }
490
+ databases.update_backup request, opts
489
491
  end
490
492
 
491
- def list_database_operations instance_id, filter: nil, page_size: nil
492
- execute do
493
- databases.list_database_operations \
494
- instance_path(instance_id),
495
- filter,
496
- page_size: page_size
497
- end
493
+ def delete_backup instance_id, backup_id, call_options: nil
494
+ opts = default_options call_options: call_options
495
+ request = { name: backup_path(instance_id, backup_id) }
496
+ databases.delete_backup request, opts
498
497
  end
499
498
 
500
- def list_backup_operations instance_id, filter: nil, page_size: nil
501
- execute do
502
- databases.list_backup_operations \
503
- instance_path(instance_id),
504
- filter,
505
- page_size: page_size
506
- end
499
+ def list_backups instance_id,
500
+ filter: nil, page_size: nil, page_token: nil,
501
+ call_options: nil
502
+ opts = default_options call_options: call_options
503
+ request = {
504
+ parent: instance_path(instance_id),
505
+ filter: filter,
506
+ page_size: page_size,
507
+ page_token: page_token
508
+ }
509
+ databases.list_backups request, opts
510
+ end
511
+
512
+ def list_database_operations instance_id,
513
+ filter: nil,
514
+ page_size: nil,
515
+ page_token: nil,
516
+ call_options: nil
517
+ opts = default_options call_options: call_options
518
+ request = {
519
+ parent: instance_path(instance_id),
520
+ filter: filter,
521
+ page_size: page_size,
522
+ page_token: page_token
523
+ }
524
+ databases.list_database_operations request, opts
525
+ end
526
+
527
+ def list_backup_operations instance_id,
528
+ filter: nil, page_size: nil,
529
+ page_token: nil,
530
+ call_options: nil
531
+ opts = default_options call_options: call_options
532
+ request = {
533
+ parent: instance_path(instance_id),
534
+ filter: filter,
535
+ page_size: page_size,
536
+ page_token: page_token
537
+ }
538
+ databases.list_backup_operations request, opts
507
539
  end
508
540
 
509
- def restore_database \
510
- backup_instance_id,
511
- backup_id,
512
- database_instance_id,
513
- database_id
514
- execute do
515
- databases.restore_database \
516
- instance_path(database_instance_id),
517
- database_id,
518
- backup: backup_path(backup_instance_id, backup_id)
519
- end
541
+ def restore_database backup_instance_id, backup_id,
542
+ database_instance_id, database_id,
543
+ call_options: nil
544
+ opts = default_options call_options: call_options
545
+ request = {
546
+ parent: instance_path(database_instance_id),
547
+ database_id: database_id,
548
+ backup: backup_path(backup_instance_id, backup_id)
549
+ }
550
+ databases.restore_database request, opts
520
551
  end
521
552
 
522
553
  def inspect
@@ -525,16 +556,6 @@ module Google
525
556
 
526
557
  protected
527
558
 
528
- def service_address
529
- return nil if host.nil?
530
- URI.parse("//#{host}").host
531
- end
532
-
533
- def service_port
534
- return nil if host.nil?
535
- URI.parse("//#{host}").port
536
- end
537
-
538
559
  def lib_name_with_prefix
539
560
  return "gccl" if [nil, "gccl"].include? lib_name
540
561
 
@@ -543,15 +564,22 @@ module Google
543
564
  value << " gccl"
544
565
  end
545
566
 
546
- def default_options_from_session session_name
547
- default_prefix = session_name.split("/sessions/").first
548
- Google::Gax::CallOptions.new kwargs: \
549
- { "google-cloud-resource-prefix" => default_prefix }
567
+ def default_options session_name: nil, call_options: nil
568
+ opts = {}
569
+ if session_name
570
+ default_prefix = session_name.split("/sessions/").first
571
+ opts[:metadata] = { "google-cloud-resource-prefix" => default_prefix }
572
+ end
573
+ if call_options
574
+ opts[:timeout] = call_options[:timeout] if call_options[:timeout]
575
+ opts[:retry_policy] = call_options[:retry_policy] if call_options[:retry_policy]
576
+ end
577
+ return opts unless opts.empty?
550
578
  end
551
579
 
552
580
  def partition_options partition_size_bytes, max_partitions
553
581
  return nil unless partition_size_bytes || max_partitions
554
- partition_opts = Google::Spanner::V1::PartitionOptions.new
582
+ partition_opts = V1::PartitionOptions.new
555
583
  if partition_size_bytes
556
584
  partition_opts.partition_size_bytes = partition_size_bytes
557
585
  end
@@ -560,48 +588,38 @@ module Google
560
588
  end
561
589
 
562
590
  def project_path
563
- Admin::Instance::V1::InstanceAdminClient.project_path project
591
+ Admin::Instance::V1::InstanceAdmin::Paths.project_path \
592
+ project: project
564
593
  end
565
594
 
566
595
  def instance_path name
567
596
  return name if name.to_s.include? "/"
568
- Admin::Instance::V1::InstanceAdminClient.instance_path(
569
- project, name
570
- )
597
+
598
+ Admin::Instance::V1::InstanceAdmin::Paths.instance_path \
599
+ project: project, instance: name
571
600
  end
572
601
 
573
602
  def instance_config_path name
574
603
  return name if name.to_s.include? "/"
575
- Admin::Instance::V1::InstanceAdminClient.instance_config_path(
576
- project, name.to_s
577
- )
604
+
605
+ Admin::Instance::V1::InstanceAdmin::Paths.instance_config_path \
606
+ project: project, instance_config: name
578
607
  end
579
608
 
580
609
  def database_path instance_id, database_id
581
- Admin::Database::V1::DatabaseAdminClient.database_path(
582
- project, instance_id, database_id
583
- )
610
+ Admin::Database::V1::DatabaseAdmin::Paths.database_path \
611
+ project: project, instance: instance_id, database: database_id
584
612
  end
585
613
 
586
614
  def session_path instance_id, database_id, session_id
587
- V1::SpannerClient.session_path(
588
- project, instance_id, database_id, session_id
589
- )
615
+ V1::Spanner::Paths.session_path \
616
+ project: project, instance: instance_id, database: database_id,
617
+ session: session_id
590
618
  end
591
619
 
592
620
  def backup_path instance_id, backup_id
593
- Admin::Database::V1::DatabaseAdminClient.backup_path(
594
- project, instance_id, backup_id
595
- )
596
- end
597
-
598
- def execute
599
- yield
600
- rescue Google::Gax::GaxError => e
601
- # GaxError wraps BadStatus, but exposes it as #cause
602
- raise Google::Cloud::Error.from_error(e.cause)
603
- rescue GRPC::BadStatus => e
604
- raise Google::Cloud::Error.from_error(e)
621
+ Admin::Database::V1::DatabaseAdmin::Paths.backup_path \
622
+ project: project, instance: instance_id, backup: backup_id
605
623
  end
606
624
  end
607
625
  end