gcloud 0.10.0 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +8 -8
  2. data/CHANGELOG.md +36 -0
  3. data/lib/gcloud/backoff.rb +5 -5
  4. data/lib/gcloud/bigquery.rb +24 -0
  5. data/lib/gcloud/bigquery/connection.rb +32 -25
  6. data/lib/gcloud/bigquery/data.rb +99 -1
  7. data/lib/gcloud/bigquery/dataset.rb +5 -13
  8. data/lib/gcloud/bigquery/dataset/list.rb +124 -2
  9. data/lib/gcloud/bigquery/job/list.rb +125 -2
  10. data/lib/gcloud/bigquery/project.rb +30 -27
  11. data/lib/gcloud/bigquery/query_data.rb +102 -1
  12. data/lib/gcloud/bigquery/table.rb +17 -2
  13. data/lib/gcloud/bigquery/table/list.rb +132 -3
  14. data/lib/gcloud/datastore.rb +30 -19
  15. data/lib/gcloud/datastore/dataset.rb +2 -22
  16. data/lib/gcloud/datastore/dataset/lookup_results.rb +160 -4
  17. data/lib/gcloud/datastore/dataset/query_results.rb +229 -23
  18. data/lib/gcloud/datastore/transaction.rb +2 -5
  19. data/lib/gcloud/dns.rb +20 -0
  20. data/lib/gcloud/dns/change/list.rb +109 -6
  21. data/lib/gcloud/dns/connection.rb +18 -9
  22. data/lib/gcloud/dns/project.rb +4 -8
  23. data/lib/gcloud/dns/record/list.rb +96 -13
  24. data/lib/gcloud/dns/zone.rb +9 -24
  25. data/lib/gcloud/dns/zone/list.rb +102 -5
  26. data/lib/gcloud/dns/zone/transaction.rb +1 -1
  27. data/lib/gcloud/logging.rb +19 -0
  28. data/lib/gcloud/logging/entry/list.rb +83 -14
  29. data/lib/gcloud/logging/metric/list.rb +89 -12
  30. data/lib/gcloud/logging/project.rb +18 -30
  31. data/lib/gcloud/logging/resource_descriptor/list.rb +105 -6
  32. data/lib/gcloud/logging/sink/list.rb +89 -12
  33. data/lib/gcloud/pubsub.rb +23 -0
  34. data/lib/gcloud/pubsub/project.rb +21 -29
  35. data/lib/gcloud/pubsub/service.rb +1 -3
  36. data/lib/gcloud/pubsub/subscription/list.rb +167 -13
  37. data/lib/gcloud/pubsub/topic.rb +15 -13
  38. data/lib/gcloud/pubsub/topic/batch.rb +10 -4
  39. data/lib/gcloud/pubsub/topic/list.rb +134 -8
  40. data/lib/gcloud/resource_manager.rb +24 -0
  41. data/lib/gcloud/resource_manager/connection.rb +18 -9
  42. data/lib/gcloud/resource_manager/manager.rb +7 -4
  43. data/lib/gcloud/resource_manager/project/list.rb +93 -14
  44. data/lib/gcloud/storage.rb +63 -0
  45. data/lib/gcloud/storage/bucket.rb +100 -61
  46. data/lib/gcloud/storage/bucket/list.rb +132 -8
  47. data/lib/gcloud/storage/connection.rb +68 -44
  48. data/lib/gcloud/storage/errors.rb +9 -3
  49. data/lib/gcloud/storage/file.rb +48 -4
  50. data/lib/gcloud/storage/file/list.rb +151 -15
  51. data/lib/gcloud/storage/file/verifier.rb +3 -3
  52. data/lib/gcloud/storage/project.rb +15 -30
  53. data/lib/gcloud/translate.rb +20 -0
  54. data/lib/gcloud/translate/connection.rb +12 -3
  55. data/lib/gcloud/version.rb +1 -1
  56. data/lib/gcloud/vision.rb +20 -0
  57. data/lib/gcloud/vision/connection.rb +10 -1
  58. data/lib/gcloud/vision/image.rb +15 -18
  59. metadata +16 -2
@@ -28,12 +28,26 @@ module Gcloud
28
28
  # Many common Array methods will return a new Array instance.
29
29
  #
30
30
  # @example
31
+ # require "gcloud"
32
+ #
33
+ # gcloud = Gcloud.new
34
+ # datastore = gcloud.datastore
35
+ #
36
+ # query = datastore.query("Task")
31
37
  # tasks = datastore.run query
38
+ #
32
39
  # tasks.size #=> 3
