google-cloud-spanner 2.3.0 → 2.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +64 -0
  3. data/CONTRIBUTING.md +1 -1
  4. data/LOGGING.md +1 -1
  5. data/OVERVIEW.md +1 -1
  6. data/lib/google-cloud-spanner.rb +2 -0
  7. data/lib/google/cloud/spanner/backup.rb +75 -4
  8. data/lib/google/cloud/spanner/backup/job.rb +8 -8
  9. data/lib/google/cloud/spanner/backup/job/list.rb +2 -2
  10. data/lib/google/cloud/spanner/backup/list.rb +2 -2
  11. data/lib/google/cloud/spanner/batch_snapshot.rb +11 -4
  12. data/lib/google/cloud/spanner/batch_update.rb +3 -1
  13. data/lib/google/cloud/spanner/client.rb +315 -83
  14. data/lib/google/cloud/spanner/commit.rb +4 -0
  15. data/lib/google/cloud/spanner/data.rb +4 -5
  16. data/lib/google/cloud/spanner/database.rb +111 -3
  17. data/lib/google/cloud/spanner/database/backup_info.rb +12 -3
  18. data/lib/google/cloud/spanner/database/job/list.rb +2 -2
  19. data/lib/google/cloud/spanner/database/list.rb +4 -4
  20. data/lib/google/cloud/spanner/fields.rb +5 -3
  21. data/lib/google/cloud/spanner/instance.rb +91 -3
  22. data/lib/google/cloud/spanner/instance/config/list.rb +4 -4
  23. data/lib/google/cloud/spanner/instance/list.rb +4 -4
  24. data/lib/google/cloud/spanner/partition.rb +4 -2
  25. data/lib/google/cloud/spanner/policy.rb +3 -2
  26. data/lib/google/cloud/spanner/pool.rb +10 -10
  27. data/lib/google/cloud/spanner/project.rb +65 -5
  28. data/lib/google/cloud/spanner/results.rb +13 -9
  29. data/lib/google/cloud/spanner/service.rb +44 -24
  30. data/lib/google/cloud/spanner/session.rb +38 -15
  31. data/lib/google/cloud/spanner/snapshot.rb +10 -2
  32. data/lib/google/cloud/spanner/status.rb +4 -1
  33. data/lib/google/cloud/spanner/transaction.rb +61 -6
  34. data/lib/google/cloud/spanner/version.rb +1 -1
  35. metadata +10 -10
@@ -71,7 +71,7 @@ module Google
71
71
  return nil unless next?
72
72
  ensure_service!
73
73
  options = { token: token, max: @max }
74
- grpc = @service.list_instances options
74
+ grpc = @service.list_instances(**options)
75
75
  self.class.from_grpc grpc, @service, @max
76
76
  end
77
77
 
@@ -120,17 +120,17 @@ module Google
120
120
  # puts instance.instance_id
121
121
  # end
122
122
  #
123
- def all request_limit: nil
123
+ def all request_limit: nil, &block
124
124
  request_limit = request_limit.to_i if request_limit
125
125
  unless block_given?
126
126
  return enum_for :all, request_limit: request_limit
127
127
  end
128
128
  results = self
129
129
  loop do
130
- results.each { |r| yield r }
130
+ results.each(&block)
131
131
  if request_limit
132
132
  request_limit -= 1
133
- break if request_limit < 0
133
+ break if request_limit.negative?
134
134
  end
135
135
  break unless results.next?
136
136
  results = results.next
@@ -45,11 +45,13 @@ module Google
45
45
  #
46
46
  class Partition
47
47
  # @ private
48
- attr_reader :execute, :read
48
+ attr_reader :execute
49
+ attr_reader :read
49
50
 
50
51
  ##
51
52
  # @private Creates a Partition object.
52
- def initialize; end
53
+ def initialize
54
+ end
53
55
 
54
56
  ##
55
57
  # Whether the partition was created for an execute_query/query
@@ -70,7 +70,8 @@ module Google
70
70
  # end
71
71
  #
72
72
  class Policy
73
- attr_reader :etag, :roles
73
+ attr_reader :etag
74
+ attr_reader :roles
74
75
 
75
76
  ##
76
77
  # @private Creates a Policy object.
@@ -169,7 +170,7 @@ module Google
169
170
  role: role_name,
170
171
  members: roles[role_name]
171
172
  )
172
- end
173
+ end.compact
173
174
  )
174
175
  end
175
176
 
