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
@@ -409,7 +409,7 @@ module Gcloud
409
409
  #
410
410
  # @return [Gcloud::Bigquery::Data]
411
411
  #
412
- # @example
412
+ # @example Paginate rows of data: (See {Data#next})
413
413
  # require "gcloud"
414
414
  #
415
415
  # gcloud = Gcloud.new
@@ -421,7 +421,22 @@ module Gcloud
421
421
  # data.each do |row|
422
422
  # puts row["first_name"]
423
423
  # end
424
- # more_data = table.data token: data.token
424
+ # if data.next?
425
+ # more_data = data.next if data.next?
426
+ # end
427
+ #
428
+ # @example Retrieve all rows of data: (See {Data#all})
429
+ # require "gcloud"
430
+ #
431
+ # gcloud = Gcloud.new
432
+ # bigquery = gcloud.bigquery
433
+ # dataset = bigquery.dataset "my_dataset"
434
+ # table = dataset.table "my_table"
435
+ #
436
+ # data = table.data
437
+ # data.all do |row|
438
+ # puts row["first_name"]
439
+ # end
425
440
  #
426
441
  # @!group Data
427
442
  #
@@ -29,26 +29,155 @@ module Gcloud
29
29
  # A hash of this page of results.
30
30
  attr_accessor :etag
31
31
 
32
- # Total number of jobs in this collection.
32
+ # Total number of tables in this collection.
33
33
  attr_accessor :total
34
34
 
35
35
  ##
36
- # Create a new Table::List with an array of jobs.
36
+ # @private Create a new Table::List with an array of tables.
37
37
  def initialize arr = []
38
38
  super arr
39
39
  end
40
40
 
41
+ ##
42
+ # Whether there is a next page of tables.
43
+ #
44
+ # @return [Boolean]
45
+ #
46
+ # @example
47
+ # require "gcloud"
48
+ #
49
+ # gcloud = Gcloud.new
50
+ # bigquery = gcloud.bigquery
51
+ # dataset = bigquery.dataset "my_dataset"
52
+ #
53
+ # tables = dataset.tables
54
+ # if tables.next?
55
+ # next_tables = tables.next
56
+ # end
57
+ #
58
+ def next?
59
+ !token.nil?
60
+ end
61
+
62
+ ##
63
+ # Retrieve the next page of tables.
64
+ #
65
+ # @return [Table::List]
66
+ #
67
+ # @example
68
+ # require "gcloud"
69
+ #
70
+ # gcloud = Gcloud.new
71
+ # bigquery = gcloud.bigquery
72
+ # dataset = bigquery.dataset "my_dataset"
73
+ #
74
+ # tables = dataset.tables
75
+ # if tables.next?
76
+ # next_tables = tables.next
77
+ # end
78
+ #
79
+ def next
80
+ return nil unless next?
81
+ ensure_connection!
82
+ options = { token: token, max: @max }
83
+ resp = @connection.list_tables @dataset_id, options
84
+ if resp.success?
85
+ self.class.from_response resp, @connection, @dataset_id, @max
86
+ else
87
+ fail ApiError.from_response(resp)
88
+ end
89
+ end
90
+
91
+ ##
92
+ # Retrieves all tables by repeatedly loading {#next} until {#next?}
93
+ # returns `false`. Calls the given block once for each table, which is
94
+ # passed as the parameter.
95
+ #
96
+ # An Enumerator is returned if no block is given.
97
+ #
98
+ # This method may make several API calls until all tables are retrieved.
99
+ # Be sure to use as narrow a search criteria as possible. Please use
100
+ # with caution.
101
+ #
102
+ # @param [Integer] request_limit The upper limit of API requests to make
103
+ # to load all tables. Default is no limit.
104
+ # @yield [table] The block for accessing each table.
105
+ # @yieldparam [Table] table The table object.
106
+ #
107
+ # @return [Enumerator]
108
+ #
109
+ # @example Iterating each result by passing a block:
110
+ # require "gcloud"
111
+ #
112
+ # gcloud = Gcloud.new
113
+ # bigquery = gcloud.bigquery
114
+ # dataset = bigquery.dataset "my_dataset"
115
+ #
116
+ # dataset.tables.all do |table|
117
+ # puts table.name
118
+ # end
119
+ #
120
+ # @example Using the enumerator by not passing a block:
121
+ # require "gcloud"
122
+ #
123
+ # gcloud = Gcloud.new
124
+ # bigquery = gcloud.bigquery
125
+ # dataset = bigquery.dataset "my_dataset"
126
+ #
127
+ # all_names = dataset.tables.all.map do |table|
128
+ # table.name
129
+ # end
130
+ #
131
+ # @example Limit the number of API requests made:
132
+ # require "gcloud"
133
+ #
134
+ # gcloud = Gcloud.new
135
+ # bigquery = gcloud.bigquery
136
+ # dataset = bigquery.dataset "my_dataset"
137
+ #
138
+ # dataset.tables.all(request_limit: 10) do |table|
139
+ # puts table.name
140
+ # end
141
+ #
142
+ def all request_limit: nil
143
+ request_limit = request_limit.to_i if request_limit
144
+ unless block_given?
145
+ return enum_for(:all, request_limit: request_limit)
146
+ end
147
+ results = self
148
+ loop do
149
+ results.each { |r| yield r }
150
+ if request_limit
151
+ request_limit -= 1
152
+ break if request_limit < 0
153
+ end
154
+ break unless results.next?
155
+ results = results.next
156
+ end
157
+ end
158
+
41
159
  ##
