gcloud 0.11.0 → 0.12.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.
Files changed (121) hide show
  1. checksums.yaml +8 -8
  2. data/AUTHENTICATION.md +3 -3
  3. data/CHANGELOG.md +92 -0
  4. data/OVERVIEW.md +3 -3
  5. data/lib/gcloud.rb +75 -25
  6. data/lib/gcloud/backoff.rb +5 -1
  7. data/lib/gcloud/bigquery.rb +25 -43
  8. data/lib/gcloud/bigquery/copy_job.rb +13 -13
  9. data/lib/gcloud/bigquery/data.rb +20 -16
  10. data/lib/gcloud/bigquery/dataset.rb +202 -177
  11. data/lib/gcloud/bigquery/dataset/access.rb +118 -104
  12. data/lib/gcloud/bigquery/dataset/list.rb +14 -18
  13. data/lib/gcloud/bigquery/extract_job.rb +12 -12
  14. data/lib/gcloud/bigquery/insert_response.rb +12 -14
  15. data/lib/gcloud/bigquery/job.rb +45 -57
  16. data/lib/gcloud/bigquery/job/list.rb +18 -24
  17. data/lib/gcloud/bigquery/load_job.rb +35 -27
  18. data/lib/gcloud/bigquery/project.rb +53 -73
  19. data/lib/gcloud/bigquery/query_data.rb +28 -35
  20. data/lib/gcloud/bigquery/query_job.rb +18 -18
  21. data/lib/gcloud/bigquery/schema.rb +359 -0
  22. data/lib/gcloud/bigquery/service.rb +506 -0
  23. data/lib/gcloud/bigquery/table.rb +185 -266
  24. data/lib/gcloud/bigquery/table/list.rb +15 -19
  25. data/lib/gcloud/bigquery/view.rb +126 -81
  26. data/lib/gcloud/datastore.rb +39 -27
  27. data/lib/gcloud/datastore/commit.rb +2 -2
  28. data/lib/gcloud/datastore/dataset.rb +8 -19
  29. data/lib/gcloud/datastore/dataset/lookup_results.rb +2 -4
  30. data/lib/gcloud/datastore/dataset/query_results.rb +0 -2
  31. data/lib/gcloud/datastore/entity.rb +7 -1
  32. data/lib/gcloud/datastore/errors.rb +5 -27
  33. data/lib/gcloud/datastore/grpc_utils.rb +4 -3
  34. data/lib/gcloud/datastore/key.rb +6 -0
  35. data/lib/gcloud/datastore/service.rb +18 -12
  36. data/lib/gcloud/datastore/transaction.rb +0 -10
  37. data/lib/gcloud/dns.rb +29 -19
  38. data/lib/gcloud/dns/change.rb +10 -15
  39. data/lib/gcloud/dns/change/list.rb +4 -4
  40. data/lib/gcloud/dns/importer.rb +1 -1
  41. data/lib/gcloud/dns/project.rb +32 -49
  42. data/lib/gcloud/dns/record.rb +8 -2
  43. data/lib/gcloud/dns/record/list.rb +4 -4
  44. data/lib/gcloud/dns/service.rb +167 -0
  45. data/lib/gcloud/dns/zone.rb +33 -52
  46. data/lib/gcloud/dns/zone/list.rb +12 -16
  47. data/lib/gcloud/errors.rb +31 -19
  48. data/lib/gcloud/logging.rb +50 -39
  49. data/lib/gcloud/logging/entry.rb +197 -24
  50. data/lib/gcloud/logging/entry/list.rb +0 -2
  51. data/lib/gcloud/logging/logger.rb +1 -1
  52. data/lib/gcloud/logging/metric.rb +3 -9
  53. data/lib/gcloud/logging/metric/list.rb +0 -2
  54. data/lib/gcloud/logging/project.rb +58 -54
  55. data/lib/gcloud/logging/resource_descriptor.rb +2 -2
  56. data/lib/gcloud/logging/resource_descriptor/list.rb +0 -2
  57. data/lib/gcloud/logging/service.rb +32 -23
  58. data/lib/gcloud/logging/sink.rb +8 -14
  59. data/lib/gcloud/logging/sink/list.rb +0 -2
  60. data/lib/gcloud/pubsub.rb +21 -16
  61. data/lib/gcloud/pubsub/policy.rb +204 -0
  62. data/lib/gcloud/pubsub/project.rb +26 -38
  63. data/lib/gcloud/pubsub/service.rb +39 -31
  64. data/lib/gcloud/pubsub/subscription.rb +56 -59
  65. data/lib/gcloud/pubsub/subscription/list.rb +4 -4
  66. data/lib/gcloud/pubsub/topic.rb +69 -66
  67. data/lib/gcloud/pubsub/topic/list.rb +0 -2
  68. data/lib/gcloud/pubsub/topic/{batch.rb → publisher.rb} +15 -2
  69. data/lib/gcloud/resource_manager.rb +27 -26
  70. data/lib/gcloud/resource_manager/manager.rb +19 -39
  71. data/lib/gcloud/resource_manager/policy.rb +211 -0
  72. data/lib/gcloud/resource_manager/project.rb +97 -121
  73. data/lib/gcloud/resource_manager/project/list.rb +7 -7
  74. data/lib/gcloud/resource_manager/project/updater.rb +4 -9
  75. data/lib/gcloud/resource_manager/service.rb +127 -0
  76. data/lib/gcloud/storage.rb +24 -42
  77. data/lib/gcloud/storage/bucket.rb +104 -192
  78. data/lib/gcloud/storage/bucket/acl.rb +47 -143
  79. data/lib/gcloud/storage/bucket/cors.rb +55 -11
  80. data/lib/gcloud/storage/bucket/list.rb +14 -14
  81. data/lib/gcloud/storage/errors.rb +3 -43
  82. data/lib/gcloud/storage/file.rb +114 -111
  83. data/lib/gcloud/storage/file/acl.rb +27 -113
  84. data/lib/gcloud/storage/file/list.rb +21 -21
  85. data/lib/gcloud/storage/project.rb +49 -59
  86. data/lib/gcloud/storage/service.rb +347 -0
  87. data/lib/gcloud/translate.rb +24 -14
  88. data/lib/gcloud/translate/api.rb +12 -21
  89. data/lib/gcloud/translate/detection.rb +5 -5
  90. data/lib/gcloud/translate/language.rb +1 -1
  91. data/lib/gcloud/translate/service.rb +80 -0
  92. data/lib/gcloud/translate/translation.rb +6 -6
  93. data/lib/gcloud/version.rb +1 -1
  94. data/lib/gcloud/vision.rb +24 -15
  95. data/lib/gcloud/vision/annotate.rb +24 -21
  96. data/lib/gcloud/vision/annotation.rb +9 -9
  97. data/lib/gcloud/vision/annotation/entity.rb +11 -11
  98. data/lib/gcloud/vision/annotation/face.rb +25 -25
  99. data/lib/gcloud/vision/annotation/properties.rb +8 -8
  100. data/lib/gcloud/vision/annotation/safe_search.rb +4 -4
  101. data/lib/gcloud/vision/annotation/text.rb +7 -7
  102. data/lib/gcloud/vision/annotation/vertex.rb +1 -1
  103. data/lib/gcloud/vision/image.rb +11 -11
  104. data/lib/gcloud/vision/location.rb +5 -2
  105. data/lib/gcloud/vision/project.rb +14 -16
  106. data/lib/gcloud/vision/service.rb +66 -0
  107. data/lib/google/api_client.rb +0 -0
  108. metadata +27 -24
  109. data/lib/gcloud/bigquery/connection.rb +0 -624
  110. data/lib/gcloud/bigquery/errors.rb +0 -68
  111. data/lib/gcloud/bigquery/table/schema.rb +0 -234
  112. data/lib/gcloud/dns/connection.rb +0 -173
  113. data/lib/gcloud/dns/errors.rb +0 -68
  114. data/lib/gcloud/resource_manager/connection.rb +0 -134
  115. data/lib/gcloud/resource_manager/errors.rb +0 -68
  116. data/lib/gcloud/storage/connection.rb +0 -444
  117. data/lib/gcloud/translate/connection.rb +0 -85
  118. data/lib/gcloud/translate/errors.rb +0 -68
  119. data/lib/gcloud/upload.rb +0 -95
  120. data/lib/gcloud/vision/connection.rb +0 -63
  121. data/lib/gcloud/vision/errors.rb +0 -69
