google-cloud-spanner 2.0.0 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +49 -0
- data/CONTRIBUTING.md +2 -2
- data/LOGGING.md +1 -1
- data/lib/google-cloud-spanner.rb +1 -0
- data/lib/google/cloud/spanner.rb +7 -5
- data/lib/google/cloud/spanner/backup.rb +10 -2
- 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 +114 -15
- data/lib/google/cloud/spanner/batch_update.rb +3 -1
- data/lib/google/cloud/spanner/client.rb +413 -78
- data/lib/google/cloud/spanner/commit_response.rb +87 -0
- data/lib/google/cloud/spanner/commit_response/commit_stats.rb +51 -0
- data/lib/google/cloud/spanner/convert.rb +9 -0
- data/lib/google/cloud/spanner/data.rb +4 -5
- data/lib/google/cloud/spanner/database.rb +25 -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 +3 -2
- 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/results.rb +105 -26
- data/lib/google/cloud/spanner/service.rb +218 -107
- data/lib/google/cloud/spanner/session.rb +361 -30
- data/lib/google/cloud/spanner/snapshot.rb +58 -4
- data/lib/google/cloud/spanner/status.rb +4 -1
- data/lib/google/cloud/spanner/transaction.rb +114 -8
- data/lib/google/cloud/spanner/version.rb +1 -1
- metadata +12 -10
@@ -0,0 +1,87 @@
|
|
1
|
+
# Copyright 2020 Google LLC
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# https://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
|
16
|
+
require "google/cloud/spanner/commit_response/commit_stats"
|
17
|
+
|
18
|
+
module Google
|
19
|
+
module Cloud
|
20
|
+
module Spanner
|
21
|
+
##
|
22
|
+
# CommitResponse is a timestamp at which the transaction committed
|
23
|
+
# with additional attributes of commit stats.
|
24
|
+
#
|
25
|
+
# @example
|
26
|
+
# require "google/cloud/spanner"
|
27
|
+
#
|
28
|
+
# spanner = Google::Cloud::Spanner.new
|
29
|
+
#
|
30
|
+
# db = spanner.client "my-instance", "my-database"
|
31
|
+
#
|
32
|
+
# timestamp = db.commit do |c|
|
33
|
+
# c.update "users", [{ id: 1, name: "Charlie", active: false }]
|
34
|
+
# c.insert "users", [{ id: 2, name: "Harvey", active: true }]
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
# puts timestamp
|
38
|
+
#
|
39
|
+
# @example With commit stats.
|
40
|
+
# require "google/cloud/spanner"
|
41
|
+
#
|
42
|
+
# spanner = Google::Cloud::Spanner.new
|
43
|
+
#
|
44
|
+
# db = spanner.client "my-instance", "my-database"
|
45
|
+
#
|
46
|
+
# commit_options = { return_commit_stats: true }
|
47
|
+
# commit_resp = db.commit commit_options: commit_options do |c|
|
48
|
+
# c.update "users", [{ id: 1, name: "Charlie", active: false }]
|
49
|
+
# c.insert "users", [{ id: 2, name: "Harvey", active: true }]
|
50
|
+
# end
|
51
|
+
#
|
52
|
+
# puts commit_resp.timestamp
|
53
|
+
# puts commit_resp.stats.mutation_count
|
54
|
+
#
|
55
|
+
class CommitResponse
|
56
|
+
##
|
57
|
+
# @private Creates a new CommitResponse instance.
|
58
|
+
def initialize grpc
|
59
|
+
@grpc = grpc
|
60
|
+
end
|
61
|
+
|
62
|
+
##
|
63
|
+
# The timestamp at which the transaction committed.
|
64
|
+
# @return [Time]
|
65
|
+
def timestamp
|
66
|
+
Convert.timestamp_to_time @grpc.commit_timestamp
|
67
|
+
end
|
68
|
+
|
69
|
+
##
|
70
|
+
# Additional statistics about a commit.
|
71
|
+
# @return [CommitStats, nil] Commit stats or nil if not stats not
|
72
|
+
# present.
|
73
|
+
def stats
|
74
|
+
CommitStats.from_grpc @grpc.commit_stats if @grpc.commit_stats
|
75
|
+
end
|
76
|
+
|
77
|
+
##
|
78
|
+
# @private
|
79
|
+
# Creates a new Commit responsee instance from a
|
80
|
+
# `Google::Cloud::Spanner::V1::CommitResponse`.
|
81
|
+
def self.from_grpc grpc
|
82
|
+
new grpc
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# Copyright 2020 Google LLC
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# https://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
|
16
|
+
require "google/cloud/spanner/convert"
|
17
|
+
|
18
|
+
module Google
|
19
|
+
module Cloud
|
20
|
+
module Spanner
|
21
|
+
class CommitResponse
|
22
|
+
##
|
23
|
+
# # CommitStats
|
24
|
+
#
|
25
|
+
# Statistical information of a transaction commit.
|
26
|
+
#
|
27
|
+
class CommitStats
|
28
|
+
##
|
29
|
+
# @private Creates a new CommitStats instance.
|
30
|
+
def initialize grpc
|
31
|
+
@grpc = grpc
|
32
|
+
end
|
33
|
+
|
34
|
+
# The total number of the mutations for the transaction.
|
35
|
+
# @return [Integer]
|
36
|
+
def mutation_count
|
37
|
+
@grpc.mutation_count
|
38
|
+
end
|
39
|
+
|
40
|
+
##
|
41
|
+
# @private
|
42
|
+
# Creates a new CommitStats instance from a
|
43
|
+
# `Google::Cloud::Spanner::V1::CommitResponse::CommitStats`.
|
44
|
+
def self.from_grpc grpc
|
45
|
+
new grpc
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -17,6 +17,7 @@ require "time"
|
|
17
17
|
require "date"
|
18
18
|
require "stringio"
|
19
19
|
require "base64"
|
20
|
+
require "bigdecimal"
|
20
21
|
require "google/cloud/spanner/data"
|
21
22
|
|
22
23
|
module Google
|
@@ -67,6 +68,9 @@ module Google
|
|
67
68
|
Google::Protobuf::Value.new bool_value: false
|
68
69
|
when Integer
|
69
70
|
Google::Protobuf::Value.new string_value: obj.to_s
|
71
|
+
# BigDecimal must be put before Numeric.
|
72
|
+
when BigDecimal
|
73
|
+
Google::Protobuf::Value.new string_value: obj.to_s("F")
|
70
74
|
when Numeric
|
71
75
|
if obj == Float::INFINITY
|
72
76
|
Google::Protobuf::Value.new string_value: "Infinity"
|
@@ -125,6 +129,9 @@ module Google
|
|
125
129
|
:BOOL
|
126
130
|
when Integer
|
127
131
|
:INT64
|
132
|
+
# BigDecimal must be put before Numeric.
|
133
|
+
when BigDecimal
|
134
|
+
:NUMERIC
|
128
135
|
when Numeric
|
129
136
|
:FLOAT64
|
130
137
|
when Time
|
@@ -214,6 +221,8 @@ module Google
|
|
214
221
|
end
|
215
222
|
when :STRUCT
|
216
223
|
Data.from_grpc value.list_value.values, type.struct_type.fields
|
224
|
+
when :NUMERIC
|
225
|
+
BigDecimal value.string_value
|
217
226
|
end
|
218
227
|
end
|
219
228
|
|
@@ -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>`.
|
@@ -400,6 +412,11 @@ module Google
|
|
400
412
|
# 366 days from the time the request is received. Required.
|
401
413
|
# Once the `expire_time` has passed, Cloud Spanner will delete the
|
402
414
|
# backup and free the resources used by the backup. Required.
|
415
|
+
# @param [Time] version_time Specifies the time to have an externally
|
416
|
+
# consistent copy of the database. If no version time is specified,
|
417
|
+
# it will be automatically set to the backup create time. The version
|
418
|
+
# time can be as far in the past as specified by the database earliest
|
419
|
+
# version time. Optional.
|
403
420
|
# @return [Google::Cloud::Spanner::Backup::Job] The job representing
|
404
421
|
# the long-running, asynchronous processing of a backup create
|
405
422
|
# operation.
|
@@ -410,7 +427,11 @@ module Google
|
|
410
427
|
# spanner = Google::Cloud::Spanner.new
|
411
428
|
# database = spanner.database "my-instance", "my-database"
|
412
429
|
#
|
413
|
-
#
|
430
|
+
# backup_id = "my-backup"
|
431
|
+
# expire_time = Time.now + (24 * 60 * 60) # 1 day from now
|
432
|
+
# version_time = Time.now - (24 * 60 * 60) # 1 day ago (optional)
|
433
|
+
#
|
434
|
+
# job = database.create_backup backup_id, expire_time, version_time: version_time
|
414
435
|
#
|
415
436
|
# job.done? #=> false
|
416
437
|
# job.reload! # API call
|
@@ -422,13 +443,14 @@ module Google
|
|
422
443
|
# backup = job.backup
|
423
444
|
# end
|
424
445
|
#
|
425
|
-
def create_backup backup_id, expire_time
|
446
|
+
def create_backup backup_id, expire_time, version_time: nil
|
426
447
|
ensure_service!
|
427
448
|
grpc = service.create_backup \
|
428
449
|
instance_id,
|
429
450
|
database_id,
|
430
451
|
backup_id,
|
431
|
-
expire_time
|
452
|
+
expire_time,
|
453
|
+
version_time
|
432
454
|
Backup::Job.from_grpc grpc, service
|
433
455
|
end
|
434
456
|
|
@@ -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
|
@@ -133,13 +133,14 @@ module Google
|
|
133
133
|
#
|
134
134
|
def types
|
135
135
|
@grpc_fields.map(&:type).map do |type|
|
136
|
-
|
136
|
+
case type.code
|
137
|
+
when :ARRAY
|
137
138
|
if type.array_element_type.code == :STRUCT
|
138
139
|
[Fields.from_grpc(type.array_element_type.struct_type.fields)]
|
139
140
|
else
|
140
141
|
[type.array_element_type.code]
|
141
142
|
end
|
142
|
-
|
143
|
+
when :STRUCT
|
143
144
|
Fields.from_grpc type.struct_type.fields
|
144
145
|
else
|
145
146
|
type.code
|
@@ -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
|
@@ -70,7 +70,8 @@ module Google
|
|
70
70
|
# end
|
71
71
|
#
|
72
72
|
class Policy
|
73
|
-
attr_reader :etag
|
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
|
|