42
160
  # @private New Table::List from a response object.
43
- def self.from_response resp, conn
161
+ def self.from_response resp, conn, dataset_id = nil, max = nil
44
162
  tables = List.new(Array(resp.data["tables"]).map do |gapi_object|
45
163
  Table.from_gapi gapi_object, conn
46
164
  end)
47
165
  tables.instance_variable_set "@token", resp.data["nextPageToken"]
48
166
  tables.instance_variable_set "@etag", resp.data["etag"]
49
167
  tables.instance_variable_set "@total", resp.data["totalItems"]
168
+ tables.instance_variable_set "@connection", conn
169
+ tables.instance_variable_set "@dataset_id", dataset_id
170
+ tables.instance_variable_set "@max", max
50
171
  tables
51
172
  end
173
+
174
+ protected
175
+
176
+ ##
177
+ # Raise an error unless an active connection is available.
178
+ def ensure_connection!
179
+ fail "Must have active connection" unless @connection
180
+ end
52
181
  end
53
182
  end
54
183
  end
@@ -205,9 +205,8 @@ module Gcloud
205
205
  #
206
206
  # ### Paginating records
207
207
  #
208
- # All records may not return at once, requiring multiple calls to Datastore
209
- # to return them all. The returned records will have a <tt>cursor</tt> if
210
- # there are more available.
208
+ # All records may not return at once, but multiple calls can be made to
209
+ # Datastore to return them all.
211
210
  #
212
211
  # ```ruby
213
212
  # require "gcloud"
@@ -215,22 +214,10 @@ module Gcloud
215
214
  # gcloud = Gcloud.new
216
215
  # datastore = gcloud.datastore
217
216
  #
218
- # task_list_key = datastore.key "TaskList", "default"
219
- #
220
- # query = datastore.query("Task").
221
- # ancestor(task_list_key)
222
- # all_tasks = []
223
- # tmp_tasks = datastore.run query
224
- # while tmp_tasks.any? do
225
- # tmp_tasks.each do |task|
226
- # all_tasks << task
227
- # end
228
- # # break loop if no more tasks available
229
- # break if tmp_tasks.cursor.nil?
230
- # # set cursor on the query
231
- # query = query.cursor tmp_tasks.cursor
232
- # # query for more records
233
- # tmp_tasks = datastore.run query
217
+ # query = datastore.query("Task")
218
+ # tasks = datastore.run query
219
+ # tasks.all do |task|
220
+ # puts t["description"]
234
221
  # end
235
222
  # ```
236
223
  #
@@ -520,6 +507,30 @@ module Gcloud
520
507
  # end
521
508
  # ```
522
509
  #
510
+ # ## Configuring Backoff
511
+ #
512
+ # The {Gcloud::Backoff} class allows users to globally configure how Cloud API
513
+ # requests are automatically retried in the case of some errors, such as a
514
+ # `500` or `503` status code, or a specific internal error code such as
515
+ # `rateLimitExceeded`.
516
+ #
517
+ # If an API call fails, the response will be inspected to see if the call
518
+ # should be retried. If the response matches the criteria, then the request
519
+ # will be retried after a delay. If another error occurs, the delay will be
520
+ # increased incrementally before a subsequent attempt. The first retry will be
521
+ # delayed one second, the second retry two seconds, and so on.
522
+ #
523
+ # ```ruby
524
+ # require "gcloud"
525
+ # require "gcloud/backoff"
526
+ #
527
+ # Gcloud::Backoff.retries = 5 # Raise the maximum number of retries from 3
528
+ # ```
529
+ #
530
+ # See the [Datastore error
531
+ # codes](https://cloud.google.com/datastore/docs/concepts/errors#error_codes)
532
+ # for a list of error conditions.
533
+ #
523
534
  # ## The Datastore Emulator
