google-cloud-bigquery 1.18.1 → 1.21.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5906552349d5601779e5fc80cbc4dbcb054ecbc810885fa6db0ec617e2253a2a
4
- data.tar.gz: 3e077eaf5f351d697058b97a89cc2fccc0c8a9f2af6f8d8263f2ea5ae7f738da
3
+ metadata.gz: f38543236358fc319ecfcc2058ffa499e24034027aa56644924d2cf496815550
4
+ data.tar.gz: 37196fa1c3db03e48df4cb0ae5ae5b9b1ee07b9d112063467ebc57d25b34551a
5
5
  SHA512:
6
- metadata.gz: 3c031b1150418cb31a835b9996c6ce31322ffc5b3cbefd05520283ffb11695967c920ec051ab53f726e8968f9c343fd1839b355bc23483145556f5c401ab1c4e
7
- data.tar.gz: da68f76f39a126cc17069a7e071721771321faeade8ee916b3cf33a580c5fccb775a463ea2e8046be803b4ca984a84833b3c21589082dc0f6aacf101e85a5fb5
6
+ metadata.gz: a234359fb8a04b42f22725f5540cf0378b7e51b3d847ddd4f24ba41f2a54b4de85068bb9aee10089995c29794c0a64694223ac6bf88202eda6a646ce02c85275
7
+ data.tar.gz: 99c6c915df70afde18de06907802c60d18df253238e6f3ab752827ea3cfc0aee0ab9bef8dc0816f5980db26334dd2b15ce0a2ecf7db3b026e2f0caa101dcafc8
@@ -1,5 +1,51 @@
1
1
  # Release History
2
2
 
3
+ ### 1.21.2 / 2020-07-21
4
+
5
+ #### Documentation
6
+
7
+ * Update Data#each samples
8
+
9
+ ### 1.21.1 / 2020-05-28
10
+
11
+ #### Documentation
12
+
13
+ * Fix a few broken links
14
+
15
+ ### 1.21.0 / 2020-03-31
16
+
17
+ #### Features
18
+
19
+ * Add Job#parent_job_id and Job#script_statistics
20
+ * Add parent_job to Project#jobs
21
+ * Add Job#num_child_jobs
22
+ * Add Job#parent_job_id
23
+ * Add Job#script_statistics
24
+
25
+ ### 1.20.0 / 2020-03-11
26
+
27
+ #### Features
28
+
29
+ * Add Range Partitioning
30
+ * Add range partitioning methods to Table and Table::Updater
31
+ * Add range partitioning methods to LoadJob
32
+ * Add range partitioning methods to QueryJob
33
+
34
+ ### 1.19.0 / 2020-02-11
35
+
36
+ #### Features
37
+
38
+ * Add Routine
39
+ * Add Dataset#create_routine
40
+ * Add Argument
41
+ * Update StandardSql classes to expose public initializer
42
+ * Add Data#ddl_target_routine and QueryJob#ddl_target_routine
43
+ * Allow row inserts to skip insert_id generation
44
+ * Streaming inserts using an insert_id are not able to be inserted as fast as inserts without an insert_id
45
+ * Add the ability for users to skip insert_id generation in order to speed up the inserts
46
+ * The default behavior continues to generate insert_id values for each row inserted
47
+ * Add yield documentation for Dataset#insert
48
+
3
49
  ### 1.18.1 / 2019-12-18
4
50
 
5
51
  #### Bug Fixes
@@ -24,14 +24,8 @@ improved, *please* create a new issue on GitHub so we can talk about it.
24
24
 
25
25
  - [New issue][gh-ruby]
26
26
 
27
- Or, you can ask questions on the [Google Cloud Platform Slack][slack-ruby]. You
28
- can use the "ruby" channel for general Ruby questions, or use the
29
- "google-cloud-ruby" channel if you have questions about this gem in particular.
30
-
31
27
  [so-ruby]: http://stackoverflow.com/questions/tagged/google-cloud-platform+ruby+bigquery
32
28
 
33
- [gh-search-ruby]: https://github.com/googlecloudplatform/google-cloud-ruby/issues?q=label%3A%22api%3A+bigquery%22
34
-
35
- [gh-ruby]: https://github.com/googlecloudplatform/google-cloud-ruby/issues/new
29
+ [gh-search-ruby]: https://github.com/googleapis/google-cloud-ruby/issues?q=label%3A%22api%3A+bigquery%22
36
30
 
37
- [slack-ruby]: https://gcp-slack.appspot.com/
31
+ [gh-ruby]: https://github.com/googleapis/google-cloud-ruby/issues/new
@@ -53,9 +53,15 @@ module Google
53
53
  # bigquery = gcloud.bigquery
54
54
  # dataset = bigquery.dataset "my_dataset"
55
55
  # table = dataset.table "my_table"
56
- # table.data.each do |row|
57
- # puts row
56
+ #
57
+ # data = table.data
58
+ #
59
+ # # Iterate over the first page of results
60
+ # data.each do |row|
61
+ # puts row[:name]
58
62
  # end
63
+ # # Retrieve the next page of results
64
+ # data = data.next if data.next?
59
65
  #
60
66
  # @example The default scope can be overridden with the `scope` option:
61
67
  # require "google/cloud"