@@ -13,13 +13,14 @@
13
13
  # limitations under the License.
14
14
 
15
15
 
16
+ require "gcloud/errors"
17
+ require "gcloud/bigquery/service"
16
18
  require "gcloud/bigquery/view"
17
19
  require "gcloud/bigquery/data"
18
20
  require "gcloud/bigquery/table/list"
19
- require "gcloud/bigquery/table/schema"
20
- require "gcloud/bigquery/errors"
21
+ require "gcloud/bigquery/schema"
21
22
  require "gcloud/bigquery/insert_response"
22
- require "gcloud/upload"
23
+ require "google/apis/bigquery_v2"
23
24
 
24
25
  module Gcloud
25
26
  module Bigquery
@@ -65,8 +66,8 @@ module Gcloud
65
66
  #
66
67
  class Table
67
68
  ##
68
- # @private The Connection object.
69
- attr_accessor :connection
69
+ # @private The Service object.
70
+ attr_accessor :service
70
71
 
71
72
  ##
72
73
  # @private The Google API Client object.
@@ -75,8 +76,8 @@ module Gcloud
75
76
  ##
76
77
  # @private Create an empty Table object.
77
78
  def initialize
78
- @connection = nil
79
- @gapi = {}
79
+ @service = nil
80
+ @gapi = Google::Apis::BigqueryV2::Table.new
80
81
  end