@@ -29,7 +29,9 @@ module Google
29
29
  # {Google::Cloud::Spanner::Session} instances.
30
30
  #
31
31
  class Pool
32
- attr_accessor :all_sessions, :session_queue, :transaction_queue
32
+ attr_accessor :all_sessions
33
+ attr_accessor :session_queue
34
+ attr_accessor :transaction_queue
33
35
 
34
36
  def initialize client, min: 10, max: 100, keepalive: 1800,
35
37
  write_ratio: 0.3, fail: true, threads: nil
@@ -38,7 +40,7 @@ module Google
38
40
  @max = max
39
41
  @keepalive = keepalive
40
42
  @write_ratio = write_ratio
41
- @write_ratio = 0 if write_ratio < 0
43
+ @write_ratio = 0 if write_ratio.negative?
42
44
  @write_ratio = 1 if write_ratio > 1
43
45
  @fail = fail
44
46
  @threads = threads || [2, Concurrent.processor_count * 2].max
@@ -143,13 +145,13 @@ module Google
143
145
  return new_transaction! if action == :new
144
146
  end
145
147
 
146
- def checkin_transaction tx
148
+ def checkin_transaction txn
147
149
  @mutex.synchronize do
148
- unless all_sessions.include? tx.session
150
+ unless all_sessions.include? txn.session
149
151
  raise ArgumentError, "Cannot checkin session"
150
152
  end
151
153
 
152
- transaction_queue.push tx
154
+ transaction_queue.push txn
153
155
 
154
156
  @resource.signal
155
157
  end
@@ -182,7 +184,7 @@ module Google
182
184
  @mutex.synchronize do
183
185
  available_count = session_queue.count + transaction_queue.count
184
186
  release_count = @min - available_count
185
- release_count = 0 if release_count < 0
187
+ release_count = 0 if release_count.negative?
186
188
 
187
189
  to_keepalive += (session_queue + transaction_queue).select do |x|
188
190
  x.idle_since? @keepalive
@@ -282,10 +284,8 @@ module Google
282
284
  @keepalive_task.execute
283
285
  end
284
286
 
285
- def future
286
- Concurrent::Future.new executor: @thread_pool do
287
- yield
288
- end.execute
287
+ def future &block
288
+ Concurrent::Future.new(executor: @thread_pool, &block).execute
289
289
  end
290
290
  end
291
291
  end
@@ -177,7 +177,10 @@ module Google
177
177
  # configuration. Values can be the `instance_config_id`, the full
178
178
  # path, or an {Instance::Config} object. Required.
179
179
  # @param [Integer] nodes The number of nodes allocated to this instance.
180
- # Required.
180
+ # Optional. Specify either `nodes` or `processing_units`
181
+ # @param [Integer] processing_units The number of processing units
182
+ # allocated to this instance. Optional. Specify either `nodes`
183
+ # or `processing_units`
181
184
  # @param [Hash] labels Cloud Labels are a flexible and lightweight
182
185
  # mechanism for organizing cloud resources into groups that reflect a
183
186
  # customer's organizational needs and deployment strategies. Cloud
@@ -195,6 +198,7 @@ module Google
195
198
  #
196
199
  # @return [Instance::Job] The job representing the long-running,
197
200
  # asynchronous processing of an instance create operation.
201
+ # @raise [ArgumentError] if both processing_units or nodes are specified.
198
202
  #
199
203
  # @example
200
204
  # require "google/cloud/spanner"
@@ -217,14 +221,36 @@ module Google
217
221
  # instance = job.instance
218
222
  # end
219
223
  #
224
+ # @example Create instance using processsing units
225
+ # require "google/cloud/spanner"
226
+ #
227
+ # spanner = Google::Cloud::Spanner.new
228
+ #
229
+ # job = spanner.create_instance "my-new-instance",
230
+ # name: "My New Instance",
231
+ # config: "regional-us-central1",
232
+ # processing_units: 500,
233
+ # labels: { production: :env }
234
+ #
235
+ # job.done? #=> false
236
+ # job.reload! # API call
237
+ # job.done? #=> true
238
+ #
239
+ # if job.error?
240
+ # status = job.error
241
+ # else
242
+ # instance = job.instance
243
+ # end
244
+ #
220
245
  def create_instance instance_id, name: nil, config: nil, nodes: nil,
221
- labels: nil
246
+ processing_units: nil, labels: nil
222
247
  config = config.path if config.respond_to? :path
248
+
223
249
  # Convert from possible Google::Protobuf::Map