33
40
  # tasks.cursor #=> Gcloud::Datastore::Cursor(c3VwZXJhd2Vzb21lIQ)
34
41
  #
35
42
  # @example Caution, many Array methods will return a new Array instance:
43
+ # require "gcloud"
44
+ #
45
+ # gcloud = Gcloud.new
46
+ # datastore = gcloud.datastore
47
+ #
48
+ # query = datastore.query("Task")
36
49
  # tasks = datastore.run query
50
+ #
37
51
  # tasks.size #=> 3
38
52
  # tasks.end_cursor #=> Gcloud::Datastore::Cursor(c3VwZXJhd2Vzb21lIQ)
39
53
  # descriptions = tasks.map { |task| task["description"] }
@@ -61,7 +75,7 @@ module Gcloud
61
75
 
62
76
  ##
63
77
  # @private
64
- attr_accessor :service, :namespace, :query
78
+ attr_accessor :service, :namespace, :cursors, :query
65
79
 
66
80
  ##
67
81
  # @private
@@ -96,19 +110,49 @@ module Gcloud
96
110
  end
97
111
 
98
112
  ##
99
- # Create a new QueryResults with an array of values.
113
+ # @private Create a new QueryResults with an array of values.
100
114
  def initialize arr = []
101
115
  super arr
102
116
  end
103
117
 
104
118
  ##
105
119
  # Whether there are more results available.
120
+ #
121
+ # @return [Boolean]
122
+ #
123
+ # @example
124
+ # require "gcloud"
125
+ #
126
+ # gcloud = Gcloud.new
127
+ # datastore = gcloud.datastore
128
+ # query = datastore.query "Task"
129
+ # tasks = datastore.run query
130
+ #
131
+ # if tasks.next?
132
+ # next_tasks = tasks.next
133
+ # end
134
+ #
106
135
  def next?
107
136
  !no_more?
108
137
  end
109
138
 
110
139
  ##
111
140
  # Retrieve the next page of results.
141
+ #
142
+ # @return [QueryResults]
143
+ #
144
+ # @example
145
+ # require "gcloud"
146
+ #
147
+ # gcloud = Gcloud.new
148
+ # datastore = gcloud.datastore
149
+ # query = datastore.query "Task"
150
+ # tasks = datastore.run query
151
+ #
152
+ # if tasks.next?
153
+ # next_tasks = tasks.next
154
+ # end
155
+ #
112
156
  def next
113
157
  return nil unless next?
114
158
  return nil if end_cursor.nil?
@@ -120,45 +164,207 @@ module Gcloud
120
164
  raise Gcloud::Error.from_error(e)
121
165
  end
122
166
 
167
+ ##
168
+ # Retrieve the {Cursor} for the provided result.
169
+ #
170
+ # @param [Entity] result The entity object to get a cursor for.
171
+ #
172
+ # @return [Cursor]
173
+ #
174
+ # @example
175
+ # require "gcloud"
176
+ #
177
+ # gcloud = Gcloud.new
178
+ # datastore = gcloud.datastore
179
+ # query = datastore.query "Task"
180
+ # tasks = datastore.run query
181
+ #
182
+ # first_task = tasks.first
183
+ # first_cursor = tasks.cursor_for first_task
184
+ #
185
+ def cursor_for result
186
+ cursor_index = index result
187
+ return nil if cursor_index.nil?
188
+ cursors[cursor_index]
189
+ end
190
+
191
+ ##
192
+ # Calls the given block once for each result and cursor combination,
193
+ # which are passed as parameters.
194
+ #
195
+ # An Enumerator is returned if no block is given.
196
+ #
197
+ # @yield [result, cursor] The block for accessing each query result and
198
+ # cursor.
199
+ # @yieldparam [Entity] result The query result object.
200
+ # @yieldparam [Cursor] cursor The cursor object.
201
+ #
202
+ # @return [Enumerator]
203
+ #
204
+ # @example
205
+ # require "gcloud"
206
+ #
207
+ # gcloud = Gcloud.new
208
+ # datastore = gcloud.datastore
209
+ # query = datastore.query "Task"
210
+ # tasks = datastore.run query
211
+ # tasks.each_with_cursor do |task, cursor|
212
+ # puts "Task #{task.key.id} (#cursor)"
213
+ # end
214
+ #
215
+ def each_with_cursor
216
+ return enum_for(:each_with_cursor) unless block_given?
217
+ zip(cursors).each { |r, c| yield [r, c] }
218
+ end
219
+
123
220
  ##
