google-cloud-spanner 1.16.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. checksums.yaml +4 -4
  2. data/AUTHENTICATION.md +1 -1
  3. data/CHANGELOG.md +54 -0
  4. data/CONTRIBUTING.md +5 -5
  5. data/TROUBLESHOOTING.md +0 -6
  6. data/lib/google-cloud-spanner.rb +11 -13
  7. data/lib/google/cloud/spanner.rb +6 -8
  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 +189 -30
  19. data/lib/google/cloud/spanner/commit.rb +14 -14
  20. data/lib/google/cloud/spanner/convert.rb +16 -7
  21. data/lib/google/cloud/spanner/credentials.rb +2 -2
  22. data/lib/google/cloud/spanner/data.rb +2 -2
  23. data/lib/google/cloud/spanner/database.rb +22 -22
  24. data/lib/google/cloud/spanner/database/backup_info.rb +1 -1
  25. data/lib/google/cloud/spanner/database/job.rb +3 -3
  26. data/lib/google/cloud/spanner/database/job/list.rb +2 -2
  27. data/lib/google/cloud/spanner/database/list.rb +1 -1
  28. data/lib/google/cloud/spanner/database/restore_info.rb +1 -1
  29. data/lib/google/cloud/spanner/fields.rb +8 -8
  30. data/lib/google/cloud/spanner/instance.rb +5 -12
  31. data/lib/google/cloud/spanner/instance/config.rb +1 -1
  32. data/lib/google/cloud/spanner/instance/config/list.rb +1 -1
  33. data/lib/google/cloud/spanner/instance/job.rb +2 -2
  34. data/lib/google/cloud/spanner/instance/list.rb +1 -1
  35. data/lib/google/cloud/spanner/partition.rb +4 -4
  36. data/lib/google/cloud/spanner/policy.rb +2 -2
  37. data/lib/google/cloud/spanner/results.rb +103 -24
  38. data/lib/google/cloud/spanner/service.rb +363 -350
  39. data/lib/google/cloud/spanner/session.rb +186 -31
  40. data/lib/google/cloud/spanner/snapshot.rb +60 -6
  41. data/lib/google/cloud/spanner/transaction.rb +116 -10
  42. data/lib/google/cloud/spanner/version.rb +1 -1
  43. metadata +20 -109
  44. data/lib/google/cloud/spanner/admin/database.rb +0 -149
  45. data/lib/google/cloud/spanner/admin/database/v1.rb +0 -147
  46. data/lib/google/cloud/spanner/admin/database/v1/credentials.rb +0 -46
  47. data/lib/google/cloud/spanner/admin/database/v1/database_admin_client.rb +0 -1513
  48. data/lib/google/cloud/spanner/admin/database/v1/database_admin_client_config.json +0 -111
  49. data/lib/google/cloud/spanner/admin/database/v1/doc/google/iam/v1/iam_policy.rb +0 -64
  50. data/lib/google/cloud/spanner/admin/database/v1/doc/google/iam/v1/options.rb +0 -33
  51. data/lib/google/cloud/spanner/admin/database/v1/doc/google/iam/v1/policy.rb +0 -151
  52. data/lib/google/cloud/spanner/admin/database/v1/doc/google/longrunning/operations.rb +0 -51
  53. data/lib/google/cloud/spanner/admin/database/v1/doc/google/protobuf/any.rb +0 -131
  54. data/lib/google/cloud/spanner/admin/database/v1/doc/google/protobuf/empty.rb +0 -29
  55. data/lib/google/cloud/spanner/admin/database/v1/doc/google/protobuf/field_mask.rb +0 -222
  56. data/lib/google/cloud/spanner/admin/database/v1/doc/google/protobuf/timestamp.rb +0 -113
  57. data/lib/google/cloud/spanner/admin/database/v1/doc/google/rpc/status.rb +0 -39
  58. data/lib/google/cloud/spanner/admin/database/v1/doc/google/spanner/admin/database/v1/backup.rb +0 -325
  59. data/lib/google/cloud/spanner/admin/database/v1/doc/google/spanner/admin/database/v1/spanner_database_admin.rb +0 -368
  60. data/lib/google/cloud/spanner/admin/database/v1/doc/google/type/expr.rb +0 -45
  61. data/lib/google/cloud/spanner/admin/instance.rb +0 -164
  62. data/lib/google/cloud/spanner/admin/instance/v1.rb +0 -162
  63. data/lib/google/cloud/spanner/admin/instance/v1/credentials.rb +0 -46
  64. data/lib/google/cloud/spanner/admin/instance/v1/doc/google/iam/v1/iam_policy.rb +0 -64
  65. data/lib/google/cloud/spanner/admin/instance/v1/doc/google/iam/v1/options.rb +0 -33
  66. data/lib/google/cloud/spanner/admin/instance/v1/doc/google/iam/v1/policy.rb +0 -151
  67. data/lib/google/cloud/spanner/admin/instance/v1/doc/google/longrunning/operations.rb +0 -51
  68. data/lib/google/cloud/spanner/admin/instance/v1/doc/google/protobuf/any.rb +0 -131
  69. data/lib/google/cloud/spanner/admin/instance/v1/doc/google/protobuf/empty.rb +0 -29
  70. data/lib/google/cloud/spanner/admin/instance/v1/doc/google/protobuf/field_mask.rb +0 -222
  71. data/lib/google/cloud/spanner/admin/instance/v1/doc/google/rpc/status.rb +0 -39
  72. data/lib/google/cloud/spanner/admin/instance/v1/doc/google/spanner/admin/instance/v1/spanner_instance_admin.rb +0 -334
  73. data/lib/google/cloud/spanner/admin/instance/v1/doc/google/type/expr.rb +0 -45
  74. data/lib/google/cloud/spanner/admin/instance/v1/instance_admin_client.rb +0 -975
  75. data/lib/google/cloud/spanner/admin/instance/v1/instance_admin_client_config.json +0 -76
  76. data/lib/google/cloud/spanner/v1.rb +0 -16
  77. data/lib/google/cloud/spanner/v1/credentials.rb +0 -42
  78. data/lib/google/cloud/spanner/v1/doc/google/protobuf/any.rb +0 -131
  79. data/lib/google/cloud/spanner/v1/doc/google/protobuf/duration.rb +0 -91
  80. data/lib/google/cloud/spanner/v1/doc/google/protobuf/empty.rb +0 -29
  81. data/lib/google/cloud/spanner/v1/doc/google/protobuf/struct.rb +0 -74
  82. data/lib/google/cloud/spanner/v1/doc/google/protobuf/timestamp.rb +0 -113
  83. data/lib/google/cloud/spanner/v1/doc/google/rpc/status.rb +0 -39
  84. data/lib/google/cloud/spanner/v1/doc/google/spanner/v1/keys.rb +0 -150
  85. data/lib/google/cloud/spanner/v1/doc/google/spanner/v1/mutation.rb +0 -95
  86. data/lib/google/cloud/spanner/v1/doc/google/spanner/v1/query_plan.rb +0 -121
  87. data/lib/google/cloud/spanner/v1/doc/google/spanner/v1/result_set.rb +0 -190
  88. data/lib/google/cloud/spanner/v1/doc/google/spanner/v1/spanner.rb +0 -570
  89. data/lib/google/cloud/spanner/v1/doc/google/spanner/v1/transaction.rb +0 -432
  90. data/lib/google/cloud/spanner/v1/doc/google/spanner/v1/type.rb +0 -112
  91. data/lib/google/cloud/spanner/v1/spanner_client.rb +0 -1485
  92. data/lib/google/cloud/spanner/v1/spanner_client_config.json +0 -121
  93. data/lib/google/spanner/admin/database/v1/backup_pb.rb +0 -98
  94. data/lib/google/spanner/admin/database/v1/common_pb.rb +0 -28
  95. data/lib/google/spanner/admin/database/v1/spanner_database_admin_pb.rb +0 -141
  96. data/lib/google/spanner/admin/database/v1/spanner_database_admin_services_pb.rb +0 -169
  97. data/lib/google/spanner/admin/instance/v1/spanner_instance_admin_pb.rb +0 -125
  98. data/lib/google/spanner/admin/instance/v1/spanner_instance_admin_services_pb.rb +0 -181
  99. data/lib/google/spanner/v1/keys_pb.rb +0 -34
  100. data/lib/google/spanner/v1/mutation_pb.rb +0 -39
  101. data/lib/google/spanner/v1/query_plan_pb.rb +0 -48
  102. data/lib/google/spanner/v1/result_set_pb.rb +0 -48
  103. data/lib/google/spanner/v1/spanner_pb.rb +0 -179
  104. data/lib/google/spanner/v1/spanner_services_pb.rb +0 -179
  105. data/lib/google/spanner/v1/transaction_pb.rb +0 -56
  106. data/lib/google/spanner/v1/type_pb.rb +0 -44