224
250
  labels = Hash[labels.map { |k, v| [String(k), String(v)] }] if labels
225
251
  grpc = service.create_instance \
226
252
  instance_id, name: name, config: config, nodes: nodes,
227
- labels: labels
253
+ processing_units: processing_units, labels: labels
228
254
  Instance::Job.from_grpc grpc, service
229
255
  end
230
256
 
@@ -380,6 +406,13 @@ module Google
380
406
  # These statements execute atomically with the creation of the
381
407
  # database: if there is an error in any statement, the database is not
382
408
  # created. Optional.
409
+ # @param [Hash] encryption_config An encryption configuration describing
410
+ # the encryption type and key resources in Cloud KMS. Optional. The
411
+ # following settings can be provided:
412
+ #
413
+ # * `:kms_key_name` (String) The name of KMS key to use which should
414
+ # be the full path, e.g., `projects/<project>/locations/<location>\
415
+ # /keyRings/<key_ring>/cryptoKeys/<kms_key_name>`
383
416
  #
384
417
  # @return [Database::Job] The job representing the long-running,
385
418
  # asynchronous processing of a database create operation.
@@ -402,9 +435,32 @@ module Google
402
435
  # database = job.database
403
436
  # end
404
437
  #
405
- def create_database instance_id, database_id, statements: []
438
+ # @example Create with encryption config
439
+ # require "google/cloud/spanner"
440
+ #
441
+ # spanner = Google::Cloud::Spanner.new
442
+ #
443
+ # kms_key_name = "projects/<project>/locations/<location>/keyRings/<key_ring>/cryptoKeys/<kms_key_name>"
444
+ # encryption_config = { kms_key_name: kms_key_name }
445
+ # job = spanner.create_database "my-instance",
446
+ # "my-new-database",
447
+ # encryption_config: encryption_config
448
+ #
449
+ # job.done? #=> false
450
+ # job.reload! # API call
451
+ # job.done? #=> true
452
+ #
453
+ # if job.error?
454
+ # status = job.error
455
+ # else
456
+ # database = job.database
457
+ # end
458
+ #
459
+ def create_database instance_id, database_id, statements: [],
460
+ encryption_config: nil
406
461
  grpc = service.create_database instance_id, database_id,
407
- statements: statements
462
+ statements: statements,
463
+ encryption_config: encryption_config
408
464
  Database::Job.from_grpc grpc, service
409
465
  end
410
466
 
@@ -460,6 +516,8 @@ module Google
460
516
  # * `:optimizer_version` (String) The version of optimizer to use.
461
517
  # Empty to use database default. "latest" to use the latest
462
518
  # available optimizer version.
519
+ # * `:optimizer_statistics_package` (String) Statistics package to
520
+ # use. Empty to use the database default.
463
521
  #
464
522
  # @return [Client] The newly created client.
465
523
  #
@@ -524,6 +582,8 @@ module Google
524
582
  # * `:optimizer_version` (String) The version of optimizer to use.
525
583
  # Empty to use database default. "latest" to use the latest
526
584
  # available optimizer version.
585
+ # * `:optimizer_statistics_package` (String) Statistics package to
586
+ # use. Empty to use the database default.
527
587
  #
528
588
  # @return [Client] The newly created client.
529
589
  #
@@ -251,14 +251,14 @@ module Google
251
251
  @service.execute_streaming_sql(
252
252
  @session_path,
253
253
  @sql,
254
- @execute_query_options.merge(resume_token: resume_token)
254
+ **@execute_query_options.merge(resume_token: resume_token)
255
255
  )
256
256
  else
257
257
  @service.streaming_read_table(
258
258
  @session_path,
259
259
  @table,
260
260
  @columns,
261
- @read_options.merge(resume_token: resume_token)
261
+ **@read_options.merge(resume_token: resume_token)
262
262
  )
263
263
  end
264
264
  end
@@ -268,9 +268,9 @@ module Google
268
268
  # Retries a request, by re-executing it from scratch.
269
269
  def retry_request
270
270
  if @execute_query_options
271
- @service.execute_streaming_sql @session_path, @sql, @execute_query_options
271
+ @service.execute_streaming_sql @session_path, @sql, **@execute_query_options
272
272
  else
273
- @service.streaming_read_table @session_path, @table, @columns, @read_options
273
+ @service.streaming_read_table @session_path, @table, @columns, **@read_options
274
274
  end
275
275
  end
276
276
 
@@ -319,14 +319,16 @@ module Google
319
319
  def self.execute_query service, session_path, sql, params: nil,
