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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5906552349d5601779e5fc80cbc4dbcb054ecbc810885fa6db0ec617e2253a2a
4
- data.tar.gz: 3e077eaf5f351d697058b97a89cc2fccc0c8a9f2af6f8d8263f2ea5ae7f738da
3
+ metadata.gz: 65c8bae8c365c4fde7d54e75abe9c15aa4eba702b2e6300371843bc97bbc27f7
4
+ data.tar.gz: 5457cacd3331a717f63b0d71b907aa5e68702256118cd41d16f90be672f187e4
5
5
  SHA512:
6
- metadata.gz: 3c031b1150418cb31a835b9996c6ce31322ffc5b3cbefd05520283ffb11695967c920ec051ab53f726e8968f9c343fd1839b355bc23483145556f5c401ab1c4e
7
- data.tar.gz: da68f76f39a126cc17069a7e071721771321faeade8ee916b3cf33a580c5fccb775a463ea2e8046be803b4ca984a84833b3c21589082dc0f6aacf101e85a5fb5
6
+ metadata.gz: b7f0438c001bccc0854ecf13b81909c056635a50489d074c8d91beb13ba3f5e00826663b20371ef7b0669a6cfcb3ee058da8eefc6ffcfd410e9da18d1dd82167
7
+ data.tar.gz: 05f8d06e52e06625655730e0c31ae57a8b6bec5c771809d73814413db90122477b143d494d0e8236f43782766673a0f0230b48480f9ce0cddb125b55065cc68a
@@ -1,5 +1,20 @@
1
1
  # Release History
2
2
 
3
+ ### 1.19.0 / 2020-02-11
4
+
5
+ #### Features
6
+
7
+ * Add Routine
8
+ * Add Dataset#create_routine
9
+ * Add Argument
10
+ * Update StandardSql classes to expose public initializer
11
+ * Add Data#ddl_target_routine and QueryJob#ddl_target_routine
12
+ * Allow row inserts to skip insert_id generation
13
+ * Streaming inserts using an insert_id are not able to be inserted as fast as inserts without an insert_id
14
+ * Add the ability for users to skip insert_id generation in order to speed up the inserts
15
+ * The default behavior continues to generate insert_id values for each row inserted
16
+ * Add yield documentation for Dataset#insert
17
+
3
18
  ### 1.18.1 / 2019-12-18
4
19
 
5
20
  #### Bug Fixes
@@ -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
  #
@@ -316,6 +316,21 @@ module Google
316
316
  job_gapi&.statistics&.query&.ddl_operation_performed
317
317
  end
318
318
 
319
+ ##
320
+ # The DDL target routine, in reference state. (See {Routine#reference?}.)
321
+ # Present only for `CREATE/DROP FUNCTION/PROCEDURE` queries. (See
322
+ # {#statement_type}.)
323
+ #
324
+ # @return [Google::Cloud::Bigquery::Routine, nil] The DDL target routine, in
325
+ # reference state.
326
+ #
327
+ def ddl_target_routine
328
+ ensure_service!
329
+ routine = job_gapi&.statistics&.query&.ddl_target_routine
330
+ return nil if routine.nil?
331
+ Google::Cloud::Bigquery::Routine.new_reference_from_gapi routine, service
332
+ end
333
+
319
334
  ##
320
335
  # The DDL target table, in reference state. (See {Table#reference?}.)
321
336
  # Present only for `CREATE/DROP TABLE/VIEW` queries. (See
@@ -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"
@@ -731,8 +732,7 @@ module Google
731
732
  #
732
733
  def tables token: nil, max: nil
733
734
  ensure_service!
734
- options = { token: token, max: max }
735
- gapi = service.list_tables dataset_id, options
735
+ gapi = service.list_tables dataset_id, token: token, max: max
736
736
  Table::List.from_gapi gapi, service, dataset_id, max
737
737
  end
738
738
 
@@ -817,6 +817,174 @@ module Google
817
817
  Model::List.from_gapi gapi, service, dataset_id, max
818
818
  end
819
819
 