@@ -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,89 @@ 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
+ 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
402
- end
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
+ service.commit request, opts
403
414
  end
404
415
 
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
416
+ def rollback session_name, transaction_id, call_options: nil
417
+ opts = default_options session_name: session_name,
418
+ call_options: call_options
419
+ request = { session: session_name, transaction_id: transaction_id }
420
+ service.rollback request, opts
410
421
  end
411
422
 
412
- def begin_transaction session_name
413
- tx_opts = Google::Spanner::V1::TransactionOptions.new(
414
- read_write: Google::Spanner::V1::TransactionOptions::ReadWrite.new
423
+ def begin_transaction session_name, call_options: nil
424
+ tx_opts = V1::TransactionOptions.new(
425
+ read_write: V1::TransactionOptions::ReadWrite.new
415
426
  )
416
- opts = default_options_from_session session_name
417
- execute do
418
- service.begin_transaction session_name, tx_opts, options: opts
419
- end
427
+ opts = default_options session_name: session_name,
428
+ call_options: call_options
429
+ request = { session: session_name, options: tx_opts }
430
+ service.begin_transaction request, opts
420
431
  end
421
432
 
422
433
  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(
434
+ staleness: nil, call_options: nil
435
+ tx_opts = V1::TransactionOptions.new(
436
+ read_only: V1::TransactionOptions::ReadOnly.new(
426
437
  {
427
438
  strong: strong,
428
439
  read_timestamp: Convert.time_to_timestamp(timestamp),
@@ -431,92 +442,107 @@ module Google
431
442
  }.delete_if { |_, v| v.nil? }
432
443
  )
433
444
  )
434
- opts = default_options_from_session session_name
435
- execute do
436
- service.begin_transaction session_name, tx_opts, options: opts
437
- end
445
+ opts = default_options session_name: session_name,
446
+ call_options: call_options
447
+ request = { session: session_name, options: tx_opts }
448
+ service.begin_transaction request, opts
438
449
  end
439
450
 
440
- def create_pdml session_name
441
- tx_opts = Google::Spanner::V1::TransactionOptions.new(
442
- partitioned_dml: \
443
- Google::Spanner::V1::TransactionOptions::PartitionedDml.new
451
+ def create_pdml session_name, call_options: nil
452
+ tx_opts = V1::TransactionOptions.new(
453
+ partitioned_dml: V1::TransactionOptions::PartitionedDml.new
444
454
  )
445
- opts = default_options_from_session session_name
446
- execute do
447
- service.begin_transaction session_name, tx_opts, options: opts
448
- end
455
+ opts = default_options session_name: session_name,
456
+ call_options: call_options
457
+ request = { session: session_name, options: tx_opts }
458
+ service.begin_transaction request, opts
449
459
  end
450
460
 
451
- def create_backup instance_id, database_id, backup_id, expire_time
461
+ def create_backup instance_id, database_id, backup_id, expire_time,
462
+ call_options: nil
463
+ opts = default_options call_options: call_options
452
464
  backup = {
453
465
  database: database_path(instance_id, database_id),
454
466
  expire_time: expire_time
455
467
  }
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
+ request = {
469
+ parent: instance_path(instance_id),
470
+ backup_id: backup_id,
471
+ backup: backup
472
+ }
473
+ databases.create_backup request, opts
468
474
  end
469
475
 
470
- def update_backup backup, update_mask
471
- execute do
472
- databases.update_backup backup, update_mask
473
- end
476
+ def get_backup instance_id, backup_id, call_options: nil
477
+ opts = default_options call_options: call_options
478
+ request = { name: backup_path(instance_id, backup_id) }
479
+ databases.get_backup request, opts
474
480
  end
475
481
 
476
- def delete_backup instance_id, backup_id
477
- execute do
478
- databases.delete_backup backup_path(instance_id, backup_id)
479
- end
482
+ def update_backup backup, update_mask, call_options: nil
483
+ opts = default_options call_options: call_options
484
+ request = { backup: backup, update_mask: update_mask }
485
+ databases.update_backup request, opts
480
486
  end
481
487
 
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
488
+ def delete_backup instance_id, backup_id, call_options: nil
489
+ opts = default_options call_options: call_options
490
+ request = { name: backup_path(instance_id, backup_id) }
491
+ databases.delete_backup request, opts
489
492
  end
490
493
 
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
498
- end
499
-
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
494
+ def list_backups instance_id,
495
+ filter: nil, page_size: nil, page_token: nil,
496
+ call_options: nil
497
+ opts = default_options call_options: call_options
498
+ request = {
499
+ parent: instance_path(instance_id),
500
+ filter: filter,
501
+ page_size: page_size,
502
+ page_token: page_token
503
+ }
504
+ databases.list_backups request, opts
505
+ end
506
+
507
+ def list_database_operations instance_id,
508
+ filter: nil,
509
+ page_size: nil,
510
+ page_token: nil,
511
+ call_options: nil
512
+ opts = default_options call_options: call_options
513
+ request = {
514
+ parent: instance_path(instance_id),
515
+ filter: filter,
516
+ page_size: page_size,
517
+ page_token: page_token
518
+ }
519
+ databases.list_database_operations request, opts
520
+ end
521
+
522
+ def list_backup_operations instance_id,
523
+ filter: nil, page_size: nil,
524
+ page_token: nil,
525
+ call_options: nil
526
+ opts = default_options call_options: call_options
527
+ request = {
528
+ parent: instance_path(instance_id),
529
+ filter: filter,
530
+ page_size: page_size,
531
+ page_token: page_token
532
+ }
533
+ databases.list_backup_operations request, opts
507
534
  end
508
535
 
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
536
+ def restore_database backup_instance_id, backup_id,
537
+ database_instance_id, database_id,
538
+ call_options: nil
539
+ opts = default_options call_options: call_options
540
+ request = {
541
+ parent: instance_path(database_instance_id),
542
+ database_id: database_id,
543
+ backup: backup_path(backup_instance_id, backup_id)
544
+ }
545
+ databases.restore_database request, opts
520
546
  end
521
547
 
522
548
  def inspect
@@ -525,16 +551,6 @@ module Google
525
551
 
526
552
  protected
527
553
 
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
554
  def lib_name_with_prefix
539
555
  return "gccl" if [nil, "gccl"].include? lib_name
540
556
 
@@ -543,15 +559,22 @@ module Google
543
559
  value << " gccl"
544
560
  end
545
561
 
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 }
562
+ def default_options session_name: nil, call_options: nil
563
+ opts = {}
564
+ if session_name
565
+ default_prefix = session_name.split("/sessions/").first
566
+ opts[:metadata] = { "google-cloud-resource-prefix" => default_prefix }
567
+ end
568
+ if call_options
569
+ opts[:timeout] = call_options[:timeout] if call_options[:timeout]
570
+ opts[:retry_policy] = call_options[:retry_policy] if call_options[:retry_policy]
571
+ end
572
+ return opts unless opts.empty?
550
573
  end
551
574
 
552
575
  def partition_options partition_size_bytes, max_partitions
553
576
  return nil unless partition_size_bytes || max_partitions
554
- partition_opts = Google::Spanner::V1::PartitionOptions.new
577
+ partition_opts = V1::PartitionOptions.new
555
578
  if partition_size_bytes
556
579
  partition_opts.partition_size_bytes = partition_size_bytes
557
580
  end
@@ -560,48 +583,38 @@ module Google
560
583
  end
561
584
 
562
585
  def project_path
563
- Admin::Instance::V1::InstanceAdminClient.project_path project
586
+ Admin::Instance::V1::InstanceAdmin::Paths.project_path \
587
+ project: project
564
588
  end
565
589
 
566
590
  def instance_path name
567
591
  return name if name.to_s.include? "/"
568
- Admin::Instance::V1::InstanceAdminClient.instance_path(
569
- project, name
570
- )
592
+
593
+ Admin::Instance::V1::InstanceAdmin::Paths.instance_path \
594
+ project: project, instance: name
571
595
  end
572
596
 
573
597
  def instance_config_path name
574
598
  return name if name.to_s.include? "/"
575
- Admin::Instance::V1::InstanceAdminClient.instance_config_path(
576
- project, name.to_s
577
- )
599
+
600
+ Admin::Instance::V1::InstanceAdmin::Paths.instance_config_path \
601
+ project: project, instance_config: name
578
602
  end
579
603
 
580
604
  def database_path instance_id, database_id
581
- Admin::Database::V1::DatabaseAdminClient.database_path(
582
- project, instance_id, database_id
583
- )
605
+ Admin::Database::V1::DatabaseAdmin::Paths.database_path \
606
+ project: project, instance: instance_id, database: database_id
584
607
  end
585
608
 
586
609
  def session_path instance_id, database_id, session_id
587
- V1::SpannerClient.session_path(
588
- project, instance_id, database_id, session_id
589
- )
610
+ V1::Spanner::Paths.session_path \
611
+ project: project, instance: instance_id, database: database_id,
612
+ session: session_id
590
613
  end
591
614
 
592
615
  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)
616
+ Admin::Database::V1::DatabaseAdmin::Paths.backup_path \
617
+ project: project, instance: instance_id, backup: backup_id
605
618
  end
606
619
  end
607
620
  end