81
82
 
82
83
  ##
@@ -87,7 +88,7 @@ module Gcloud
87
88
  # @!group Attributes
88
89
  #
89
90
  def table_id
90
- @gapi["tableReference"]["tableId"]
91
+ @gapi.table_reference.table_id
91
92
  end
92
93
 
93
94
  ##
@@ -96,7 +97,7 @@ module Gcloud
96
97
  # @!group Attributes
97
98
  #
98
99
  def dataset_id
99
- @gapi["tableReference"]["datasetId"]
100
+ @gapi.table_reference.dataset_id
100
101
  end
101
102
 
102
103
  ##
@@ -105,7 +106,7 @@ module Gcloud
105
106
  # @!group Attributes
106
107
  #
107
108
  def project_id
108
- @gapi["tableReference"]["projectId"]
109
+ @gapi.table_reference.project_id
109
110
  end
110
111
 
111
112
  ##
@@ -113,7 +114,7 @@ module Gcloud
113
114
  # The gapi fragment containing the Project ID, Dataset ID, and Table ID as
114
115
  # a camel-cased hash.
115
116
  def table_ref
116
- table_ref = @gapi["tableReference"]
117
+ table_ref = @gapi.table_reference
117
118
  table_ref = table_ref.to_hash if table_ref.respond_to? :to_hash
118
119
  table_ref
119
120
  end
@@ -128,7 +129,7 @@ module Gcloud
128
129
  # @!group Attributes
129
130
  #
130
131
  def id
131
- @gapi["id"]
132
+ @gapi.id
132
133
  end
133
134
 
134
135
  ##
@@ -159,7 +160,7 @@ module Gcloud
159
160
  # @!group Attributes
160
161
  #
161
162
  def name
162
- @gapi["friendlyName"]
163
+ @gapi.friendly_name
163
164
  end
164
165
 
165
166
  ##
@@ -168,7 +169,8 @@ module Gcloud
168
169
  # @!group Attributes
169
170
  #
170
171
  def name= new_name
171
- patch_gapi! name: new_name
172
+ @gapi.update! friendly_name: new_name
173
+ patch_gapi! :friendly_name
172
174
  end
173
175
 
174
176
  ##
@@ -178,7 +180,7 @@ module Gcloud
178
180
  #
179
181
  def etag
180
182
  ensure_full_data!
181
- @gapi["etag"]
183
+ @gapi.etag
182
184
  end
183
185
 
184
186
  ##
@@ -188,7 +190,7 @@ module Gcloud
188
190
  #
189
191
  def api_url
190
192
  ensure_full_data!
191
- @gapi["selfLink"]
193
+ @gapi.self_link
192
194
  end
193
195
 
194
196
  ##
@@ -198,7 +200,7 @@ module Gcloud
198
200
  #
199
201
  def description
200
202
  ensure_full_data!
201
- @gapi["description"]
203
+ @gapi.description
202
204
  end
203
205
 
204
206
  ##
@@ -207,7 +209,8 @@ module Gcloud
207
209
  # @!group Attributes
208
210
  #
209
211
  def description= new_description
210
- patch_gapi! description: new_description
212
+ @gapi.update! description: new_description
213
+ patch_gapi! :description
211
214
  end
212
215
 
213
216
  ##
@@ -217,7 +220,11 @@ module Gcloud
217
220
  #
218
221
  def bytes_count
219
222
  ensure_full_data!
220
- @gapi["numBytes"]
223
+ begin
224
+ Integer @gapi.num_bytes
225
+ rescue
226
+ nil
227
+ end
221
228
  end