820
+ ##
821
+ # Creates a new routine. The following attributes may be set in the yielded block:
822
+ # {Routine::Updater#routine_type=}, {Routine::Updater#language=}, {Routine::Updater#arguments=},
823
+ # {Routine::Updater#return_type=}, {Routine::Updater#imported_libraries=}, {Routine::Updater#body=}, and
824
+ # {Routine::Updater#description=}.
825
+ #
826
+ # @param [String] routine_id The ID of the routine. The ID must contain only
827
+ # letters (a-z, A-Z), numbers (0-9), or underscores (_). The maximum length
828
+ # is 256 characters.
829
+ # @yield [routine] A block for setting properties on the routine.
830
+ # @yieldparam [Google::Cloud::Bigquery::Routine::Updater] routine An updater to set additional properties on the
831
+ # routine.
832
+ #
833
+ # @return [Google::Cloud::Bigquery::Routine] A new routine object.
834
+ #
835
+ # @example
836
+ # require "google/cloud/bigquery"
837
+ #
838
+ # bigquery = Google::Cloud::Bigquery.new
839
+ # dataset = bigquery.dataset "my_dataset"
840
+ #
841
+ # routine = dataset.create_routine "my_routine" do |r|
842
+ # r.routine_type = "SCALAR_FUNCTION"
843
+ # r.language = "SQL"
844
+ # r.arguments = [
845
+ # Google::Cloud::Bigquery::Argument.new(name: "x", data_type: "INT64")
846
+ # ]
847
+ # r.body = "x * 3"
848
+ # r.description = "My routine description"
849
+ # end
850
+ #
851
+ # puts routine.routine_id
852
+ #
853
+ # @example Extended example:
854
+ # require "google/cloud/bigquery"
855
+ #
856
+ # bigquery = Google::Cloud::Bigquery.new
857
+ # dataset = bigquery.dataset "my_dataset"
858
+ # routine = dataset.create_routine "my_routine" do |r|
859
+ # r.routine_type = "SCALAR_FUNCTION"
860
+ # r.language = :SQL
861
+ # r.body = "(SELECT SUM(IF(elem.name = \"foo\",elem.val,null)) FROM UNNEST(arr) AS elem)"
862
+ # r.arguments = [
863
+ # Google::Cloud::Bigquery::Argument.new(
864
+ # name: "arr",
865
+ # argument_kind: "FIXED_TYPE",
866
+ # data_type: Google::Cloud::Bigquery::StandardSql::DataType.new(
867
+ # type_kind: "ARRAY",
868
+ # array_element_type: Google::Cloud::Bigquery::StandardSql::DataType.new(
869
+ # type_kind: "STRUCT",
870
+ # struct_type: Google::Cloud::Bigquery::StandardSql::StructType.new(
871
+ # fields: [
872
+ # Google::Cloud::Bigquery::StandardSql::Field.new(
873
+ # name: "name",
874
+ # type: Google::Cloud::Bigquery::StandardSql::DataType.new(type_kind: "STRING")
875
+ # ),
876
+ # Google::Cloud::Bigquery::StandardSql::Field.new(
877
+ # name: "val",
878
+ # type: Google::Cloud::Bigquery::StandardSql::DataType.new(type_kind: "INT64")
879
+ # )
880
+ # ]
881
+ # )
882
+ # )
883
+ # )
884
+ # )
885
+ # ]
886
+ # end
887
+ #
888
+ # @!group Routine
889
+ #
890
+ def create_routine routine_id
891
+ ensure_service!
892
+ new_tb = Google::Apis::BigqueryV2::Routine.new(
893
+ routine_reference: Google::Apis::BigqueryV2::RoutineReference.new(
894
+ project_id: project_id, dataset_id: dataset_id, routine_id: routine_id
895
+ )
896
+ )
897
+ updater = Routine::Updater.new new_tb
898
+
899
+ yield updater if block_given?
900
+
901
+ gapi = service.insert_routine dataset_id, updater.to_gapi
902
+ Routine.from_gapi gapi, service
903
+ end
904
+
905
+ ##
906
+ # Retrieves an existing routine by ID.
907
+ #
908
+ # @param [String] routine_id The ID of a routine.
909
+ # @param [Boolean] skip_lookup Optionally create just a local reference
910
+ # object without verifying that the resource exists on the BigQuery
911
+ # service. Calls made on this object will raise errors if the resource
912
+ # does not exist. Default is `false`. Optional.
913
+ #
914
+ # @return [Google::Cloud::Bigquery::Routine, nil] Returns `nil` if the
915
+ # routine does not exist.
916
+ #
917
+ # @example
918
+ # require "google/cloud/bigquery"
919
+ #
920
+ # bigquery = Google::Cloud::Bigquery.new
921
+ # dataset = bigquery.dataset "my_dataset"
922
+ #
923
+ # routine = dataset.routine "my_routine"
924
+ # puts routine.routine_id
925
+ #
926
+ # @example Avoid retrieving the routine resource with `skip_lookup`:
927
+ # require "google/cloud/bigquery"
928
+ #
929
+ # bigquery = Google::Cloud::Bigquery.new
930
+ #
931
+ # dataset = bigquery.dataset "my_dataset"
932
+ #
933
+ # routine = dataset.routine "my_routine", skip_lookup: true
934
+ #
935
+ # @!group Routine
936
+ #
937
+ def routine routine_id, skip_lookup: nil
938
+ ensure_service!
939
+ return Routine.new_reference project_id, dataset_id, routine_id, service if skip_lookup
940
+ gapi = service.get_routine dataset_id, routine_id
941
+ Routine.from_gapi gapi, service
942
+ rescue Google::Cloud::NotFoundError
943
+ nil
944
+ end
945
+
946
+ ##
947
+ # Retrieves the list of routines belonging to the dataset.
948
+ #
949
+ # @param [String] token A previously-returned page token representing
950
+ # part of the larger set of results to view.
951
+ # @param [Integer] max Maximum number of routines to return.
952
+ # @param [String] filter If set, then only the routines matching this filter are returned. The current supported
953
+ # form is `routineType:`, with a {Routine#routine_type} enum value. Example: `routineType:SCALAR_FUNCTION`.
954
+ #
955
+ # @return [Array<Google::Cloud::Bigquery::Routine>] An array of routines
956
+ # (See {Google::Cloud::Bigquery::Routine::List})
957
+ #
958
+ # @example
959
+ # require "google/cloud/bigquery"
960
+ #
961
+ # bigquery = Google::Cloud::Bigquery.new
962
+ # dataset = bigquery.dataset "my_dataset"
963
+ #
964
+ # routines = dataset.routines
965
+ # routines.each do |routine|
966
+ # puts routine.routine_id
967
+ # end
968
+ #
969
+ # @example Retrieve all routines: (See {Routine::List#all})
970
+ # require "google/cloud/bigquery"
971
+ #
972
+ # bigquery = Google::Cloud::Bigquery.new
973
+ # dataset = bigquery.dataset "my_dataset"
974
+ #
975
+ # routines = dataset.routines
976
+ # routines.all do |routine|
977
+ # puts routine.routine_id
978
+ # end
979
+ #
980
+ # @!group Routine
981
+ #
982
+ def routines token: nil, max: nil, filter: nil
983
+ ensure_service!
984
+ gapi = service.list_routines dataset_id, token: token, max: max, filter: filter
985
+ Routine::List.from_gapi gapi, service, dataset_id, max, filter: filter
986
+ end
987
+
820
988
  ##
