gcloud 0.11.0 → 0.12.0

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