gcloud 0.8.2 → 0.9.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 +8 -8
- data/CHANGELOG.md +26 -0
- data/OVERVIEW.md +10 -8
- data/lib/gcloud.rb +12 -13
- data/lib/gcloud/bigquery/dataset/list.rb +2 -4
- data/lib/gcloud/bigquery/job/list.rb +3 -5
- data/lib/gcloud/bigquery/table/list.rb +3 -5
- data/lib/gcloud/datastore.rb +326 -97
- data/lib/gcloud/datastore/commit.rb +73 -56
- data/lib/gcloud/datastore/credentials.rb +1 -12
- data/lib/gcloud/datastore/cursor.rb +76 -0
- data/lib/gcloud/datastore/dataset.rb +337 -134
- data/lib/gcloud/datastore/dataset/lookup_results.rb +12 -12
- data/lib/gcloud/datastore/dataset/query_results.rb +117 -27
- data/lib/gcloud/datastore/entity.rb +159 -93
- data/lib/gcloud/datastore/errors.rb +0 -21
- data/lib/gcloud/datastore/gql_query.rb +211 -0
- data/lib/gcloud/datastore/grpc_utils.rb +131 -0
- data/lib/gcloud/datastore/key.rb +74 -65
- data/lib/gcloud/datastore/properties.rb +14 -1
- data/lib/gcloud/datastore/query.rb +188 -52
- data/lib/gcloud/datastore/service.rb +161 -0
- data/lib/gcloud/datastore/transaction.rb +175 -60
- data/lib/gcloud/dns/change/list.rb +2 -4
- data/lib/gcloud/dns/record/list.rb +2 -4
- data/lib/gcloud/dns/zone/list.rb +2 -4
- data/lib/gcloud/grpc_utils.rb +11 -0
- data/lib/gcloud/logging/entry.rb +6 -17
- data/lib/gcloud/logging/entry/list.rb +8 -9
- data/lib/gcloud/logging/metric/list.rb +4 -5
- data/lib/gcloud/logging/resource.rb +1 -12
- data/lib/gcloud/logging/resource_descriptor.rb +9 -12
- data/lib/gcloud/logging/resource_descriptor/list.rb +4 -5
- data/lib/gcloud/logging/sink/list.rb +4 -5
- data/lib/gcloud/pubsub/message.rb +1 -3
- data/lib/gcloud/pubsub/subscription.rb +5 -7
- data/lib/gcloud/pubsub/topic.rb +1 -3
- data/lib/gcloud/resource_manager/project/list.rb +2 -4
- data/lib/gcloud/translate/api.rb +5 -3
- data/lib/gcloud/translate/connection.rb +4 -4
- data/lib/gcloud/version.rb +1 -1
- metadata +9 -20
- data/lib/gcloud/datastore/connection.rb +0 -203
- data/lib/gcloud/datastore/proto.rb +0 -266
- data/lib/gcloud/proto/datastore_v1.pb.rb +0 -377
- data/lib/google/protobuf/any.rb +0 -17
- data/lib/google/protobuf/api.rb +0 -31
- data/lib/google/protobuf/duration.rb +0 -17
- data/lib/google/protobuf/empty.rb +0 -15
- data/lib/google/protobuf/field_mask.rb +0 -16
- data/lib/google/protobuf/source_context.rb +0 -16
- data/lib/google/protobuf/struct.rb +0 -35
- data/lib/google/protobuf/timestamp.rb +0 -17
- data/lib/google/protobuf/type.rb +0 -79
- data/lib/google/protobuf/wrappers.rb +0 -48
@@ -71,6 +71,17 @@ module Gcloud
|
|
71
71
|
end
|
72
72
|
alias_method :to_hash, :to_h
|
73
73
|
|
74
|
+
def to_grpc
|
75
|
+
Hash[@hash.map { |(k, v)| [k.to_s, GRPCUtils.to_value(v)] }]
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.from_grpc grpc_map
|
79
|
+
# For some reason Google::Protobuf::Map#map isn't returning the value.
|
80
|
+
# It returns nil every time. COnvert to Hash to get actual objects.
|
81
|
+
grpc_hash = GRPCUtils.map_to_hash grpc_map
|
82
|
+
new Hash[grpc_hash.map { |(k, v)| [k.to_s, GRPCUtils.from_value(v)] }]
|
83
|
+
end
|
84
|
+
|
74
85
|
protected
|
75
86
|
|
76
87
|
##
|
@@ -82,7 +93,7 @@ module Gcloud
|
|
82
93
|
end
|
83
94
|
|
84
95
|
# rubocop:disable all
|
85
|
-
# Disabled rubocop because this needs to match
|
96
|
+
# Disabled rubocop because this needs to match GRPCUtils.to_value
|
86
97
|
|
87
98
|
##
|
88
99
|
# Ensures the value is a type that can be persisted,
|
@@ -100,6 +111,8 @@ module Gcloud
|
|
100
111
|
return value
|
101
112
|
elsif value.respond_to?(:to_time)
|
102
113
|
return value
|
114
|
+
elsif value.respond_to?(:to_hash) && value.keys.sort == [:latitude, :longitude]
|
115
|
+
return value
|
103
116
|
elsif value.respond_to?(:read) && value.respond_to?(:rewind)
|
104
117
|
# Always convert an IO object to a StringIO when storing.
|
105
118
|
value.rewind
|
@@ -15,7 +15,6 @@
|
|
15
15
|
|
16
16
|
require "gcloud/datastore/entity"
|
17
17
|
require "gcloud/datastore/key"
|
18
|
-
require "gcloud/datastore/proto"
|
19
18
|
|
20
19
|
module Gcloud
|
21
20
|
module Datastore
|
@@ -24,12 +23,19 @@ module Gcloud
|
|
24
23
|
#
|
25
24
|
# Represents the search criteria against a Datastore.
|
26
25
|
#
|
26
|
+
# @see https://cloud.google.com/datastore/docs/concepts/queries Datastore
|
27
|
+
# Queries
|
28
|
+
# @see https://cloud.google.com/datastore/docs/concepts/metadataqueries
|
29
|
+
# Datastore Metadata
|
30
|
+
#
|
27
31
|
# @example
|
28
32
|
# query = Gcloud::Datastore::Query.new
|
29
33
|
# query.kind("Task").
|
30
|
-
# where("
|
34
|
+
# where("done", "=", false).
|
35
|
+
# where("priority", ">=", 4).
|
36
|
+
# order("priority", :desc)
|
31
37
|
#
|
32
|
-
#
|
38
|
+
# tasks = datastore.run query
|
33
39
|
#
|
34
40
|
class Query
|
35
41
|
##
|
@@ -39,22 +45,28 @@ module Gcloud
|
|
39
45
|
# query = Gcloud::Datastore::Query.new
|
40
46
|
#
|
41
47
|
def initialize
|
42
|
-
@
|
48
|
+
@grpc = Google::Datastore::V1beta3::Query.new
|
43
49
|
end
|
44
50
|
|
45
51
|
##
|
46
52
|
# Add the kind of entities to query.
|
47
53
|
#
|
54
|
+
# Special entity kinds such as `__namespace__`, `__kind__`, and
|
55
|
+
# `__property__` can be used for [metadata
|
56
|
+
# queries](https://cloud.google.com/datastore/docs/concepts/metadataqueries).
|
57
|
+
#
|
48
58
|
# @example
|
49
59
|
# query = Gcloud::Datastore::Query.new
|
50
60
|
# query.kind "Task"
|
51
61
|
#
|
52
|
-
#
|
62
|
+
# tasks = datastore.run query
|
53
63
|
#
|
54
64
|
def kind *kinds
|
55
|
-
|
56
|
-
|
57
|
-
|
65
|
+
kinds.each do |kind|
|
66
|
+
grpc_kind = Google::Datastore::V1beta3::KindExpression.new(name: kind)
|
67
|
+
@grpc.kind << grpc_kind
|
68
|
+
end
|
69
|
+
|
58
70
|
self
|
59
71
|
end
|
60
72
|
|
@@ -64,21 +76,72 @@ module Gcloud
|
|
64
76
|
# @example
|
65
77
|
# query = Gcloud::Datastore::Query.new
|
66
78
|
# query.kind("Task").
|
67
|
-
# where("
|
79
|
+
# where("done", "=", false)
|
80
|
+
#
|
81
|
+
# tasks = datastore.run query
|
82
|
+
#
|
83
|
+
# @example Add a composite property filter:
|
84
|
+
# query = Gcloud::Datastore::Query.new
|
85
|
+
# query.kind("Task").
|
86
|
+
# where("done", "=", false).
|
87
|
+
# where("priority", ">=", 4)
|
88
|
+
#
|
89
|
+
# tasks = datastore.run query
|
90
|
+
#
|
91
|
+
# @example Add an inequality filter on a **single** property only:
|
92
|
+
# query = Gcloud::Datastore::Query.new
|
93
|
+
# query.kind("Task").
|
94
|
+
# where("created", ">=", Time.utc(1990, 1, 1)).
|
95
|
+
# where("created", "<", Time.utc(2000, 1, 1))
|
96
|
+
#
|
97
|
+
# tasks = datastore.run query
|
98
|
+
#
|
99
|
+
# @example Add a composite filter on an array property:
|
100
|
+
# query = Gcloud::Datastore::Query.new
|
101
|
+
# query.kind("Task").
|
102
|
+
# where("tag", "=", "fun").
|
103
|
+
# where("tag", "=", "programming")
|
68
104
|
#
|
69
|
-
#
|
105
|
+
# tasks = datastore.run query
|
106
|
+
#
|
107
|
+
# @example Add an inequality filter on an array property :
|
108
|
+
# query = Gcloud::Datastore::Query.new
|
109
|
+
# query.kind("Task").
|
110
|
+
# where("tag", ">", "learn").
|
111
|
+
# where("tag", "<", "math")
|
112
|
+
#
|
113
|
+
# tasks = datastore.run query
|
114
|
+
#
|
115
|
+
# @example Add a key filter using the special property `__key__`:
|
116
|
+
# query = Gcloud::Datastore::Query.new
|
117
|
+
# query.kind("Task").
|
118
|
+
# where("__key__", ">", datastore.key("Task", "someTask"))
|
119
|
+
#
|
120
|
+
# tasks = datastore.run query
|
121
|
+
#
|
122
|
+
# @example Add a key filter to a *kindless* query:
|
123
|
+
# last_seen_key = datastore.key "Task", "a"
|
124
|
+
# query = Gcloud::Datastore::Query.new
|
125
|
+
# query.where("__key__", ">", last_seen_key)
|
126
|
+
#
|
127
|
+
# tasks = datastore.run query
|
70
128
|
#
|
71
129
|
def where name, operator, value
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
filter
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
130
|
+
@grpc.filter ||= Google::Datastore::V1beta3::Filter.new(
|
131
|
+
composite_filter: Google::Datastore::V1beta3::CompositeFilter.new(
|
132
|
+
op: :AND
|
133
|
+
)
|
134
|
+
)
|
135
|
+
@grpc.filter.composite_filter.filters << \
|
136
|
+
Google::Datastore::V1beta3::Filter.new(
|
137
|
+
property_filter: Google::Datastore::V1beta3::PropertyFilter.new(
|
138
|
+
property: Google::Datastore::V1beta3::PropertyReference.new(
|
139
|
+
name: name),
|
140
|
+
op: GRPCUtils.to_prop_filter_op(operator),
|
141
|
+
value: GRPCUtils.to_value(value)
|
142
|
+
)
|
143
|
+
)
|
144
|
+
|
82
145
|
self
|
83
146
|
end
|
84
147
|
alias_method :filter, :where
|
@@ -87,11 +150,13 @@ module Gcloud
|
|
87
150
|
# Add a filter for entities that inherit from a key.
|
88
151
|
#
|
89
152
|
# @example
|
153
|
+
# task_list_key = datastore.key "TaskList", "default"
|
154
|
+
#
|
90
155
|
# query = Gcloud::Datastore::Query.new
|
91
156
|
# query.kind("Task").
|
92
|
-
# ancestor(
|
157
|
+
# ancestor(task_list_key)
|
93
158
|
#
|
94
|
-
#
|
159
|
+
# tasks = datastore.run query
|
95
160
|
#
|
96
161
|
def ancestor parent
|
97
162
|
# Use key if given an entity
|
@@ -105,20 +170,44 @@ module Gcloud
|
|
105
170
|
# To sort in descending order, provide a second argument
|
106
171
|
# of a string or symbol that starts with "d".
|
107
172
|
#
|
108
|
-
# @example
|
173
|
+
# @example With ascending sort order:
|
174
|
+
# query = Gcloud::Datastore::Query.new
|
175
|
+
# query.kind("Task").
|
176
|
+
# order("created")
|
177
|
+
#
|
178
|
+
# tasks = datastore.run query
|
179
|
+
#
|
180
|
+
# @example With descending sort order:
|
181
|
+
# query = Gcloud::Datastore::Query.new
|
182
|
+
# query.kind("Task").
|
183
|
+
# order("created", :desc)
|
184
|
+
#
|
185
|
+
# tasks = datastore.run query
|
186
|
+
#
|
187
|
+
# @example With multiple sort orders:
|
188
|
+
# query = Gcloud::Datastore::Query.new
|
189
|
+
# query.kind("Task").
|
190
|
+
# order("priority", :desc).
|
191
|
+
# order("created")
|
192
|
+
#
|
193
|
+
# tasks = datastore.run query
|
194
|
+
#
|
195
|
+
# @example A property used in an inequality filter must be ordered first:
|
109
196
|
# query = Gcloud::Datastore::Query.new
|
110
197
|
# query.kind("Task").
|
111
|
-
#
|
198
|
+
# where("priority", ">", 3).
|
199
|
+
# order("priority").
|
200
|
+
# order("created")
|
112
201
|
#
|
113
|
-
#
|
202
|
+
# tasks = datastore.run query
|
114
203
|
#
|
115
204
|
def order name, direction = :asc
|
116
|
-
@
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
205
|
+
@grpc.order << Google::Datastore::V1beta3::PropertyOrder.new(
|
206
|
+
property: Google::Datastore::V1beta3::PropertyReference.new(
|
207
|
+
name: name),
|
208
|
+
direction: prop_order_direction(direction)
|
209
|
+
)
|
210
|
+
|
122
211
|
self
|
123
212
|
end
|
124
213
|
|
@@ -128,12 +217,13 @@ module Gcloud
|
|
128
217
|
# @example
|
129
218
|
# query = Gcloud::Datastore::Query.new
|
130
219
|
# query.kind("Task").
|
131
|
-
# limit(
|
220
|
+
# limit(5)
|
132
221
|
#
|
133
|
-
#
|
222
|
+
# tasks = datastore.run query
|
134
223
|
#
|
135
224
|
def limit num
|
136
|
-
@
|
225
|
+
@grpc.limit = Google::Protobuf::Int32Value.new(value: num)
|
226
|
+
|
137
227
|
self
|
138
228
|
end
|
139
229
|
|
@@ -143,13 +233,14 @@ module Gcloud
|
|
143
233
|
# @example
|
144
234
|
# query = Gcloud::Datastore::Query.new
|
145
235
|
# query.kind("Task").
|
146
|
-
# limit(
|
147
|
-
# offset(
|
236
|
+
# limit(5).
|
237
|
+
# offset(10)
|
148
238
|
#
|
149
|
-
#
|
239
|
+
# tasks = datastore.run query
|
150
240
|
#
|
151
241
|
def offset num
|
152
|
-
@
|
242
|
+
@grpc.offset = num
|
243
|
+
|
153
244
|
self
|
154
245
|
end
|
155
246
|
|
@@ -159,13 +250,20 @@ module Gcloud
|
|
159
250
|
# @example
|
160
251
|
# query = Gcloud::Datastore::Query.new
|
161
252
|
# query.kind("Task").
|
162
|
-
# limit(
|
163
|
-
#
|
253
|
+
# limit(page_size).
|
254
|
+
# start(page_cursor)
|
164
255
|
#
|
165
|
-
#
|
256
|
+
# tasks = datastore.run query
|
166
257
|
#
|
167
258
|
def start cursor
|
168
|
-
|
259
|
+
if cursor.is_a? Cursor
|
260
|
+
@grpc.start_cursor = cursor.to_grpc
|
261
|
+
elsif cursor.is_a? String
|
262
|
+
@grpc.start_cursor = GRPCUtils.decode_bytes cursor
|
263
|
+
else
|
264
|
+
fail ArgumentError, "Can't set a cursor using a #{cursor.class}."
|
265
|
+
end
|
266
|
+
|
169
267
|
self
|
170
268
|
end
|
171
269
|
alias_method :cursor, :start
|
@@ -176,13 +274,30 @@ module Gcloud
|
|
176
274
|
# @example
|
177
275
|
# query = Gcloud::Datastore::Query.new
|
178
276
|
# query.kind("Task").
|
179
|
-
# select("
|
277
|
+
# select("priority", "percent_complete")
|
278
|
+
#
|
279
|
+
# priorities = []
|
280
|
+
# percent_completes = []
|
281
|
+
# datastore.run(query).each do |task|
|
282
|
+
# priorities << task["priority"]
|
283
|
+
# percent_completes << task["percent_complete"]
|
284
|
+
# end
|
285
|
+
#
|
286
|
+
# @example A keys-only query using the special property `__key__`:
|
287
|
+
# query = Gcloud::Datastore::Query.new
|
288
|
+
# query.kind("Task").
|
289
|
+
# select("__key__")
|
180
290
|
#
|
181
|
-
#
|
291
|
+
# keys = datastore.run(query).map(&:key)
|
182
292
|
#
|
183
293
|
def select *names
|
184
|
-
|
185
|
-
|
294
|
+
names.each do |name|
|
295
|
+
grpc_projection = Google::Datastore::V1beta3::Projection.new(
|
296
|
+
property: Google::Datastore::V1beta3::PropertyReference.new(
|
297
|
+
name: name))
|
298
|
+
@grpc.projection << grpc_projection
|
299
|
+
end
|
300
|
+
|
186
301
|
self
|
187
302
|
end
|
188
303
|
alias_method :projection, :select
|
@@ -193,19 +308,40 @@ module Gcloud
|
|
193
308
|
# @example
|
194
309
|
# query = Gcloud::Datastore::Query.new
|
195
310
|
# query.kind("Task").
|
196
|
-
#
|
311
|
+
# distinct_on("type", "priority").
|
312
|
+
# order("type").
|
313
|
+
# order("priority")
|
197
314
|
#
|
198
|
-
#
|
315
|
+
# tasks = datastore.run query
|
199
316
|
#
|
200
317
|
def group_by *names
|
201
|
-
|
202
|
-
|
318
|
+
names.each do |name|
|
319
|
+
grpc_property = Google::Datastore::V1beta3::PropertyReference.new(
|
320
|
+
name: name)
|
321
|
+
@grpc.distinct_on << grpc_property
|
322
|
+
end
|
323
|
+
|
203
324
|
self
|
204
325
|
end
|
326
|
+
alias_method :distinct_on, :group_by
|
205
327
|
|
206
328
|
# @private
|
207
|
-
def
|
208
|
-
@
|
329
|
+
def to_grpc
|
330
|
+
@grpc
|
331
|
+
end
|
332
|
+
|
333
|
+
protected
|
334
|
+
|
335
|
+
##
|
336
|
+
# @private Get the property order direction for a string.
|
337
|
+
def prop_order_direction direction
|
338
|
+
if direction.to_s.downcase.start_with? "a"
|
339
|
+
:ASCENDING
|
340
|
+
elsif direction.to_s.downcase.start_with? "d"
|
341
|
+
:DESCENDING
|
342
|
+
else
|
343
|
+
:DIRECTION_UNSPECIFIED
|
344
|
+
end
|
209
345
|
end
|
210
346
|
end
|
211
347
|
end
|
@@ -0,0 +1,161 @@
|
|
1
|
+
# Copyright 2016 Google Inc. All rights reserved.
|
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
|
+
# http://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 "gcloud/datastore/credentials"
|
17
|
+
require "google/datastore/v1beta3/datastore_services"
|
18
|
+
require "gcloud/backoff"
|
19
|
+
|
20
|
+
module Gcloud
|
21
|
+
module Datastore
|
22
|
+
##
|
23
|
+
# @private Represents the gRPC Datastore service, including all the API
|
24
|
+
# methods.
|
25
|
+
class Service
|
26
|
+
attr_accessor :project, :credentials, :host
|
27
|
+
|
28
|
+
##
|
29
|
+
# Creates a new Service instance.
|
30
|
+
def initialize project, credentials
|
31
|
+
@project = project
|
32
|
+
@credentials = credentials
|
33
|
+
@host = "datastore.googleapis.com"
|
34
|
+
end
|
35
|
+
|
36
|
+
def creds
|
37
|
+
return credentials if insecure?
|
38
|
+
GRPC::Core::ChannelCredentials.new.compose \
|
39
|
+
GRPC::Core::CallCredentials.new credentials.client.updater_proc
|
40
|
+
end
|
41
|
+
|
42
|
+
def datastore
|
43
|
+
return mocked_datastore if mocked_datastore
|
44
|
+
@datastore ||= Google::Datastore::V1beta3::Datastore::Stub.new(
|
45
|
+
host, creds)
|
46
|
+
end
|
47
|
+
attr_accessor :mocked_datastore
|
48
|
+
|
49
|
+
def insecure?
|
50
|
+
credentials == :this_channel_is_insecure
|
51
|
+
end
|
52
|
+
|
53
|
+
##
|
54
|
+
# Allocate IDs for incomplete keys.
|
55
|
+
# (This is useful for referencing an entity before it is inserted.)
|
56
|
+
def allocate_ids *incomplete_keys
|
57
|
+
allocate_req = Google::Datastore::V1beta3::AllocateIdsRequest.new(
|
58
|
+
project_id: project,
|
59
|
+
keys: incomplete_keys
|
60
|
+
)
|
61
|
+
|
62
|
+
backoff { datastore.allocate_ids allocate_req }
|
63
|
+
end
|
64
|
+
|
65
|
+
##
|
66
|
+
# Look up entities by keys.
|
67
|
+
def lookup *keys, consistency: nil, transaction: nil
|
68
|
+
lookup_req = Google::Datastore::V1beta3::LookupRequest.new(
|
69
|
+
project_id: project,
|
70
|
+
keys: keys
|
71
|
+
)
|
72
|
+
lookup_req.read_options = generate_read_options consistency, transaction
|
73
|
+
|
74
|
+
backoff { datastore.lookup lookup_req }
|
75
|
+
end
|
76
|
+
|
77
|
+
# Query for entities.
|
78
|
+
def run_query query, namespace = nil, consistency: nil, transaction: nil
|
79
|
+
run_req = Google::Datastore::V1beta3::RunQueryRequest.new(
|
80
|
+
project_id: project)
|
81
|
+
if query.is_a? Google::Datastore::V1beta3::Query
|
82
|
+
run_req["query"] = query
|
83
|
+
elsif query.is_a? Google::Datastore::V1beta3::GqlQuery
|
84
|
+
run_req["gql_query"] = query
|
85
|
+
else
|
86
|
+
fail ArgumentError, "Unable to query with a #{query.class} object."
|
87
|
+
end
|
88
|
+
run_req.read_options = generate_read_options consistency, transaction
|
89
|
+
|
90
|
+
run_req.partition_id = Google::Datastore::V1beta3::PartitionId.new(
|
91
|
+
namespace_id: namespace) if namespace
|
92
|
+
|
93
|
+
backoff { datastore.run_query run_req }
|
94
|
+
end
|
95
|
+
|
96
|
+
##
|
97
|
+
# Begin a new transaction.
|
98
|
+
def begin_transaction
|
99
|
+
tx_req = Google::Datastore::V1beta3::BeginTransactionRequest.new(
|
100
|
+
project_id: project
|
101
|
+
)
|
102
|
+
|
103
|
+
backoff { datastore.begin_transaction tx_req }
|
104
|
+
end
|
105
|
+
|
106
|
+
##
|
107
|
+
# Commit a transaction, optionally creating, deleting or modifying
|
108
|
+
# some entities.
|
109
|
+
def commit mutations, transaction: nil
|
110
|
+
commit_req = Google::Datastore::V1beta3::CommitRequest.new(
|
111
|
+
project_id: project,
|
112
|
+
mode: :NON_TRANSACTIONAL,
|
113
|
+
mutations: mutations
|
114
|
+
)
|
115
|
+
if transaction
|
116
|
+
commit_req.mode = :TRANSACTIONAL
|
117
|
+
commit_req.transaction = transaction
|
118
|
+
end
|
119
|
+
|
120
|
+
backoff { datastore.commit commit_req }
|
121
|
+
end
|
122
|
+
|
123
|
+
##
|
124
|
+
# Roll back a transaction.
|
125
|
+
def rollback transaction
|
126
|
+
rb_req = Google::Datastore::V1beta3::RollbackRequest.new(
|
127
|
+
project_id: project,
|
128
|
+
transaction: transaction
|
129
|
+
)
|
130
|
+
|
131
|
+
backoff { datastore.rollback rb_req }
|
132
|
+
end
|
133
|
+
|
134
|
+
def inspect
|
135
|
+
"#{self.class}(#{@project})"
|
136
|
+
end
|
137
|
+
|
138
|
+
def backoff options = {}
|
139
|
+
Gcloud::Backoff.new(options).execute_grpc do
|
140
|
+
yield
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
protected
|
145
|
+
|
146
|
+
def generate_read_options consistency, transaction
|
147
|
+
if consistency == :eventual
|
148
|
+
return Google::Datastore::V1beta3::ReadOptions.new(
|
149
|
+
read_consistency: :EVENTUAL)
|
150
|
+
elsif consistency == :strong
|
151
|
+
return Google::Datastore::V1beta3::ReadOptions.new(
|
152
|
+
read_consistency: :STRONG)
|
153
|
+
elsif transaction
|
154
|
+
return Google::Datastore::V1beta3::ReadOptions.new(
|
155
|
+
transaction: transaction)
|
156
|
+
end
|
157
|
+
nil
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|