821
989
  # Queries data by creating a [query
822
990
  # job](https://cloud.google.com/bigquery/docs/query-overview#query_jobs).
@@ -1073,7 +1241,7 @@ module Google
1073
1241
  #
1074
1242
  # job.wait_until_done!
1075
1243
  # if !job.failed?
1076
- # table_ref = job.ddl_target_table
1244
+ # table_ref = job.ddl_target_table # Or ddl_target_routine for CREATE/DROP FUNCTION/PROCEDURE
1077
1245
  # end
1078
1246
  #
1079
1247
  # @example Execute a DML statement:
@@ -1321,7 +1489,7 @@ module Google
1321
1489
  #
1322
1490
  # data = bigquery.query "CREATE TABLE my_table (x INT64)"
1323
1491
  #
1324
- # table_ref = data.ddl_target_table
1492
+ # table_ref = data.ddl_target_table # Or ddl_target_routine for CREATE/DROP FUNCTION/PROCEDURE
1325
1493
  #
1326
1494
  # @example Execute a DML statement:
1327
1495
  # require "google/cloud/bigquery"
@@ -1942,7 +2110,7 @@ module Google
1942
2110
  # dataset = bigquery.dataset "my_dataset", skip_lookup: true
1943
2111
  # dataset.exists? # true
1944
2112
  #
1945
- def exists? force: nil
2113
+ def exists? force: false
1946
2114
  return gapi_exists? if force
1947
2115
  # If we have a memoized value, return it
1948
2116
  return @exists unless @exists.nil?
@@ -2052,7 +2220,7 @@ module Google
2052
2220
  end
2053
2221
 
2054
2222
  ##
2055
- # @private New lazy Dataset object without making an HTTP request.
2223
+ # @private New lazy Dataset object without making an HTTP request, for use with the skip_lookup option.
2056
2224
  def self.new_reference project_id, dataset_id, service
2057
2225
  raise ArgumentError, "dataset_id is required" unless dataset_id
2058
2226
  new.tap do |b|
@@ -2083,12 +2251,13 @@ module Google
2083
2251
  # @param [String] table_id The ID of the destination table.