320
320
  types: nil, transaction: nil,
321
321
  partition_token: nil, seqno: nil,
322
- query_options: nil, call_options: nil
322
+ query_options: nil, request_options: nil,
323
+ call_options: nil
323
324
  execute_query_options = {
324
325
  transaction: transaction, params: params, types: types,
325
326
  partition_token: partition_token, seqno: seqno,
326
- query_options: query_options, call_options: call_options
327
+ query_options: query_options, request_options: request_options,
328
+ call_options: call_options
327
329
  }
328
330
  enum = service.execute_streaming_sql session_path, sql,
329
- execute_query_options
331
+ **execute_query_options
330
332
  from_enum(enum, service).tap do |results|
331
333
  results.instance_variable_set :@session_path, session_path
332
334
  results.instance_variable_set :@sql, sql
@@ -338,15 +340,17 @@ module Google
338
340
  # @private
339
341
  def self.read service, session_path, table, columns, keys: nil,
340
342
  index: nil, limit: nil, transaction: nil,
341
- partition_token: nil, call_options: nil
343
+ partition_token: nil, request_options: nil,
344
+ call_options: nil
342
345
  read_options = {
343
346
  keys: keys, index: index, limit: limit,
344
347
  transaction: transaction,
345
348
  partition_token: partition_token,
349
+ request_options: request_options,
346
350
  call_options: call_options
347
351
  }
348
352
  enum = service.streaming_read_table \
349
- session_path, table, columns, read_options
353
+ session_path, table, columns, **read_options
350
354
  from_enum(enum, service).tap do |results|
351
355
  results.instance_variable_set :@session_path, session_path
352
356
  results.instance_variable_set :@table, table
@@ -28,8 +28,12 @@ module Google
28
28
  # @private Represents the gRPC Spanner service, including all the API
29
29
  # methods.
30
30
  class Service
31
- attr_accessor :project, :credentials, :timeout, :host, :lib_name,
32
- :lib_version
31
+ attr_accessor :project
32
+ attr_accessor :credentials
33
+ attr_accessor :timeout
34
+ attr_accessor :host
35
+ attr_accessor :lib_name
36
+ attr_accessor :lib_version
33
37
 
34
38
  ##
35
39
  # Creates a new Service instance.
@@ -123,13 +127,15 @@ module Google
123
127
  end
124
128
 
125
129
  def create_instance instance_id, name: nil, config: nil, nodes: nil,
126
- labels: nil, call_options: nil
130
+ processing_units: nil, labels: nil,
131
+ call_options: nil
127
132
  opts = default_options call_options: call_options
128
133
  labels = Hash[labels.map { |k, v| [String(k), String(v)] }] if labels
129
134
 
130
135
  create_obj = Admin::Instance::V1::Instance.new({
131
136
  display_name: name, config: instance_config_path(config),
132
- node_count: nodes, labels: labels
137
+ node_count: nodes, processing_units: processing_units,
138
+ labels: labels
133
139
  }.delete_if { |_, v| v.nil? })
134
140
 
