google-cloud-bigquery 1.21.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +16 -0
  3. data/AUTHENTICATION.md +158 -0
  4. data/CHANGELOG.md +397 -0
  5. data/CODE_OF_CONDUCT.md +40 -0
  6. data/CONTRIBUTING.md +188 -0
  7. data/LICENSE +201 -0
  8. data/LOGGING.md +27 -0
  9. data/OVERVIEW.md +463 -0
  10. data/TROUBLESHOOTING.md +31 -0
  11. data/lib/google-cloud-bigquery.rb +139 -0
  12. data/lib/google/cloud/bigquery.rb +145 -0
  13. data/lib/google/cloud/bigquery/argument.rb +197 -0
  14. data/lib/google/cloud/bigquery/convert.rb +383 -0
  15. data/lib/google/cloud/bigquery/copy_job.rb +316 -0
  16. data/lib/google/cloud/bigquery/credentials.rb +50 -0
  17. data/lib/google/cloud/bigquery/data.rb +526 -0
  18. data/lib/google/cloud/bigquery/dataset.rb +2845 -0
  19. data/lib/google/cloud/bigquery/dataset/access.rb +1021 -0
  20. data/lib/google/cloud/bigquery/dataset/list.rb +162 -0
  21. data/lib/google/cloud/bigquery/encryption_configuration.rb +123 -0
  22. data/lib/google/cloud/bigquery/external.rb +2432 -0
  23. data/lib/google/cloud/bigquery/extract_job.rb +368 -0
  24. data/lib/google/cloud/bigquery/insert_response.rb +180 -0
  25. data/lib/google/cloud/bigquery/job.rb +657 -0
  26. data/lib/google/cloud/bigquery/job/list.rb +162 -0
  27. data/lib/google/cloud/bigquery/load_job.rb +1704 -0
  28. data/lib/google/cloud/bigquery/model.rb +740 -0
  29. data/lib/google/cloud/bigquery/model/list.rb +164 -0
  30. data/lib/google/cloud/bigquery/project.rb +1655 -0
  31. data/lib/google/cloud/bigquery/project/list.rb +161 -0
  32. data/lib/google/cloud/bigquery/query_job.rb +1695 -0
  33. data/lib/google/cloud/bigquery/routine.rb +1108 -0
  34. data/lib/google/cloud/bigquery/routine/list.rb +165 -0
  35. data/lib/google/cloud/bigquery/schema.rb +564 -0
  36. data/lib/google/cloud/bigquery/schema/field.rb +668 -0
  37. data/lib/google/cloud/bigquery/service.rb +589 -0
  38. data/lib/google/cloud/bigquery/standard_sql.rb +495 -0
  39. data/lib/google/cloud/bigquery/table.rb +3340 -0
  40. data/lib/google/cloud/bigquery/table/async_inserter.rb +520 -0
  41. data/lib/google/cloud/bigquery/table/list.rb +172 -0
  42. data/lib/google/cloud/bigquery/time.rb +65 -0
  43. data/lib/google/cloud/bigquery/version.rb +22 -0
  44. metadata +297 -0