2084
2252
  # @param [Hash, Array<Hash>] rows A hash object or array of hash objects
2085
2253
  # 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.
2254
+ # @param [Array<String|Symbol>, Symbol] insert_ids A unique ID for each row. BigQuery uses this property to
2255
+ # detect duplicate insertion requests on a best-effort basis. For more information, see [data
2256
+ # consistency](https://cloud.google.com/bigquery/streaming-data-into-bigquery#dataconsistency). Optional. If
2257
+ # not provided, the client library will assign a UUID to each row before the request is sent.
2258
+ #
2259
+ # The value `:skip` can be provided to skip the generation of IDs for all rows, or to skip the generation of an
2260
+ # ID for a specific row in the array.
2092
2261
  # @param [Boolean] skip_invalid Insert all valid rows of a request, even
2093
2262
  # if invalid rows exist. The default value is `false`, which causes
2094
2263
  # the entire request to fail if any invalid rows exist.
@@ -2099,6 +2268,12 @@ module Google
2099
2268
  # a new table with the given `table_id`, if no table is found for
2100
2269
  # `table_id`. The default value is false.
2101
2270
  #
2271
+ # @yield [table] a block for setting the table
2272
+ # @yieldparam [Google::Cloud::Bigquery::Table::Updater] table An updater
2273
+ # to set additional properties on the table in the API request to
2274
+ # create it. Only used when `autocreate` is set and the table does not
2275
+ # already exist.
2276
+ #
2102
2277
  # @return [Google::Cloud::Bigquery::InsertResponse] An insert response
2103
2278
  # object.
2104
2279
  #
@@ -2144,32 +2319,19 @@ module Google
2144
2319
  #
2145
2320
  # @!group Data
2146
2321
  #
2147
- def insert table_id, rows, insert_ids: nil, skip_invalid: nil, ignore_unknown: nil, autocreate: nil
2322
+ def insert table_id, rows, insert_ids: nil, skip_invalid: nil, ignore_unknown: nil, autocreate: nil, &block
2148
2323
  rows = [rows] if rows.is_a? Hash
2324
+ raise ArgumentError, "No rows provided" if rows.empty?
2325
+
2326
+ insert_ids = Array.new(rows.count) { :skip } if insert_ids == :skip
2149
2327
  insert_ids = Array insert_ids
2150
2328
  if insert_ids.count.positive? && insert_ids.count != rows.count
2151
2329
  raise ArgumentError, "insert_ids must be the same size as rows"
2152
2330
  end
2153
2331
 
2154
2332
  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
2333
+ insert_data_with_autocreate table_id, rows, skip_invalid: skip_invalid, ignore_unknown: ignore_unknown,
2334
+ insert_ids: insert_ids, &block
2173
2335
  else
2174
2336
  insert_data table_id, rows, skip_invalid: skip_invalid, ignore_unknown: ignore_unknown,
2175
2337
  insert_ids: insert_ids
@@ -2239,15 +2401,30 @@ module Google
2239
2401
 
2240
2402
  protected
2241
2403
 
2242
- def insert_data table_id, rows, skip_invalid: nil, ignore_unknown: nil,
2243
- insert_ids: nil
2404
+ def insert_data_with_autocreate table_id, rows, skip_invalid: nil, ignore_unknown: nil, insert_ids: nil
2405
+ insert_data table_id, rows, skip_invalid: skip_invalid, ignore_unknown: ignore_unknown, insert_ids: insert_ids
2406
+ rescue Google::Cloud::NotFoundError
2407
+ sleep rand(1..60)
2408
+ begin
2409
+ create_table table_id do |tbl_updater|
2410
+ yield tbl_updater if block_given?
2411
+ end
2412
+ # rubocop:disable Lint/HandleExceptions
2413
+ rescue Google::Cloud::AlreadyExistsError
2414
+ end
2415
+ # rubocop:enable Lint/HandleExceptions
2416
+
2417
+ sleep 60
2418
+ retry
2419
+ end
2420
+
2421
+ def insert_data table_id, rows, skip_invalid: nil, ignore_unknown: nil, insert_ids: nil
2244
2422
  rows = [rows] if rows.is_a? Hash
2245
2423
  raise ArgumentError, "No rows provided" if rows.empty?
2246
2424
  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
2425
+ gapi = service.insert_tabledata dataset_id, table_id, rows, skip_invalid: skip_invalid,
2426
+ ignore_unknown: ignore_unknown,
2427
+ insert_ids: insert_ids
2251
2428
  InsertResponse.from_gapi rows, gapi
2252
2429
  end
2253
2430
 