222
229
 
223
230
  ##
@@ -227,7 +234,11 @@ module Gcloud
227
234
  #
228
235
  def rows_count
229
236
  ensure_full_data!
230
- @gapi["numRows"]
237
+ begin
238
+ Integer @gapi.num_rows
239
+ rescue
240
+ nil
241
+ end
231
242
  end
232
243
 
233
244
  ##
@@ -237,7 +248,11 @@ module Gcloud
237
248
  #
238
249
  def created_at
239
250
  ensure_full_data!
240
- Time.at(@gapi["creationTime"] / 1000.0)
251
+ begin
252
+ Time.at(Integer(@gapi.creation_time) / 1000.0)
253
+ rescue
254
+ nil
255
+ end
241
256
  end
242
257
 
243
258
  ##
@@ -249,8 +264,11 @@ module Gcloud
249
264
  #
250
265
  def expires_at
251
266
  ensure_full_data!
252
- return nil if @gapi["expirationTime"].nil?
253
- Time.at(@gapi["expirationTime"] / 1000.0)
267
+ begin
268
+ Time.at(Integer(@gapi.expiration_time) / 1000.0)
269
+ rescue
270
+ nil
271
+ end
254
272
  end
255
273
 
256
274
  ##
@@ -260,7 +278,11 @@ module Gcloud
260
278
  #
261
279
  def modified_at
262
280
  ensure_full_data!
263
- Time.at(@gapi["lastModifiedTime"] / 1000.0)
281
+ begin
282
+ Time.at(Integer(@gapi.last_modified_time) / 1000.0)
283
+ rescue
284
+ nil
285
+ end
264
286
  end
265
287
 
266
288
  ##
@@ -269,7 +291,7 @@ module Gcloud
269
291
  # @!group Attributes
270
292
  #
271
293
  def table?
272
- @gapi["type"] == "TABLE"
294
+ @gapi.type == "TABLE"
273
295
  end
274
296
 
275
297
  ##
@@ -278,7 +300,7 @@ module Gcloud
278
300
  # @!group Attributes
279
301
  #
280
302
  def view?
281
- @gapi["type"] == "VIEW"
303
+ @gapi.type == "VIEW"
282
304
  end
283
305
 
284
306
  ##
@@ -289,16 +311,13 @@ module Gcloud
289
311
  #
290
312
  def location
291
313
  ensure_full_data!
292
- @gapi["location"]
314
+ @gapi.location
293
315
  end
294
316
 
295
317
  ##
296
- # Returns the table's schema as hash containing the keys and values
297
- # returned by the Google Cloud BigQuery [Rest API
298
- # ](https://cloud.google.com/bigquery/docs/reference/v2/tables#resource).
299
- # This method can also be used to set, replace, or add to the schema by
300
- # passing a block. See {Table::Schema} for available methods. To set the
301
- # schema by passing a hash instead, use {#schema=}.
318
+ # Returns the table's schema. This method can also be used to set,
319
+ # replace, or add to the schema by passing a block. See {Schema} for
320
+ # available methods.
302
321
  #
303
322
  # @param [Boolean] replace Whether to replace the existing schema with the
304
323
  # new schema. If `true`, the fields will replace the existing schema. If
@@ -308,6 +327,8 @@ module Gcloud
308
327
  # @yield [schema] a block for setting the schema
309
328
  # @yieldparam [Table::Schema] schema the object accepting the schema
310
329
  #
330
+ # @return [Gcloud::Bigquery::Schema]
331
+ #
311
332
  # @example
312
333
  # require "gcloud"
313
334
  #
@@ -328,53 +349,20 @@ module Gcloud
328
349
  #
329
350
  def schema replace: false
330
351
  ensure_full_data!
