google-cloud-bigquery 1.1.0 → 1.2.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.
@@ -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