124
221
  # Retrieves all query results by repeatedly loading {#next} until
125
- # {#next?} returns `false`. Returns the list instance for method
126
- # chaining.
222
+ # {#next?} returns `false`. Calls the given block once for each query
223
+ # result, which is passed as the parameter.
224
+ #
225
+ # An Enumerator is returned if no block is given.
127
226
  #
128
227
  # This method may make several API calls until all query results are
129
228
  # retrieved. Be sure to use as narrow a search criteria as possible.
130
229
  # Please use with caution.
131
230
  #
132
- # @example
231
+ # @param [Integer] request_limit The upper limit of API requests to make
232
+ # to load all query results. Default is no limit.
233
+ # @yield [result] The block for accessing each query result.
234
+ # @yieldparam [Entity] result The query result object.
235
+ #
236
+ # @return [Enumerator]
237
+ #
238
+ # @example Iterating each query result by passing a block:
239
+ # require "gcloud"
240
+ #
241
+ # gcloud = Gcloud.new
242
+ # datastore = gcloud.datastore
243
+ # query = datastore.query "Task"
244
+ # tasks = datastore.run query
245
+ # tasks.all do |task|
246
+ # puts "Task #{task.key.id} (#cursor)"
247
+ # end
248
+ #
249
+ # @example Using the enumerator by not passing a block:
250
+ # require "gcloud"
251
+ #
252
+ # gcloud = Gcloud.new
253
+ # datastore = gcloud.datastore
254
+ # query = datastore.query "Task"
255
+ # tasks = datastore.run query
256
+ # tasks.all.map(&:key).each do |key|
257
+ # puts "Key #{key.id}"
258
+ # end
259
+ #
260
+ # @example Limit the number of API calls made:
261
+ # require "gcloud"
262
+ #
263
+ # gcloud = Gcloud.new
264
+ # datastore = gcloud.datastore
265
+ # query = datastore.query "Task"
266
+ # tasks = datastore.run query
267
+ # tasks.all(request_limit: 10) do |task|
268
+ # puts "Task #{task.key.id} (#cursor)"
269
+ # end
270
+ #
271
+ def all request_limit: nil
272
+ request_limit = request_limit.to_i if request_limit
273
+ unless block_given?
274
+ return enum_for(:all, request_limit: request_limit)
275
+ end
276
+ results = self
277
+ loop do
278
+ results.each { |r| yield r }
279
+ if request_limit
280
+ request_limit -= 1
281
+ break if request_limit < 0
282
+ end
283
+ break unless results.next?
284
+ results = results.next
285
+ end
286
+ end
287
+
288
+ ##
289
+ # Retrieves all query results and cursors by repeatedly loading {#next}
290
+ # until {#next?} returns `false`. Calls the given block once for each
291
+ # result and cursor combination, which are passed as parameters.
292
+ #
293
+ # An Enumerator is returned if no block is given.
294
+ #
295
+ # This method may make several API calls until all query results are
296
+ # retrieved. Be sure to use as narrow a search criteria as possible.
297
+ # Please use with caution.
298
+ #
299
+ # @param [Integer] request_limit The upper limit of API requests to make
300
+ # to load all tables. Default is no limit.
301
+ # @yield [result, cursor] The block for accessing each query result and
302
+ # cursor.
303
+ # @yieldparam [Entity] result The query result object.
304
+ # @yieldparam [Cursor] cursor The cursor object.
305
+ #
306
+ # @return [Enumerator]
307
+ #
308
+ # @example Iterating all results and cursors by passing a block:
309
+ # require "gcloud"
310
+ #
311
+ # gcloud = Gcloud.new
312
+ # datastore = gcloud.datastore
313
+ # query = datastore.query "Task"
314
+ # tasks = datastore.run query
315
+ # tasks.all_with_cursor do |task, cursor|
316
+ # puts "Task #{task.key.id} (#cursor)"
317
+ # end
318
+ #
319
+ # @example Using the enumerator by not passing a block:
320
+ # require "gcloud"
321
+ #
322
+ # gcloud = Gcloud.new
323
+ # datastore = gcloud.datastore
324
+ # query = datastore.query "Task"
325
+ # tasks = datastore.run query
326
+ # tasks.all_with_cursor.count #=> number of result/cursor pairs
327
+ #
328
+ # @example Limit the number of API calls made:
133
329
  # require "gcloud"
134
330
  #
135
331
  # gcloud = Gcloud.new
136
332
  # datastore = gcloud.datastore
