google-cloud-bigquery 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,124 @@
1
+ # Copyright 2018 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require "google/apis/bigquery_v2"
16
+
17
+ module Google
18
+ module Cloud
19
+ module Bigquery
20
+ ##
21
+ # # Encryption Configuration
22
+ #
23
+ # A builder for BigQuery table encryption configurations, passed to block
24
+ # arguments to {Dataset#create_table} and
25
+ # {Table#encryption_configuration}.
26
+ #
27
+ # @see https://cloud.google.com/bigquery/docs/customer-managed-encryption
28
+ # Protecting Data with Cloud KMS Keys
29
+ #
30
+ # @example
31
+ # require "google/cloud/bigquery"
32
+ #
33
+ # bigquery = Google::Cloud::Bigquery.new
34
+ # dataset = bigquery.dataset "my_dataset"
35
+ # key_name = "projects/a/locations/b/keyRings/c/cryptoKeys/d"
36
+ # encrypt_config = bigquery.encryption kms_key: key_name
37
+ # table = dataset.create_table "my_table" do |updater|
38
+ # updater.encryption = encrypt_config
39
+ # end
40
+ #
41
+ class EncryptionConfiguration
42
+ ##
43
+ # @private The Google API Client object.
44
+ attr_accessor :gapi
45
+
46
+ ##
47
+ # @private Create an empty EncryptionConfiguration object.
48
+ def initialize
49
+ @gapi = Google::Apis::BigqueryV2::EncryptionConfiguration.new
50
+ end
51
+
52
+ ##
53
+ # The Cloud KMS encryption key that will be used to protect the table.
54
+ # For example: `projects/a/locations/b/keyRings/c/cryptoKeys/d`
55
+ # The default value is `nil`, which means default encryption is used.
56
+ #
57
+ # @return [String]
58
+ #
59
+ # @example
60
+ # require "google/cloud/bigquery"
61
+ #
62
+ # config = Google::Cloud::Bigquery::EncryptionConfiguration.new
63
+ # key_name = "projects/a/locations/b/keyRings/c/cryptoKeys/d"
64
+ # config.kms_key = key_name
65
+ #
66
+ def kms_key
67
+ @gapi.kms_key_name
68
+ end
69
+
70
+ ##
71
+ # Set the Cloud KMS encryption key that will be used to protect the
72
+ # table. For example: `projects/a/locations/b/keyRings/c/cryptoKeys/d`
73
+ # The default value is `nil`, which means default encryption is used.
74
+ #
75
+ # @param [String] new_kms_key_name New Cloud KMS key name
76
+ #
77
+ # @example
78
+ # require "google/cloud/bigquery"
79
+ #
80
+ # config = Google::Cloud::Bigquery::EncryptionConfiguration.new
81
+ # key_name = "projects/a/locations/b/keyRings/c/cryptoKeys/d"
82
+ # config.kms_key = key_name
83
+ #
84
+ def kms_key= new_kms_key_name
85
+ frozen_check!
86
+ @gapi.kms_key_name = new_kms_key_name
87
+ end
88
+
89
+ # @private
90
+ def changed?
91
+ return false if frozen?
92
+ @original_json != @gapi.to_json
93
+ end
94
+
95
+ ##
96
+ # @private Google API Client object.
97
+ def to_gapi
98
+ @gapi
99
+ end
100
+
101
+ ##
102
+ # @private Google API Client object.
103
+ def self.from_gapi gapi
104
+ new_config = new
105
+ new_config.instance_variable_set :@gapi, gapi
106
+ new_config
107
+ end
108
+
109
+ # @private
110
+ def == other
111
+ return false unless other.is_a? EncryptionConfiguration
112
+ to_gapi.to_json == other.to_gapi.to_json
113
+ end
114
+
115
+ protected
116
+
117
+ def frozen_check!
118
+ return unless frozen?
119
+ raise ArgumentError, "Cannot modify a frozen encryption configuration"
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
@@ -155,6 +155,155 @@ module Google
155
155
  def destinations_counts
156
156
  Hash[destinations.zip destinations_file_counts]
157
157
  end
