google-cloud-spanner 2.4.0 → 2.8.1
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.
- checksums.yaml +4 -4
- data/AUTHENTICATION.md +2 -1
- data/CHANGELOG.md +56 -0
- data/CONTRIBUTING.md +1 -1
- data/LOGGING.md +1 -1
- data/OVERVIEW.md +1 -1
- data/lib/google-cloud-spanner.rb +2 -0
- data/lib/google/cloud/spanner/backup.rb +67 -4
- data/lib/google/cloud/spanner/backup/job.rb +8 -8
- data/lib/google/cloud/spanner/backup/job/list.rb +2 -2
- data/lib/google/cloud/spanner/backup/list.rb +2 -2
- data/lib/google/cloud/spanner/batch_snapshot.rb +11 -4
- data/lib/google/cloud/spanner/batch_update.rb +3 -1
- data/lib/google/cloud/spanner/client.rb +315 -83
- data/lib/google/cloud/spanner/commit.rb +4 -0
- data/lib/google/cloud/spanner/data.rb +4 -5
- data/lib/google/cloud/spanner/database.rb +88 -2
- data/lib/google/cloud/spanner/database/job/list.rb +2 -2
- data/lib/google/cloud/spanner/database/list.rb +4 -4
- data/lib/google/cloud/spanner/fields.rb +5 -3
- data/lib/google/cloud/spanner/instance.rb +91 -3
- data/lib/google/cloud/spanner/instance/config/list.rb +4 -4
- data/lib/google/cloud/spanner/instance/list.rb +4 -4
- data/lib/google/cloud/spanner/partition.rb +4 -2
- data/lib/google/cloud/spanner/policy.rb +3 -2
- data/lib/google/cloud/spanner/pool.rb +10 -10
- data/lib/google/cloud/spanner/project.rb +65 -5
- data/lib/google/cloud/spanner/results.rb +13 -9
- data/lib/google/cloud/spanner/service.rb +42 -23
- data/lib/google/cloud/spanner/session.rb +38 -15
- data/lib/google/cloud/spanner/snapshot.rb +10 -2
- data/lib/google/cloud/spanner/status.rb +4 -1
- data/lib/google/cloud/spanner/transaction.rb +61 -6
- data/lib/google/cloud/spanner/version.rb +1 -1
- metadata +10 -10
@@ -69,6 +69,7 @@ module Google
|
|
69
69
|
# | `BOOL` | `true`/`false` | |
|
70
70
|
# | `INT64` | `Integer` | |
|
71
71
|
# | `FLOAT64` | `Float` | |
|
72
|
+
# | `NUMERIC` | `BigDecimal` | |
|
72
73
|
# | `STRING` | `String` | |
|
73
74
|
# | `DATE` | `Date` | |
|
74
75
|
# | `TIMESTAMP` | `Time`, `DateTime` | |
|
@@ -127,6 +128,7 @@ module Google
|
|
127
128
|
# | `BOOL` | `true`/`false` | |
|
128
129
|
# | `INT64` | `Integer` | |
|
129
130
|
# | `FLOAT64` | `Float` | |
|
131
|
+
# | `NUMERIC` | `BigDecimal` | |
|
130
132
|
# | `STRING` | `String` | |
|
131
133
|
# | `DATE` | `Date` | |
|
132
134
|
# | `TIMESTAMP` | `Time`, `DateTime` | |
|
@@ -184,6 +186,7 @@ module Google
|
|
184
186
|
# | `BOOL` | `true`/`false` | |
|
185
187
|
# | `INT64` | `Integer` | |
|
186
188
|
# | `FLOAT64` | `Float` | |
|
189
|
+
# | `NUMERIC` | `BigDecimal` | |
|
187
190
|
# | `STRING` | `String` | |
|
188
191
|
# | `DATE` | `Date` | |
|
189
192
|
# | `TIMESTAMP` | `Time`, `DateTime` | |
|
@@ -243,6 +246,7 @@ module Google
|
|
243
246
|
# | `BOOL` | `true`/`false` | |
|
244
247
|
# | `INT64` | `Integer` | |
|
245
248
|
# | `FLOAT64` | `Float` | |
|
249
|
+
# | `NUMERIC` | `BigDecimal` | |
|
246
250
|
# | `STRING` | `String` | |
|
247
251
|
# | `DATE` | `Date` | |
|
248
252
|
# | `TIMESTAMP` | `Time`, `DateTime` | |
|
@@ -139,9 +139,10 @@ module Google
|
|
139
139
|
#
|
140
140
|
def to_a skip_dup_check: nil
|
141
141
|
values.map do |value|
|
142
|
-
|
142
|
+
case value
|
143
|
+
when Data
|
143
144
|
value.to_h skip_dup_check: skip_dup_check
|
144
|
-
|
145
|
+
when Array
|
145
146
|
value.map do |v|
|
146
147
|
v.is_a?(Data) ? v.to_h(skip_dup_check: skip_dup_check) : v
|
147
148
|
end
|
@@ -169,9 +170,7 @@ module Google
|
|
169
170
|
# or indexes and corresponding values.
|
170
171
|
#
|
171
172
|
def to_h skip_dup_check: nil
|
172
|
-
|
173
|
-
raise DuplicateNameError if fields.duplicate_names?
|
174
|
-
end
|
173
|
+
raise DuplicateNameError if !skip_dup_check && fields.duplicate_names?
|
175
174
|
|
176
175
|
Hash[keys.zip to_a(skip_dup_check: skip_dup_check)]
|
177
176
|
end
|
@@ -113,6 +113,38 @@ module Google
|
|
113
113
|
@grpc.state
|
114
114
|
end
|
115
115
|
|
116
|
+
##
|
117
|
+
# Time at which the database creation started.
|
118
|
+
# @return [Time]
|
119
|
+
def create_time
|
120
|
+
Convert.timestamp_to_time @grpc.create_time
|
121
|
+
end
|
122
|
+
|
123
|
+
# An encryption configuration describing the encryption type and key
|
124
|
+
# resources in Cloud KMS.
|
125
|
+
#
|
126
|
+
# @return [Google::Cloud::Spanner::Admin::Database::V1::EncryptionConfig, nil]
|
127
|
+
def encryption_config
|
128
|
+
@grpc.encryption_config
|
129
|
+
end
|
130
|
+
|
131
|
+
# Encryption information for the database.
|
132
|
+
#
|
133
|
+
# For databases that are using customer managed encryption, this
|
134
|
+
# field contains the encryption information for the database, such as
|
135
|
+
# encryption state and the Cloud KMS key versions that are in use.
|
136
|
+
#
|
137
|
+
# For databases that are using Google default or other types of encryption,
|
138
|
+
# this field is empty.
|
139
|
+
#
|
140
|
+
# This field is propagated lazily from the backend. There might be a delay
|
141
|
+
# from when a key version is being used and when it appears in this field.
|
142
|
+
#
|
143
|
+
# @return [Array<Google::Cloud::Spanner::Admin::Database::V1::EncryptionInfo>]
|
144
|
+
def encryption_info
|
145
|
+
@grpc.encryption_info.to_a
|
146
|
+
end
|
147
|
+
|
116
148
|
##
|
117
149
|
# The database is still being created. Operations on the database may
|
118
150
|
# raise with `FAILED_PRECONDITION` in this state.
|
@@ -417,6 +449,26 @@ module Google
|
|
417
449
|
# it will be automatically set to the backup create time. The version
|
418
450
|
# time can be as far in the past as specified by the database earliest
|
419
451
|
# version time. Optional.
|
452
|
+
# @param [Hash] encryption_config An encryption configuration describing
|
453
|
+
# the encryption type and key resources in Cloud KMS. Optional. The
|
454
|
+
# following settings can be provided:
|
455
|
+
#
|
456
|
+
# * `:kms_key_name` (String) The name of KMS key to use which should
|
457
|
+
# be the full path, e.g., `projects/<project>/locations/<location>\
|
458
|
+
# /keyRings/<key_ring>/cryptoKeys/<kms_key_name>`
|
459
|
+
# This field should be set only when encryption type
|
460
|
+
# `:CUSTOMER_MANAGED_ENCRYPTION`.
|
461
|
+
# * `:encryption_type` (Symbol) The encryption type of the backup.
|
462
|
+
# Valid values are:
|
463
|
+
# 1. `:USE_DATABASE_ENCRYPTION` - Use the same encryption configuration as
|
464
|
+
# the database.
|
465
|
+
# 2. `:GOOGLE_DEFAULT_ENCRYPTION` - Google default encryption.
|
466
|
+
# 3. `:CUSTOMER_MANAGED_ENCRYPTION` - Use customer managed encryption.
|
467
|
+
# If specified, `:kms_key_name` must contain a valid Cloud KMS key.
|
468
|
+
#
|
469
|
+
# @raise [ArgumentError] if `:CUSTOMER_MANAGED_ENCRYPTION` specified without
|
470
|
+
# customer managed kms key.
|
471
|
+
#
|
420
472
|
# @return [Google::Cloud::Spanner::Backup::Job] The job representing
|
421
473
|
# the long-running, asynchronous processing of a backup create
|
422
474
|
# operation.
|
@@ -443,14 +495,48 @@ module Google
|
|
443
495
|
# backup = job.backup
|
444
496
|
# end
|
445
497
|
#
|
446
|
-
|
498
|
+
# @example Create backup with encryption config
|
499
|
+
# require "google/cloud/spanner"
|
500
|
+
#
|
501
|
+
# spanner = Google::Cloud::Spanner.new
|
502
|
+
# database = spanner.database "my-instance", "my-database"
|
503
|
+
#
|
504
|
+
# kms_key_name = "projects/<project>/locations/<location>/keyRings/<key_ring>/cryptoKeys/<kms_key_name>"
|
505
|
+
# encryption_config = {
|
506
|
+
# kms_key_name: kms_key_name,
|
507
|
+
# encryption_type: :CUSTOMER_MANAGED_ENCRYPTION
|
508
|
+
# }
|
509
|
+
# job = database.create_backup "my-backup",
|
510
|
+
# Time.now + 36000,
|
511
|
+
# encryption_config: encryption_config
|
512
|
+
#
|
513
|
+
# job.done? #=> false
|
514
|
+
# job.reload! # API call
|
515
|
+
# job.done? #=> true
|
516
|
+
#
|
517
|
+
# if job.error?
|
518
|
+
# status = job.error
|
519
|
+
# else
|
520
|
+
# backup = job.backup
|
521
|
+
# end
|
522
|
+
#
|
523
|
+
def create_backup backup_id, expire_time,
|
524
|
+
version_time: nil, encryption_config: nil
|
447
525
|
ensure_service!
|
526
|
+
|
527
|
+
if encryption_config&.include?(:kms_key_name) &&
|
528
|
+
encryption_config[:encryption_type] != :CUSTOMER_MANAGED_ENCRYPTION
|
529
|
+
raise Google::Cloud::InvalidArgumentError,
|
530
|
+
"kms_key_name only used with CUSTOMER_MANAGED_ENCRYPTION"
|
531
|
+
end
|
532
|
+
|
448
533
|
grpc = service.create_backup \
|
449
534
|
instance_id,
|
450
535
|
database_id,
|
451
536
|
backup_id,
|
452
537
|
expire_time,
|
453
|
-
version_time
|
538
|
+
version_time,
|
539
|
+
encryption_config: encryption_config
|
454
540
|
Backup::Job.from_grpc grpc, service
|
455
541
|
end
|
456
542
|
|
@@ -130,12 +130,12 @@ module Google
|
|
130
130
|
# job.database.database_id
|
131
131
|
# end
|
132
132
|
#
|
133
|
-
def all
|
133
|
+
def all &block
|
134
134
|
return enum_for :all unless block_given?
|
135
135
|
|
136
136
|
results = self
|
137
137
|
loop do
|
138
|
-
results.each
|
138
|
+
results.each(&block)
|
139
139
|
break unless next?
|
140
140
|
grpc.next_page
|
141
141
|
results = self.class.from_grpc grpc, service
|
@@ -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_databases @instance_id, options
|
74
|
+
grpc = @service.list_databases @instance_id, **options
|
75
75
|
self.class.from_grpc grpc, @service, @max
|
76
76
|
end
|
77
77
|
|
@@ -123,17 +123,17 @@ module Google
|
|
123
123
|
# puts database.database_id
|
124
124
|
# end
|
125
125
|
#
|
126
|
-
def all request_limit: nil
|
126
|
+
def all request_limit: nil, &block
|
127
127
|
request_limit = request_limit.to_i if request_limit
|
128
128
|
unless block_given?
|
129
129
|
return enum_for :all, request_limit: request_limit
|
130
130
|
end
|
131
131
|
results = self
|
132
132
|
loop do
|
133
|
-
results.each
|
133
|
+
results.each(&block)
|
134
134
|
if request_limit
|
135
135
|
request_limit -= 1
|
136
|
-
break if request_limit
|
136
|
+
break if request_limit.negative?
|
137
137
|
end
|
138
138
|
break unless results.next?
|
139
139
|
results = results.next
|
@@ -57,12 +57,13 @@ module Google
|
|
57
57
|
# Hash values must contain the type value. If a Hash is used the
|
58
58
|
# fields will be created using the same order as the Hash keys.
|
59
59
|
#
|
60
|
-
# Supported type values
|
60
|
+
# Supported type values include:
|
61
61
|
#
|
62
62
|
# * `:BOOL`
|
63
63
|
# * `:BYTES`
|
64
64
|
# * `:DATE`
|
65
65
|
# * `:FLOAT64`
|
66
|
+
# * `:NUMERIC`
|
66
67
|
# * `:INT64`
|
67
68
|
# * `:STRING`
|
68
69
|
# * `:TIMESTAMP`
|
@@ -133,13 +134,14 @@ module Google
|
|
133
134
|
#
|
134
135
|
def types
|
135
136
|
@grpc_fields.map(&:type).map do |type|
|
136
|
-
|
137
|
+
case type.code
|
138
|
+
when :ARRAY
|
137
139
|
if type.array_element_type.code == :STRUCT
|
138
140
|
[Fields.from_grpc(type.array_element_type.struct_type.fields)]
|
139
141
|
else
|
140
142
|
[type.array_element_type.code]
|
141
143
|
end
|
142
|
-
|
144
|
+
when :STRUCT
|
143
145
|
Fields.from_grpc type.struct_type.fields
|
144
146
|
else
|
145
147
|
type.code
|
@@ -68,6 +68,7 @@ module Google
|
|
68
68
|
def initialize grpc, service
|
69
69
|
@grpc = grpc
|
70
70
|
@service = service
|
71
|
+
@current_values = grpc.to_h
|
71
72
|
end
|
72
73
|
|
73
74
|
# The unique identifier for the project.
|
@@ -134,6 +135,23 @@ module Google
|
|
134
135
|
end
|
135
136
|
alias node_count= nodes=
|
136
137
|
|
138
|
+
##
|
139
|
+
# The number of processing units allocated to this instance.
|
140
|
+
#
|
141
|
+
# @return [Integer]
|
142
|
+
def processing_units
|
143
|
+
@grpc.processing_units
|
144
|
+
end
|
145
|
+
|
146
|
+
##
|
147
|
+
# Updates number of processing units allocated to this instance.
|
148
|
+
#
|
149
|
+
# @param units [Integer] The number of processing units allocated
|
150
|
+
# to this instance.
|
151
|
+
def processing_units= units
|
152
|
+
@grpc.processing_units = units
|
153
|
+
end
|
154
|
+
|
137
155
|
##
|
138
156
|
# The current instance state. Possible values are `:CREATING` and
|
139
157
|
# `:READY`.
|
@@ -188,8 +206,50 @@ module Google
|
|
188
206
|
)
|
189
207
|
end
|
190
208
|
|
209
|
+
##
|
210
|
+
# Update changes.
|
211
|
+
# `display_name`, `labels`, `nodes`, `processing_units` can be
|
212
|
+
# updated. `processing_units` and `nodes` can be used interchangeably
|
213
|
+
# to update.
|
214
|
+
#
|
215
|
+
# @return [Instance::Job] The job representing the long-running,
|
216
|
+
# asynchronous processing of an instance update operation.
|
217
|
+
# @raise [ArgumentError] if both processing_units or nodes are specified.
|
218
|
+
#
|
219
|
+
# @example
|
220
|
+
# require "google/cloud/spanner"
|
221
|
+
#
|
222
|
+
# spanner = Google::Cloud::Spanner.new
|
223
|
+
#
|
224
|
+
# instance = spanner.instance "my-instance"
|
225
|
+
# instance.display_name = "prod-instance"
|
226
|
+
# instance.labels = { env: "prod", app: "api" }
|
227
|
+
# instance.nodes = 2
|
228
|
+
# # OR
|
229
|
+
# # instance.processing_units = 500
|
230
|
+
#
|
231
|
+
# job = instance.save
|
232
|
+
#
|
233
|
+
# job.done? #=> false
|
234
|
+
# job.reload! # API call
|
235
|
+
# job.done? #=> true
|
236
|
+
#
|
237
|
+
# if job.error?
|
238
|
+
# status = job.error
|
239
|
+
# else
|
240
|
+
# instance = job.instance
|
241
|
+
# end
|
242
|
+
#
|
191
243
|
def save
|
192
|
-
|
244
|
+
ensure_service!
|
245
|
+
|
246
|
+
field_mask = []
|
247
|
+
@current_values.each do |field, value|
|
248
|
+
field_mask << field unless @grpc[field.to_s] == value
|
249
|
+
end
|
250
|
+
|
251
|
+
job_grpc = service.update_instance @grpc, field_mask: field_mask
|
252
|
+
@current_values = @grpc.to_h
|
193
253
|
Instance::Job.from_grpc job_grpc, service
|
194
254
|
end
|
195
255
|
alias update save
|
@@ -306,6 +366,13 @@ module Google
|
|
306
366
|
# These statements execute atomically with the creation of the
|
307
367
|
# database: if there is an error in any statement, the database is not
|
308
368
|
# created. Optional.
|
369
|
+
# @param [Hash] encryption_config An encryption configuration describing
|
370
|
+
# the encryption type and key resources in Cloud KMS. Optional. The
|
371
|
+
# following settings can be provided:
|
372
|
+
#
|
373
|
+
# * `:kms_key_name` (String) The name of KMS key to use which should
|
374
|
+
# be the full path, e.g., `projects/<project>/locations/<location>\
|
375
|
+
# /keyRings/<key_ring>/cryptoKeys/<kms_key_name>`
|
309
376
|
#
|
310
377
|
# @return [Database::Job] The job representing the long-running,
|
311
378
|
# asynchronous processing of a database create operation.
|
@@ -328,9 +395,30 @@ module Google
|
|
328
395
|
# database = job.database
|
329
396
|
# end
|
330
397
|
#
|
331
|
-
|
398
|
+
# @example Create with encryption config
|
399
|
+
# require "google/cloud/spanner"
|
400
|
+
#
|
401
|
+
# spanner = Google::Cloud::Spanner.new
|
402
|
+
#
|
403
|
+
# instance = spanner.instance "my-instance"
|
404
|
+
#
|
405
|
+
# kms_key_name = "projects/<project>/locations/<location>/keyRings/<key_ring>/cryptoKeys/<kms_key_name>"
|
406
|
+
# job = instance.create_database "my-new-database", encryption_config: { kms_key_name: kms_key_name }
|
407
|
+
#
|
408
|
+
# job.done? #=> false
|
409
|
+
# job.reload! # API call
|
410
|
+
# job.done? #=> true
|
411
|
+
#
|
412
|
+
# if job.error?
|
413
|
+
# status = job.error
|
414
|
+
# else
|
415
|
+
# database = job.database
|
416
|
+
# end
|
417
|
+
#
|
418
|
+
def create_database database_id, statements: [], encryption_config: nil
|
332
419
|
grpc = service.create_database instance_id, database_id,
|
333
|
-
statements: statements
|
420
|
+
statements: statements,
|
421
|
+
encryption_config: encryption_config
|
334
422
|
Database::Job.from_grpc grpc, service
|
335
423
|
end
|
336
424
|
|
@@ -73,7 +73,7 @@ module Google
|
|
73
73
|
return nil unless next?
|
74
74
|
ensure_service!
|
75
75
|
options = { token: token, max: @max }
|
76
|
-
grpc = @service.list_instance_configs
|
76
|
+
grpc = @service.list_instance_configs(**options)
|
77
77
|
self.class.from_grpc grpc, @service, @max
|
78
78
|
end
|
79
79
|
|
@@ -123,17 +123,17 @@ module Google
|
|
123
123
|
# puts config.instance_config_id
|
124
124
|
# end
|
125
125
|
#
|
126
|
-
def all request_limit: nil
|
126
|
+
def all request_limit: nil, &block
|
127
127
|
request_limit = request_limit.to_i if request_limit
|
128
128
|
unless block_given?
|
129
129
|
return enum_for :all, request_limit: request_limit
|
130
130
|
end
|
131
131
|
results = self
|
132
132
|
loop do
|
133
|
-
results.each
|
133
|
+
results.each(&block)
|
134
134
|
if request_limit
|
135
135
|
request_limit -= 1
|
136
|
-
break if request_limit
|
136
|
+
break if request_limit.negative?
|
137
137
|
end
|
138
138
|
break unless results.next?
|
139
139
|
results = results.next
|
@@ -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
|
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
|
130
|
+
results.each(&block)
|
131
131
|
if request_limit
|
132
132
|
request_limit -= 1
|
133
|
-
break if request_limit
|
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
|
48
|
+
attr_reader :execute
|
49
|
+
attr_reader :read
|
49
50
|
|
50
51
|
##
|
51
52
|
# @private Creates a Partition object.
|
52
|
-
def initialize
|
53
|
+
def initialize
|
54
|
+
end
|
53
55
|
|
54
56
|
##
|
55
57
|
# Whether the partition was created for an execute_query/query
|