137
- # query = datastore.query("Tasks")
138
- # all_tasks = datastore.run(query).all
139
- #
140
- def all
141
- while next?
142
- next_records = self.next
143
- push(*next_records)
144
- self.end_cursor = next_records.end_cursor
145
- self.more_results = next_records.more_results
146
- self.service = next_records.service
147
- self.namespace = next_records.namespace
148
- self.query = next_records.query
333
+ # query = datastore.query "Task"
334
+ # tasks = datastore.run query
335
+ # tasks.all_with_cursor(request_limit: 10) do |task, cursor|
336
+ # puts "Task #{task.key.id} (#cursor)"
337
+ # end
338
+ #
339
+ def all_with_cursor request_limit: nil
340
+ request_limit = request_limit.to_i if request_limit
341
+ unless block_given?
342
+ return enum_for(:all_with_cursor, request_limit: request_limit)
343
+ end
344
+ results = self
345
+
346
+ loop do
347
+ results.zip(results.cursors).each { |r, c| yield r, c }
348
+ if request_limit
349
+ request_limit -= 1
350
+ break if request_limit < 0
351
+ end
352
+ break unless results.next?
353
+ results = results.next
149
354
  end
150
- self
151
355
  end
152
356
 
153
357
  ##
154
358
  # @private New Dataset::QueryResults from a
155
359
  # Google::Dataset::V1beta3::RunQueryResponse object.
156
360
  def self.from_grpc query_res, service, namespace, query
157
- entities = Array(query_res.batch.entity_results).map do |result|
158
- # TODO: Make this return an EntityResult with cursor...
159
- Entity.from_grpc result.entity
160
- end
161
- new(entities).tap do |qr|
361
+ r, c = Array(query_res.batch.entity_results).map do |result|
362
+ [Entity.from_grpc(result.entity), Cursor.from_grpc(result.cursor)]
363
+ end.transpose
364
+ r ||= []
365
+ c ||= []
366
+ new(r).tap do |qr|
367
+ qr.cursors = c
162
368
  qr.end_cursor = Cursor.from_grpc query_res.batch.end_cursor
163
369
  qr.more_results = query_res.batch.more_results
164
370
  qr.service = service
@@ -198,12 +198,9 @@ module Gcloud
198
198
  #
199
199
  def find_all *keys
200
200
  ensure_service!
