gcloud 0.8.2 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|