331
- g = @gapi
332
- g = g.to_hash if g.respond_to? :to_hash
333
- s = g["schema"] ||= {}
334
- return s unless block_given?
335
- s = nil if replace
336
- schema_builder = Schema.new s
337
- yield schema_builder
338
- self.schema = schema_builder.schema if schema_builder.changed?
339
- end
340
-
341
- ##
342
- # Updates the schema of the table.
343
- # To update the schema using a block instead, use #schema.
344
- #
345
- # @param [Hash] new_schema A hash containing keys and values as specified
346
- # by the Google Cloud BigQuery [Rest API
347
- # ](https://cloud.google.com/bigquery/docs/reference/v2/tables#resource)
348
- # .
349
- #
350
- # @example
351
- # require "gcloud"
352
- #
353
- # gcloud = Gcloud.new
354
- # bigquery = gcloud.bigquery
355
- # dataset = bigquery.dataset "my_dataset"
356
- # table = dataset.create_table "my_table"
357
- #
358
- # schema = {
359
- # "fields" => [
360
- # {
361
- # "name" => "first_name",
362
- # "type" => "STRING",
363
- # "mode" => "REQUIRED"
364
- # },
365
- # {
366
- # "name" => "age",
367
- # "type" => "INTEGER",
368
- # "mode" => "REQUIRED"
369
- # }
370
- # ]
371
- # }
372
- # table.schema = schema
373
- #
374
- # @!group Attributes
375
- #
376
- def schema= new_schema
377
- patch_gapi! schema: new_schema
352
+ schema_builder = Schema.from_gapi @gapi.schema
353
+ if block_given?
354
+ if replace
355
+ empty_schema = Google::Apis::BigqueryV2::TableSchema.new fields: []
356
+ schema_builder = Schema.from_gapi empty_schema
357
+ end
358
+ yield schema_builder
359
+ schema_builder.check_for_mutated_schema!
360
+ if schema_builder.changed?
361
+ @gapi.schema = schema_builder.to_gapi
362
+ patch_gapi! :schema
363
+ end
364
+ end
365
+ schema_builder.freeze
378
366
  end
379
367
 
380
368
  ##
@@ -383,10 +371,7 @@ module Gcloud
383
371
  # @!group Attributes
384
372
  #
385
373
  def fields
386
- f = schema["fields"]
387
- f = f.to_hash if f.respond_to? :to_hash
388
- f = [] if f.nil?
389
- f
374
+ schema.fields
390
375
  end
391
376
 
392
377
  ##
@@ -395,7 +380,7 @@ module Gcloud
395
380
  # @!group Attributes
396
381
  #
397
382
  def headers
398
- fields.map { |f| f["name"] }
383
+ fields.map(&:name)
399
384
  end
400
385
 
401
386
  ##
@@ -441,14 +426,10 @@ module Gcloud
441
426
  # @!group Data
442
427
  #
443
428
  def data token: nil, max: nil, start: nil
444
- ensure_connection!
429
+ ensure_service!
445
430
  options = { token: token, max: max, start: start }
446
- resp = connection.list_tabledata dataset_id, table_id, options
447
- if resp.success?
448
- Data.from_response resp, self
449
- else
450
- fail ApiError.from_response(resp)
451
- end
431
+ gapi = service.list_tabledata dataset_id, table_id, options
432
+ Data.from_gapi gapi, self
452
433
  end
453
434
 
454
435
  ##
@@ -505,54 +486,12 @@ module Gcloud
505
486
  # @!group Data
506
487
  #
507
488
  def copy destination_table, create: nil, write: nil, dryrun: nil
508
- ensure_connection!
509
- options = { create: create, write: write, dryrun: dryrun }
510
- resp = connection.copy_table table_ref,
511
- get_table_ref(destination_table),
512
- options
513
- if resp.success?
514
- Job.from_gapi resp.data, connection
515
- else
516
- fail ApiError.from_response(resp)
517
- end
518
- end
519
-
520
- ##
521
- # @private
522
- # Links the table to a source table identified by a URI.
523
- #
524
- # @param [String] source_url The URI of source table to link.
525
- # @param [String] create Specifies whether the job is allowed to create
526
- # new tables.
527
- #
528
- # The following values are supported:
529
- #
530
- # * `needed` - Create the table if it does not exist.
531
- # * `never` - The table must already exist. A 'notFound' error is
532
- # raised if the table does not exist.
533
- # @param [String] write Specifies how to handle data already present in
534
- # the destination table. The default value is `empty`.
535
- #
536
- # The following values are supported:
537
- #
538
- # * `truncate` - BigQuery overwrites the table data.
539
- # * `append` - BigQuery appends the data to the table.
540
- # * `empty` - An error will be returned if the destination table already
541
- # contains data.
542
- #
543
- # @return [Gcloud::Bigquery::Job]
544
- #
545
- # @!group Data
546
- #
547
- def link source_url, create: nil, write: nil, dryrun: nil
548
- ensure_connection!
489
+ ensure_service!
549
490
  options = { create: create, write: write, dryrun: dryrun }