201
- lookup_res = service.lookup(*keys.map(&:to_grpc),
201
+ lookup_res = service.lookup(*Array(keys).flatten.map(&:to_grpc),
202
202
  transaction: @id)
203
- entities = to_gcloud_entities lookup_res.found
204
- deferred = to_gcloud_keys lookup_res.deferred
205
- missing = to_gcloud_entities lookup_res.missing
206
- LookupResults.new entities, deferred, missing
203
+ LookupResults.from_grpc lookup_res, service, nil, @id
207
204
  rescue GRPC::BadStatus => e
208
205
  raise Gcloud::Error.from_error(e)
209
206
  end
data/lib/gcloud/dns.rb CHANGED
@@ -301,6 +301,26 @@ module Gcloud
301
301
  # zone.export "path/to/db.example.com"
302
302
  # ```
303
303
  #
304
+ # ## Configuring Backoff
305
+ #
306
+ # The {Gcloud::Backoff} class allows users to globally configure how Cloud API
307
+ # requests are automatically retried in the case of some errors, such as a
308
+ # `500` or `503` status code, or a specific internal error code such as
309
+ # `rateLimitExceeded`.
310
+ #
311
+ # If an API call fails, the response will be inspected to see if the call
312
+ # should be retried. If the response matches the criteria, then the request
313
+ # will be retried after a delay. If another error occurs, the delay will be
314
+ # increased incrementally before a subsequent attempt. The first retry will be
315
+ # delayed one second, the second retry two seconds, and so on.
316
+ #
317
+ # ```ruby
318
+ # require "gcloud"
319
+ # require "gcloud/backoff"
320
+ #
321
+ # Gcloud::Backoff.retries = 5 # Raise the maximum number of retries from 3
322
+ # ```
323
+ #
304
324
  module Dns
305
325
  end
306
326
  end
@@ -22,38 +22,141 @@ module Gcloud
22
22
  # Change::List is a special case Array with additional values.
23
23
  class List < DelegateClass(::Array)
24
24
  ##
25
- # If not empty, indicates that there are more records that match
25
+ # If not empty, indicates that there are more changes that match
26
26
  # the request and this value should be passed to continue.
27
27
  attr_accessor :token
28
28
 
29
29
  ##
30
- # Create a new Change::List with an array of Change instances.
30
+ # @private Create a new Change::List with an array of Change instances.
31
31
  def initialize arr = []
32
32
  super arr
33
33
  end
34
34
 
35
35
  ##
36
- # Whether there a next page of zones.
36
+ # Whether there a next page of changes.
37
+ #
38
+ # @return [Boolean]
39
+ #
40
+ # @example
41
+ # require "gcloud"
42
+ #
43
+ # gcloud = Gcloud.new
44
+ # dns = gcloud.dns
45
+ # zone = dns.zone "example-com"
46
+ #
47
+ # changes = zone.changes
48
+ # if changes.next?
49
+ # next_changes = changes.next
50
+ # end
51
+ #
37
52
  def next?
38
53
  !token.nil?
39
54
  end
40
55
 
41
56
  ##
42
- # Retrieve the next page of zones.
57
+ # Retrieve the next page of changes.
58
+ #
59
+ # @return [Change::List]
60
+ #
61
+ # @example
62
+ # require "gcloud"
63
+ #
64
+ # gcloud = Gcloud.new
65
+ # dns = gcloud.dns
66
+ # zone = dns.zone "example-com"
67
+ #
68
+ # changes = zone.changes
69
+ # if changes.next?
70
+ # next_changes = changes.next
71
+ # end
72
+ #
43
73
  def next
44
74
  return nil unless next?
45
75
  ensure_zone!
46
- @zone.changes token: token
76
+ @zone.changes token: token, max: @max, order: @order
77
+ end
78
+
79
+ ##
80
+ # Retrieves all changes by repeatedly loading {#next} until {#next?}
81
+ # returns `false`. Calls the given block once for each change, which is
82
+ # passed as the parameter.
83
+ #
84
+ # An Enumerator is returned if no block is given.
85
+ #
86
+ # This method may make several API calls until all changes are
87
+ # retrieved. Be sure to use as narrow a search criteria as possible.
88
+ # Please use with caution.
89
+ #
90
+ # @param [Integer] request_limit The upper limit of API requests to make
91
+ # to load all changes. Default is no limit.
92
+ # @yield [change] The block for accessing each change.
93
+ # @yieldparam [Change] change The change object.
94
+ #
95
+ # @return [Enumerator]
96
+ #
97
+ # @example Iterating each change by passing a block:
98
+ # require "gcloud"
99
+ #
100
+ # gcloud = Gcloud.new
101
+ # dns = gcloud.dns
102
+ # zone = dns.zone "example-com"
103
+ # changes = zone.changes
104
+ #
105
+ # changes.all do |change|
106
+ # puts change.name
107
+ # end
108
+ #
109
+ # @example Using the enumerator by not passing a block:
110
+ # require "gcloud"
111
+ #
112
+ # gcloud = Gcloud.new
113
+ # dns = gcloud.dns
114
+ # zone = dns.zone "example-com"
115
+ # changes = zone.changes
116
+ #
117
+ # all_names = changes.all.map do |change|
118
+ # change.name
119
+ # end
120
+ #
121
+ # @example Limit the number of API calls made:
122
+ # require "gcloud"
123
+ #
124
+ # gcloud = Gcloud.new
125
+ # dns = gcloud.dns
126
+ # zone = dns.zone "example-com"
127
+ # changes = zone.changes
128
+ #
129
+ # changes.all(request_limit: 10) do |change|
130
+ # puts change.name
131
+ # end
132
+ #
133
+ def all request_limit: nil
134
+ request_limit = request_limit.to_i if request_limit
135
+ unless block_given?
136
+ return enum_for(:all, request_limit: request_limit)
137
+ end
138
+ results = self
139
+ loop do
140
+ results.each { |r| yield r }
141
+ if request_limit
142
+ request_limit -= 1
143
+ break if request_limit < 0
144
+ end
145
+ break unless results.next?
146
+ results = results.next
147
+ end
47
148
  end
48
149
 
49
150
  ##
50
151
  # @private New Changes::List from a response object.
51
- def self.from_response resp, zone
152
+ def self.from_response resp, zone, max = nil, order = nil
52
153
  changes = new(Array(resp.data["changes"]).map do |gapi_object|
53
154
  Change.from_gapi gapi_object, zone
54
155
  end)
55
156
  changes.instance_variable_set "@token", resp.data["nextPageToken"]
56
157
  changes.instance_variable_set "@zone", zone
158
+ changes.instance_variable_set "@max", max
159
+ changes.instance_variable_set "@order", order
57
160
  changes
58
161
  end
59
162