158
+
159
+ ##
160
+ # Yielded to a block to accumulate changes for an API request.
161
+ class Updater < ExtractJob
162
+ ##
163
+ # @private Create an Updater object.
164
+ def initialize gapi
165
+ @gapi = gapi
166
+ end
167
+
168
+ ##
169
+ # @private Create an Updater from an options hash.
170
+ #
171
+ # @return [Google::Cloud::Bigquery::ExtractJob::Updater] A job
172
+ # configuration object for setting query options.
173
+ def self.from_options service, table, storage_files, options = {}
174
+ job_ref = service.job_ref_from options[:job_id], options[:prefix]
175
+ storage_urls = Array(storage_files).map do |url|
176
+ url.respond_to?(:to_gs_url) ? url.to_gs_url : url
177
+ end
178
+ dest_format = options[:format]
179
+ if dest_format.nil?
180
+ dest_format = Convert.derive_source_format storage_urls.first
181
+ end
182
+ req = Google::Apis::BigqueryV2::Job.new(
183
+ job_reference: job_ref,
184
+ configuration: Google::Apis::BigqueryV2::JobConfiguration.new(
185
+ extract: Google::Apis::BigqueryV2::JobConfigurationExtract.new(
186
+ destination_uris: Array(storage_urls),
187
+ source_table: table
188
+ ),
189
+ dry_run: options[:dryrun]
190
+ )
191
+ )
192
+
193
+ updater = ExtractJob::Updater.new req
194
+ updater.compression = options[:compression]
195
+ updater.delimiter = options[:delimiter]
196
+ updater.format = dest_format
197
+ updater.header = options[:header]
198
+ updater.labels = options[:labels] if options[:labels]
199
+ updater
200
+ end
201
+
202
+ ##
203
+ # Sets the geographic location where the job should run. Required
204
+ # except for US and EU.
205
+ #
206
+ # @param [String] value A geographic location, such as "US", "EU" or
207
+ # "asia-northeast1". Required except for US and EU.
208
+ #
209
+ # @example
210
+ # require "google/cloud/bigquery"
211
+ #
212
+ # bigquery = Google::Cloud::Bigquery.new
213
+ # dataset = bigquery.dataset "my_dataset"
214
+ # table = dataset.table "my_table"
215
+ #
216
+ # destination = "gs://my-bucket/file-name.csv"
217
+ # extract_job = table.extract_job destination do |j|
218
+ # j.location = "EU"
219
+ # end
220
+ #
221
+ # extract_job.wait_until_done!
222
+ # extract_job.done? #=> true
223
+ #
224
+ # @!group Attributes
225
+ def location= value
226
+ @gapi.job_reference.location = value
227
+ end
228
+
229
+ ##
230
+ # Sets the compression type.
231
+ #
232
+ # @param [String] value The compression type to use for exported
233
+ # files. Possible values include `GZIP` and `NONE`. The default
234
+ # value is `NONE`.
235
+ #
236
+ # @!group Attributes
237
+ def compression= value
238
+ @gapi.configuration.extract.compression = value
239
+ end
240
+
241
+ ##
242
+ # Sets the field delimiter.
243
+ #
244
+ # @param [String] value Delimiter to use between fields in the
245
+ # exported data. Default is <code>,</code>.
246
+ #
247
+ # @!group Attributes
248
+ def delimiter= value
249
+ @gapi.configuration.extract.field_delimiter = value
250
+ end
251
+
252
+ ##
253
+ # Sets the destination file format. The default value is `csv`.
254
+ #
255
+ # The following values are supported:
256
+ #
257
+ # * `csv` - CSV
258
+ # * `json` - [Newline-delimited JSON](http://jsonlines.org/)
259
+ # * `avro` - [Avro](http://avro.apache.org/)
260
+ #
261
+ # @param [String] new_format The new source format.
262
+ #
263
+ # @!group Attributes
264
+ #
265
+ def format= new_format
266
+ @gapi.configuration.extract.update! destination_format:
267
+ Convert.source_format(new_format)
268
+ end
269
+
270
+ ##
271
+ # Print a header row in the exported file.
272
+ #
273
+ # @param [Boolean] value Whether to print out a header row in the
274
+ # results. Default is `true`.
275
+ #
276
+ # @!group Attributes
277
+ def header= value
278
+ @gapi.configuration.extract.print_header = value
279
+ end
280
+
281
+ ##
282
+ # Sets the labels to use for the job.
283
+ #
284
+ # @param [Hash] value A hash of user-provided labels associated with
285
+ # the job. You can use these to organize and group your jobs. Label
286
+ # keys and values can be no longer than 63 characters, can only
287
+ # contain lowercase letters, numeric characters, underscores and
288
+ # dashes. International characters are allowed. Label values are
289
+ # optional. Label keys must start with a letter and each label in
290
+ # the list must have a different key.
291
+ #
292
+ # @!group Attributes
293
+ #
294
+ def labels= value
295
+ @gapi.configuration.update! labels: value
296
+ end
297
+
298
+ ##
299
+ # @private Returns the Google API client library version of this job.
300
+ #
301
+ # @return [<Google::Apis::BigqueryV2::Job>] (See
302
+ # {Google::Apis::BigqueryV2::Job})
303
+ def to_gapi
304
+ @gapi
305
+ end
306
+ end
158
307
  end
159
308
  end
160
309
  end
@@ -90,6 +90,17 @@ module Google
90
90
  @gapi.job_reference.project_id
91
91
  end
92
92
 
93
+ ##
94
+ # The geographic location where the job runs.
95
+ #
96
+ # @return [String] A geographic location, such as "US", "EU" or
97
+ # "asia-northeast1".
98
+ #
99
+ # @!group Attributes
100
+ def location
101
+ @gapi.job_reference.location
102
+ end
103
+
93
104
  ##
94
105
  # The email address of the user who ran the job.
95
106
  #
@@ -293,7 +304,7 @@ module Google
293
304
  #
294
305
  def cancel
295
306
  ensure_service!
296
- resp = service.cancel_job job_id
307
+ resp = service.cancel_job job_id, location: location
297
308
  @gapi = resp.job
298
309
  true
299
310
  end
@@ -316,7 +327,7 @@ module Google
316
327
  #
317
328
  def rerun!
318
329
  ensure_service!