550
- resp = connection.link_table table_ref, source_url, options
551
- if resp.success?
552
- Job.from_gapi resp.data, connection
553
- else
554
- fail ApiError.from_response(resp)
555
- end
491
+ gapi = service.copy_table table_ref,
492
+ get_table_ref(destination_table),
493
+ options
494
+ Job.from_gapi gapi, service
556
495
  end
557
496
 
558
497
  ##
@@ -598,21 +537,17 @@ module Gcloud
598
537
  #
599
538
  def extract extract_url, format: nil, compression: nil, delimiter: nil,
600
539
  header: nil, dryrun: nil
601
- ensure_connection!
540
+ ensure_service!
602
541
  options = { format: format, compression: compression,
603
542
  delimiter: delimiter, header: header, dryrun: dryrun }
604
- resp = connection.extract_table table_ref, extract_url, options
605
- if resp.success?
606
- Job.from_gapi resp.data, connection
607
- else
608
- fail ApiError.from_response(resp)
609
- end
543
+ gapi = service.extract_table table_ref, extract_url, options
544
+ Job.from_gapi gapi, service
610
545
  end
611
546
 
612
547
  ##
613
- # Loads data into the table. You can pass a gcloud storage file path or
614
- # a gcloud storage file instance. Or, you can upload a file directly.
615
- # See [Loading Data with a POST Request](
548
+ # Loads data into the table. You can pass a gcloud-ruby storage file path
549
+ # or a gcloud-ruby storage file instance. Or, you can upload a file
550
+ # directly. See [Loading Data with a POST Request](
616
551
  # https://cloud.google.com/bigquery/loading-data-post-request#multipart).
617
552
  #
618
553
  # A `chunk_size` value can be provided in the options to be used in
@@ -698,10 +633,6 @@ module Gcloud
698
633
  # file that BigQuery will skip when loading the data. The default value
699
634
  # is `0`. This property is useful if you have header rows in the file
700
635
  # that should be skipped.
701
- # @param [Integer] chunk_size The number of bytes per chunk in a resumable
702
- # upload. Must be divisible by 256KB. If it is not divisible by 265KB
703
- # then it will be lowered to the nearest acceptable value. If no value
704
- # is provided it will use {Gcloud::Upload.default_chunk_size}. Optional.
705
636
  #
706
637
  # @return [Gcloud::Bigquery::LoadJob]
707
638
  #
@@ -715,7 +646,7 @@ module Gcloud
715
646
  #
716
647
  # load_job = table.load "gs://my-bucket/file-name.csv"
717
648
  #
718
- # @example Pass a gcloud storage file instance:
649
+ # @example Pass a gcloud-ruby storage file instance:
719
650
  # require "gcloud"
720
651
  # require "gcloud/storage"
721
652
  #
@@ -740,46 +671,18 @@ module Gcloud
740
671
  # file = File.open "my_data.csv"
741
672
  # load_job = table.load file
742
673
  #
743
- # ### A note about large direct uploads
744
- #
745
- # You may encounter a Broken pipe (Errno::EPIPE) error when attempting to
746
- # upload large files. To avoid this problem, add the
747
- # [httpclient](https://rubygems.org/gems/httpclient) gem to your project,
748
- # and the line (or lines) of configuration shown below. These lines must
749
- # execute after you require gcloud but before you make your first gcloud
750
- # connection. The first statement configures
751
- # [Faraday](https://rubygems.org/gems/faraday) to use httpclient. The
752
- # second statement, which should only be added if you are using a version
753
- # of Faraday at or above 0.9.2, is a workaround for [this gzip
754
- # issue](https://github.com/GoogleCloudPlatform/gcloud-ruby/issues/367).
755
- #
756
- # @example
757
- # require "gcloud"
758
- #
759
- # # Use httpclient to avoid broken pipe errors with large uploads
760
- # Faraday.default_adapter = :httpclient
761
- #
762
- # # Only add the following statement if using Faraday >= 0.9.2
763
- # # Override gzip middleware with no-op for httpclient
764
- # Faraday::Response.register_middleware :gzip =>
765
- # Faraday::Response::Middleware
766
- #
767
- # gcloud = Gcloud.new
768
- # bigquery = gcloud.bigquery
769
- #
770
674
  # @!group Data
771
675
  #
772
676
  def load file, format: nil, create: nil, write: nil,
773
677
  projection_fields: nil, jagged_rows: nil, quoted_newlines: nil,
774
678
  encoding: nil, delimiter: nil, ignore_unknown: nil,