524
535
  #
525
536
  # As of this release, the Datastore emulator that is part of the gcloud SDK is
@@ -339,12 +339,9 @@ module Gcloud
339
339
  def find_all *keys, consistency: nil
340
340
  ensure_service!
341
341
  check_consistency! consistency
342
- lookup_res = service.lookup(*keys.map(&:to_grpc),
342
+ lookup_res = service.lookup(*Array(keys).flatten.map(&:to_grpc),
343
343
  consistency: consistency)
344
- entities = to_gcloud_entities lookup_res.found
345
- deferred = to_gcloud_keys lookup_res.deferred
346
- missing = to_gcloud_entities lookup_res.missing
347
- LookupResults.new entities, deferred, missing
344
+ LookupResults.from_grpc lookup_res, service, consistency
348
345
  rescue GRPC::BadStatus => e
349
346
  raise Gcloud::Error.from_error(e)
350
347
  end
@@ -663,23 +660,6 @@ module Gcloud
663
660
  fail "Must have active connection to service" unless service
664
661
  end
665
662
 
666
- ##
667
- # Convenience method to convert GRPC entities to Gcloud entities.
668
- def to_gcloud_entities grpc_entity_results
669
- # Entities are nested in an object.
670
- Array(grpc_entity_results).map do |result|
671
- # TODO: Make this return an EntityResult with cursor...
672
- Entity.from_grpc result.entity
673
- end
674
- end
675
-
676
- ##
677
- # Convenience method to convert GRPC keys to Gcloud keys.
678
- def to_gcloud_keys grpc_keys
679
- # Keys are not nested in an object like entities are.
680
- Array(grpc_keys).map { |key| Key.from_grpc key }
681
- end
682
-
683
663
  def check_consistency! consistency
684
664
  fail(ArgumentError,
685
665
  format("Consistency must be :eventual or :strong, not %s.",
@@ -53,11 +53,167 @@ module Gcloud
53
53
  attr_accessor :missing
54
54
 
55
55
  ##
56
- # Create a new LookupResults with an array of values.
57
- def initialize arr = [], deferred = [], missing = []
56
+ # @private Create a new LookupResults with an array of values.
57
+ def initialize arr = []
58
58
  super arr
59
- @deferred = deferred
60
- @missing = missing
59
+ end
60
+
61
+ ##
62
+ # Whether there are more results available.
63
+ #
64
+ # @return [Boolean]
65
+ #
66
+ # @example
67
+ # gcloud = Gcloud.new
68
+ # datastore = gcloud.datastore
69
+ #
70
+ # task_key1 = datastore.key "Task", "sampleTask1"
71
+ # task_key2 = datastore.key "Task", "sampleTask2"
72
+ # tasks = datastore.find_all task_key1, task_key2
73
+ # if tasks.next?
74
+ # next_tasks = tasks.next
75
+ # end
76
+ #
77
+ def next?
78
+ Array(@deferred).any?
79
+ end
80
+
81
+ ##
82
+ # Retrieve the next page of results.
83
+ #
84
+ # @return [LookupResults]
85
+ #
86
+ # @example
87
+ # gcloud = Gcloud.new
88
+ # datastore = gcloud.datastore
89
+ #
90
+ # task_key1 = datastore.key "Task", "sampleTask1"
91
+ # task_key2 = datastore.key "Task", "sampleTask2"
92
+ # tasks = datastore.find_all task_key1, task_key2
93
+ # if tasks.next?
94
+ # next_tasks = tasks.next
95
+ # end
96
+ #
97
+ def next
98
+ return nil unless next?
99
+ ensure_service!
100
+ lookup_res = @service.lookup(*Array(@deferred).flatten.map(&:to_grpc),
101
+ consistency: @consistency,
102
+ transaction: @transaction)
103
+ self.class.from_grpc lookup_res, @service, @consistency
104
+ rescue GRPC::BadStatus => e
105
+ raise Gcloud::Error.from_error(e)
106
+ end
107
+
108
+ ##
109
+ # Retrieves all lookup results by repeatedly loading {#next} until
110
+ # {#next?} returns `false`. Calls the given block once for each result,
111
+ # which is passed as the parameter.
112
+ #
113
+ # An Enumerator is returned if no block is given.
114
+ #
115
+ # This method may make several API calls until all lookup results are
116
+ # retrieved. Be sure to use as narrow a search criteria as possible.
117
+ # Please use with caution.
118
+ #
119
+ # @param [Integer] request_limit The upper limit of API requests to make
120
+ # to load all lookup results. Default is no limit.
121
+ # @yield [result] The block for accessing each lookup result.
122
+ # @yieldparam [Entity] result The lookup result object.
123
+ #
124
+ # @return [Enumerator]
125
+ #
126
+ # @example Iterating each result by passing a block:
127
+ # gcloud = Gcloud.new
128
+ # datastore = gcloud.datastore
129
+ #
130
+ # task_key1 = datastore.key "Task", "sampleTask1"
131
+ # task_key2 = datastore.key "Task", "sampleTask2"
132
+ # tasks = datastore.find_all task_key1, task_key2
133
+ # tasks.all do |task|
134
+ # puts "Task #{task.key.id} (#cursor)"
135
+ # end
136
+ #
137
+ # @example Using the enumerator by not passing a block:
138
+ # gcloud = Gcloud.new
139
+ # datastore = gcloud.datastore
140
+ #
141
+ # task_key1 = datastore.key "Task", "sampleTask1"
142
+ # task_key2 = datastore.key "Task", "sampleTask2"
143
+ # tasks = datastore.find_all task_key1, task_key2
144
+ # all_keys = tasks.all.map(&:key).each do |task|
145
+ # task.key
146
+ # end
147
+ #
148
+ # @example Limit the number of API calls made:
149
+ # gcloud = Gcloud.new
150
+ # datastore = gcloud.datastore
151
+ #
152
+ # task_key1 = datastore.key "Task", "sampleTask1"
153
+ # task_key2 = datastore.key "Task", "sampleTask2"
154
+ # tasks = datastore.find_all task_key1, task_key2
155
+ # tasks.all(request_limit: 10) do |task|
156
+ # puts "Task #{task.key.id} (#cursor)"
157
+ # end
158
+ #
159
+ def all request_limit: nil
160
+ request_limit = request_limit.to_i if request_limit
161
+ unless block_given?
162
+ return enum_for(:all, request_limit: request_limit)
163
+ end
164
+ results = self
165
+ loop do
166
+ results.each { |r| yield r }
167
+ if request_limit
168
+ request_limit -= 1
169
+ break if request_limit < 0
170
+ end
171
+ break unless results.next?
172
+ results = results.next
173
+ end
174
+ end
175
+
176
+ ##
177
+ # @private New Dataset::LookupResults from a
178
+ # Google::Dataset::V1beta3::LookupResponse object.
179
+ def self.from_grpc lookup_res, service, consistency = nil, tx = nil
180
+ entities = to_gcloud_entities lookup_res.found
181
+ deferred = to_gcloud_keys lookup_res.deferred
182
+ missing = to_gcloud_entities lookup_res.missing
183
+ new(entities).tap do |lr|
184
+ lr.instance_variable_set :@service, service
185
+ lr.instance_variable_set :@consistency, consistency
186
+ lr.instance_variable_set :@transaction, tx
187
+ lr.instance_variable_set :@deferred, deferred
188
+ lr.instance_variable_set :@missing, missing
189
+ end
190
+ end
191
+
192
+ protected
193
+
194
+ ##
195
+ # @private Raise an error unless an active connection to the service is
196
+ # available.
197
+ def ensure_service!
198
+ msg = "Must have active connection to datastore service to get next"
199
+ fail msg if @service.nil?
200
+ end
201
+
202
+ ##
203
+ # Convenience method to convert GRPC entities to Gcloud entities.
204
+ def self.to_gcloud_entities grpc_entity_results
205
+ # Entities are nested in an object.
206
+ Array(grpc_entity_results).map do |result|
207
+ # TODO: Make this return an EntityResult with cursor...
208
+ Entity.from_grpc result.entity
209
+ end
210
+ end
211
+
212
+ ##
213
+ # Convenience method to convert GRPC keys to Gcloud keys.
214
+ def self.to_gcloud_keys grpc_keys
215
+ # Keys are not nested in an object like entities are.
216
+ Array(grpc_keys).map { |key| Key.from_grpc key }
61
217
  end
62
218
  end
63
219
  end