319
- gapi = service.insert_job @gapi.configuration
330
+ gapi = service.insert_job @gapi.configuration, location: location
320
331
  Job.from_gapi gapi, service
321
332
  end
322
333
 
@@ -339,7 +350,7 @@ module Google
339
350
  #
340
351
  def reload!
341
352
  ensure_service!
342
- gapi = service.get_job job_id
353
+ gapi = service.get_job job_id, location: location
343
354
  @gapi = gapi
344
355
  end
345
356
  alias refresh! reload!
@@ -14,6 +14,7 @@
14
14
 
15
15
 
16
16
  require "google/cloud/bigquery/service"
17
+ require "google/cloud/bigquery/encryption_configuration"
17
18
 
18
19
  module Google
19
20
  module Cloud
@@ -303,6 +304,19 @@ module Google
303
304
  nil
304
305
  end
305
306
 
307
+ ##
308
+ # The encryption configuration of the destination table.
309
+ #
310
+ # @return [Google::Cloud::BigQuery::EncryptionConfiguration] Custom
311
+ # encryption configuration (e.g., Cloud KMS keys).
312
+ #
313
+ # @!group Attributes
314
+ def encryption
315
+ EncryptionConfiguration.from_gapi(
316
+ @gapi.configuration.load.destination_encryption_configuration
317
+ )
318
+ end
319
+
306
320
  ##
307
321
  # The number of bytes that have been loaded into the table. While an
308
322
  # import job is in the running state, this value may change.
@@ -314,6 +328,762 @@ module Google
314
328
  rescue StandardError
315
329
  nil
316
330
  end