135
141
  request = {
@@ -140,12 +146,17 @@ module Google
140
146
  instances.create_instance request, opts
141
147
  end
142
148
 
143
- def update_instance instance, call_options: nil
149
+ def update_instance instance, field_mask: nil, call_options: nil
144
150
  opts = default_options call_options: call_options
145
- mask = Google::Protobuf::FieldMask.new(
146
- paths: %w[display_name node_count labels]
147
- )
148
- request = { instance: instance, field_mask: mask }
151
+
152
+ if field_mask.nil? || field_mask.empty?
153
+ field_mask = %w[display_name node_count labels]
154
+ end
155
+
156
+ request = {
157
+ instance: instance,
158
+ field_mask: Google::Protobuf::FieldMask.new(paths: field_mask)
159
+ }
149
160
  instances.update_instance request, opts
150
161
  end
151
162
 
@@ -210,12 +221,13 @@ module Google
210
221
  end
211
222
 
212
223
  def create_database instance_id, database_id, statements: [],
213
- call_options: nil
224
+ call_options: nil, encryption_config: nil
214
225
  opts = default_options call_options: call_options
215
226
  request = {
216
227
  parent: instance_path(instance_id),
217
228
  create_statement: "CREATE DATABASE `#{database_id}`",
218
- extra_statements: Array(statements)
229
+ extra_statements: Array(statements),
230
+ encryption_config: encryption_config
219
231
  }
220
232
  databases.create_database request, opts
221
233
  end
@@ -308,7 +320,8 @@ module Google
308
320
  def execute_streaming_sql session_name, sql, transaction: nil,
309
321
  params: nil, types: nil, resume_token: nil,
310
322
  partition_token: nil, seqno: nil,
311
- query_options: nil, call_options: nil
323
+ query_options: nil, request_options: nil,
324
+ call_options: nil
312
325
  opts = default_options session_name: session_name,
313
326
  call_options: call_options
314
327
  request = {
@@ -320,13 +333,14 @@ module Google
320
333
  resume_token: resume_token,
321
334
  partition_token: partition_token,
322
335
  seqno: seqno,
323
- query_options: query_options
336
+ query_options: query_options,
337
+ request_options: request_options
324
338
  }
325
339
  service.execute_streaming_sql request, opts
326
340
  end
327
341
 
328
342
  def execute_batch_dml session_name, transaction, statements, seqno,
329
- call_options: nil
343
+ request_options: nil, call_options: nil
330
344
  opts = default_options session_name: session_name,
331
345
  call_options: call_options
332
346
  statements = statements.map(&:to_grpc)
@@ -334,7 +348,8 @@ module Google
334
348
  session: session_name,
335
349
  transaction: transaction,
336
350
  statements: statements,
337
- seqno: seqno
351
+ seqno: seqno,
352
+ request_options: request_options
338
353
  }
339
354
  results = service.execute_batch_dml request, opts
340
355
 
@@ -352,14 +367,14 @@ module Google
352
367
  def streaming_read_table session_name, table_name, columns, keys: nil,
353
368
  index: nil, transaction: nil, limit: nil,
354
369
  resume_token: nil, partition_token: nil,
355
- call_options: nil
370
+ request_options: nil, call_options: nil
356
371
  opts = default_options session_name: session_name,
357
372
  call_options: call_options
358
373
  request = {
359
374
  session: session_name, table: table_name, columns: columns,
360
375
  key_set: keys, transaction: transaction, index: index,
361
376
  limit: limit, resume_token: resume_token,
362
- partition_token: partition_token
377
+ partition_token: partition_token, request_options: request_options
363
378
  }
364
379
  service.streaming_read request, opts
365
380
  end
@@ -397,7 +412,7 @@ module Google
397
412
  end
398
413
 
399
414
  def commit session_name, mutations = [], transaction_id: nil,
400
- commit_options: nil, call_options: nil
415
+ commit_options: nil, request_options: nil, call_options: nil
401
416
  tx_opts = nil
402
417
  if transaction_id.nil?
403
418
  tx_opts = V1::TransactionOptions.new(
@@ -408,7 +423,8 @@ module Google
408
423
  call_options: call_options
409
424
  request = {
410
425
  session: session_name, transaction_id: transaction_id,
411
- single_use_transaction: tx_opts, mutations: mutations
426
+ single_use_transaction: tx_opts, mutations: mutations,
427
+ request_options: request_options
412
428
  }
413
429
 
414
430
  if commit_options
@@ -464,16 +480,19 @@ module Google
464
480
  end
465
481
 
466
482
  def create_backup instance_id, database_id, backup_id, expire_time,
467
- call_options: nil
483
+ version_time, call_options: nil,
484
+ encryption_config: nil
468
485
  opts = default_options call_options: call_options
469
486
  backup = {
470
487
  database: database_path(instance_id, database_id),
471
- expire_time: expire_time
488
+ expire_time: expire_time,
489
+ version_time: version_time
472
490
  }
473
491
  request = {
474
492
  parent: instance_path(instance_id),
475
493
  backup_id: backup_id,
476
- backup: backup
494
+ backup: backup,
495
+ encryption_config: encryption_config
477
496
  }
478
497
  databases.create_backup request, opts
479
498
  end
@@ -540,12 +559,13 @@ module Google
540
559
 
541
560
  def restore_database backup_instance_id, backup_id,
542
561
  database_instance_id, database_id,
543
- call_options: nil
562
+ call_options: nil, encryption_config: nil
544
563
  opts = default_options call_options: call_options
545
564
  request = {
546
565
  parent: instance_path(database_instance_id),
547
566
  database_id: database_id,
548
- backup: backup_path(backup_instance_id, backup_id)
567
+ backup: backup_path(backup_instance_id, backup_id),
568
+ encryption_config: encryption_config
549
569
  }
550
570
  databases.restore_database request, opts
551
571
  end