google-cloud-spanner 2.1.0 → 2.2.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 +11 -0
- data/lib/google-cloud-spanner.rb +1 -0
- data/lib/google/cloud/spanner/convert.rb +9 -0
- data/lib/google/cloud/spanner/results.rb +94 -18
- data/lib/google/cloud/spanner/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 01dd371ff37296529b691fd13961d7e7681e63480a88202b9e958a8c28bc480b
|
4
|
+
data.tar.gz: 9915fdf52be7508c55380b193a9586a35c702617080d3bf93a9f53b37b62be84
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0a34c4eeaaf84abe4d311350a155b22190c7dbc426a48719df4ad553692d841aa1a2d3a72d7f043b2fef7b3fa87a81cda69f965f5eef58a8ce17a77bf186a48e
|
7
|
+
data.tar.gz: 36062397079b8960916575b9188c0ad10f376d27b7d194a20e7f4c6e69f29eeb018b499576209bf1b2d2985725233db5de3e233ff840b5c93790d15b9b4204ab
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
# Release History
|
2
2
|
|
3
|
+
### 2.2.0 / 2020-09-15
|
4
|
+
|
5
|
+
#### Features
|
6
|
+
|
7
|
+
* quota_project can be set via library configuration
|
8
|
+
* Support numeric type.
|
9
|
+
|
10
|
+
#### Bug Fixes
|
11
|
+
|
12
|
+
* retry or resume eos and rst_stream errors
|
13
|
+
|
3
14
|
### 2.1.0 / 2020-08-05
|
4
15
|
|
5
16
|
#### Features
|
data/lib/google-cloud-spanner.rb
CHANGED
@@ -174,6 +174,7 @@ Google::Cloud.configure.add_config! :spanner do |config|
|
|
174
174
|
allow_nil: true
|
175
175
|
config.add_alias! :keyfile, :credentials
|
176
176
|
config.add_field! :scope, default_scopes, match: [String, Array]
|
177
|
+
config.add_field! :quota_project, nil, match: String
|
177
178
|
config.add_field! :timeout, nil, match: Integer
|
178
179
|
config.add_field! :endpoint, "spanner.googleapis.com", match: String
|
179
180
|
config.add_field! :emulator_host, default_emulator, match: String, allow_nil: true
|
@@ -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
|
|
@@ -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
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
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
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
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
|
-
|
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
|
-
|
167
|
-
|
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
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: google-cloud-spanner
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Moore
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2020-
|
12
|
+
date: 2020-09-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: google-cloud-core
|
@@ -329,7 +329,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
329
329
|
- !ruby/object:Gem::Version
|
330
330
|
version: '0'
|
331
331
|
requirements: []
|
332
|
-
rubygems_version: 3.1.
|
332
|
+
rubygems_version: 3.1.4
|
333
333
|
signing_key:
|
334
334
|
specification_version: 4
|
335
335
|
summary: API Client library for Google Cloud Spanner API
|