@@ -0,0 +1,197 @@
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 "google/cloud/bigquery/standard_sql"
17
+
18
+ module Google
19
+ module Cloud
20
+ module Bigquery
21
+ ##
22
+ # # Argument
23
+ #
24
+ # Input/output argument of a function or a stored procedure. See {Routine}.
25
+ #
26
+ # @example
27
+ # require "google/cloud/bigquery"
28
+ #
29
+ # bigquery = Google::Cloud::Bigquery.new
30
+ # dataset = bigquery.dataset "my_dataset"
31
+ # routine = dataset.create_routine "my_routine" do |r|
32
+ # r.routine_type = "SCALAR_FUNCTION"
33
+ # r.language = :SQL
34
+ # r.body = "(SELECT SUM(IF(elem.name = \"foo\",elem.val,null)) FROM UNNEST(arr) AS elem)"
35
+ # r.arguments = [
36
+ # Google::Cloud::Bigquery::Argument.new(
37
+ # name: "arr",
38
+ # argument_kind: "FIXED_TYPE",
39
+ # data_type: Google::Cloud::Bigquery::StandardSql::DataType.new(
40
+ # type_kind: "ARRAY",
41
+ # array_element_type: Google::Cloud::Bigquery::StandardSql::DataType.new(
42
+ # type_kind: "STRUCT",
43
+ # struct_type: Google::Cloud::Bigquery::StandardSql::StructType.new(
44
+ # fields: [
45
+ # Google::Cloud::Bigquery::StandardSql::Field.new(
46
+ # name: "name",
47
+ # type: Google::Cloud::Bigquery::StandardSql::DataType.new(type_kind: "STRING")
48
+ # ),
49
+ # Google::Cloud::Bigquery::StandardSql::Field.new(
50
+ # name: "val",
51
+ # type: Google::Cloud::Bigquery::StandardSql::DataType.new(type_kind: "INT64")
52
+ # )
53
+ # ]
54
+ # )
55
+ # )
56
+ # )
57
+ # )
58
+ # ]
59
+ # end
60
+ #
61
+ class Argument
62
+ ##
63
+ # Creates a new, immutable Argument object.
64
+ #
65
+ # @overload initialize(data_type, kind, mode, name)
66
+ # @param [StandardSql::DataType, String] data_type The data type of the argument. Required unless
67
+ # {#argument_kind} is `ANY_TYPE`.
68
+ # @param [String] argument_kind The kind of argument. Optional. Defaults to `FIXED_TYPE`.
69
+ #
70
+ # * `FIXED_TYPE` - The argument is a variable with fully specified type, which can be a struct or an array,
71
+ # but not a table.
72
+ # * `ANY_TYPE` - The argument is any type, including struct or array, but not a table.
73
+ #
74
+ # To be added: `FIXED_TABLE`, `ANY_TABLE`.
75
+ # @param [String] mode Specifies whether the argument is input or output. Optional. Can be set for procedures
76
+ # only.
77
+ #
78
+ # * IN - The argument is input-only.
79
+ # * OUT - The argument is output-only.
80
+ # * INOUT - The argument is both an input and an output.
81
+ # @param [String] name The name of the argument. Optional. Can be absent for a function return argument.
82
+ #
83
+ def initialize **kwargs
84
+ kwargs[:data_type] = StandardSql::DataType.gapi_from_string_or_data_type kwargs[:data_type]
85
+ @gapi = Google::Apis::BigqueryV2::Argument.new(**kwargs)
86
+ end
87
+
88
+ ##
89
+ # The data type of the argument. Required unless {#argument_kind} is `ANY_TYPE`.
90
+ #
91
+ # @return [StandardSql::DataType] The data type.
92
+ #
93
+ def data_type
94
+ StandardSql::DataType.from_gapi @gapi.data_type
95
+ end
96
+
97
+ ##
98
+ # The kind of argument. Optional. Defaults to `FIXED_TYPE`.
99
+ #
100
+ # * `FIXED_TYPE` - The argument is a variable with fully specified type, which can be a struct or an array, but
101
+ # not a table.
102
+ # * `ANY_TYPE` - The argument is any type, including struct or array, but not a table.
103
+ #
104
+ # To be added: `FIXED_TABLE`, `ANY_TABLE`.
105
+ #
106
+ # @return [String] The upper case kind of argument.
107
+ #
108
+ def argument_kind
109
+ @gapi.argument_kind
110
+ end
111
+
112
+ ##
113
+ # Checks if the value of {#argument_kind} is `FIXED_TYPE`. The default is `true`.
114
+ #
115
+ # @return [Boolean] `true` when `FIXED_TYPE`, `false` otherwise.
116
+ #
117
+ def fixed_type?
118
+ return true if @gapi.argument_kind.nil?
119
+ @gapi.argument_kind == "FIXED_TYPE"
120
+ end
121
+
122
+ ##
123
+ # Checks if the value of {#argument_kind} is `ANY_TYPE`. The default is `false`.
124
+ #
125
+ # @return [Boolean] `true` when `ANY_TYPE`, `false` otherwise.
126
+ #
127
+ def any_type?
128
+ @gapi.argument_kind == "ANY_TYPE"
129
+ end
130
+
131
+ ##
132
+ # Specifies whether the argument is input or output. Optional. Can be set for procedures only.
133
+ #
134
+ # * IN - The argument is input-only.
135
+ # * OUT - The argument is output-only.
136
+ # * INOUT - The argument is both an input and an output.
137
+ #
138
+ # @return [String] The upper case input/output mode of the argument.
139
+ #
140
+ def mode
141
+ @gapi.mode
142
+ end
143
+
144
+ ##
145
+ # Checks if the value of {#mode} is `IN`. Can be set for procedures only. The default is `false`.
146
+ #
147
+ # @return [Boolean] `true` when `IN`, `false` otherwise.
148
+ #
149
+ def in?
150
+ @gapi.mode == "IN"
151
+ end
152
+
153
+ ##
154
+ # Checks if the value of {#mode} is `OUT`. Can be set for procedures only. The default is `false`.
155
+ #
156
+ # @return [Boolean] `true` when `OUT`, `false` otherwise.
157
+ #
158
+ def out?
159
+ @gapi.mode == "OUT"
160
+ end
161
+
162
+ ##
163
+ # Checks if the value of {#mode} is `INOUT`. Can be set for procedures only. The default is `false`.
164
+ #
165
+ # @return [Boolean] `true` when `INOUT`, `false` otherwise.
166
+ #
167
+ def inout?
168
+ @gapi.mode == "INOUT"
169
+ end
170
+
171
+ ##
172
+ #
173
+ # The name of the argument. Optional. Can be absent for a function return argument.
174
+ #
175
+ # @return [String] The name of the argument.
176
+ #
177
+ def name
178
+ @gapi.name
179
+ end
180
+
181
+ ##
182
+ # @private
183
+ def to_gapi
184
+ @gapi
185
+ end
186
+
187
+ ##
188
+ # @private New Argument from a Google API Client object.
189
+ def self.from_gapi gapi
190
+ new.tap do |a|
191
+ a.instance_variable_set :@gapi, gapi
192
+ end
193
+ end
194
+ end
195
+ end
196
+ end
197
+ end
@@ -152,7 +152,7 @@ module Google
152
152
  #