331
+
332
+ ##
333
+ # Yielded to a block to accumulate changes for a patch request.
334
+ class Updater < LoadJob
335
+ ##
336
+ # A list of attributes that were updated.
337
+ attr_reader :updates
338
+
339
+ ##
340
+ # @private Create an Updater object.
341
+ def initialize gapi
342
+ @updates = []
343
+ @gapi = gapi
344
+ @schema = nil
345
+ end
346
+
347
+ ##
348
+ # Returns the table's schema. This method can also be used to set,
349
+ # replace, or add to the schema by passing a block. See {Schema} for
350
+ # available methods.
351
+ #
352
+ # @param [Boolean] replace Whether to replace the existing schema with
353
+ # the new schema. If `true`, the fields will replace the existing
354
+ # schema. If `false`, the fields will be added to the existing
355
+ # schema. When a table already contains data, schema changes must be
356
+ # additive. Thus, the default value is `false`.
357
+ # @yield [schema] a block for setting the schema
358
+ # @yieldparam [Schema] schema the object accepting the schema
359
+ #
360
+ # @return [Google::Cloud::Bigquery::Schema]
361
+ #
362
+ # @example
363
+ # require "google/cloud/bigquery"
364
+ #
365
+ # bigquery = Google::Cloud::Bigquery.new
366
+ # dataset = bigquery.dataset "my_dataset"
367
+ # job = dataset.load_job "my_table", "gs://abc/file" do |j|
368
+ # j.schema do |s|
369
+ # s.string "first_name", mode: :required
370
+ # s.record "cities_lived", mode: :repeated do |r|
371
+ # r.string "place", mode: :required
372
+ # r.integer "number_of_years", mode: :required
373
+ # end
374
+ # end
375
+ # end
376
+ #
377
+ # @!group Schema
378
+ #
379
+ def schema replace: false
380
+ # Same as Table#schema, but not frozen
381
+ # TODO: make sure to call ensure_full_data! on Dataset#update
382
+ @schema ||= Schema.from_gapi @gapi.configuration.load.schema
383
+ if block_given?
384
+ @schema = Schema.from_gapi if replace
385
+ yield @schema
386
+ check_for_mutated_schema!
387
+ end
388
+ # Do not freeze on updater, allow modifications
389
+ @schema
390
+ end
391
+
392
+ ##
393
+ # Sets the schema of the destination table.
394
+ #
395
+ # @param [Google::Cloud::Bigquery::Schema] new_schema The schema for
396
+ # the destination table. Optional. The schema can be omitted if the
397
+ # destination table already exists, or if you're loading data from a
398
+ # source that includes a schema, such as Avro or a Google Cloud
399
+ # Datastore backup.
400
+ #
401
+ # @example
402
+ # require "google/cloud/bigquery"
403
+ #
404
+ # bigquery = Google::Cloud::Bigquery.new
405
+ # schema = bigquery.schema do |s|
406
+ # s.string "first_name", mode: :required
407
+ # s.record "cities_lived", mode: :repeated do |nested_schema|
408
+ # nested_schema.string "place", mode: :required
409
+ # nested_schema.integer "number_of_years", mode: :required
410
+ # end
411
+ # end
412
+ # dataset = bigquery.dataset "my_dataset"
413
+ # job = dataset.load_job "my_table", "gs://abc/file" do |j|
414
+ # j.schema = schema
415
+ # end
416
+ #
417
+ # @!group Schema
418
+ #
419
+ def schema= new_schema
420
+ @schema = new_schema
421
+ end
422
+
423
+ ##
424
+ # Adds a string field to the schema.
425
+ #
426
+ # See {Schema#string}.
427
+ #
428
+ # @param [String] name The field name. The name must contain only
429
+ # letters (a-z, A-Z), numbers (0-9), or underscores (_), and must
430
+ # start with a letter or underscore. The maximum length is 128
431
+ # characters.
432
+ # @param [String] description A description of the field.
433
+ # @param [Symbol] mode The field's mode. The possible values are
434
+ # `:nullable`, `:required`, and `:repeated`. The default value is
435
+ # `:nullable`.
436
+ #
437
+ # @example
438
+ # require "google/cloud/bigquery"
439
+ #
440
+ # bigquery = Google::Cloud::Bigquery.new
441
+ # dataset = bigquery.dataset "my_dataset"
442
+ # job = dataset.load_job "my_table", "gs://abc/file" do |schema|
443
+ # schema.string "first_name", mode: :required
444
+ # end
445
+ #
446
+ # @!group Schema
447
+ def string name, description: nil, mode: :nullable
448
+ schema.string name, description: description, mode: mode
449
+ end
450
+
451
+ ##
452
+ # Adds an integer field to the schema.
453
+ #
454
+ # See {Schema#integer}.
455
+ #
456
+ # @param [String] name The field name. The name must contain only
457
+ # letters (a-z, A-Z), numbers (0-9), or underscores (_), and must
458
+ # start with a letter or underscore. The maximum length is 128
459
+ # characters.
460
+ # @param [String] description A description of the field.
461
+ # @param [Symbol] mode The field's mode. The possible values are
462
+ # `:nullable`, `:required`, and `:repeated`. The default value is
463
+ # `:nullable`.
464
+ #
465
+ # @example
466
+ # require "google/cloud/bigquery"
467
+ #
468
+ # bigquery = Google::Cloud::Bigquery.new
469
+ # dataset = bigquery.dataset "my_dataset"
470
+ # job = dataset.load_job "my_table", "gs://abc/file" do |schema|
471
+ # schema.integer "age", mode: :required
472
+ # end
473
+ #
474
+ # @!group Schema
475
+ def integer name, description: nil, mode: :nullable
476
+ schema.integer name, description: description, mode: mode
477
+ end
478
+
479
+ ##
480
+ # Adds a floating-point number field to the schema.
481
+ #
482
+ # See {Schema#float}.
483
+ #
484
+ # @param [String] name The field name. The name must contain only
485
+ # letters (a-z, A-Z), numbers (0-9), or underscores (_), and must
486
+ # start with a letter or underscore. The maximum length is 128
487
+ # characters.
488
+ # @param [String] description A description of the field.
489
+ # @param [Symbol] mode The field's mode. The possible values are
490
+ # `:nullable`, `:required`, and `:repeated`. The default value is
491
+ # `:nullable`.
492
+ #
493
+ # @example
494
+ # require "google/cloud/bigquery"
495
+ #
496
+ # bigquery = Google::Cloud::Bigquery.new
497
+ # dataset = bigquery.dataset "my_dataset"
498
+ # job = dataset.load_job "my_table", "gs://abc/file" do |schema|
499
+ # schema.float "price", mode: :required
500
+ # end
501
+ #
502
+ # @!group Schema
503
+ def float name, description: nil, mode: :nullable
504
+ schema.float name, description: description, mode: mode
505
+ end
506
+
507
+ ##
508
+ # Adds a boolean field to the schema.
509
+ #
510
+ # See {Schema#boolean}.
511
+ #
512
+ # @param [String] name The field name. The name must contain only
513
+ # letters (a-z, A-Z), numbers (0-9), or underscores (_), and must
514
+ # start with a letter or underscore. The maximum length is 128
515
+ # characters.
516
+ # @param [String] description A description of the field.
517
+ # @param [Symbol] mode The field's mode. The possible values are
518
+ # `:nullable`, `:required`, and `:repeated`. The default value is
519
+ # `:nullable`.
520
+ #
521
+ # @example
522
+ # require "google/cloud/bigquery"
523
+ #
524
+ # bigquery = Google::Cloud::Bigquery.new
525
+ # dataset = bigquery.dataset "my_dataset"
526
+ # job = dataset.load_job "my_table", "gs://abc/file" do |schema|
527
+ # schema.boolean "active", mode: :required
528
+ # end
529
+ #
530
+ # @!group Schema
531
+ def boolean name, description: nil, mode: :nullable
532
+ schema.boolean name, description: description, mode: mode
533
+ end
534
+
535
+ ##
536
+ # Adds a bytes field to the schema.
537
+ #
538
+ # See {Schema#bytes}.
539
+ #
540
+ # @param [String] name The field name. The name must contain only
541
+ # letters (a-z, A-Z), numbers (0-9), or underscores (_), and must
542
+ # start with a letter or underscore. The maximum length is 128
543
+ # characters.
544
+ # @param [String] description A description of the field.
545
+ # @param [Symbol] mode The field's mode. The possible values are
546
+ # `:nullable`, `:required`, and `:repeated`. The default value is
547
+ # `:nullable`.
548
+ #
549
+ # @example
550
+ # require "google/cloud/bigquery"
551
+ #
552
+ # bigquery = Google::Cloud::Bigquery.new
553
+ # dataset = bigquery.dataset "my_dataset"
554
+ # job = dataset.load_job "my_table", "gs://abc/file" do |schema|
555
+ # schema.bytes "avatar", mode: :required
556
+ # end
557
+ #
558
+ # @!group Schema
559
+ def bytes name, description: nil, mode: :nullable
560
+ schema.bytes name, description: description, mode: mode
561
+ end
562
+
563
+ ##
564
+ # Adds a timestamp field to the schema.
565
+ #
566
+ # See {Schema#timestamp}.
567
+ #
568
+ # @param [String] name The field name. The name must contain only
569
+ # letters (a-z, A-Z), numbers (0-9), or underscores (_), and must
570
+ # start with a letter or underscore. The maximum length is 128
571
+ # characters.
572
+ # @param [String] description A description of the field.
573
+ # @param [Symbol] mode The field's mode. The possible values are
574
+ # `:nullable`, `:required`, and `:repeated`. The default value is
575
+ # `:nullable`.
576
+ #
577
+ # @example
578
+ # require "google/cloud/bigquery"
579
+ #
580
+ # bigquery = Google::Cloud::Bigquery.new
581
+ # dataset = bigquery.dataset "my_dataset"
582
+ # job = dataset.load_job "my_table", "gs://abc/file" do |schema|
583
+ # schema.timestamp "creation_date", mode: :required
584
+ # end
585
+ #
586
+ # @!group Schema
587
+ def timestamp name, description: nil, mode: :nullable
588
+ schema.timestamp name, description: description, mode: mode
589
+ end
590
+
591
+ ##
592
+ # Adds a time field to the schema.
593
+ #
594
+ # See {Schema#time}.
595
+ #
596
+ # @param [String] name The field name. The name must contain only
597
+ # letters (a-z, A-Z), numbers (0-9), or underscores (_), and must
598
+ # start with a letter or underscore. The maximum length is 128
599
+ # characters.
600
+ # @param [String] description A description of the field.
601
+ # @param [Symbol] mode The field's mode. The possible values are
602
+ # `:nullable`, `:required`, and `:repeated`. The default value is
603
+ # `:nullable`.
604
+ #
605
+ # @example
606
+ # require "google/cloud/bigquery"
607
+ #
608
+ # bigquery = Google::Cloud::Bigquery.new
609
+ # dataset = bigquery.dataset "my_dataset"
610
+ # job = dataset.load_job "my_table", "gs://abc/file" do |schema|
611
+ # schema.time "duration", mode: :required
612
+ # end
613
+ #
614
+ # @!group Schema
615
+ def time name, description: nil, mode: :nullable
616
+ schema.time name, description: description, mode: mode
617
+ end
618
+
619
+ ##
620
+ # Adds a datetime field to the schema.
621
+ #
622
+ # See {Schema#datetime}.
623
+ #
624
+ # @param [String] name The field name. The name must contain only
625
+ # letters (a-z, A-Z), numbers (0-9), or underscores (_), and must
626
+ # start with a letter or underscore. The maximum length is 128
627
+ # characters.
628
+ # @param [String] description A description of the field.
629
+ # @param [Symbol] mode The field's mode. The possible values are
630
+ # `:nullable`, `:required`, and `:repeated`. The default value is
631
+ # `:nullable`.
632
+ #
633
+ # @example
634
+ # require "google/cloud/bigquery"
635
+ #
636
+ # bigquery = Google::Cloud::Bigquery.new
637
+ # dataset = bigquery.dataset "my_dataset"
638
+ # job = dataset.load_job "my_table", "gs://abc/file" do |schema|
639
+ # schema.datetime "target_end", mode: :required
640
+ # end
641
+ #
642
+ # @!group Schema
643
+ def datetime name, description: nil, mode: :nullable
644
+ schema.datetime name, description: description, mode: mode
645
+ end
646
+
647
+ ##
648
+ # Adds a date field to the schema.
649
+ #
650
+ # See {Schema#date}.
651
+ #
652
+ # @param [String] name The field name. The name must contain only
653
+ # letters (a-z, A-Z), numbers (0-9), or underscores (_), and must
654
+ # start with a letter or underscore. The maximum length is 128
655
+ # characters.
656
+ # @param [String] description A description of the field.
657
+ # @param [Symbol] mode The field's mode. The possible values are
658
+ # `:nullable`, `:required`, and `:repeated`. The default value is
659
+ # `:nullable`.
660
+ #
661
+ # @example
662
+ # require "google/cloud/bigquery"
663
+ #
664
+ # bigquery = Google::Cloud::Bigquery.new
665
+ # dataset = bigquery.dataset "my_dataset"
666
+ # job = dataset.load_job "my_table", "gs://abc/file" do |schema|
667
+ # schema.date "birthday", mode: :required
668
+ # end
669
+ #
670
+ # @!group Schema
671
+ def date name, description: nil, mode: :nullable
672
+ schema.date name, description: description, mode: mode
673
+ end
674
+
675
+ ##
676
+ # Adds a record field to the schema. A block must be passed describing
677
+ # the nested fields of the record. For more information about nested
678
+ # and repeated records, see [Preparing Data for BigQuery
679
+ # ](https://cloud.google.com/bigquery/preparing-data-for-bigquery).
680
+ #
681
+ # See {Schema#record}.
682
+ #
683
+ # @param [String] name The field name. The name must contain only
684
+ # letters (a-z, A-Z), numbers (0-9), or underscores (_), and must
685
+ # start with a letter or underscore. The maximum length is 128
686
+ # characters.
687
+ # @param [String] description A description of the field.
688
+ # @param [Symbol] mode The field's mode. The possible values are
689
+ # `:nullable`, `:required`, and `:repeated`. The default value is
690
+ # `:nullable`.
691
+ # @yield [nested_schema] a block for setting the nested schema
692
+ # @yieldparam [Schema] nested_schema the object accepting the
693
+ # nested schema
694
+ #
695
+ # @example
696
+ # require "google/cloud/bigquery"
697
+ #
698
+ # bigquery = Google::Cloud::Bigquery.new
699
+ # dataset = bigquery.dataset "my_dataset"
700
+ # job = dataset.load_job "my_table", "gs://abc/file" do |schema|
701
+ # schema.record "cities_lived", mode: :repeated do |cities_lived|
702
+ # cities_lived.string "place", mode: :required
703
+ # cities_lived.integer "number_of_years", mode: :required
704
+ # end
705
+ # end
706
+ #
707
+ # @!group Schema
708
+ #
709
+ def record name, description: nil, mode: nil, &block
710
+ schema.record name, description: description, mode: mode, &block
711
+ end
712
+
713
+ ##
714
+ # Make sure any access changes are saved
715
+ def check_for_mutated_schema!
716
+ return if @schema.nil?
717
+ return unless @schema.changed?
718
+ @gapi.configuration.load.schema = @schema.to_gapi
719
+ patch_gapi! :schema
720
+ end
721
+
722
+ ##
723
+ # Sets the geographic location where the job should run. Required
724
+ # except for US and EU.
725
+ #
726
+ # @param [String] value A geographic location, such as "US", "EU" or
727
+ # "asia-northeast1". Required except for US and EU.
728
+ #
729
+ # @example
730
+ # require "google/cloud/bigquery"
731
+ #
732
+ # bigquery = Google::Cloud::Bigquery.new
733
+ # dataset = bigquery.dataset "my_dataset"
734
+ # job = dataset.load_job "my_table", "gs://abc/file" do |j|
735
+ # j.schema do |s|
736
+ # s.string "first_name", mode: :required
737
+ # s.record "cities_lived", mode: :repeated do |r|
738
+ # r.string "place", mode: :required
739
+ # r.integer "number_of_years", mode: :required
740
+ # end
741
+ # end
742
+ # j.location = "EU"
743
+ # end
744
+ #
745
+ # @!group Attributes
746
+ def location= value
747
+ @gapi.job_reference.location = value
748
+ end
749
+
750
+ ##
751
+ # Sets the source file format. The default value is `csv`.
752
+ #
753
+ # The following values are supported:
754
+ #
755
+ # * `csv` - CSV
756
+ # * `json` - [Newline-delimited JSON](http://jsonlines.org/)
757
+ # * `avro` - [Avro](http://avro.apache.org/)
758
+ # * `datastore_backup` - Cloud Datastore backup
759
+ #
760
+ # @param [String] new_format The new source format.
761
+ #
762
+ # @!group Attributes
763
+ #
764
+ def format= new_format
765
+ @gapi.configuration.load.update! source_format:
766
+ Convert.source_format(new_format)
767
+ end
768
+
769
+ ##
770
+ # Sets the create disposition.
771
+ #
772
+ # This specifies whether the job is allowed to create new tables. The
773
+ # default value is `needed`.
774
+ #
775
+ # The following values are supported:
776
+ #
777
+ # * `needed` - Create the table if it does not exist.
778
+ # * `never` - The table must already exist. A 'notFound' error is
779
+ # raised if the table does not exist.
780
+ #
781
+ # @param [String] new_create The new create disposition.
782
+ #
783
+ # @!group Attributes
784
+ #
785
+ def create= new_create
786
+ @gapi.configuration.load.update! create_disposition:
787
+ Convert.create_disposition(new_create)
788
+ end
789
+
790
+ ##
791
+ # Sets the write disposition.
792
+ #
793
+ # This specifies how to handle data already present in the table. The
794
+ # default value is `append`.
795
+ #
796
+ # The following values are supported:
797
+ #
798
+ # * `truncate` - BigQuery overwrites the table data.
799
+ # * `append` - BigQuery appends the data to the table.
800
+ # * `empty` - An error will be returned if the table already contains
801
+ # data.
802
+ #
803
+ # @param [String] new_write The new write disposition.
804
+ #
805
+ # @!group Attributes
806
+ #
807
+ def write= new_write
808
+ @gapi.configuration.load.update! write_disposition:
809
+ Convert.write_disposition(new_write)
810
+ end
811
+
812
+ ##
813
+ # Sets the projection fields.
814
+ #
815
+ # If the `format` option is set to `datastore_backup`, indicates
816
+ # which entity properties to load from a Cloud Datastore backup.
817
+ # Property names are case sensitive and must be top-level properties.
818
+ # If not set, BigQuery loads all properties. If any named property
819
+ # isn't found in the Cloud Datastore backup, an invalid error is
820
+ # returned.
821
+ #
822
+ # @param [Array<String>] new_fields The new projection fields.
823
+ #
824
+ # @!group Attributes
825
+ #
826
+ def projection_fields= new_fields
827
+ if new_fields.nil?
828
+ @gapi.configuration.load.update! projection_fields: nil
829
+ else
830
+ @gapi.configuration.load.update! projection_fields:
831
+ Array(new_fields)
832
+ end
833
+ end
834
+
835
+ ##
836
+ # Sets the source URIs to load.
837
+ #
838
+ # The fully-qualified URIs that point to your data in Google Cloud.
839
+ #
840
+ # * For Google Cloud Storage URIs: Each URI can contain one '*'
841
+ # wildcard character and it must come after the 'bucket' name. Size
842
+ # limits related to load jobs apply to external data sources. For
843
+ # * Google Cloud Bigtable URIs: Exactly one URI can be specified and
844
+ # it has be a fully specified and valid HTTPS URL for a Google Cloud
845
+ # Bigtable table.
846
+ # * For Google Cloud Datastore backups: Exactly one URI can be
847
+ # specified. Also, the '*' wildcard character is not allowed.
848
+ #
849
+ # @param [Array<String>] new_uris The new source URIs to load.
850
+ #
851
+ # @!group Attributes
852
+ #
853
+ def source_uris= new_uris
854
+ if new_uris.nil?
855
+ @gapi.configuration.load.update! source_uris: nil
856
+ else
857
+ @gapi.configuration.load.update! source_uris: Array(new_uris)
858
+ end
859
+ end
860
+
861
+ ##
862
+ # Sets flag for allowing jagged rows.
863
+ #
864
+ # Accept rows that are missing trailing optional columns. The missing
865
+ # values are treated as nulls. If `false`, records with missing
866
+ # trailing columns are treated as bad records, and if there are too
867
+ # many bad records, an invalid error is returned in the job result.
868
+ # The default value is `false`. Only applicable to CSV, ignored for
869
+ # other formats.
870
+ #
871
+ # @param [Boolean] val Accept rows that are missing trailing optional
872
+ # columns.
873
+ #
874
+ # @!group Attributes
875
+ #
876
+ def jagged_rows= val
877
+ @gapi.configuration.load.update! allow_jagged_rows: val
878
+ end
879
+
880
+ ##
881
+ # Allows quoted data sections to contain newline characters in CSV.
882
+ #
883
+ # @param [Boolean] val Indicates if BigQuery should allow quoted data
884
+ # sections that contain newline characters in a CSV file. The
885
+ # default value is `false`.
886
+ #
887
+ # @!group Attributes
888
+ #
889
+ def quoted_newlines= val
890
+ @gapi.configuration.load.update! allow_quoted_newlines: val
891
+ end
892
+
893
+ ##
894
+ # Allows BigQuery to autodetect the schema.
895
+ #
896
+ # @param [Boolean] val Indicates if BigQuery should automatically
897
+ # infer the options and schema for CSV and JSON sources. The default
898
+ # value is `false`.
899
+ #
900
+ # @!group Attributes
901
+ #
902
+ def autodetect= val
903
+ @gapi.configuration.load.update! autodetect: val
904
+ end
905
+
906
+ ##
907
+ # Sets the character encoding of the data.
908
+ #
909
+ # @param [String] val The character encoding of the data. The
910
+ # supported values are `UTF-8` or `ISO-8859-1`. The default value
911
+ # is `UTF-8`.
912
+ #
913
+ # @!group Attributes
914
+ #
915
+ def encoding= val
916
+ @gapi.configuration.load.update! encoding: val
917
+ end
918
+
919
+ ##
920
+ # Sets the separator for fields in a CSV file.
921
+ #
922
+ # @param [String] val Specifices the separator for fields in a CSV
923
+ # file. BigQuery converts the string to `ISO-8859-1` encoding, and
924
+ # then uses the first byte of the encoded string to split the data
925
+ # in its raw, binary state. Default is <code>,</code>.
926
+ #
927
+ # @!group Attributes
928
+ #
929
+ def delimiter= val
930
+ @gapi.configuration.load.update! field_delimiter: val
931
+ end
932
+
933
+ ##
934
+ # Allows unknown columns to be ignored.
935
+ #
936
+ # @param [Boolean] val Indicates if BigQuery should allow extra
937
+ # values that are not represented in the table schema. If true, the
938
+ # extra values are ignored. If false, records with extra columns are
939
+ # treated as bad records, and if there are too many bad records, an
940
+ # invalid error is returned in the job result. The default value is
941
+ # `false`.
942
+ #
943
+ # The `format` property determines what BigQuery treats as an extra
944
+ # value:
945
+ #
946
+ # * `CSV`: Trailing columns
947
+ # * `JSON`: Named values that don't match any column names
948
+ #
949
+ # @!group Attributes
950
+ #
951
+ def ignore_unknown= val
952
+ @gapi.configuration.load.update! ignore_unknown_values: val
953
+ end
954
+
955
+ ##
956
+ # Sets the maximum number of bad records that can be ignored.
957
+ #
958
+ # @param [Integer] val The maximum number of bad records that
959
+ # BigQuery can ignore when running the job. If the number of bad
960
+ # records exceeds this value, an invalid error is returned in the
961
+ # job result. The default value is `0`, which requires that all
962
+ # records are valid.
963
+ #
964
+ # @!group Attributes
965
+ #
966
+ def max_bad_records= val
967
+ @gapi.configuration.load.update! max_bad_records: val
968
+ end
969
+
970
+ ##
971
+ # Sets the string that represents a null value in a CSV file.
972
+ #
973
+ # @param [String] val Specifies a string that represents a null value
974
+ # in a CSV file. For example, if you specify `\N`, BigQuery
975
+ # interprets `\N` as a null value when loading a CSV file. The
976
+ # default value is the empty string. If you set this property to a
977
+ # custom value, BigQuery throws an error if an empty string is
978
+ # present for all data types except for STRING and BYTE. For STRING
979
+ # and BYTE columns, BigQuery interprets the empty string as an empty
980
+ # value.
981
+ #
982
+ # @!group Attributes
983
+ #
984
+ def null_marker= val
985
+ @gapi.configuration.load.update! null_marker: val
986
+ end
987
+
988
+ ##
989
+ # Sets the character to use to quote string values in CSVs.
990
+ #
991
+ # @param [String] val The value that is used to quote data sections
992
+ # in a CSV file. BigQuery converts the string to ISO-8859-1
993
+ # encoding, and then uses the first byte of the encoded string to
994
+ # split the data in its raw, binary state. The default value is a
995
+ # double-quote <code>"</code>. If your data does not contain quoted
996
+ # sections, set the property value to an empty string. If your data
997
+ # contains quoted newline characters, you must also set the
998
+ # allowQuotedNewlines property to true.
999
+ #
1000
+ # @!group Attributes
1001
+ #
1002
+ def quote= val
1003
+ @gapi.configuration.load.update! quote: val
1004
+ end
1005
+
1006
+ ##
1007
+ # Sets the number of leading rows to skip in the file.
1008
+ #
1009
+ # @param [Integer] val The number of rows at the top of a CSV file
1010
+ # that BigQuery will skip when loading the data. The default
1011
+ # value is `0`. This property is useful if you have header rows in
1012
+ # the file that should be skipped.
1013
+ #
1014
+ # @!group Attributes
1015
+ #
1016
+ def skip_leading= val
1017
+ @gapi.configuration.load.update! skip_leading_rows: val
1018
+ end
1019
+
1020
+ ##
1021
+ # Sets the encryption configuration of the destination table.
1022
+ #
1023
+ # @param [Google::Cloud::BigQuery::EncryptionConfiguration] val
1024
+ # Custom encryption configuration (e.g., Cloud KMS keys).
1025
+ #
1026
+ # @example
1027
+ # require "google/cloud/bigquery"
1028
+ #
1029
+ # bigquery = Google::Cloud::Bigquery.new
1030
+ # dataset = bigquery.dataset "my_dataset"
1031
+ #
1032
+ # key_name = "projects/a/locations/b/keyRings/c/cryptoKeys/d"
1033
+ # encrypt_config = bigquery.encryption kms_key: key_name
1034
+ # job = dataset.load_job "my_table", "gs://abc/file" do |job|
1035
+ # job.encryption = encrypt_config
1036
+ # end
1037
+ #
1038
+ # @!group Attributes
1039
+ def encryption= val
1040
+ @gapi.configuration.load.update!(
1041
+ destination_encryption_configuration: val.to_gapi
1042
+ )
1043
+ end
1044
+
1045
+ ##
1046
+ # Sets the labels to use for the load job.
1047
+ #
1048
+ # @param [Hash] val A hash of user-provided labels associated with
1049
+ # the job. You can use these to organize and group your jobs. Label
1050
+ # keys and values can be no longer than 63 characters, can only
1051
+ # contain lowercase letters, numeric characters, underscores and
1052
+ # dashes. International characters are allowed. Label values are
1053
+ # optional. Label keys must start with a letter and each label in
1054
+ # the list must have a different key.
1055
+ #
1056
+ # @!group Attributes
1057
+ #
1058
+ def labels= val
1059
+ @gapi.configuration.update! labels: val
1060
+ end
1061
+
1062
+ ##
1063
+ # @private Returns the Google API client library version of this job.
1064
+ #
1065
+ # @return [<Google::Apis::BigqueryV2::Job>] (See
1066
+ # {Google::Apis::BigqueryV2::Job})
1067
+ def to_gapi
1068
+ check_for_mutated_schema!
1069
+ @gapi
1070
+ end
1071
+
1072
+ protected
1073
+
1074
+ ##
1075
+ # Change to a NOOP
1076
+ def ensure_full_data!
1077
+ # Do nothing because we trust the gapi is full before we get here.
1078
+ end
1079
+
1080
+ ##
1081
+ # Queue up all the updates instead of making them.
1082
+ def patch_gapi! attribute
1083
+ @updates << attribute
1084
+ @updates.uniq!
1085
+ end
1086
+ end
317
1087
  end
318
1088
  end
319
1089
  end