775
- max_bad_records: nil, quote: nil, skip_leading: nil, dryrun: nil,
776
- chunk_size: nil
777
- ensure_connection!
679
+ max_bad_records: nil, quote: nil, skip_leading: nil, dryrun: nil
680
+ ensure_service!
778
681
  options = { format: format, create: create, write: write,
779
682
  projection_fields: projection_fields,
780
683
  jagged_rows: jagged_rows, quoted_newlines: quoted_newlines,
781
684
  encoding: encoding, delimiter: delimiter,
782
- ignore_unknown: ignore_unknown, chunk_size: chunk_size,
685
+ ignore_unknown: ignore_unknown,
783
686
  max_bad_records: max_bad_records, quote: quote,
784
687
  skip_leading: skip_leading, dryrun: dryrun }
785
688
  return load_storage(file, options) if storage_url? file
@@ -824,14 +727,10 @@ module Gcloud
824
727
  #
825
728
  def insert rows, skip_invalid: nil, ignore_unknown: nil
826
729
  rows = [rows] if rows.is_a? Hash
827
- ensure_connection!
730
+ ensure_service!
828
731
  options = { skip_invalid: skip_invalid, ignore_unknown: ignore_unknown }
829
- resp = connection.insert_tabledata dataset_id, table_id, rows, options
830
- if resp.success?
831
- InsertResponse.from_gapi rows, resp.data
832
- else
833
- fail ApiError.from_response(resp)
834
- end
732
+ gapi = service.insert_tabledata dataset_id, table_id, rows, options
733
+ InsertResponse.from_gapi rows, gapi
835
734
  end
836
735
 
837
736
  ##
@@ -852,13 +751,9 @@ module Gcloud
852
751
  # @!group Lifecycle
853
752
  #
854
753
  def delete
855
- ensure_connection!
856
- resp = connection.delete_table dataset_id, table_id
857
- if resp.success?
858
- true
859
- else
860
- fail ApiError.from_response(resp)
861
- end
754
+ ensure_service!
755
+ service.delete_table dataset_id, table_id
756
+ true
862
757
  end
863
758
 
864
759
  ##
@@ -867,13 +762,9 @@ module Gcloud
867
762
  # @!group Lifecycle
868
763
  #
869
764
  def reload!
870
- ensure_connection!
871
- resp = connection.get_table dataset_id, table_id
872
- if resp.success?
873
- @gapi = resp.data
874
- else
875
- fail ApiError.from_response(resp)
876
- end
765
+ ensure_service!
766
+ gapi = service.get_table dataset_id, table_id
767
+ @gapi = gapi
877
768
  end
878
769
  alias_method :refresh!, :reload!
879
770
 
@@ -883,77 +774,47 @@ module Gcloud
883
774
  klass = class_for gapi
884
775
  klass.new.tap do |f|
885
776
  f.gapi = gapi
886
- f.connection = conn
777
+ f.service = conn
887
778
  end
888
779
  end
889
780
 
890
781
  protected
891
782
 
892
783
  ##
893
- # Raise an error unless an active connection is available.
894
- def ensure_connection!
895
- fail "Must have active connection" unless connection
784
+ # Raise an error unless an active service is available.
785
+ def ensure_service!
786
+ fail "Must have active connection" unless service
896
787
  end
897
788
 
898
- def patch_gapi! options = {}
899
- ensure_connection!
900
- resp = connection.patch_table dataset_id, table_id, options
901
- if resp.success?
902
- @gapi = resp.data
903
- else
904
- fail ApiError.from_response(resp)
905
- end
789
+ def patch_gapi! *attributes
790
+ return if attributes.empty?
791
+ ensure_service!
792
+ patch_args = Hash[attributes.map do |attr|
793
+ [attr, @gapi.send(attr)]
794
+ end]
795
+ patch_gapi = Google::Apis::BigqueryV2::Table.new patch_args
796
+ @gapi = service.patch_table dataset_id, table_id, patch_gapi
906
797
  end
907
798
 
908
799
  def self.class_for gapi
909
- return View if gapi["type"] == "VIEW"
800
+ return View if gapi.type == "VIEW"
910
801
  self
911
802
  end
912
803
 
913
- def load_storage file, options = {}
804
+ def load_storage url, options = {}
914
805
  # Convert to storage URL
915
- file = file.to_gs_url if file.respond_to? :to_gs_url
806
+ url = url.to_gs_url if url.respond_to? :to_gs_url
916
807
 
