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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +64 -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 +75 -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 +111 -3
- data/lib/google/cloud/spanner/database/backup_info.rb +12 -3
- 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 +44 -24
- 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
|
@@ -85,6 +85,18 @@ module Google
|
|
85
85
|
@grpc.name.split("/")[5]
|
86
86
|
end
|
87
87
|
|
88
|
+
# The version retention period for a database.
|
89
|
+
# @return [String]
|
90
|
+
def version_retention_period
|
91
|
+
@grpc.version_retention_period
|
92
|
+
end
|
93
|
+
|
94
|
+
# The earliest available version time for a database.
|
95
|
+
# @return [Time]
|
96
|
+
def earliest_version_time
|
97
|
+
Convert.timestamp_to_time @grpc.earliest_version_time
|
98
|
+
end
|
99
|
+
|
88
100
|
##
|
89
101
|
# The full path for the database resource. Values are of the form
|
90
102
|
# `projects/<project_id>/instances/<instance_id>/databases/<database_id>`.
|
@@ -101,6 +113,38 @@ module Google
|
|
101
113
|
@grpc.state
|
102
114
|
end
|
103
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
|
+
|
104
148
|
##
|
105
149
|
# The database is still being created. Operations on the database may
|
106
150
|
# raise with `FAILED_PRECONDITION` in this state.
|
@@ -400,6 +444,31 @@ module Google
|
|
400
444
|
# 366 days from the time the request is received. Required.
|
401
445
|
# Once the `expire_time` has passed, Cloud Spanner will delete the
|
402
446
|
# backup and free the resources used by the backup. Required.
|
447
|
+
# @param [Time] version_time Specifies the time to have an externally
|
448
|
+
# consistent copy of the database. If no version time is specified,
|
449
|
+
# it will be automatically set to the backup create time. The version
|
450
|
+
# time can be as far in the past as specified by the database earliest
|
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
|
+
#
|
403
472
|
# @return [Google::Cloud::Spanner::Backup::Job] The job representing
|
404
473
|
# the long-running, asynchronous processing of a backup create
|
405
474
|
# operation.
|
@@ -410,7 +479,36 @@ module Google
|
|
410
479
|
# spanner = Google::Cloud::Spanner.new
|
411
480
|
# database = spanner.database "my-instance", "my-database"
|
412
481
|
#
|
413
|
-
#
|
482
|
+
# backup_id = "my-backup"
|
483
|
+
# expire_time = Time.now + (24 * 60 * 60) # 1 day from now
|
484
|
+
# version_time = Time.now - (24 * 60 * 60) # 1 day ago (optional)
|
485
|
+
#
|
486
|
+
# job = database.create_backup backup_id, expire_time, version_time: version_time
|
487
|
+
#
|
488
|
+
# job.done? #=> false
|
489
|
+
# job.reload! # API call
|
490
|
+
# job.done? #=> true
|
491
|
+
#
|
492
|
+
# if job.error?
|
493
|
+
# status = job.error
|
494
|
+
# else
|
495
|
+
# backup = job.backup
|
496
|
+
# end
|
497
|
+
#
|
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
|
414
512
|
#
|
415
513
|
# job.done? #=> false
|
416
514
|
# job.reload! # API call
|
@@ -422,13 +520,23 @@ module Google
|
|
422
520
|
# backup = job.backup
|
423
521
|
# end
|
424
522
|
#
|
425
|
-
def create_backup backup_id, expire_time
|
523
|
+
def create_backup backup_id, expire_time,
|
524
|
+
version_time: nil, encryption_config: nil
|
426
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
|
+
|
427
533
|
grpc = service.create_backup \
|
428
534
|
instance_id,
|
429
535
|
database_id,
|
430
536
|
backup_id,
|
431
|
-
expire_time
|
537
|
+
expire_time,
|
538
|
+
version_time,
|
539
|
+
encryption_config: encryption_config
|
432
540
|
Backup::Job.from_grpc grpc, service
|
433
541
|
end
|
434
542
|
|
@@ -84,14 +84,23 @@ module Google
|
|
84
84
|
end
|
85
85
|
|
86
86
|
##
|
87
|
-
# The
|
88
|
-
# `source_database` at the timestamp specified by `create_time`.
|
89
|
-
# received.
|
87
|
+
# The timestamp indicating the creation of the backup.
|
90
88
|
# @return [Time]
|
91
89
|
def create_time
|
92
90
|
Convert.timestamp_to_time @grpc.create_time
|
93
91
|
end
|
94
92
|
|
93
|
+
##
|
94
|
+
# The backup contains an externally consistent copy of
|
95
|
+
# `source_database` at the timestamp specified by
|
96
|
+
# the `version_time` received. If no `version_time` was
|
97
|
+
# given during the creation of the backup, the `version_time`
|
98
|
+
# will be the same as the `create_time`.
|
99
|
+
# @return [Time]
|
100
|
+
def version_time
|
101
|
+
Convert.timestamp_to_time @grpc.version_time
|
102
|
+
end
|
103
|
+
|
95
104
|
##
|
96
105
|
# @private Creates a new Database::BackupInfo instance from a
|
97
106
|
# `Google::Cloud::Spanner::Admin::Database::V1::BackupInfo`.
|
@@ -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
|