@@ -0,0 +1,383 @@
1
+ # Copyright 2017 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
+
16
+ require "google/apis/bigquery_v2"
17
+ require "stringio"
18
+ require "base64"
19
+ require "bigdecimal"
20
+ require "time"
21
+ require "date"
22
+
23
+ module Google
24
+ module Cloud
25
+ module Bigquery
26
+ # rubocop:disable Metrics/ModuleLength
27
+
28
+ ##
29
+ # @private
30
+ #
31
+ # Internal conversion of raw data values to/from Bigquery values
32
+ #
33
+ # | BigQuery | Ruby | Notes |
34
+ # |-------------|----------------|---|
35
+ # | `BOOL` | `true`/`false` | |
36
+ # | `INT64` | `Integer` | |
37
+ # | `FLOAT64` | `Float` | |
38
+ # | `NUMERIC` | `BigDecimal` | Will be rounded to 9 decimal places |
39
+ # | `STRING` | `String` | |
40
+ # | `DATETIME` | `DateTime` | `DATETIME` does not support time zone. |
41
+ # | `DATE` | `Date` | |
42
+ # | `TIMESTAMP` | `Time` | |
43
+ # | `TIME` | `Google::Cloud::BigQuery::Time` | |
44
+ # | `BYTES` | `File`, `IO`, `StringIO`, or similar | |
45
+ # | `ARRAY` | `Array` | Nested arrays, `nil` values are not supported. |
46
+ # | `STRUCT` | `Hash` | Hash keys may be strings or symbols. |
47
+ module Convert
48
+ ##
49
+ # @private
50
+ def self.format_rows rows, fields
51
+ Array(rows).map do |row|
52
+ # convert TableRow to hash to handle nested TableCell values
53
+ format_row row.to_h, fields
54
+ end
55
+ end
56
+
57
+ ##
58
+ # @private
59
+ def self.format_row row, fields
60
+ row_pairs = fields.zip(row[:f]).map do |f, v|
61
+ [f.name.to_sym, format_value(v, f)]
62
+ end
63
+ Hash[row_pairs]
64
+ end
65
+
66
+ # rubocop:disable all
67
+
68
+ def self.format_value value, field
69
+ if value.nil?
70
+ nil
71
+ elsif value.empty?
72
+ nil
73
+ elsif value[:v].nil?
74
+ nil
75
+ elsif Array === value[:v]
76
+ value[:v].map { |v| format_value v, field }
77
+ elsif Hash === value[:v]
78
+ format_row value[:v], field.fields
79
+ elsif field.type == "STRING"
80
+ String value[:v]
81
+ elsif field.type == "INTEGER"
82
+ Integer value[:v]
83
+ elsif field.type == "FLOAT"
84
+ if value[:v] == "Infinity"
85
+ Float::INFINITY
86
+ elsif value[:v] == "-Infinity"
87
+ -Float::INFINITY
88
+ elsif value[:v] == "NaN"
89
+ Float::NAN
90
+ else
91
+ Float value[:v]
92
+ end
93
+ elsif field.type == "NUMERIC"
94
+ BigDecimal value[:v]
95
+ elsif field.type == "BOOLEAN"
96
+ (value[:v] == "true" ? true : (value[:v] == "false" ? false : nil))
97
+ elsif field.type == "BYTES"
98
+ StringIO.new Base64.decode64 value[:v]
99
+ elsif field.type == "TIMESTAMP"
100
+ ::Time.at Float(value[:v])
101
+ elsif field.type == "TIME"
102
+ Bigquery::Time.new value[:v]
103
+ elsif field.type == "DATETIME"
104
+ ::Time.parse("#{value[:v]} UTC").to_datetime
105
+ elsif field.type == "DATE"
106
+ Date.parse value[:v]
107
+ else
108
+ value[:v]
109
+ end
110
+ end
111
+
112
+ ##
113
+ # @private
114
+ def self.to_query_param param, type = nil
115
+ type ||= default_query_param_type_for param
116
+
117
+ Google::Apis::BigqueryV2::QueryParameter.new(
118
+ parameter_type: to_query_param_type(type),
119
+ parameter_value: to_query_param_value(param)
120
+ )
121
+ end
122
+
123
+ ##
124
+ # @private
125
+ def self.to_query_param_value value
126
+ return Google::Apis::BigqueryV2::QueryParameterValue.new value: nil if value.nil?
127
+
128
+ json_value = to_json_value value
129
+
130
+ if Array === json_value
131
+ array_values = json_value.map { |v| to_query_param_value v }
132
+ Google::Apis::BigqueryV2::QueryParameterValue.new array_values: array_values
133
+ elsif Hash === json_value
134
+ struct_pairs = json_value.map do |key, value|
135
+ [String(key), to_query_param_value(value)]
136
+ end
137
+ struct_values = Hash[struct_pairs]
138
+ Google::Apis::BigqueryV2::QueryParameterValue.new struct_values: struct_values
139
+ else
140
+ # Everything else is converted to a string, per the API expectations.
141
+ Google::Apis::BigqueryV2::QueryParameterValue.new value: json_value.to_s
142
+ end
143
+ end
144
+
145
+ def self.to_query_param_type type
146
+ if Array === type
147
+ Google::Apis::BigqueryV2::QueryParameterType.new(
148
+ type: "ARRAY".freeze,
149
+ array_type: to_query_param_type(type.first)
150
+ )
151
+ elsif Hash === type
152
+ Google::Apis::BigqueryV2::QueryParameterType.new(
153
+ type: "STRUCT".freeze,
154
+ struct_types: type.map do |key, val|
155
+ Google::Apis::BigqueryV2::QueryParameterType::StructType.new(
156
+ name: String(key),
157
+ type: to_query_param_type(val)
158
+ )
159
+ end
160
+ )
161
+ else
162
+ Google::Apis::BigqueryV2::QueryParameterType.new(type: type.to_s.freeze)
163
+ end
164
+ end
165
+
166
+ def self.default_query_param_type_for param
167
+ raise ArgumentError, "nil params are not supported, must assign optional type" if param.nil?
168
+
169
+ case param
170
+ when String
171
+ :STRING
172
+ when Symbol
173
+ :STRING
174
+ when TrueClass
175
+ :BOOL
176
+ when FalseClass
177
+ :BOOL
178
+ when Integer
179
+ :INT64
180
+ when BigDecimal
181
+ :NUMERIC
182
+ when Numeric
183
+ :FLOAT64
184
+ when ::Time
185
+ :TIMESTAMP
186
+ when Bigquery::Time
187
+ :TIME
188
+ when DateTime
189
+ :DATETIME
190
+ when Date
191
+ :DATE
192
+ when Array
193
+ if param.empty?
194
+ raise ArgumentError, "Cannot determine type for empty array values"
195
+ end
196
+ non_nil_values = param.compact.map { |p| default_query_param_type_for p }.compact
197
+ if non_nil_values.empty?
198
+ raise ArgumentError, "Cannot determine type for array of nil values"
199
+ end
200
+ if non_nil_values.uniq.count > 1
201
+ raise ArgumentError, "Cannot determine type for array of different types of values"
202
+ end
203
+ [non_nil_values.first]
204
+ when Hash
205
+ Hash[param.map do |key, value|
206
+ [key, default_query_param_type_for(value)]
207
+ end]
208
+ else
209
+ if param.respond_to?(:read) && param.respond_to?(:rewind)
210
+ :BYTES
211
+ else
212
+ raise "A query parameter of type #{param.class} is not supported"
213
+ end
214
+ end
215
+ end
216
+
217
+ ##
218
+ # @private
219
+ def self.to_json_value value
220
+ if DateTime === value
221
+ value.strftime "%Y-%m-%d %H:%M:%S.%6N"
222
+ elsif Date === value
223
+ value.to_s
224
+ elsif ::Time === value
225
+ value.strftime "%Y-%m-%d %H:%M:%S.%6N%:z"
226
+ elsif Bigquery::Time === value
227
+ value.value
228
+ elsif BigDecimal === value
229
+ # Round to precision of 9
230
+ value.finite? ? value.round(9).to_s("F") : value.to_s
231
+ elsif value.respond_to?(:read) && value.respond_to?(:rewind)
232
+ value.rewind
233
+ Base64.strict_encode64(value.read.force_encoding("ASCII-8BIT"))
234
+ elsif Array === value
235
+ value.map { |v| to_json_value v }
236
+ elsif Hash === value
237
+ Hash[value.map { |k, v| [k.to_s, to_json_value(v)] }]
238
+ else
239
+ value
240
+ end
241
+ end
242
+
243
+ # rubocop:enable all
244
+
245
+ ##
246
+ # @private
247
+ def self.to_json_rows rows
248
+ rows.map { |row| to_json_row row }
249
+ end
250
+
251
+ ##
252
+ # @private
253
+ def self.to_json_row row
254
+ Hash[row.map { |k, v| [k.to_s, to_json_value(v)] }]
255
+ end
256
+
257
+ def self.resolve_legacy_sql standard_sql, legacy_sql
258
+ return !standard_sql unless standard_sql.nil?
259
+ return legacy_sql unless legacy_sql.nil?
260
+ false
261
+ end
262
+
263
+ ##
264
+ # @private
265
+ #
266
+ # Converts create disposition strings to API values.
267
+ #
268
+ # @return [String] API representation of create disposition.
269
+ def self.create_disposition str
270
+ val = {
271
+ "create_if_needed" => "CREATE_IF_NEEDED",
272
+ "createifneeded" => "CREATE_IF_NEEDED",
273
+ "if_needed" => "CREATE_IF_NEEDED",
274
+ "needed" => "CREATE_IF_NEEDED",
275
+ "create_never" => "CREATE_NEVER",
276
+ "createnever" => "CREATE_NEVER",
277
+ "never" => "CREATE_NEVER"
278
+ }[str.to_s.downcase]
279
+ return val unless val.nil?
280
+ str
281
+ end
282
+
283
+ ##
284
+ # @private
285
+ #
286
+ # Converts write disposition strings to API values.
287
+ #
288
+ # @return [String] API representation of write disposition.
289
+ def self.write_disposition str
290
+ val = {
291
+ "write_truncate" => "WRITE_TRUNCATE",
292
+ "writetruncate" => "WRITE_TRUNCATE",
293
+ "truncate" => "WRITE_TRUNCATE",
294
+ "write_append" => "WRITE_APPEND",
295
+ "writeappend" => "WRITE_APPEND",
296
+ "append" => "WRITE_APPEND",
297
+ "write_empty" => "WRITE_EMPTY",
298
+ "writeempty" => "WRITE_EMPTY",
299
+ "empty" => "WRITE_EMPTY"
300
+ }[str.to_s.downcase]
301
+ return val unless val.nil?
302
+ str
303
+ end
304
+
305
+ ##
306
+ # @private
307
+ #
308
+ # Converts source format strings to API values.
309
+ #
310
+ # @return [String] API representation of source format.
311
+ def self.source_format format
312
+ val = {
313
+ "csv" => "CSV",
314
+ "json" => "NEWLINE_DELIMITED_JSON",
315
+ "newline_delimited_json" => "NEWLINE_DELIMITED_JSON",
316
+ "avro" => "AVRO",
317
+ "orc" => "ORC",
318
+ "parquet" => "PARQUET",
319
+ "datastore" => "DATASTORE_BACKUP",
320
+ "backup" => "DATASTORE_BACKUP",
321
+ "datastore_backup" => "DATASTORE_BACKUP"
322
+ }[format.to_s.downcase]
323
+ return val unless val.nil?
324
+ format
325
+ end
326
+
327
+ ##
328
+ # @private
329
+ #
330
+ # Converts file paths into source format by extension.
331
+ #
332
+ # @return [String] API representation of source format.
333
+ def self.derive_source_format_from_list paths
334
+ paths.map do |path|
335
+ derive_source_format path
336
+ end.compact.uniq.first
337
+ end
338
+
339
+ ##
340
+ # @private
341
+ #
342
+ # Converts file path into source format by extension.
343
+ #
344
+ # @return [String] API representation of source format.
345
+ def self.derive_source_format path
346
+ return "CSV" if path.end_with? ".csv"
347
+ return "NEWLINE_DELIMITED_JSON" if path.end_with? ".json"
348
+ return "AVRO" if path.end_with? ".avro"
349
+ return "ORC" if path.end_with? ".orc"
350
+ return "PARQUET" if path.end_with? ".parquet"
351
+ return "DATASTORE_BACKUP" if path.end_with? ".backup_info"
352
+ nil
353
+ end
354
+
355
+ ##
356
+ # @private
357
+ #
358
+ # Converts a primitive time value in milliseconds to a Ruby Time object.
359
+ #
360
+ # @return [Time, nil] The Ruby Time object, or nil if the given argument
361
+ # is nil.
362
+ def self.millis_to_time time_millis
363
+ return nil unless time_millis
364
+ ::Time.at Rational(time_millis, 1000)
365
+ end
366
+
367
+ ##
368
+ # @private
369
+ #
370
+ # Converts a Ruby Time object to a primitive time value in milliseconds.
371
+ #
372
+ # @return [Integer, nil] The primitive time value in milliseconds, or
373
+ # nil if the given argument is nil.
374
+ def self.time_to_millis time_obj
375
+ return nil unless time_obj
376
+ (time_obj.to_i * 1000) + (time_obj.nsec / 1_000_000)
377
+ end
378
+ end
379
+
380
+ # rubocop:enable Metrics/ModuleLength
381
+ end
382
+ end
383
+ end
@@ -0,0 +1,316 @@
1
+ # Copyright 2015 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/cloud/bigquery/encryption_configuration"
16
+
17
+ module Google
18
+ module Cloud
19
+ module Bigquery
20
+ ##
21
+ # # CopyJob
22
+ #
23
+ # A {Job} subclass representing a copy operation that may be performed on
24
+ # a {Table}. A CopyJob instance is created when you call {Table#copy_job}.
25
+ #
26
+ # @see https://cloud.google.com/bigquery/docs/tables#copy-table Copying
27
+ # an Existing Table
28
+ # @see https://cloud.google.com/bigquery/docs/reference/v2/jobs Jobs API
29
+ # reference
30
+ #
31
+ # @example
32
+ # require "google/cloud/bigquery"
33
+ #
34
+ # bigquery = Google::Cloud::Bigquery.new
35
+ # dataset = bigquery.dataset "my_dataset"
36
+ # table = dataset.table "my_table"
37
+ # destination_table = dataset.table "my_destination_table"
38
+ #
39
+ # copy_job = table.copy_job destination_table
40
+ #
41
+ # copy_job.wait_until_done!
42
+ # copy_job.done? #=> true
43
+ #
44
+ class CopyJob < Job
45
+ ##
46
+ # The table from which data is copied. This is the table on
47
+ # which {Table#copy_job} was called.
48
+ #
49
+ # @return [Table] A table instance.
50
+ #
51
+ def source
52
+ table = @gapi.configuration.copy.source_table
53
+ return nil unless table
54
+ retrieve_table table.project_id, table.dataset_id, table.table_id
55
+ end
56
+
57
+ ##
58
+ # The table to which data is copied.
59
+ #
60
+ # @return [Table] A table instance.
61
+ #
62
+ def destination
63
+ table = @gapi.configuration.copy.destination_table
64
+ return nil unless table
65
+ retrieve_table table.project_id, table.dataset_id, table.table_id
66
+ end
67
+
68
+ ##
69
+ # Checks if the create disposition for the job is `CREATE_IF_NEEDED`,
70
+ # which provides the following behavior: If the table does not exist,
71
+ # the copy operation creates the table. This is the default create
72
+ # disposition for copy jobs.
73
+ #
74
+ # @return [Boolean] `true` when `CREATE_IF_NEEDED`, `false` otherwise.
75
+ #
76
+ def create_if_needed?
77
+ disp = @gapi.configuration.copy.create_disposition
78
+ disp == "CREATE_IF_NEEDED"
79
+ end
80
+
81
+ ##
82
+ # Checks if the create disposition for the job is `CREATE_NEVER`, which
83
+ # provides the following behavior: The table must already exist; if it
84
+ # does not, an error is returned in the job result.
85
+ #
86
+ # @return [Boolean] `true` when `CREATE_NEVER`, `false` otherwise.
87
+ #
88
+ def create_never?
89
+ disp = @gapi.configuration.copy.create_disposition
90
+ disp == "CREATE_NEVER"
91
+ end
92
+
93
+ ##
94
+ # Checks if the write disposition for the job is `WRITE_TRUNCATE`, which
95
+ # provides the following behavior: If the table already exists, the copy
96
+ # operation overwrites the table data.
97
+ #
98
+ # @return [Boolean] `true` when `WRITE_TRUNCATE`, `false` otherwise.
99
+ #
100
+ def write_truncate?
101
+ disp = @gapi.configuration.copy.write_disposition
102
+ disp == "WRITE_TRUNCATE"
103
+ end
104
+
105
+ ##
106
+ # Checks if the write disposition for the job is `WRITE_APPEND`, which
107
+ # provides the following behavior: If the table already exists, the copy
108
+ # operation appends the data to the table.
109
+ #
110
+ # @return [Boolean] `true` when `WRITE_APPEND`, `false` otherwise.
111
+ #
112
+ def write_append?
113
+ disp = @gapi.configuration.copy.write_disposition
114
+ disp == "WRITE_APPEND"
115
+ end
116
+
117
+ ##
118
+ # Checks if the write disposition for the job is `WRITE_EMPTY`, which
119
+ # provides the following behavior: If the table already exists and
120
+ # contains data, the job will have an error. This is the default write
121
+ # disposition for copy jobs.
122
+ #
123
+ # @return [Boolean] `true` when `WRITE_EMPTY`, `false` otherwise.
124
+ #
125
+ def write_empty?
126
+ disp = @gapi.configuration.copy.write_disposition
127
+ disp == "WRITE_EMPTY"
128
+ end
129
+
130
+ ##
131
+ # The encryption configuration of the destination table.
132
+ #
133
+ # @return [Google::Cloud::BigQuery::EncryptionConfiguration] Custom
134
+ # encryption configuration (e.g., Cloud KMS keys).
135
+ #
136
+ # @!group Attributes
137
+ def encryption
138
+ EncryptionConfiguration.from_gapi @gapi.configuration.copy.destination_encryption_configuration
139
+ end
140
+
141
+ ##
142
+ # Yielded to a block to accumulate changes for an API request.
143
+ class Updater < CopyJob
144
+ ##
145
+ # @private Create an Updater object.
146
+ def initialize gapi
147
+ @gapi = gapi
148
+ end
149
+
150
+ ##
151
+ # @private Create an Updater from an options hash.
152
+ #
153
+ # @return [Google::Cloud::Bigquery::CopyJob::Updater] A job
154
+ # configuration object for setting copy options.
155
+ def self.from_options service, source, target, options
156
+ job_ref = service.job_ref_from options[:job_id], options[:prefix]
157
+ copy_cfg = Google::Apis::BigqueryV2::JobConfigurationTableCopy.new(
158
+ source_table: source,
159
+ destination_table: target
160
+ )
161
+ req = Google::Apis::BigqueryV2::Job.new(
162
+ job_reference: job_ref,
163
+ configuration: Google::Apis::BigqueryV2::JobConfiguration.new(
164
+ copy: copy_cfg,
165
+ dry_run: options[:dryrun]
166
+ )
167
+ )
168
+
169
+ updater = CopyJob::Updater.new req
170
+ updater.create = options[:create]
171
+ updater.write = options[:write]
172
+ updater.labels = options[:labels] if options[:labels]
173
+ updater
174
+ end
175
+
176
+ ##
177
+ # Sets the geographic location where the job should run. Required
178
+ # except for US and EU.
179
+ #
180
+ # @param [String] value A geographic location, such as "US", "EU" or
181
+ # "asia-northeast1". Required except for US and EU.
182
+ #
183
+ # @example
184
+ # require "google/cloud/bigquery"
185
+ #
186
+ # bigquery = Google::Cloud::Bigquery.new
187
+ # dataset = bigquery.dataset "my_dataset"
188
+ # table = dataset.table "my_table"
189
+ # destination_table = dataset.table "my_destination_table"
190
+ #
191
+ # copy_job = table.copy_job destination_table do |j|
192
+ # j.location = "EU"
193
+ # end
194
+ #
195
+ # copy_job.wait_until_done!
196
+ # copy_job.done? #=> true
197
+ #
198
+ # @!group Attributes
199
+ def location= value
200
+ @gapi.job_reference.location = value
201
+ return unless value.nil?
202
+
203
+ # Treat assigning value of nil the same as unsetting the value.
204
+ unset = @gapi.job_reference.instance_variables.include? :@location
205
+ @gapi.job_reference.remove_instance_variable :@location if unset
206
+ end
207
+
208
+ ##
209
+ # Sets the create disposition.
210
+ #
211
+ # This specifies whether the job is allowed to create new tables. The
212
+ # default value is `needed`.
213
+ #
214
+ # The following values are supported:
215
+ #
216
+ # * `needed` - Create the table if it does not exist.
217
+ # * `never` - The table must already exist. A 'notFound' error is
218
+ # raised if the table does not exist.
219
+ #
220
+ # @param [String] new_create The new create disposition.
221
+ #
222
+ # @!group Attributes
223
+ def create= new_create
224
+ @gapi.configuration.copy.update! create_disposition: Convert.create_disposition(new_create)
225
+ end
226
+
227
+ ##
228
+ # Sets the write disposition.
229
+ #
230
+ # This specifies how to handle data already present in the table. The
231
+ # default value is `append`.
232
+ #
233
+ # The following values are supported:
234
+ #
235
+ # * `truncate` - BigQuery overwrites the table data.
236
+ # * `append` - BigQuery appends the data to the table.
237
+ # * `empty` - An error will be returned if the table already contains
238
+ # data.
239
+ #
240
+ # @param [String] new_write The new write disposition.
241
+ #
242
+ # @!group Attributes
243
+ def write= new_write
244
+ @gapi.configuration.copy.update! write_disposition: Convert.write_disposition(new_write)
245
+ end
246
+
247
+ ##
248
+ # Sets the encryption configuration of the destination table.
249
+ #
250
+ # @param [Google::Cloud::BigQuery::EncryptionConfiguration] val
251
+ # Custom encryption configuration (e.g., Cloud KMS keys).
252
+ #
253
+ # @example
254
+ # require "google/cloud/bigquery"
255
+ #
256
+ # bigquery = Google::Cloud::Bigquery.new
257
+ # dataset = bigquery.dataset "my_dataset"
258
+ # table = dataset.table "my_table"
259
+ #
260
+ # key_name = "projects/a/locations/b/keyRings/c/cryptoKeys/d"
261
+ # encrypt_config = bigquery.encryption kms_key: key_name
262
+ # job = table.copy_job "my_dataset.new_table" do |job|
263
+ # job.encryption = encrypt_config
264
+ # end
265
+ #
266
+ # @!group Attributes
267
+ def encryption= val
268
+ @gapi.configuration.copy.update! destination_encryption_configuration: val.to_gapi
269
+ end
270
+
271
+ ##
272
+ # Sets the labels to use for the job.
273
+ #
274
+ # @param [Hash] value A hash of user-provided labels associated with
275
+ # the job. You can use these to organize and group your jobs. Label
276
+ # keys and values can be no longer than 63 characters, can only
277
+ # contain lowercase letters, numeric characters, underscores and
278
+ # dashes. International characters are allowed. Label values are
279
+ # optional. Label keys must start with a letter and each label in
280
+ # the list must have a different key.
281
+ #
282
+ # @!group Attributes
283
+ def labels= value
284
+ @gapi.configuration.update! labels: value
285
+ end
286
+
287
+ def cancel
288
+ raise "not implemented in #{self.class}"
289
+ end
290
+
291
+ def rerun!
292
+ raise "not implemented in #{self.class}"
293
+ end
294
+
295
+ def reload!
296
+ raise "not implemented in #{self.class}"
297
+ end
298
+ alias refresh! reload!
299
+
300
+ def wait_until_done!
301
+ raise "not implemented in #{self.class}"
302
+ end
303
+
304
+ ##
305
+ # @private Returns the Google API client library version of this job.
306
+ #
307
+ # @return [<Google::Apis::BigqueryV2::Job>] (See
308
+ # {Google::Apis::BigqueryV2::Job})
309
+ def to_gapi
310
+ @gapi
311
+ end
312
+ end
313
+ end
314
+ end
315
+ end
316
+ end