google-cloud-bigquery 1.18.1 → 1.19.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +15 -0
- data/lib/google/cloud/bigquery/argument.rb +197 -0
- data/lib/google/cloud/bigquery/copy_job.rb +18 -1
- data/lib/google/cloud/bigquery/data.rb +15 -0
- data/lib/google/cloud/bigquery/dataset.rb +321 -41
- data/lib/google/cloud/bigquery/dataset/list.rb +1 -2
- data/lib/google/cloud/bigquery/extract_job.rb +19 -2
- data/lib/google/cloud/bigquery/job/list.rb +5 -5
- data/lib/google/cloud/bigquery/load_job.rb +17 -0
- data/lib/google/cloud/bigquery/model.rb +6 -4
- data/lib/google/cloud/bigquery/project.rb +4 -6
- data/lib/google/cloud/bigquery/project/list.rb +1 -2
- data/lib/google/cloud/bigquery/query_job.rb +33 -0
- data/lib/google/cloud/bigquery/routine.rb +1108 -0
- data/lib/google/cloud/bigquery/routine/list.rb +165 -0
- data/lib/google/cloud/bigquery/service.rb +93 -38
- data/lib/google/cloud/bigquery/standard_sql.rb +257 -53
- data/lib/google/cloud/bigquery/table.rb +109 -16
- data/lib/google/cloud/bigquery/table/async_inserter.rb +18 -8
- data/lib/google/cloud/bigquery/table/list.rb +1 -2
- data/lib/google/cloud/bigquery/version.rb +1 -1
- metadata +5 -2
@@ -0,0 +1,165 @@
|
|
1
|
+
# Copyright 2020 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 "delegate"
|
17
|
+
|
18
|
+
module Google
|
19
|
+
module Cloud
|
20
|
+
module Bigquery
|
21
|
+
class Routine
|
22
|
+
##
|
23
|
+
# Routine::List is a special case Array with additional values.
|
24
|
+
class List < DelegateClass(::Array)
|
25
|
+
##
|
26
|
+
# If not empty, indicates that there are more records that match
|
27
|
+
# the request and this value should be passed to continue.
|
28
|
+
attr_accessor :token
|
29
|
+
|
30
|
+
##
|
31
|
+
# @private Create a new Routine::List with an array of routines.
|
32
|
+
def initialize arr = []
|
33
|
+
super arr
|
34
|
+
end
|
35
|
+
|
36
|
+
##
|
37
|
+
# Whether there is a next page of routines.
|
38
|
+
#
|
39
|
+
# @return [Boolean]
|
40
|
+
#
|
41
|
+
# @example
|
42
|
+
# require "google/cloud/bigquery"
|
43
|
+
#
|
44
|
+
# bigquery = Google::Cloud::Bigquery.new
|
45
|
+
# dataset = bigquery.dataset "my_dataset"
|
46
|
+
#
|
47
|
+
# routines = dataset.routines
|
48
|
+
# if routines.next?
|
49
|
+
# next_routines = routines.next
|
50
|
+
# end
|
51
|
+
#
|
52
|
+
def next?
|
53
|
+
!token.nil?
|
54
|
+
end
|
55
|
+
|
56
|
+
##
|
57
|
+
# Retrieve the next page of routines.
|
58
|
+
#
|
59
|
+
# @return [Routine::List]
|
60
|
+
#
|
61
|
+
# @example
|
62
|
+
# require "google/cloud/bigquery"
|
63
|
+
#
|
64
|
+
# bigquery = Google::Cloud::Bigquery.new
|
65
|
+
# dataset = bigquery.dataset "my_dataset"
|
66
|
+
#
|
67
|
+
# routines = dataset.routines
|
68
|
+
# if routines.next?
|
69
|
+
# next_routines = routines.next
|
70
|
+
# end
|
71
|
+
#
|
72
|
+
def next
|
73
|
+
return nil unless next?
|
74
|
+
ensure_service!
|
75
|
+
gapi = @service.list_routines @dataset_id, token: token, max: @max, filter: @filter
|
76
|
+
self.class.from_gapi gapi, @service, @dataset_id, @max, filter: @filter
|
77
|
+
end
|
78
|
+
|
79
|
+
##
|
80
|
+
# Retrieves remaining results by repeatedly invoking {#next} until
|
81
|
+
# {#next?} returns `false`. Calls the given block once for each
|
82
|
+
# result, which is passed as the argument to the block.
|
83
|
+
#
|
84
|
+
# An Enumerator is returned if no block is given.
|
85
|
+
#
|
86
|
+
# This method will make repeated API calls until all remaining results
|
87
|
+
# are retrieved. (Unlike `#each`, for example, which merely iterates
|
88
|
+
# over the results returned by a single API call.) Use with caution.
|
89
|
+
#
|
90
|
+
# @param [Integer] request_limit The upper limit of API requests to
|
91
|
+
# make to load all routines. Default is no limit.
|
92
|
+
# @yield [routine] The block for accessing each routine.
|
93
|
+
# @yieldparam [Routine] routine The routine object.
|
94
|
+
#
|
95
|
+
# @return [Enumerator]
|
96
|
+
#
|
97
|
+
# @example Iterating each result by passing a block:
|
98
|
+
# require "google/cloud/bigquery"
|
99
|
+
#
|
100
|
+
# bigquery = Google::Cloud::Bigquery.new
|
101
|
+
# dataset = bigquery.dataset "my_dataset"
|
102
|
+
#
|
103
|
+
# dataset.routines.all do |routine|
|
104
|
+
# puts routine.routine_id
|
105
|
+
# end
|
106
|
+
#
|
107
|
+
# @example Using the enumerator by not passing a block:
|
108
|
+
# require "google/cloud/bigquery"
|
109
|
+
#
|
110
|
+
# bigquery = Google::Cloud::Bigquery.new
|
111
|
+
# dataset = bigquery.dataset "my_dataset"
|
112
|
+
#
|
113
|
+
# all_names = dataset.routines.all.map do |routine|
|
114
|
+
# routine.routine_id
|
115
|
+
# end
|
116
|
+
#
|
117
|
+
# @example Limit the number of API requests made:
|
118
|
+
# require "google/cloud/bigquery"
|
119
|
+
#
|
120
|
+
# bigquery = Google::Cloud::Bigquery.new
|
121
|
+
# dataset = bigquery.dataset "my_dataset"
|
122
|
+
#
|
123
|
+
# dataset.routines.all(request_limit: 10) do |routine|
|
124
|
+
# puts routine.routine_id
|
125
|
+
# end
|
126
|
+
#
|
127
|
+
def all request_limit: nil
|
128
|
+
request_limit = request_limit.to_i if request_limit
|
129
|
+
return enum_for :all, request_limit: request_limit unless block_given?
|
130
|
+
results = self
|
131
|
+
loop do
|
132
|
+
results.each { |r| yield r }
|
133
|
+
if request_limit
|
134
|
+
request_limit -= 1
|
135
|
+
break if request_limit.negative?
|
136
|
+
end
|
137
|
+
break unless results.next?
|
138
|
+
results = results.next
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
##
|
143
|
+
# @private New Routine::List from a response object.
|
144
|
+
def self.from_gapi gapi_list, service, dataset_id = nil, max = nil, filter: nil
|
145
|
+
routines = List.new(Array(gapi_list.routines).map { |gapi| Routine.from_gapi gapi, service })
|
146
|
+
routines.instance_variable_set :@token, gapi_list.next_page_token
|
147
|
+
routines.instance_variable_set :@service, service
|
148
|
+
routines.instance_variable_set :@dataset_id, dataset_id
|
149
|
+
routines.instance_variable_set :@max, max
|
150
|
+
routines.instance_variable_set :@filter, filter
|
151
|
+
routines
|
152
|
+
end
|
153
|
+
|
154
|
+
protected
|
155
|
+
|
156
|
+
##
|
157
|
+
# Raise an error unless an active service is available.
|
158
|
+
def ensure_service!
|
159
|
+
raise "Must have active connection" unless @service
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
@@ -78,12 +78,10 @@ module Google
|
|
78
78
|
##
|
79
79
|
# Lists all datasets in the specified project to which you have
|
80
80
|
# been granted the READER dataset role.
|
81
|
-
def list_datasets
|
81
|
+
def list_datasets all: nil, filter: nil, max: nil, token: nil
|
82
82
|
# The list operation is considered idempotent
|
83
83
|
execute backoff: true do
|
84
|
-
service.list_datasets
|
85
|
-
@project, all: options[:all], filter: options[:filter],
|
86
|
-
max_results: options[:max], page_token: options[:token]
|
84
|
+
service.list_datasets @project, all: all, filter: filter, max_results: max, page_token: token
|
87
85
|
end
|
88
86
|
end
|
89
87
|
|
@@ -133,10 +131,10 @@ module Google
|
|
133
131
|
##
|
134
132
|
# Lists all tables in the specified dataset.
|
135
133
|
# Requires the READER dataset role.
|
136
|
-
def list_tables dataset_id,
|
134
|
+
def list_tables dataset_id, max: nil, token: nil
|
137
135
|
# The list operation is considered idempotent
|
138
136
|
execute backoff: true do
|
139
|
-
service.list_tables @project, dataset_id, max_results:
|
137
|
+
service.list_tables @project, dataset_id, max_results: max, page_token: token
|
140
138
|
end
|
141
139
|
end
|
142
140
|
|
@@ -190,38 +188,45 @@ module Google
|
|
190
188
|
|
191
189
|
##
|
192
190
|
# Retrieves data from the table.
|
193
|
-
def list_tabledata dataset_id, table_id,
|
191
|
+
def list_tabledata dataset_id, table_id, max: nil, token: nil, start: nil
|
194
192
|
# The list operation is considered idempotent
|
195
193
|
execute backoff: true do
|
196
194
|
json_txt = service.list_table_data \
|
197
195
|
@project, dataset_id, table_id,
|
198
|
-
max_results:
|
199
|
-
page_token:
|
200
|
-
start_index:
|
196
|
+
max_results: max,
|
197
|
+
page_token: token,
|
198
|
+
start_index: start,
|
201
199
|
options: { skip_deserialization: true }
|
202
200
|
JSON.parse json_txt, symbolize_names: true
|
203
201
|
end
|
204
202
|
end
|
205
203
|
|
206
|
-
def insert_tabledata dataset_id, table_id, rows,
|
204
|
+
def insert_tabledata dataset_id, table_id, rows, insert_ids: nil, ignore_unknown: nil, skip_invalid: nil
|
207
205
|
json_rows = Array(rows).map { |row| Convert.to_json_row row }
|
208
|
-
insert_tabledata_json_rows dataset_id, table_id, json_rows,
|
206
|
+
insert_tabledata_json_rows dataset_id, table_id, json_rows, insert_ids: insert_ids,
|
207
|
+
ignore_unknown: ignore_unknown,
|
208
|
+
skip_invalid: skip_invalid
|
209
209
|
end
|
210
210
|
|
211
|
-
def insert_tabledata_json_rows dataset_id, table_id, json_rows,
|
212
|
-
|
211
|
+
def insert_tabledata_json_rows dataset_id, table_id, json_rows, insert_ids: nil, ignore_unknown: nil,
|
212
|
+
skip_invalid: nil
|
213
|
+
rows_and_ids = Array(json_rows).zip Array(insert_ids)
|
213
214
|
insert_rows = rows_and_ids.map do |json_row, insert_id|
|
214
|
-
insert_id
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
215
|
+
if insert_id == :skip
|
216
|
+
{ json: json_row }
|
217
|
+
else
|
218
|
+
insert_id ||= SecureRandom.uuid
|
219
|
+
{
|
220
|
+
insertId: insert_id,
|
221
|
+
json: json_row
|
222
|
+
}
|
223
|
+
end
|
219
224
|
end
|
220
225
|
|
221
226
|
insert_req = {
|
222
227
|
rows: insert_rows,
|
223
|
-
ignoreUnknownValues:
|
224
|
-
skipInvalidRows:
|
228
|
+
ignoreUnknownValues: ignore_unknown,
|
229
|
+
skipInvalidRows: skip_invalid
|
225
230
|
}.to_json
|
226
231
|
|
227
232
|
# The insertAll with insertId operation is considered idempotent
|
@@ -281,16 +286,66 @@ module Google
|
|
281
286
|
execute { service.delete_model @project, dataset_id, model_id }
|
282
287
|
end
|
283
288
|
|
289
|
+
##
|
290
|
+
# Creates a new routine in the dataset.
|
291
|
+
def insert_routine dataset_id, new_routine_gapi
|
292
|
+
execute { service.insert_routine @project, dataset_id, new_routine_gapi }
|
293
|
+
end
|
294
|
+
|
295
|
+
##
|
296
|
+
# Lists all routines in the specified dataset.
|
297
|
+
# Requires the READER dataset role.
|
298
|
+
# Unless readMask is set in the request, only the following fields are populated:
|
299
|
+
# etag, projectId, datasetId, routineId, routineType, creationTime, lastModifiedTime, and language.
|
300
|
+
def list_routines dataset_id, max: nil, token: nil, filter: nil
|
301
|
+
# The list operation is considered idempotent
|
302
|
+
execute backoff: true do
|
303
|
+
service.list_routines @project, dataset_id, max_results: max,
|
304
|
+
page_token: token,
|
305
|
+
filter: filter
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
##
|
310
|
+
# Gets the specified routine resource by routine ID.
|
311
|
+
def get_routine dataset_id, routine_id
|
312
|
+
# The get operation is considered idempotent
|
313
|
+
execute backoff: true do
|
314
|
+
service.get_routine @project, dataset_id, routine_id
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
##
|
319
|
+
# Updates information in an existing routine, replacing the entire routine resource.
|
320
|
+
def update_routine dataset_id, routine_id, new_routine_gapi
|
321
|
+
update_with_backoff = false
|
322
|
+
options = {}
|
323
|
+
if new_routine_gapi.etag
|
324
|
+
options[:header] = { "If-Match" => new_routine_gapi.etag }
|
325
|
+
# The update with etag operation is considered idempotent
|
326
|
+
update_with_backoff = true
|
327
|
+
end
|
328
|
+
execute backoff: update_with_backoff do
|
329
|
+
service.update_routine @project, dataset_id, routine_id, new_routine_gapi, options: options
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
##
|
334
|
+
# Deletes the routine specified by routine_id from the dataset.
|
335
|
+
def delete_routine dataset_id, routine_id
|
336
|
+
execute { service.delete_routine @project, dataset_id, routine_id }
|
337
|
+
end
|
338
|
+
|
284
339
|
##
|
285
340
|
# Lists all jobs in the specified project to which you have
|
286
341
|
# been granted the READER job role.
|
287
|
-
def list_jobs
|
342
|
+
def list_jobs all: nil, max: nil, token: nil, filter: nil, min_created_at: nil, max_created_at: nil
|
288
343
|
# The list operation is considered idempotent
|
289
|
-
min_creation_time = Convert.time_to_millis
|
290
|
-
max_creation_time = Convert.time_to_millis
|
344
|
+
min_creation_time = Convert.time_to_millis min_created_at
|
345
|
+
max_creation_time = Convert.time_to_millis max_created_at
|
291
346
|
execute backoff: true do
|
292
|
-
service.list_jobs @project, all_users:
|
293
|
-
page_token:
|
347
|
+
service.list_jobs @project, all_users: all, max_results: max,
|
348
|
+
page_token: token, projection: "full", state_filter: filter,
|
294
349
|
min_creation_time: min_creation_time, max_creation_time: max_creation_time
|
295
350
|
end
|
296
351
|
end
|
@@ -329,15 +384,15 @@ module Google
|
|
329
384
|
|
330
385
|
##
|
331
386
|
# Returns the query data for the job
|
332
|
-
def job_query_results job_id,
|
387
|
+
def job_query_results job_id, location: nil, max: nil, token: nil, start: nil, timeout: nil
|
333
388
|
# The get operation is considered idempotent
|
334
389
|
execute backoff: true do
|
335
390
|
service.get_job_query_results @project, job_id,
|
336
|
-
location:
|
337
|
-
max_results:
|
338
|
-
page_token:
|
339
|
-
start_index:
|
340
|
-
timeout_ms:
|
391
|
+
location: location,
|
392
|
+
max_results: max,
|
393
|
+
page_token: token,
|
394
|
+
start_index: start,
|
395
|
+
timeout_ms: timeout
|
341
396
|
end
|
342
397
|
end
|
343
398
|
|
@@ -405,9 +460,9 @@ module Google
|
|
405
460
|
|
406
461
|
##
|
407
462
|
# Lists all projects to which you have been granted any project role.
|
408
|
-
def list_projects
|
463
|
+
def list_projects max: nil, token: nil
|
409
464
|
execute backoff: true do
|
410
|
-
service.list_projects max_results:
|
465
|
+
service.list_projects max_results: max, page_token: token
|
411
466
|
end
|
412
467
|
end
|
413
468
|
|
@@ -485,10 +540,10 @@ module Google
|
|
485
540
|
sleep delay
|
486
541
|
end
|
487
542
|
|
488
|
-
def initialize
|
489
|
-
@retries = (
|
490
|
-
@reasons = (
|
491
|
-
@backoff =
|
543
|
+
def initialize retries: nil, reasons: nil, backoff: nil
|
544
|
+
@retries = (retries || Backoff.retries).to_i
|
545
|
+
@reasons = (reasons || Backoff.reasons).to_a
|
546
|
+
@backoff = backoff || Backoff.backoff
|
492
547
|
end
|
493
548
|
|
494
549
|
def execute
|
@@ -18,89 +18,226 @@ module Google
|
|
18
18
|
module Bigquery
|
19
19
|
##
|
20
20
|
# BigQuery standard SQL is compliant with the SQL 2011 standard and has
|
21
|
-
# extensions that support querying nested and repeated data.
|
21
|
+
# extensions that support querying nested and repeated data. See {Routine} and {Argument}.
|
22
|
+
#
|
23
|
+
# @example
|
24
|
+
# require "google/cloud/bigquery"
|
25
|
+
#
|
26
|
+
# bigquery = Google::Cloud::Bigquery.new
|
27
|
+
# dataset = bigquery.dataset "my_dataset"
|
28
|
+
# routine = dataset.create_routine "my_routine" do |r|
|
29
|
+
# r.routine_type = "SCALAR_FUNCTION"
|
30
|
+
# r.language = :SQL
|
31
|
+
# r.body = "(SELECT SUM(IF(elem.name = \"foo\",elem.val,null)) FROM UNNEST(arr) AS elem)"
|
32
|
+
# r.arguments = [
|
33
|
+
# Google::Cloud::Bigquery::Argument.new(
|
34
|
+
# name: "arr",
|
35
|
+
# argument_kind: "FIXED_TYPE",
|
36
|
+
# data_type: Google::Cloud::Bigquery::StandardSql::DataType.new(
|
37
|
+
# type_kind: "ARRAY",
|
38
|
+
# array_element_type: Google::Cloud::Bigquery::StandardSql::DataType.new(
|
39
|
+
# type_kind: "STRUCT",
|
40
|
+
# struct_type: Google::Cloud::Bigquery::StandardSql::StructType.new(
|
41
|
+
# fields: [
|
42
|
+
# Google::Cloud::Bigquery::StandardSql::Field.new(
|
43
|
+
# name: "name",
|
44
|
+
# type: Google::Cloud::Bigquery::StandardSql::DataType.new(type_kind: "STRING")
|
45
|
+
# ),
|
46
|
+
# Google::Cloud::Bigquery::StandardSql::Field.new(
|
47
|
+
# name: "val",
|
48
|
+
# type: Google::Cloud::Bigquery::StandardSql::DataType.new(type_kind: "INT64")
|
49
|
+
# )
|
50
|
+
# ]
|
51
|
+
# )
|
52
|
+
# )
|
53
|
+
# )
|
54
|
+
# )
|
55
|
+
# ]
|
56
|
+
# end
|
57
|
+
#
|
22
58
|
module StandardSql
|
23
59
|
##
|
24
|
-
# A field or a column.
|
60
|
+
# A field or a column. See {Routine} and {Argument}.
|
61
|
+
#
|
62
|
+
# @example
|
63
|
+
# require "google/cloud/bigquery"
|
64
|
+
#
|
65
|
+
# bigquery = Google::Cloud::Bigquery.new
|
66
|
+
# dataset = bigquery.dataset "my_dataset"
|
67
|
+
# routine = dataset.create_routine "my_routine" do |r|
|
68
|
+
# r.routine_type = "SCALAR_FUNCTION"
|
69
|
+
# r.language = :SQL
|
70
|
+
# r.body = "(SELECT SUM(IF(elem.name = \"foo\",elem.val,null)) FROM UNNEST(arr) AS elem)"
|
71
|
+
# r.arguments = [
|
72
|
+
# Google::Cloud::Bigquery::Argument.new(
|
73
|
+
# name: "arr",
|
74
|
+
# argument_kind: "FIXED_TYPE",
|
75
|
+
# data_type: Google::Cloud::Bigquery::StandardSql::DataType.new(
|
76
|
+
# type_kind: "ARRAY",
|
77
|
+
# array_element_type: Google::Cloud::Bigquery::StandardSql::DataType.new(
|
78
|
+
# type_kind: "STRUCT",
|
79
|
+
# struct_type: Google::Cloud::Bigquery::StandardSql::StructType.new(
|
80
|
+
# fields: [
|
81
|
+
# Google::Cloud::Bigquery::StandardSql::Field.new(
|
82
|
+
# name: "name",
|
83
|
+
# type: Google::Cloud::Bigquery::StandardSql::DataType.new(type_kind: "STRING")
|
84
|
+
# ),
|
85
|
+
# Google::Cloud::Bigquery::StandardSql::Field.new(
|
86
|
+
# name: "val",
|
87
|
+
# type: Google::Cloud::Bigquery::StandardSql::DataType.new(type_kind: "INT64")
|
88
|
+
# )
|
89
|
+
# ]
|
90
|
+
# )
|
91
|
+
# )
|
92
|
+
# )
|
93
|
+
# )
|
94
|
+
# ]
|
95
|
+
# end
|
96
|
+
#
|
25
97
|
class Field
|
26
98
|
##
|
27
|
-
#
|
28
|
-
|
29
|
-
|
99
|
+
# Creates a new, immutable StandardSql::Field object.
|
100
|
+
#
|
101
|
+
# @overload initialize(name, type)
|
102
|
+
# @param [String] name The name of the field. Optional. Can be absent for struct fields.
|
103
|
+
# @param [StandardSql::DataType, String] type The type of the field. Optional. Absent if not explicitly
|
104
|
+
# specified (e.g., `CREATE FUNCTION` statement can omit the return type; in this case the output parameter
|
105
|
+
# does not have this "type" field).
|
106
|
+
#
|
107
|
+
def initialize **kwargs
|
108
|
+
# Convert client object kwargs to a gapi object
|
109
|
+
kwargs[:type] = DataType.gapi_from_string_or_data_type kwargs[:type] if kwargs[:type]
|
110
|
+
@gapi = Google::Apis::BigqueryV2::StandardSqlField.new(**kwargs)
|
30
111
|
end
|
31
112
|
|
32
113
|
##
|
33
|
-
# The name of the field.
|
114
|
+
# The name of the field. Optional. Can be absent for struct fields.
|
34
115
|
#
|
35
116
|
# @return [String, nil]
|
36
117
|
#
|
37
118
|
def name
|
38
|
-
return
|
39
|
-
|
40
|
-
@gapi_json[:name]
|
119
|
+
return if @gapi.name == "".freeze
|
120
|
+
@gapi.name
|
41
121
|
end
|
42
122
|
|
43
123
|
##
|
44
|
-
# The type of the field.
|
124
|
+
# The type of the field. Optional. Absent if not explicitly specified (e.g., `CREATE FUNCTION` statement can
|
125
|
+
# omit the return type; in this case the output parameter does not have this "type" field).
|
45
126
|
#
|
46
|
-
# @return [DataType]
|
127
|
+
# @return [DataType, nil] The type of the field.
|
47
128
|
#
|
48
129
|
def type
|
49
|
-
DataType.
|
130
|
+
DataType.from_gapi @gapi.type if @gapi.type
|
131
|
+
end
|
132
|
+
|
133
|
+
##
|
134
|
+
# @private New Google::Apis::BigqueryV2::StandardSqlField object.
|
135
|
+
def to_gapi
|
136
|
+
@gapi
|
50
137
|
end
|
51
138
|
|
52
139
|
##
|
53
|
-
# @private New StandardSql::Field from a
|
54
|
-
def self.
|
140
|
+
# @private New StandardSql::Field from a Google::Apis::BigqueryV2::StandardSqlField object.
|
141
|
+
def self.from_gapi gapi
|
55
142
|
new.tap do |f|
|
56
|
-
f.instance_variable_set :@
|
143
|
+
f.instance_variable_set :@gapi, gapi
|
57
144
|
end
|
58
145
|
end
|
59
146
|
end
|
60
147
|
|
61
148
|
##
|
62
|
-
# The type of a
|
149
|
+
# The type of a variable, e.g., a function argument. See {Routine} and {Argument}.
|
150
|
+
#
|
151
|
+
# @example
|
152
|
+
# require "google/cloud/bigquery"
|
153
|
+
#
|
154
|
+
# bigquery = Google::Cloud::Bigquery.new
|
155
|
+
# dataset = bigquery.dataset "my_dataset"
|
156
|
+
# routine = dataset.create_routine "my_routine" do |r|
|
157
|
+
# r.routine_type = "SCALAR_FUNCTION"
|
158
|
+
# r.language = :SQL
|
159
|
+
# r.body = "(SELECT SUM(IF(elem.name = \"foo\",elem.val,null)) FROM UNNEST(arr) AS elem)"
|
160
|
+
# r.arguments = [
|
161
|
+
# Google::Cloud::Bigquery::Argument.new(
|
162
|
+
# name: "arr",
|
163
|
+
# argument_kind: "FIXED_TYPE",
|
164
|
+
# data_type: Google::Cloud::Bigquery::StandardSql::DataType.new(
|
165
|
+
# type_kind: "ARRAY",
|
166
|
+
# array_element_type: Google::Cloud::Bigquery::StandardSql::DataType.new(
|
167
|
+
# type_kind: "STRUCT",
|
168
|
+
# struct_type: Google::Cloud::Bigquery::StandardSql::StructType.new(
|
169
|
+
# fields: [
|
170
|
+
# Google::Cloud::Bigquery::StandardSql::Field.new(
|
171
|
+
# name: "name",
|
172
|
+
# type: Google::Cloud::Bigquery::StandardSql::DataType.new(type_kind: "STRING")
|
173
|
+
# ),
|
174
|
+
# Google::Cloud::Bigquery::StandardSql::Field.new(
|
175
|
+
# name: "val",
|
176
|
+
# type: Google::Cloud::Bigquery::StandardSql::DataType.new(type_kind: "INT64")
|
177
|
+
# )
|
178
|
+
# ]
|
179
|
+
# )
|
180
|
+
# )
|
181
|
+
# )
|
182
|
+
# )
|
183
|
+
# ]
|
184
|
+
# end
|
185
|
+
#
|
186
|
+
# @see https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types Standard SQL Data Types
|
187
|
+
#
|
63
188
|
class DataType
|
64
189
|
##
|
65
|
-
#
|
66
|
-
|
67
|
-
|
190
|
+
# Creates a new, immutable StandardSql::DataType object.
|
191
|
+
#
|
192
|
+
# @overload initialize(type_kind, array_element_type, struct_type)
|
193
|
+
# @param [String] type_kind The top level type of this field. Required. Can be [any standard SQL data
|
194
|
+
# type](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types) (e.g., `INT64`, `DATE`,
|
195
|
+
# `ARRAY`).
|
196
|
+
# @param [DataType, String] array_element_type The type of the array's elements, if {#type_kind} is `ARRAY`.
|
197
|
+
# See {#array?}. Optional.
|
198
|
+
# @param [StructType] struct_type The fields of the struct, in order, if {#type_kind} is `STRUCT`. See
|
199
|
+
# {#struct?}. Optional.
|
200
|
+
#
|
201
|
+
def initialize **kwargs
|
202
|
+
# Convert client object kwargs to a gapi object
|
203
|
+
if kwargs[:array_element_type]
|
204
|
+
kwargs[:array_element_type] = self.class.gapi_from_string_or_data_type kwargs[:array_element_type]
|
205
|
+
end
|
206
|
+
kwargs[:struct_type] = kwargs[:struct_type].to_gapi if kwargs[:struct_type]
|
207
|
+
|
208
|
+
@gapi = Google::Apis::BigqueryV2::StandardSqlDataType.new(**kwargs)
|
68
209
|
end
|
69
210
|
|
70
211
|
##
|
71
|
-
# The top level type of this field.
|
72
|
-
#
|
73
|
-
# Can be any standard SQL data type (e.g., "INT64", "DATE", "ARRAY").
|
212
|
+
# The top level type of this field. Required. Can be any standard SQL data type (e.g., `INT64`, `DATE`,
|
213
|
+
# `ARRAY`).
|
74
214
|
#
|
75
|
-
# @see https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types
|
76
|
-
# Standard SQL Data Types
|
215
|
+
# @see https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types Standard SQL Data Types
|
77
216
|
#
|
78
|
-
# @return [String]
|
217
|
+
# @return [String] The upper case type.
|
79
218
|
#
|
80
219
|
def type_kind
|
81
|
-
@
|
220
|
+
@gapi.type_kind
|
82
221
|
end
|
83
222
|
|
84
223
|
##
|
85
|
-
# The type of
|
224
|
+
# The type of the array's elements, if {#type_kind} is `ARRAY`. See {#array?}. Optional.
|
86
225
|
#
|
87
226
|
# @return [DataType, nil]
|
88
227
|
#
|
89
228
|
def array_element_type
|
90
|
-
return if @
|
91
|
-
|
92
|
-
DataType.from_gapi_json @gapi_json[:arrayElementType]
|
229
|
+
return if @gapi.array_element_type.nil?
|
230
|
+
DataType.from_gapi @gapi.array_element_type
|
93
231
|
end
|
94
232
|
|
95
233
|
##
|
96
|
-
# The fields of the struct
|
234
|
+
# The fields of the struct, in order, if {#type_kind} is `STRUCT`. See {#struct?}. Optional.
|
97
235
|
#
|
98
236
|
# @return [StructType, nil]
|
99
237
|
#
|
100
238
|
def struct_type
|
101
|
-
return if @
|
102
|
-
|
103
|
-
StructType.from_gapi_json @gapi_json[:structType]
|
239
|
+
return if @gapi.struct_type.nil?
|
240
|
+
StructType.from_gapi @gapi.struct_type
|
104
241
|
end
|
105
242
|
|
106
243
|
##
|
@@ -247,41 +384,108 @@ module Google
|
|
247
384
|
end
|
248
385
|
|
249
386
|
##
|
250
|
-
# @private New
|
251
|
-
def
|
252
|
-
|
253
|
-
|
387
|
+
# @private New Google::Apis::BigqueryV2::StandardSqlDataType object.
|
388
|
+
def to_gapi
|
389
|
+
@gapi
|
390
|
+
end
|
391
|
+
|
392
|
+
##
|
393
|
+
# @private New StandardSql::DataType from a Google::Apis::BigqueryV2::StandardSqlDataType object.
|
394
|
+
def self.from_gapi gapi
|
395
|
+
new.tap do |f|
|
396
|
+
f.instance_variable_set :@gapi, gapi
|
397
|
+
end
|
398
|
+
end
|
399
|
+
|
400
|
+
##
|
401
|
+
# @private New Google::Apis::BigqueryV2::StandardSqlDataType from a String or StandardSql::DataType object.
|
402
|
+
def self.gapi_from_string_or_data_type data_type
|
403
|
+
return if data_type.nil?
|
404
|
+
if data_type.is_a? StandardSql::DataType
|
405
|
+
data_type.to_gapi
|
406
|
+
elsif data_type.is_a? Hash
|
407
|
+
data_type
|
408
|
+
elsif data_type.is_a?(String) || data_type.is_a?(Symbol)
|
409
|
+
Google::Apis::BigqueryV2::StandardSqlDataType.new type_kind: data_type.to_s.upcase
|
410
|
+
else
|
411
|
+
raise ArgumentError, "Unable to convert #{data_type} to Google::Apis::BigqueryV2::StandardSqlDataType"
|
254
412
|
end
|
255
413
|
end
|
256
414
|
end
|
257
415
|
|
258
416
|
##
|
259
|
-
# The
|
417
|
+
# The fields of a `STRUCT` type. See {DataType#struct_type}. See {Routine} and {Argument}.
|
418
|
+
#
|
419
|
+
# @example
|
420
|
+
# require "google/cloud/bigquery"
|
421
|
+
#
|
422
|
+
# bigquery = Google::Cloud::Bigquery.new
|
423
|
+
# dataset = bigquery.dataset "my_dataset"
|
424
|
+
# routine = dataset.create_routine "my_routine" do |r|
|
425
|
+
# r.routine_type = "SCALAR_FUNCTION"
|
426
|
+
# r.language = :SQL
|
427
|
+
# r.body = "(SELECT SUM(IF(elem.name = \"foo\",elem.val,null)) FROM UNNEST(arr) AS elem)"
|
428
|
+
# r.arguments = [
|
429
|
+
# Google::Cloud::Bigquery::Argument.new(
|
430
|
+
# name: "arr",
|
431
|
+
# argument_kind: "FIXED_TYPE",
|
432
|
+
# data_type: Google::Cloud::Bigquery::StandardSql::DataType.new(
|
433
|
+
# type_kind: "ARRAY",
|
434
|
+
# array_element_type: Google::Cloud::Bigquery::StandardSql::DataType.new(
|
435
|
+
# type_kind: "STRUCT",
|
436
|
+
# struct_type: Google::Cloud::Bigquery::StandardSql::StructType.new(
|
437
|
+
# fields: [
|
438
|
+
# Google::Cloud::Bigquery::StandardSql::Field.new(
|
439
|
+
# name: "name",
|
440
|
+
# type: Google::Cloud::Bigquery::StandardSql::DataType.new(type_kind: "STRING")
|
441
|
+
# ),
|
442
|
+
# Google::Cloud::Bigquery::StandardSql::Field.new(
|
443
|
+
# name: "val",
|
444
|
+
# type: Google::Cloud::Bigquery::StandardSql::DataType.new(type_kind: "INT64")
|
445
|
+
# )
|
446
|
+
# ]
|
447
|
+
# )
|
448
|
+
# )
|
449
|
+
# )
|
450
|
+
# )
|
451
|
+
# ]
|
452
|
+
# end
|
453
|
+
#
|
260
454
|
class StructType
|
261
455
|
##
|
262
|
-
#
|
263
|
-
|
264
|
-
|
456
|
+
# Creates a new, immutable StandardSql::StructType object.
|
457
|
+
#
|
458
|
+
# @overload initialize(fields)
|
459
|
+
# @param [Array<Field>] fields The fields of the struct. Required.
|
460
|
+
#
|
461
|
+
def initialize **kwargs
|
462
|
+
# Convert each field client object to gapi object, if fields given (self.from_gapi does not pass kwargs)
|
463
|
+
kwargs[:fields] = kwargs[:fields]&.map(&:to_gapi) if kwargs[:fields]
|
464
|
+
@gapi = Google::Apis::BigqueryV2::StandardSqlStructType.new(**kwargs)
|
265
465
|
end
|
266
466
|
|
267
467
|
##
|
268
|
-
# The
|
468
|
+
# The fields of the struct.
|
269
469
|
#
|
270
|
-
#
|
271
|
-
#
|
272
|
-
# @return [Array<Field>]
|
470
|
+
# @return [Array<Field>] A frozen array of fields.
|
273
471
|
#
|
274
472
|
def fields
|
275
|
-
Array(@
|
276
|
-
Field.
|
277
|
-
end
|
473
|
+
Array(@gapi.fields).map do |field_gapi|
|
474
|
+
Field.from_gapi field_gapi
|
475
|
+
end.freeze
|
476
|
+
end
|
477
|
+
|
478
|
+
##
|
479
|
+
# @private New Google::Apis::BigqueryV2::StandardSqlStructType object.
|
480
|
+
def to_gapi
|
481
|
+
@gapi
|
278
482
|
end
|
279
483
|
|
280
484
|
##
|
281
|
-
# @private New StandardSql::StructType from a
|
282
|
-
def self.
|
283
|
-
new.tap do |
|
284
|
-
|
485
|
+
# @private New StandardSql::StructType from a Google::Apis::BigqueryV2::StandardSqlStructType object.
|
486
|
+
def self.from_gapi gapi
|
487
|
+
new.tap do |f|
|
488
|
+
f.instance_variable_set :@gapi, gapi
|
285
489
|
end
|
286
490
|
end
|
287
491
|
end
|