@@ -2444,14 +2621,14 @@ module Google
2444
2621
  end
2445
2622
 
2446
2623
  ##
2447
- # Yielded to a block to accumulate changes for a patch request.
2624
+ # Yielded to a block to accumulate changes for a create request. See {Project#create_dataset}.
2448
2625
  class Updater < Dataset
2449
2626
  ##
2450
- # A list of attributes that were updated.
2627
+ # @private A list of attributes that were updated.
2451
2628
  attr_reader :updates
2452
2629
 
2453
2630
  ##
2454
- # Create an Updater object.
2631
+ # @private Create an Updater object.
2455
2632
  def initialize gapi
2456
2633
  @updates = []
2457
2634
  @gapi = gapi
@@ -2468,8 +2645,109 @@ module Google
2468
2645
  @access
2469
2646
  end
2470
2647
 
2648
+ # rubocop:disable Style/MethodDefParentheses
2649
+
2650
+ ##
2651
+ # @raise [RuntimeError] not implemented
2652
+ def delete(*)
2653
+ raise "not implemented in #{self.class}"
2654
+ end
2655
+
2656
+ ##
2657
+ # @raise [RuntimeError] not implemented
2658
+ def create_table(*)
2659
+ raise "not implemented in #{self.class}"
2660
+ end
2661
+
2662
+ ##
2663
+ # @raise [RuntimeError] not implemented
2664
+ def create_view(*)
2665
+ raise "not implemented in #{self.class}"
2666
+ end
2667
+
2668
+ ##
2669
+ # @raise [RuntimeError] not implemented
2670
+ def table(*)
2671
+ raise "not implemented in #{self.class}"
2672
+ end
2673
+
2674
+ ##
2675
+ # @raise [RuntimeError] not implemented
2676
+ def tables(*)
2677
+ raise "not implemented in #{self.class}"
2678
+ end
2679
+
2680
+ ##
2681
+ # @raise [RuntimeError] not implemented
2682
+ def model(*)
2683
+ raise "not implemented in #{self.class}"
2684
+ end
2685
+
2471
2686
  ##
2472
- # Make sure any access changes are saved
2687
+ # @raise [RuntimeError] not implemented
2688
+ def models(*)
2689
+ raise "not implemented in #{self.class}"
2690
+ end
2691
+
2692
+ ##
2693
+ # @raise [RuntimeError] not implemented
2694
+ def create_routine(*)
2695
+ raise "not implemented in #{self.class}"
2696
+ end
2697
+
2698
+ ##
2699
+ # @raise [RuntimeError] not implemented
2700
+ def routine(*)
2701
+ raise "not implemented in #{self.class}"
2702
+ end
2703
+
2704
+ ##
2705
+ # @raise [RuntimeError] not implemented
2706
+ def routines(*)
2707
+ raise "not implemented in #{self.class}"
2708
+ end
2709
+
2710
+ ##
2711
+ # @raise [RuntimeError] not implemented
2712
+ def query_job(*)
2713
+ raise "not implemented in #{self.class}"
2714
+ end
2715
+
2716
+ ##
2717
+ # @raise [RuntimeError] not implemented
2718
+ def query(*)
2719
+ raise "not implemented in #{self.class}"
2720
+ end
2721
+
2722
+ ##
2723
+ # @raise [RuntimeError] not implemented
2724
+ def external(*)
2725
+ raise "not implemented in #{self.class}"
2726
+ end
2727
+
2728
+ ##
2729
+ # @raise [RuntimeError] not implemented
2730
+ def load_job(*)
2731
+ raise "not implemented in #{self.class}"
2732
+ end
2733
+
2734
+ ##
2735
+ # @raise [RuntimeError] not implemented
2736
+ def load(*)
2737
+ raise "not implemented in #{self.class}"
2738
+ end
2739
+
2740
+ ##
2741
+ # @raise [RuntimeError] not implemented
2742
+ def reload!
2743
+ raise "not implemented in #{self.class}"
2744
+ end
2745
+ alias refresh! reload!
2746
+
2747
+ # rubocop:enable Style/MethodDefParentheses
2748
+
2749
+ ##
2750
+ # @private Make sure any access changes are saved
2473
2751
  def check_for_mutated_access!
2474
2752
  return if @access.nil?
2475
2753
  return unless @access.changed?
@@ -2477,6 +2755,8 @@ module Google
2477
2755
  patch_gapi! :access
2478
2756
  end
2479
2757
 
2758
+ ##
2759
+ # @private
2480
2760
  def to_gapi
2481
2761
  check_for_mutated_access!
2482
2762
  @gapi