917
- resp = connection.load_table table_ref, file, options
918
- if resp.success?
919
- Job.from_gapi resp.data, connection
920
- else
921
- fail ApiError.from_response(resp)
922
- end
808
+ gapi = service.load_table_gs_url dataset_id, table_id, url, options
809
+ Job.from_gapi gapi, service
923
810
  end
924
811
 
925
812
  def load_local file, options = {}
926
- if resumable_upload? file
927
- load_resumable file, options
928
- else
929
- load_multipart file, options
930
- end
931
- end
932
-
933
- def load_resumable file, options = {}
934
- chunk_size = Gcloud::Upload.verify_chunk_size options[:chunk_size],
935
- file.length
936
- resp = connection.load_resumable table_ref, file, chunk_size, options
937
- if resp.success?
938
- Job.from_gapi resp.data, connection
939
- else
940
- fail ApiError.from_response(resp)
941
- end
942
- end
943
-
944
- def load_multipart file, options = {}
945
- resp = connection.load_multipart table_ref, file, options
946
- if resp.success?
947
- Job.from_gapi resp.data, connection
948
- else
949
- fail ApiError.from_response(resp)
950
- end
951
- end
813
+ # Convert to storage URL
814
+ file = file.to_gs_url if file.respond_to? :to_gs_url
952
815
 
953
- ##
954
- # @private Determines if a resumable upload should be used.
955
- def resumable_upload? file
956
- ::File.size?(file).to_i > Upload.resumable_threshold
816
+ gapi = service.load_table_file dataset_id, table_id, file, options
817
+ Job.from_gapi gapi, service
957
818
  end
958
819
 
959
820
  def storage_url? file
@@ -976,17 +837,13 @@ module Gcloud
976
837
  end
977
838
 
978
839
  def reload_gapi!
979
- ensure_connection!
980
- resp = connection.get_table dataset_id, table_id
981
- if resp.success?
982
- @gapi = resp.data
983
- else
984
- fail ApiError.from_response(resp)
985
- end
840
+ ensure_service!
841
+ gapi = service.get_table dataset_id, table_id
842
+ @gapi = gapi
986
843
  end
987
844
 
988
845
  def data_complete?
989
- !@gapi["creationTime"].nil?
846
+ @gapi.is_a? Google::Apis::BigqueryV2::Table
990
847
  end
991
848
 
992
849
  private
@@ -995,7 +852,69 @@ module Gcloud
995
852
  if table.respond_to? :table_ref
996
853
  table.table_ref
997
854
  else
998
- Connection.table_ref_from_s table, table_ref
855
+ Service.table_ref_from_s table, table_ref
856
+ end
857
+ end
858
+
859
+ ##
860
+ # Yielded to a block to accumulate changes for a patch request.
861
+ class Updater < Table
862
+ ##
863
+ # A list of attributes that were updated.
864
+ attr_reader :updates
865
+
866
+ ##
867
+ # Create an Updater object.
868
+ def initialize gapi
869
+ @updates = []
870
+ @gapi = gapi
871
+ @schema = nil
872
+ end
873
+
874
+ def schema replace: false
875
+ # Same as Table#schema, but not frozen
876
+ # TODO: make sure to call ensure_full_data! on Dataset#update
877
+ @schema ||= Schema.from_gapi @gapi.schema
878
+ if block_given?
879
+ if replace
880
+ @schema = Schema.from_gapi \
881
+ Google::Apis::BigqueryV2::TableSchema.new(fields: [])
882
+ end
883
+ yield @schema
884
+ check_for_mutated_schema!
885
+ end
886
+ # Do not freeze on updater, allow modifications
887
+ @schema
888
+ end
889
+
890
+ ##
891
+ # Make sure any access changes are saved
892
+ def check_for_mutated_schema!
893
+ return if @schema.nil?
894
+ @schema.check_for_mutated_schema!
895
+ return unless @schema.changed?
896
+ @gapi.schema = @schema.to_gapi
897
+ patch_gapi! :schema
898
+ end
899
+
900
+ def to_gapi
901
+ check_for_mutated_schema!
902
+ @gapi
903
+ end
904
+
905
+ protected
906
+
907
+ ##
908
+ # Change to a NOOP
909
+ def ensure_full_data!
910
+ # Do nothing because we trust the gapi is full before we get here.
911
+ end
912
+
913
+ ##
914
+ # Queue up all the updates instead of making them.
915
+ def patch_gapi! attribute
916
+ @updates << attribute
917
+ @updates.uniq!
999
918
  end
1000
919
  end
1001
920
  end