153
153
  # @return [Google::Cloud::Bigquery::CopyJob::Updater] A job
154
154
  # configuration object for setting copy options.
155
- def self.from_options service, source, target, options = {}
155
+ def self.from_options service, source, target, options
156
156
  job_ref = service.job_ref_from options[:job_id], options[:prefix]
157
157
  copy_cfg = Google::Apis::BigqueryV2::JobConfigurationTableCopy.new(
158
158
  source_table: source,
@@ -284,6 +284,23 @@ module Google
284
284
  @gapi.configuration.update! labels: value
285
285
  end
286
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
+
287
304
  ##
288
305
  # @private Returns the Google API client library version of this job.
289
306
  #
@@ -41,9 +41,12 @@ module Google
41
41
  #
42
42
  # data.count # 100000
43
43
  # data.total # 164656
44
+ #
45
+ # # Iterate over the first page of results
44
46
  # data.each do |row|
45
47
  # puts row[:word]
46
48
  # end
49
+ # # Retrieve the next page of results
47
50
  # data = data.next if data.next?
48
51
  #
49
52
  class Data < DelegateClass(::Array)
@@ -117,9 +120,12 @@ module Google
117
120
  #
118
121
  # data.count # 100000
119
122
  # data.total # 164656
123
+ #
124
+ # # Iterate over the first page of results
120
125
  # data.each do |row|
121
126
  # puts row[:word]
122
127
  # end
128
+ # # Retrieve the next page of results
123
129
  # data = data.next if data.next?
124
130
  #
125
131
  def total
@@ -316,6 +322,21 @@ module Google
316
322
  job_gapi&.statistics&.query&.ddl_operation_performed
317
323
  end
318
324
 
325
+ ##
326
+ # The DDL target routine, in reference state. (See {Routine#reference?}.)
327
+ # Present only for `CREATE/DROP FUNCTION/PROCEDURE` queries. (See
328
+ # {#statement_type}.)
329
+ #
330
+ # @return [Google::Cloud::Bigquery::Routine, nil] The DDL target routine, in
331
+ # reference state.
332
+ #
333
+ def ddl_target_routine
334
+ ensure_service!
335
+ routine = job_gapi&.statistics&.query&.ddl_target_routine
336
+ return nil if routine.nil?
337
+ Google::Cloud::Bigquery::Routine.new_reference_from_gapi routine, service
338
+ end
339
+
319
340
  ##
320
341
  # The DDL target table, in reference state. (See {Table#reference?}.)
321
342
  # Present only for `CREATE/DROP TABLE/VIEW` queries. (See
@@ -360,9 +381,12 @@ module Google
360
381
  #
361
382
  # data.count # 100000
362
383
  # data.total # 164656
384
+ #
385
+ # # Iterate over the first page of results
363
386
  # data.each do |row|
364
387
  # puts row[:word]
365
388
  # end
389
+ # # Retrieve the next page of results
366
390
  # data = data.next if data.next?
367
391
  #
368
392
  def next?
@@ -387,9 +411,12 @@ module Google
387
411
  #
388
412
  # data.count # 100000
389
413
  # data.total # 164656
414
+ #
415
+ # # Iterate over the first page of results
390
416
  # data.each do |row|
391
417
  # puts row[:word]
392
418
  # end
419
+ # # Retrieve the next page of results
393
420
  # data = data.next if data.next?
394
421
  #
395
422
  def next
@@ -18,6 +18,7 @@ require "google/cloud/errors"
18
18
  require "google/cloud/bigquery/service"
19
19
  require "google/cloud/bigquery/table"
20
20
  require "google/cloud/bigquery/model"
21
+ require "google/cloud/bigquery/routine"
21
22
  require "google/cloud/bigquery/external"
22
23
  require "google/cloud/bigquery/dataset/list"
23
24
  require "google/cloud/bigquery/dataset/access"
@@ -554,6 +555,40 @@ module Google
554
555
  # end
555
556
  # end
556
557
  #
558
+ # @example With time partitioning and clustering.
559
+ # require "google/cloud/bigquery"
560
+ #
561
+ # bigquery = Google::Cloud::Bigquery.new
562
+ # dataset = bigquery.dataset "my_dataset"
563
+ #
564
+ # table = dataset.create_table "my_table" do |t|
565
+ # t.schema do |schema|
566
+ # schema.timestamp "dob", mode: :required
567
+ # schema.string "first_name", mode: :required
568
+ # schema.string "last_name", mode: :required
569
+ # end
570
+ # t.time_partitioning_type = "DAY"
571
+ # t.time_partitioning_field = "dob"
572
+ # t.clustering_fields = ["last_name", "first_name"]
573
+ # end
574
+ #
575
+ # @example With range partitioning.
576
+ # require "google/cloud/bigquery"
577
+ #
578
+ # bigquery = Google::Cloud::Bigquery.new
579
+ # dataset = bigquery.dataset "my_dataset"
580
+ #
581
+ # table = dataset.create_table "my_table" do |t|
582
+ # t.schema do |schema|
583
+ # schema.integer "my_table_id", mode: :required
584
+ # schema.string "my_table_data", mode: :required
585
+ # end
586
+ # t.range_partitioning_field = "my_table_id"
587
+ # t.range_partitioning_start = 0
588
+ # t.range_partitioning_interval = 10
589
+ # t.range_partitioning_end = 100
590
+ # end
591
+ #
557
592
  # @!group Table
558
593
  #
559
594
  def create_table table_id, name: nil, description: nil
@@ -601,12 +636,20 @@ module Google
601
636
  # SQL](https://cloud.google.com/bigquery/docs/reference/legacy-sql)
602
637
  # dialect. Optional. The default value is false.
603
638
  # @param [Array<String>, String] udfs User-defined function resources
604
- # used in the query. May be either a code resource to load from a
605
- # Google Cloud Storage URI (`gs://bucket/path`), or an inline resource
639
+ # used in a legacy SQL query. May be either a code resource to load from
640
+ # a Google Cloud Storage URI (`gs://bucket/path`), or an inline resource
606
641
  # that contains code for a user-defined function (UDF). Providing an
607
642
  # inline code resource is equivalent to providing a URI for a file
608
- # containing the same code. See [User-Defined
609
- # Functions](https://cloud.google.com/bigquery/docs/reference/standard-sql/user-defined-functions).
643
+ # containing the same code.
644
+ #
645
+ # This parameter is used for defining User Defined Function (UDF)
646
+ # resources only when using legacy SQL. Users of standard SQL should
647
+ # leverage either DDL (e.g. `CREATE [TEMPORARY] FUNCTION ...`) or the
648
+ # Routines API to define UDF resources.
649
+ #
650
+ # For additional information on migrating, see: [Migrating to
651
+ # standard SQL - Differences in user-defined JavaScript
652
+ # functions](https://cloud.google.com/bigquery/docs/reference/standard-sql/migrating-from-legacy-sql#differences_in_user-defined_javascript_functions)
610
653
  #
611
654
  # @return [Google::Cloud::Bigquery::Table] A new table object.
612
655
  #
@@ -731,8 +774,7 @@ module Google
731
774
  #
732
775
  def tables token: nil, max: nil
733
776
  ensure_service!
734
- options = { token: token, max: max }
735
- gapi = service.list_tables dataset_id, options
777
+ gapi = service.list_tables dataset_id, token: token, max: max
736
778
  Table::List.from_gapi gapi, service, dataset_id, max
737
779
  end
738
780
 
@@ -817,6 +859,174 @@ module Google
817
859
  Model::List.from_gapi gapi, service, dataset_id, max
818
860
  end
819
861
 
862
+ ##
863
+ # Creates a new routine. The following attributes may be set in the yielded block:
864
+ # {Routine::Updater#routine_type=}, {Routine::Updater#language=}, {Routine::Updater#arguments=},
865
+ # {Routine::Updater#return_type=}, {Routine::Updater#imported_libraries=}, {Routine::Updater#body=}, and
866
+ # {Routine::Updater#description=}.
867
+ #
868
+ # @param [String] routine_id The ID of the routine. The ID must contain only
869
+ # letters (a-z, A-Z), numbers (0-9), or underscores (_). The maximum length
870
+ # is 256 characters.
871
+ # @yield [routine] A block for setting properties on the routine.
872
+ # @yieldparam [Google::Cloud::Bigquery::Routine::Updater] routine An updater to set additional properties on the
873
+ # routine.
874
+ #
875
+ # @return [Google::Cloud::Bigquery::Routine] A new routine object.
876
+ #
877
+ # @example
878
+ # require "google/cloud/bigquery"
879
+ #
880
+ # bigquery = Google::Cloud::Bigquery.new
881
+ # dataset = bigquery.dataset "my_dataset"
882
+ #
883
+ # routine = dataset.create_routine "my_routine" do |r|
884
+ # r.routine_type = "SCALAR_FUNCTION"
885
+ # r.language = "SQL"
886
+ # r.arguments = [
887
+ # Google::Cloud::Bigquery::Argument.new(name: "x", data_type: "INT64")
888
+ # ]
889
+ # r.body = "x * 3"
890
+ # r.description = "My routine description"
891
+ # end
892
+ #
893
+ # puts routine.routine_id
894
+ #
895
+ # @example Extended example:
896
+ # require "google/cloud/bigquery"
897
+ #
898
+ # bigquery = Google::Cloud::Bigquery.new
899
+ # dataset = bigquery.dataset "my_dataset"
900
+ # routine = dataset.create_routine "my_routine" do |r|
901
+ # r.routine_type = "SCALAR_FUNCTION"
902
+ # r.language = :SQL
903
+ # r.body = "(SELECT SUM(IF(elem.name = \"foo\",elem.val,null)) FROM UNNEST(arr) AS elem)"
904
+ # r.arguments = [
905
+ # Google::Cloud::Bigquery::Argument.new(
906
+ # name: "arr",
907
+ # argument_kind: "FIXED_TYPE",
908
+ # data_type: Google::Cloud::Bigquery::StandardSql::DataType.new(
909
+ # type_kind: "ARRAY",
910
+ # array_element_type: Google::Cloud::Bigquery::StandardSql::DataType.new(
911
+ # type_kind: "STRUCT",
912
+ # struct_type: Google::Cloud::Bigquery::StandardSql::StructType.new(
913
+ # fields: [
914
+ # Google::Cloud::Bigquery::StandardSql::Field.new(
915
+ # name: "name",
916
+ # type: Google::Cloud::Bigquery::StandardSql::DataType.new(type_kind: "STRING")
917
+ # ),
918
+ # Google::Cloud::Bigquery::StandardSql::Field.new(
919
+ # name: "val",
920
+ # type: Google::Cloud::Bigquery::StandardSql::DataType.new(type_kind: "INT64")
921
+ # )
922
+ # ]
923
+ # )
924
+ # )
925
+ # )
926
+ # )
927
+ # ]
928
+ # end
929
+ #
930
+ # @!group Routine
931
+ #
932
+ def create_routine routine_id
933
+ ensure_service!
934
+ new_tb = Google::Apis::BigqueryV2::Routine.new(
935
+ routine_reference: Google::Apis::BigqueryV2::RoutineReference.new(
936
+ project_id: project_id, dataset_id: dataset_id, routine_id: routine_id
937
+ )
938
+ )
939
+ updater = Routine::Updater.new new_tb
940
+
941
+ yield updater if block_given?
942
+
943
+ gapi = service.insert_routine dataset_id, updater.to_gapi
944
+ Routine.from_gapi gapi, service
945
+ end
946
+
947
+ ##
948
+ # Retrieves an existing routine by ID.
949
+ #
950
+ # @param [String] routine_id The ID of a routine.
951
+ # @param [Boolean] skip_lookup Optionally create just a local reference
952
+ # object without verifying that the resource exists on the BigQuery
953
+ # service. Calls made on this object will raise errors if the resource
954
+ # does not exist. Default is `false`. Optional.
955
+ #
956
+ # @return [Google::Cloud::Bigquery::Routine, nil] Returns `nil` if the
957
+ # routine does not exist.
958
+ #
959
+ # @example
960
+ # require "google/cloud/bigquery"
961
+ #
962
+ # bigquery = Google::Cloud::Bigquery.new
963
+ # dataset = bigquery.dataset "my_dataset"
964
+ #
965
+ # routine = dataset.routine "my_routine"
966
+ # puts routine.routine_id
967
+ #
968
+ # @example Avoid retrieving the routine resource with `skip_lookup`:
969
+ # require "google/cloud/bigquery"
970
+ #
971
+ # bigquery = Google::Cloud::Bigquery.new
972
+ #
973
+ # dataset = bigquery.dataset "my_dataset"
974
+ #
975
+ # routine = dataset.routine "my_routine", skip_lookup: true
976
+ #
977
+ # @!group Routine
978
+ #
979
+ def routine routine_id, skip_lookup: nil
980
+ ensure_service!
981
+ return Routine.new_reference project_id, dataset_id, routine_id, service if skip_lookup
982
+ gapi = service.get_routine dataset_id, routine_id
983
+ Routine.from_gapi gapi, service
984
+ rescue Google::Cloud::NotFoundError
985
+ nil
986
+ end
987
+
988
+ ##
989
+ # Retrieves the list of routines belonging to the dataset.
990
+ #
991
+ # @param [String] token A previously-returned page token representing
992
+ # part of the larger set of results to view.
993
+ # @param [Integer] max Maximum number of routines to return.
994
+ # @param [String] filter If set, then only the routines matching this filter are returned. The current supported
995
+ # form is `routineType:`, with a {Routine#routine_type} enum value. Example: `routineType:SCALAR_FUNCTION`.
996
+ #
997
+ # @return [Array<Google::Cloud::Bigquery::Routine>] An array of routines
998
+ # (See {Google::Cloud::Bigquery::Routine::List})
999
+ #
1000
+ # @example
1001
+ # require "google/cloud/bigquery"
1002
+ #
1003
+ # bigquery = Google::Cloud::Bigquery.new
1004
+ # dataset = bigquery.dataset "my_dataset"
1005
+ #
1006
+ # routines = dataset.routines
1007
+ # routines.each do |routine|
1008
+ # puts routine.routine_id
1009
+ # end
1010
+ #
1011
+ # @example Retrieve all routines: (See {Routine::List#all})
1012
+ # require "google/cloud/bigquery"
1013
+ #
1014
+ # bigquery = Google::Cloud::Bigquery.new
1015
+ # dataset = bigquery.dataset "my_dataset"
1016
+ #
1017
+ # routines = dataset.routines
1018
+ # routines.all do |routine|
1019
+ # puts routine.routine_id
1020
+ # end
1021
+ #
1022
+ # @!group Routine
1023
+ #
1024
+ def routines token: nil, max: nil, filter: nil
1025
+ ensure_service!
1026
+ gapi = service.list_routines dataset_id, token: token, max: max, filter: filter
1027
+ Routine::List.from_gapi gapi, service, dataset_id, max, filter: filter
1028
+ end
1029
+
820
1030
  ##
821
1031
  # Queries data by creating a [query
822
1032
  # job](https://cloud.google.com/bigquery/docs/query-overview#query_jobs).
@@ -969,12 +1179,20 @@ module Google
969
1179
  # list must have a different key. See [Requirements for
970
1180
  # labels](https://cloud.google.com/bigquery/docs/creating-managing-labels#requirements).
971
1181
  # @param [Array<String>, String] udfs User-defined function resources
972
- # used in the query. May be either a code resource to load from a
973
- # Google Cloud Storage URI (`gs://bucket/path`), or an inline resource
1182
+ # used in a legacy SQL query. May be either a code resource to load from
1183
+ # a Google Cloud Storage URI (`gs://bucket/path`), or an inline resource
974
1184
  # that contains code for a user-defined function (UDF). Providing an
975
1185
  # inline code resource is equivalent to providing a URI for a file
976
- # containing the same code. See [User-Defined
977
- # Functions](https://cloud.google.com/bigquery/docs/reference/standard-sql/user-defined-functions).
1186
+ # containing the same code.
1187
+ #
1188
+ # This parameter is used for defining User Defined Function (UDF)
1189
+ # resources only when using legacy SQL. Users of standard SQL should
1190
+ # leverage either DDL (e.g. `CREATE [TEMPORARY] FUNCTION ...`) or the
1191
+ # Routines API to define UDF resources.
1192
+ #
1193
+ # For additional information on migrating, see: [Migrating to
1194
+ # standard SQL - Differences in user-defined JavaScript
1195
+ # functions](https://cloud.google.com/bigquery/docs/reference/standard-sql/migrating-from-legacy-sql#differences_in_user-defined_javascript_functions)
978
1196
  # @param [Integer] maximum_billing_tier Deprecated: Change the billing
979
1197
  # tier to allow high-compute queries.
980
1198
  # @yield [job] a job configuration object
@@ -1073,7 +1291,7 @@ module Google
1073
1291
  #
1074
1292
  # job.wait_until_done!
1075
1293
  # if !job.failed?
1076
- # table_ref = job.ddl_target_table
1294
+ # table_ref = job.ddl_target_table # Or ddl_target_routine for CREATE/DROP FUNCTION/PROCEDURE
1077
1295
  # end
1078
1296
  #
1079
1297
  # @example Execute a DML statement:
@@ -1256,9 +1474,12 @@ module Google
1256
1474
  #
1257
1475
  # data = dataset.query "SELECT name FROM my_table"
1258
1476
  #
1477
+ # # Iterate over the first page of results
1259
1478
  # data.each do |row|
1260
1479
  # puts row[:name]
1261
1480
  # end
1481
+ # # Retrieve the next page of results
1482
+ # data = data.next if data.next?
1262
1483
  #
1263
1484
  # @example Query using legacy SQL:
1264
1485
  # require "google/cloud/bigquery"
@@ -1269,9 +1490,12 @@ module Google
1269
1490
  # data = dataset.query "SELECT name FROM my_table",
1270
1491
  # legacy_sql: true
1271
1492
  #
1493
+ # # Iterate over the first page of results
1272
1494
  # data.each do |row|
1273
1495
  # puts row[:name]
1274
1496
  # end
1497
+ # # Retrieve the next page of results
1498
+ # data = data.next if data.next?
1275
1499
  #
1276
1500
  # @example Query using positional query parameters:
1277
1501
  # require "google/cloud/bigquery"
@@ -1282,9 +1506,12 @@ module Google
1282
1506
  # data = dataset.query "SELECT name FROM my_table WHERE id = ?",
1283
1507
  # params: [1]
1284
1508
  #
1509
+ # # Iterate over the first page of results
1285
1510
  # data.each do |row|
1286
1511
  # puts row[:name]
1287
1512
  # end
1513
+ # # Retrieve the next page of results
1514
+ # data = data.next if data.next?
1288
1515
  #
1289
1516
  # @example Query using named query parameters:
1290
1517
  # require "google/cloud/bigquery"
@@ -1295,9 +1522,12 @@ module Google
1295
1522
  # data = dataset.query "SELECT name FROM my_table WHERE id = @id",
1296
1523
  # params: { id: 1 }
1297
1524
  #
1525
+ # # Iterate over the first page of results
1298
1526
  # data.each do |row|
1299
1527
  # puts row[:name]
1300
1528
  # end
1529
+ # # Retrieve the next page of results
1530
+ # data = data.next if data.next?
1301
1531
  #
1302
1532
  # @example Query using named query parameters with types:
1303
1533
  # require "google/cloud/bigquery"
@@ -1310,9 +1540,12 @@ module Google
1310
1540
  # params: { ids: [] },
1311
1541
  # types: { ids: [:INT64] }
1312
1542
  #
1543
+ # # Iterate over the first page of results
1313
1544
  # data.each do |row|
1314
1545
  # puts row[:name]
1315
1546
  # end
1547
+ # # Retrieve the next page of results
1548
+ # data = data.next if data.next?
1316
1549
  #
1317
1550
  # @example Execute a DDL statement:
1318
1551
  # require "google/cloud/bigquery"
@@ -1321,7 +1554,7 @@ module Google
1321
1554
  #
1322
1555
  # data = bigquery.query "CREATE TABLE my_table (x INT64)"
1323
1556
  #
1324
- # table_ref = data.ddl_target_table
1557
+ # table_ref = data.ddl_target_table # Or ddl_target_routine for CREATE/DROP FUNCTION/PROCEDURE
1325
1558
  #
1326
1559
  # @example Execute a DML statement:
1327
1560
  # require "google/cloud/bigquery"
@@ -1351,9 +1584,12 @@ module Google
1351
1584
  # query.table = dataset.table "my_table", skip_lookup: true
1352
1585
  # end
1353
1586
  #
1587
+ # # Iterate over the first page of results
1354
1588
  # data.each do |row|
1355
1589
  # puts row[:name]
1356
1590
  # end
1591
+ # # Retrieve the next page of results
1592
+ # data = data.next if data.next?
1357
1593
  #
1358
1594
  # @!group Data
1359
1595
  #
@@ -1942,7 +2178,7 @@ module Google
1942
2178
  # dataset = bigquery.dataset "my_dataset", skip_lookup: true
1943
2179
  # dataset.exists? # true
1944
2180
  #
1945
- def exists? force: nil
2181
+ def exists? force: false
1946
2182
  return gapi_exists? if force
1947
2183
  # If we have a memoized value, return it
1948
2184
  return @exists unless @exists.nil?
@@ -2052,7 +2288,7 @@ module Google
2052
2288
  end
2053
2289
 
2054
2290
  ##
2055
- # @private New lazy Dataset object without making an HTTP request.
2291
+ # @private New lazy Dataset object without making an HTTP request, for use with the skip_lookup option.
2056
2292
  def self.new_reference project_id, dataset_id, service
2057
2293
  raise ArgumentError, "dataset_id is required" unless dataset_id
2058
2294
  new.tap do |b|
@@ -2083,12 +2319,13 @@ module Google
2083
2319
  # @param [String] table_id The ID of the destination table.
2084
2320
  # @param [Hash, Array<Hash>] rows A hash object or array of hash objects
2085
2321
  # containing the data. Required.
2086
- # @param [Array<String>] insert_ids A unique ID for each row. BigQuery
2087
- # uses this property to detect duplicate insertion requests on a
2088
- # best-effort basis. For more information, see [data
2089
- # consistency](https://cloud.google.com/bigquery/streaming-data-into-bigquery#dataconsistency).
2090
- # Optional. If not provided, the client library will assign a UUID to
2091
- # each row before the request is sent.
2322
+ # @param [Array<String|Symbol>, Symbol] insert_ids A unique ID for each row. BigQuery uses this property to
2323
+ # detect duplicate insertion requests on a best-effort basis. For more information, see [data
2324
+ # consistency](https://cloud.google.com/bigquery/streaming-data-into-bigquery#dataconsistency). Optional. If
2325
+ # not provided, the client library will assign a UUID to each row before the request is sent.
2326
+ #
2327
+ # The value `:skip` can be provided to skip the generation of IDs for all rows, or to skip the generation of an
2328
+ # ID for a specific row in the array.
2092
2329
  # @param [Boolean] skip_invalid Insert all valid rows of a request, even
2093
2330
  # if invalid rows exist. The default value is `false`, which causes
2094
2331
  # the entire request to fail if any invalid rows exist.
@@ -2099,6 +2336,12 @@ module Google
2099
2336
  # a new table with the given `table_id`, if no table is found for
2100
2337
  # `table_id`. The default value is false.
2101
2338
  #
2339
+ # @yield [table] a block for setting the table
2340
+ # @yieldparam [Google::Cloud::Bigquery::Table::Updater] table An updater
2341
+ # to set additional properties on the table in the API request to
2342
+ # create it. Only used when `autocreate` is set and the table does not
2343
+ # already exist.
2344
+ #
2102
2345
  # @return [Google::Cloud::Bigquery::InsertResponse] An insert response
2103
2346
  # object.
2104
2347
  #
@@ -2144,32 +2387,19 @@ module Google
2144
2387
  #
2145
2388
  # @!group Data
2146
2389
  #
2147
- def insert table_id, rows, insert_ids: nil, skip_invalid: nil, ignore_unknown: nil, autocreate: nil
2390
+ def insert table_id, rows, insert_ids: nil, skip_invalid: nil, ignore_unknown: nil, autocreate: nil, &block
2148
2391
  rows = [rows] if rows.is_a? Hash
2392
+ raise ArgumentError, "No rows provided" if rows.empty?
2393
+
2394
+ insert_ids = Array.new(rows.count) { :skip } if insert_ids == :skip
2149
2395
  insert_ids = Array insert_ids
2150
2396
  if insert_ids.count.positive? && insert_ids.count != rows.count
2151
2397
  raise ArgumentError, "insert_ids must be the same size as rows"
2152
2398
  end
2153
2399
 
2154
2400
  if autocreate
2155
- begin
2156
- insert_data table_id, rows,
2157
- skip_invalid: skip_invalid, ignore_unknown: ignore_unknown, insert_ids: insert_ids
2158
- rescue Google::Cloud::NotFoundError
2159
- sleep rand(1..60)
2160
- begin
2161
- create_table table_id do |tbl_updater|
2162
- yield tbl_updater if block_given?
2163
- end
2164
- # rubocop:disable Lint/HandleExceptions
2165
- rescue Google::Cloud::AlreadyExistsError
2166
- end
2167
- # rubocop:enable Lint/HandleExceptions
2168
-
2169
- sleep 60
2170
- insert table_id, rows, skip_invalid: skip_invalid, ignore_unknown: ignore_unknown, autocreate: true,
2171
- insert_ids: insert_ids
2172
- end
2401
+ insert_data_with_autocreate table_id, rows, skip_invalid: skip_invalid, ignore_unknown: ignore_unknown,
2402
+ insert_ids: insert_ids, &block
2173
2403
  else
2174
2404
  insert_data table_id, rows, skip_invalid: skip_invalid, ignore_unknown: ignore_unknown,
2175
2405
  insert_ids: insert_ids
@@ -2239,15 +2469,30 @@ module Google
2239
2469
 
2240
2470
  protected
2241
2471
 
2242
- def insert_data table_id, rows, skip_invalid: nil, ignore_unknown: nil,
2243
- insert_ids: nil
2472
+ def insert_data_with_autocreate table_id, rows, skip_invalid: nil, ignore_unknown: nil, insert_ids: nil
2473
+ insert_data table_id, rows, skip_invalid: skip_invalid, ignore_unknown: ignore_unknown, insert_ids: insert_ids
2474
+ rescue Google::Cloud::NotFoundError
2475
+ sleep rand(1..60)
2476
+ begin
2477
+ create_table table_id do |tbl_updater|
2478
+ yield tbl_updater if block_given?
2479
+ end
2480
+ # rubocop:disable Lint/HandleExceptions
2481
+ rescue Google::Cloud::AlreadyExistsError
2482
+ end
2483
+ # rubocop:enable Lint/HandleExceptions
2484
+
2485
+ sleep 60
2486
+ retry
2487
+ end
2488
+
2489
+ def insert_data table_id, rows, skip_invalid: nil, ignore_unknown: nil, insert_ids: nil
2244
2490
  rows = [rows] if rows.is_a? Hash
2245
2491
  raise ArgumentError, "No rows provided" if rows.empty?
2246
2492
  ensure_service!
2247
- options = { skip_invalid: skip_invalid,
2248
- ignore_unknown: ignore_unknown,
2249
- insert_ids: insert_ids }
2250
- gapi = service.insert_tabledata dataset_id, table_id, rows, options
2493
+ gapi = service.insert_tabledata dataset_id, table_id, rows, skip_invalid: skip_invalid,
2494
+ ignore_unknown: ignore_unknown,
2495
+ insert_ids: insert_ids
2251
2496
  InsertResponse.from_gapi rows, gapi
2252
2497
  end
2253
2498
 
@@ -2444,14 +2689,14 @@ module Google
2444
2689
  end
2445
2690
 
2446
2691
  ##
2447
- # Yielded to a block to accumulate changes for a patch request.
2692
+ # Yielded to a block to accumulate changes for a create request. See {Project#create_dataset}.
2448
2693
  class Updater < Dataset
2449
2694
  ##
2450
- # A list of attributes that were updated.
2695
+ # @private A list of attributes that were updated.
2451
2696
  attr_reader :updates
2452
2697
 
2453
2698
  ##
2454
- # Create an Updater object.
2699
+ # @private Create an Updater object.
2455
2700
  def initialize gapi
2456
2701
  @updates = []
2457
2702
  @gapi = gapi
@@ -2468,8 +2713,109 @@ module Google
2468
2713
  @access
2469
2714
  end
2470
2715
 
2716
+ # rubocop:disable Style/MethodDefParentheses
2717
+
2718
+ ##
2719
+ # @raise [RuntimeError] not implemented
2720
+ def delete(*)
2721
+ raise "not implemented in #{self.class}"
2722
+ end
2723
+
2471
2724
  ##
2472
- # Make sure any access changes are saved
2725
+ # @raise [RuntimeError] not implemented
2726
+ def create_table(*)
2727
+ raise "not implemented in #{self.class}"
2728
+ end
2729
+
2730
+ ##
2731
+ # @raise [RuntimeError] not implemented
2732
+ def create_view(*)
2733
+ raise "not implemented in #{self.class}"
2734
+ end
2735
+
2736
+ ##
2737
+ # @raise [RuntimeError] not implemented
2738
+ def table(*)
2739
+ raise "not implemented in #{self.class}"
2740
+ end
2741
+
2742
+ ##
2743
+ # @raise [RuntimeError] not implemented
2744
+ def tables(*)
2745
+ raise "not implemented in #{self.class}"
2746
+ end
2747
+
2748
+ ##
2749
+ # @raise [RuntimeError] not implemented
2750
+ def model(*)
2751
+ raise "not implemented in #{self.class}"
2752
+ end
2753
+
2754
+ ##
2755
+ # @raise [RuntimeError] not implemented
2756
+ def models(*)
2757
+ raise "not implemented in #{self.class}"
2758
+ end
2759
+
2760
+ ##
2761
+ # @raise [RuntimeError] not implemented
2762
+ def create_routine(*)
2763
+ raise "not implemented in #{self.class}"
2764
+ end
2765
+
2766
+ ##
2767
+ # @raise [RuntimeError] not implemented
2768
+ def routine(*)
2769
+ raise "not implemented in #{self.class}"
2770
+ end
2771
+
2772
+ ##
2773
+ # @raise [RuntimeError] not implemented
2774
+ def routines(*)
2775
+ raise "not implemented in #{self.class}"
2776
+ end
2777
+
2778
+ ##
2779
+ # @raise [RuntimeError] not implemented
2780
+ def query_job(*)
2781
+ raise "not implemented in #{self.class}"
2782
+ end
2783
+
2784
+ ##
2785
+ # @raise [RuntimeError] not implemented
2786
+ def query(*)
2787
+ raise "not implemented in #{self.class}"
2788
+ end
2789
+
2790
+ ##
2791
+ # @raise [RuntimeError] not implemented
2792
+ def external(*)
2793
+ raise "not implemented in #{self.class}"
2794
+ end
2795
+
2796
+ ##
2797
+ # @raise [RuntimeError] not implemented
2798
+ def load_job(*)
2799
+ raise "not implemented in #{self.class}"
2800
+ end
2801
+
2802
+ ##
2803
+ # @raise [RuntimeError] not implemented
2804
+ def load(*)
2805
+ raise "not implemented in #{self.class}"
2806
+ end
2807
+
2808
+ ##
2809
+ # @raise [RuntimeError] not implemented
2810
+ def reload!
2811
+ raise "not implemented in #{self.class}"
2812
+ end
2813
+ alias refresh! reload!
2814
+
2815
+ # rubocop:enable Style/MethodDefParentheses
2816
+
2817
+ ##
2818
+ # @private Make sure any access changes are saved
2473
2819
  def check_for_mutated_access!
2474
2820
  return if @access.nil?
2475
2821
  return unless @access.changed?
@@ -2477,6 +2823,8 @@ module Google
2477
2823
  patch_gapi! :access
2478
2824
  end
2479
2825
 
2826
+ ##
2827
+ # @private
2480
2828
  def to_gapi
2481
2829
  check_for_mutated_access!
2482
2830
  @gapi