google-cloud-bigquery 1.14.0 → 1.42.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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/AUTHENTICATION.md +17 -54
  3. data/CHANGELOG.md +377 -0
  4. data/CONTRIBUTING.md +328 -116
  5. data/LOGGING.md +1 -1
  6. data/OVERVIEW.md +21 -20
  7. data/TROUBLESHOOTING.md +2 -8
  8. data/lib/google/cloud/bigquery/argument.rb +197 -0
  9. data/lib/google/cloud/bigquery/convert.rb +155 -173
  10. data/lib/google/cloud/bigquery/copy_job.rb +74 -26
  11. data/lib/google/cloud/bigquery/credentials.rb +5 -12
  12. data/lib/google/cloud/bigquery/data.rb +109 -18
  13. data/lib/google/cloud/bigquery/dataset/access.rb +474 -52
  14. data/lib/google/cloud/bigquery/dataset/list.rb +7 -13
  15. data/lib/google/cloud/bigquery/dataset/tag.rb +67 -0
  16. data/lib/google/cloud/bigquery/dataset.rb +1044 -287
  17. data/lib/google/cloud/bigquery/external/avro_source.rb +107 -0
  18. data/lib/google/cloud/bigquery/external/bigtable_source/column.rb +404 -0
  19. data/lib/google/cloud/bigquery/external/bigtable_source/column_family.rb +945 -0
  20. data/lib/google/cloud/bigquery/external/bigtable_source.rb +230 -0
  21. data/lib/google/cloud/bigquery/external/csv_source.rb +481 -0
  22. data/lib/google/cloud/bigquery/external/data_source.rb +771 -0
  23. data/lib/google/cloud/bigquery/external/json_source.rb +170 -0
  24. data/lib/google/cloud/bigquery/external/parquet_source.rb +148 -0
  25. data/lib/google/cloud/bigquery/external/sheets_source.rb +166 -0
  26. data/lib/google/cloud/bigquery/external.rb +50 -2256
  27. data/lib/google/cloud/bigquery/extract_job.rb +226 -61
  28. data/lib/google/cloud/bigquery/insert_response.rb +1 -3
  29. data/lib/google/cloud/bigquery/job/list.rb +10 -14
  30. data/lib/google/cloud/bigquery/job.rb +289 -14
  31. data/lib/google/cloud/bigquery/load_job.rb +810 -136
  32. data/lib/google/cloud/bigquery/model/list.rb +5 -9
  33. data/lib/google/cloud/bigquery/model.rb +247 -16
  34. data/lib/google/cloud/bigquery/policy.rb +432 -0
  35. data/lib/google/cloud/bigquery/project/list.rb +6 -11
  36. data/lib/google/cloud/bigquery/project.rb +509 -250
  37. data/lib/google/cloud/bigquery/query_job.rb +594 -128
  38. data/lib/google/cloud/bigquery/routine/list.rb +165 -0
  39. data/lib/google/cloud/bigquery/routine.rb +1227 -0
  40. data/lib/google/cloud/bigquery/schema/field.rb +413 -63
  41. data/lib/google/cloud/bigquery/schema.rb +221 -48
  42. data/lib/google/cloud/bigquery/service.rb +204 -112
  43. data/lib/google/cloud/bigquery/standard_sql.rb +269 -53
  44. data/lib/google/cloud/bigquery/table/async_inserter.rb +86 -43
  45. data/lib/google/cloud/bigquery/table/list.rb +6 -11
  46. data/lib/google/cloud/bigquery/table.rb +1470 -377
  47. data/lib/google/cloud/bigquery/time.rb +6 -0
  48. data/lib/google/cloud/bigquery/version.rb +1 -1
  49. data/lib/google/cloud/bigquery.rb +4 -6
  50. data/lib/google-cloud-bigquery.rb +14 -13
  51. metadata +66 -38
@@ -0,0 +1,945 @@
1
+ # Copyright 2021 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ require "google/apis/bigquery_v2"
17
+ require "base64"
18
+ require "google/cloud/bigquery/external/bigtable_source/column"
19
+
20
+ module Google
21
+ module Cloud
22
+ module Bigquery
23
+ module External
24
+ class BigtableSource < External::DataSource
25
+ ##
26
+ # # BigtableSource::ColumnFamily
27
+ #
28
+ # A Bigtable column family used to expose in the table schema along
29
+ # with its types and columns.
30
+ #
31
+ # @example
32
+ # require "google/cloud/bigquery"
33
+ #
34
+ # bigquery = Google::Cloud::Bigquery.new
35
+ #
36
+ # bigtable_url = "https://googleapis.com/bigtable/projects/..."
37
+ # bigtable_table = bigquery.external bigtable_url do |bt|
38
+ # bt.rowkey_as_string = true
39
+ # bt.add_family "user" do |u|
40
+ # u.add_string "name"
41
+ # u.add_string "email"
42
+ # u.add_integer "age"
43
+ # u.add_boolean "active"
44
+ # end
45
+ # end
46
+ #
47
+ # data = bigquery.query "SELECT * FROM my_ext_table",
48
+ # external: { my_ext_table: bigtable_table }
49
+ #
50
+ # # Iterate over the first page of results
51
+ # data.each do |row|
52
+ # puts row[:name]
53
+ # end
54
+ # # Retrieve the next page of results
55
+ # data = data.next if data.next?
56
+ #
57
+ class ColumnFamily
58
+ ##
59
+ # @private Create an empty BigtableSource::ColumnFamily object.
60
+ def initialize
61
+ @gapi = Google::Apis::BigqueryV2::BigtableColumnFamily.new
62
+ @columns = []
63
+ end
64
+
65
+ ##
66
+ # The encoding of the values when the type is not `STRING`.
67
+ #
68
+ # @return [String]
69
+ #
70
+ # @example
71
+ # require "google/cloud/bigquery"
72
+ #
73
+ # bigquery = Google::Cloud::Bigquery.new
74
+ #
75
+ # bigtable_url = "https://googleapis.com/bigtable/projects/..."
76
+ # bigtable_table = bigquery.external bigtable_url do |bt|
77
+ # bt.add_family "user" do |u|
78
+ # u.encoding = "UTF-8"
79
+ # end
80
+ # end
81
+ #
82
+ # bigtable_table.families[0].encoding #=> "UTF-8"
83
+ #
84
+ def encoding
85
+ @gapi.encoding
86
+ end
87
+
88
+ ##
89
+ # Set the encoding of the values when the type is not `STRING`.
90
+ # Acceptable encoding values are:
91
+ #
92
+ # * `TEXT` - indicates values are alphanumeric text strings.
93
+ # * `BINARY` - indicates values are encoded using HBase
94
+ # `Bytes.toBytes` family of functions. This can be overridden on a
95
+ # column.
96
+ #
97
+ # @param [String] new_encoding New encoding value
98
+ #
99
+ # @example
100
+ # require "google/cloud/bigquery"
101
+ #
102
+ # bigquery = Google::Cloud::Bigquery.new
103
+ #
104
+ # bigtable_url = "https://googleapis.com/bigtable/projects/..."
105
+ # bigtable_table = bigquery.external bigtable_url do |bt|
106
+ # bt.add_family "user" do |u|
107
+ # u.encoding = "UTF-8"
108
+ # end
109
+ # end
110
+ #
111
+ # bigtable_table.families[0].encoding #=> "UTF-8"
112
+ #
113
+ def encoding= new_encoding
114
+ frozen_check!
115
+ @gapi.encoding = new_encoding
116
+ end
117
+
118
+ ##
119
+ # Identifier of the column family.
120
+ #
121
+ # @return [String]
122
+ #
123
+ # @example
124
+ # require "google/cloud/bigquery"
125
+ #
126
+ # bigquery = Google::Cloud::Bigquery.new
127
+ #
128
+ # bigtable_url = "https://googleapis.com/bigtable/projects/..."
129
+ # bigtable_table = bigquery.external bigtable_url do |bt|
130
+ # bt.add_family "user"
131
+ # end
132
+ #
133
+ # bigtable_table.families[0].family_id #=> "user"
134
+ #
135
+ def family_id
136
+ @gapi.family_id
137
+ end
138
+
139
+ ##
140
+ # Set the identifier of the column family.
141
+ #
142
+ # @param [String] new_family_id New family_id value
143
+ #
144
+ # @example
145
+ # require "google/cloud/bigquery"
146
+ #
147
+ # bigquery = Google::Cloud::Bigquery.new
148
+ #
149
+ # bigtable_url = "https://googleapis.com/bigtable/projects/..."
150
+ # bigtable_table = bigquery.external bigtable_url do |bt|
151
+ # bt.add_family "user"
152
+ # end
153
+ #
154
+ # bigtable_table.families[0].family_id #=> "user"
155
+ # bigtable_table.families[0].family_id = "User"
156
+ # bigtable_table.families[0].family_id #=> "User"
157
+ #
158
+ def family_id= new_family_id
159
+ frozen_check!
160
+ @gapi.family_id = new_family_id
161
+ end
162
+
163
+ ##
164
+ # Whether only the latest version of value are exposed for all
165
+ # columns in this column family.
166
+ #
167
+ # @return [Boolean]
168
+ #
169
+ # @example
170
+ # require "google/cloud/bigquery"
171
+ #
172
+ # bigquery = Google::Cloud::Bigquery.new
173
+ #
174
+ # bigtable_url = "https://googleapis.com/bigtable/projects/..."
175
+ # bigtable_table = bigquery.external bigtable_url do |bt|
176
+ # bt.add_family "user" do |u|
177
+ # u.latest = true
178
+ # end
179
+ # end
180
+ #
181
+ # bigtable_table.families[0].latest #=> true
182
+ #
183
+ def latest
184
+ @gapi.only_read_latest
185
+ end
186
+
187
+ ##
188
+ # Set whether only the latest version of value are exposed for all
189
+ # columns in this column family.
190
+ #
191
+ # @param [Boolean] new_latest New latest value
192
+ #
193
+ # @example
194
+ # require "google/cloud/bigquery"
195
+ #
196
+ # bigquery = Google::Cloud::Bigquery.new
197
+ #
198
+ # bigtable_url = "https://googleapis.com/bigtable/projects/..."
199
+ # bigtable_table = bigquery.external bigtable_url do |bt|
200
+ # bt.add_family "user" do |u|
201
+ # u.latest = true
202
+ # end
203
+ # end
204
+ #
205
+ # bigtable_table.families[0].latest #=> true
206
+ #
207
+ def latest= new_latest
208
+ frozen_check!
209
+ @gapi.only_read_latest = new_latest
210
+ end
211
+
212
+ ##
213
+ # The type to convert the value in cells of this column family. The
214
+ # values are expected to be encoded using HBase `Bytes.toBytes`
215
+ # function when using the `BINARY` encoding value. The following
216
+ # BigQuery types are allowed:
217
+ #
218
+ # * `BYTES`
219
+ # * `STRING`
220
+ # * `INTEGER`
221
+ # * `FLOAT`
222
+ # * `BOOLEAN`
223
+ #
224
+ # Default type is `BYTES`. This can be overridden on a column.
225
+ #
226
+ # @return [String]
227
+ #
228
+ # @example
229
+ # require "google/cloud/bigquery"
230
+ #
231
+ # bigquery = Google::Cloud::Bigquery.new
232
+ #
233
+ # bigtable_url = "https://googleapis.com/bigtable/projects/..."
234
+ # bigtable_table = bigquery.external bigtable_url do |bt|
235
+ # bt.add_family "user" do |u|
236
+ # u.type = "STRING"
237
+ # end
238
+ # end
239
+ #
240
+ # bigtable_table.families[0].type #=> "STRING"
241
+ #
242
+ def type
243
+ @gapi.type
244
+ end
245
+
246
+ ##
247
+ # Set the type to convert the value in cells of this column family.
248
+ # The values are expected to be encoded using HBase `Bytes.toBytes`
249
+ # function when using the `BINARY` encoding value. The following
250
+ # BigQuery types are allowed:
251
+ #
252
+ # * `BYTES`
253
+ # * `STRING`
254
+ # * `INTEGER`
255
+ # * `FLOAT`
256
+ # * `BOOLEAN`
257
+ #
258
+ # Default type is `BYTES`. This can be overridden on a column.
259
+ #
260
+ # @param [String] new_type New type value
261
+ #
262
+ # @example
263
+ # require "google/cloud/bigquery"
264
+ #
265
+ # bigquery = Google::Cloud::Bigquery.new
266
+ #
267
+ # bigtable_url = "https://googleapis.com/bigtable/projects/..."
268
+ # bigtable_table = bigquery.external bigtable_url do |bt|
269
+ # bt.add_family "user" do |u|
270
+ # u.type = "STRING"
271
+ # end
272
+ # end
273
+ #
274
+ # bigtable_table.families[0].type #=> "STRING"
275
+ #
276
+ def type= new_type
277
+ frozen_check!
278
+ @gapi.type = new_type
279
+ end
280
+
281
+ ##
282
+ # Lists of columns that should be exposed as individual fields.
283
+ #
284
+ # @return [Array<BigtableSource::Column>]
285
+ #
286
+ # @example
287
+ # require "google/cloud/bigquery"
288
+ #
289
+ # bigquery = Google::Cloud::Bigquery.new
290
+ #
291
+ # bigtable_url = "https://googleapis.com/bigtable/projects/..."
292
+ # bigtable_table = bigquery.external bigtable_url do |bt|
293
+ # bt.rowkey_as_string = true
294
+ # bt.add_family "user" do |u|
295
+ # u.add_string "name"
296
+ # u.add_string "email"
297
+ # u.add_integer "age"
298
+ # u.add_boolean "active"
299
+ # end
300
+ # end
301
+ #
302
+ # bigtable_table.families[0].columns.count #=> 4
303
+ #
304
+ def columns
305
+ @columns
306
+ end
307
+
308
+ ##
309
+ # Add a column to the column family to expose in the table schema
310
+ # along with its types.
311
+ #
312
+ # @param [String] qualifier Qualifier of the column. See
313
+ # {BigtableSource::Column#qualifier}.
314
+ # @param [String] as A valid identifier to be used as the column
315
+ # field name if the qualifier is not a valid BigQuery field
316
+ # identifier (i.e. does not match `[a-zA-Z][a-zA-Z0-9_]*`). See
317
+ # {BigtableSource::Column#field_name}.
318
+ # @param [String] type The type to convert the value in cells of
319
+ # this column. See {BigtableSource::Column#type}. The following
320
+ # BigQuery types are allowed:
321
+ #
322
+ # * `BYTES`
323
+ # * `STRING`
324
+ # * `INTEGER`
325
+ # * `FLOAT`
326
+ # * `BOOLEAN`
327
+ #
328
+ # @yield [column] a block for setting the column
329
+ # @yieldparam [BigtableSource::Column] column the column object
330
+ #
331
+ # @return [Array<BigtableSource::Column>]
332
+ #
333
+ # @example
334
+ # require "google/cloud/bigquery"
335
+ #
336
+ # bigquery = Google::Cloud::Bigquery.new
337
+ #
338
+ # bigtable_url = "https://googleapis.com/bigtable/projects/..."
339
+ # bigtable_table = bigquery.external bigtable_url do |bt|
340
+ # bt.rowkey_as_string = true
341
+ # bt.add_family "user" do |u|
342
+ # u.add_column "name", type: "STRING"
343
+ # end
344
+ # end
345
+ #
346
+ def add_column qualifier, as: nil, type: nil
347
+ frozen_check!
348
+ col = BigtableSource::Column.new
349
+ col.qualifier = qualifier
350
+ col.field_name = as if as
351
+ col.type = type if type
352
+ yield col if block_given?
353
+ @columns << col
354
+ col
355
+ end
356
+
357
+ ##
358
+ # Add a column to the column family to expose in the table schema
359
+ # that is specified as the `BYTES` type.
360
+ #
361
+ # @param [String] qualifier Qualifier of the column. See
362
+ # {BigtableSource::Column#qualifier}.
363
+ # @param [String] as A valid identifier to be used as the column
364
+ # field name if the qualifier is not a valid BigQuery field
365
+ # identifier (i.e. does not match `[a-zA-Z][a-zA-Z0-9_]*`). See
366
+ # {BigtableSource::Column#field_name}.
367
+ #
368
+ # @yield [column] a block for setting the column
369
+ # @yieldparam [BigtableSource::Column] column the column object
370
+ #
371
+ # @return [Array<BigtableSource::Column>]
372
+ #
373
+ # @example
374
+ # require "google/cloud/bigquery"
375
+ #
376
+ # bigquery = Google::Cloud::Bigquery.new
377
+ #
378
+ # bigtable_url = "https://googleapis.com/bigtable/projects/..."
379
+ # bigtable_table = bigquery.external bigtable_url do |bt|
380
+ # bt.rowkey_as_string = true
381
+ # bt.add_family "user" do |u|
382
+ # u.add_bytes "avatar"
383
+ # end
384
+ # end
385
+ #
386
+ def add_bytes qualifier, as: nil
387
+ col = add_column qualifier, as: as, type: "BYTES"
388
+ yield col if block_given?
389
+ col
390
+ end
391
+
392
+ ##
393
+ # Add a column to the column family to expose in the table schema
394
+ # that is specified as the `STRING` type.
395
+ #
396
+ # @param [String] qualifier Qualifier of the column. See
397
+ # {BigtableSource::Column#qualifier}.
398
+ # @param [String] as A valid identifier to be used as the column
399
+ # field name if the qualifier is not a valid BigQuery field
400
+ # identifier (i.e. does not match `[a-zA-Z][a-zA-Z0-9_]*`). See
401
+ # {BigtableSource::Column#field_name}.
402
+ #
403
+ # @yield [column] a block for setting the column
404
+ # @yieldparam [BigtableSource::Column] column the column object
405
+ #
406
+ # @return [Array<BigtableSource::Column>]
407
+ #
408
+ # @example
409
+ # require "google/cloud/bigquery"
410
+ #
411
+ # bigquery = Google::Cloud::Bigquery.new
412
+ #
413
+ # bigtable_url = "https://googleapis.com/bigtable/projects/..."
414
+ # bigtable_table = bigquery.external bigtable_url do |bt|
415
+ # bt.rowkey_as_string = true
416
+ # bt.add_family "user" do |u|
417
+ # u.add_string "name"
418
+ # end
419
+ # end
420
+ #
421
+ def add_string qualifier, as: nil
422
+ col = add_column qualifier, as: as, type: "STRING"
423
+ yield col if block_given?
424
+ col
425
+ end
426
+
427
+ ##
428
+ # Add a column to the column family to expose in the table schema
429
+ # that is specified as the `INTEGER` type.
430
+ #
431
+ # @param [String] qualifier Qualifier of the column. See
432
+ # {BigtableSource::Column#qualifier}.
433
+ # @param [String] as A valid identifier to be used as the column
434
+ # field name if the qualifier is not a valid BigQuery field
435
+ # identifier (i.e. does not match `[a-zA-Z][a-zA-Z0-9_]*`). See
436
+ # {BigtableSource::Column#field_name}.
437
+ #
438
+ # @yield [column] a block for setting the column
439
+ # @yieldparam [BigtableSource::Column] column the column object
440
+ #
441
+ # @return [Array<BigtableSource::Column>]
442
+ #
443
+ # @example
444
+ # require "google/cloud/bigquery"
445
+ #
446
+ # bigquery = Google::Cloud::Bigquery.new
447
+ #
448
+ # bigtable_url = "https://googleapis.com/bigtable/projects/..."
449
+ # bigtable_table = bigquery.external bigtable_url do |bt|
450
+ # bt.rowkey_as_string = true
451
+ # bt.add_family "user" do |u|
452
+ # u.add_integer "age"
453
+ # end
454
+ # end
455
+ #
456
+ def add_integer qualifier, as: nil
457
+ col = add_column qualifier, as: as, type: "INTEGER"
458
+ yield col if block_given?
459
+ col
460
+ end
461
+
462
+ ##
463
+ # Add a column to the column family to expose in the table schema
464
+ # that is specified as the `FLOAT` type.
465
+ #
466
+ # @param [String] qualifier Qualifier of the column. See
467
+ # {BigtableSource::Column#qualifier}.
468
+ # @param [String] as A valid identifier to be used as the column
469
+ # field name if the qualifier is not a valid BigQuery field
470
+ # identifier (i.e. does not match `[a-zA-Z][a-zA-Z0-9_]*`). See
471
+ # {BigtableSource::Column#field_name}.
472
+ #
473
+ # @yield [column] a block for setting the column
474
+ # @yieldparam [BigtableSource::Column] column the column object
475
+ #
476
+ # @return [Array<BigtableSource::Column>]
477
+ #
478
+ # @example
479
+ # require "google/cloud/bigquery"
480
+ #
481
+ # bigquery = Google::Cloud::Bigquery.new
482
+ #
483
+ # bigtable_url = "https://googleapis.com/bigtable/projects/..."
484
+ # bigtable_table = bigquery.external bigtable_url do |bt|
485
+ # bt.rowkey_as_string = true
486
+ # bt.add_family "user" do |u|
487
+ # u.add_float "score"
488
+ # end
489
+ # end
490
+ #
491
+ def add_float qualifier, as: nil
492
+ col = add_column qualifier, as: as, type: "FLOAT"
493
+ yield col if block_given?
494
+ col
495
+ end
496
+
497
+ ##
498
+ # Add a column to the column family to expose in the table schema
499
+ # that is specified as the `BOOLEAN` type.
500
+ #
501
+ # @param [String] qualifier Qualifier of the column. See
502
+ # {BigtableSource::Column#qualifier}.
503
+ # @param [String] as A valid identifier to be used as the column
504
+ # field name if the qualifier is not a valid BigQuery field
505
+ # identifier (i.e. does not match `[a-zA-Z][a-zA-Z0-9_]*`). See
506
+ # {BigtableSource::Column#field_name}.
507
+ #
508
+ # @yield [column] a block for setting the column
509
+ # @yieldparam [BigtableSource::Column] column the column object
510
+ #
511
+ # @return [Array<BigtableSource::Column>]
512
+ #
513
+ # @example
514
+ # require "google/cloud/bigquery"
515
+ #
516
+ # bigquery = Google::Cloud::Bigquery.new
517
+ #
518
+ # bigtable_url = "https://googleapis.com/bigtable/projects/..."
519
+ # bigtable_table = bigquery.external bigtable_url do |bt|
520
+ # bt.rowkey_as_string = true
521
+ # bt.add_family "user" do |u|
522
+ # u.add_boolean "active"
523
+ # end
524
+ # end
525
+ #
526
+ def add_boolean qualifier, as: nil
527
+ col = add_column qualifier, as: as, type: "BOOLEAN"
528
+ yield col if block_given?
529
+ col
530
+ end
531
+
532
+ ##
533
+ # @private Google API Client object.
534
+ def to_gapi
535
+ @gapi.columns = @columns.map(&:to_gapi)
536
+ @gapi
537
+ end
538
+
539
+ ##
540
+ # @private Google API Client object.
541
+ def self.from_gapi gapi
542
+ new_fam = new
543
+ new_fam.instance_variable_set :@gapi, gapi
544
+ columns = Array(gapi.columns).map { |col_gapi| BigtableSource::Column.from_gapi col_gapi }
545
+ new_fam.instance_variable_set :@columns, columns
546
+ new_fam
547
+ end
548
+
549
+ ##
550
+ # @private
551
+ def freeze
552
+ @columns.map(&:freeze!)
553
+ @columns.freeze!
554
+ super
555
+ end
556
+
557
+ protected
558
+
559
+ def frozen_check!
560
+ return unless frozen?
561
+ raise ArgumentError, "Cannot modify external data source when frozen"
562
+ end
563
+ end
564
+
565
+ ##
566
+ # # BigtableSource::Column
567
+ #
568
+ # A Bigtable column to expose in the table schema along with its
569
+ # types.
570
+ #
571
+ # @example
572
+ # require "google/cloud/bigquery"
573
+ #
574
+ # bigquery = Google::Cloud::Bigquery.new
575
+ #
576
+ # bigtable_url = "https://googleapis.com/bigtable/projects/..."
577
+ # bigtable_table = bigquery.external bigtable_url do |bt|
578
+ # bt.rowkey_as_string = true
579
+ # bt.add_family "user" do |u|
580
+ # u.add_string "name"
581
+ # u.add_string "email"
582
+ # u.add_integer "age"
583
+ # u.add_boolean "active"
584
+ # end
585
+ # end
586
+ #
587
+ # data = bigquery.query "SELECT * FROM my_ext_table",
588
+ # external: { my_ext_table: bigtable_table }
589
+ #
590
+ # # Iterate over the first page of results
591
+ # data.each do |row|
592
+ # puts row[:name]
593
+ # end
594
+ # # Retrieve the next page of results
595
+ # data = data.next if data.next?
596
+ #
597
+ class Column
598
+ ##
599
+ # @private Create an empty BigtableSource::Column object.
600
+ def initialize
601
+ @gapi = Google::Apis::BigqueryV2::BigtableColumn.new
602
+ end
603
+
604
+ ##
605
+ # Qualifier of the column. Columns in the parent column family that
606
+ # has this exact qualifier are exposed as `.` field. If the
607
+ # qualifier is valid UTF-8 string, it will be represented as a UTF-8
608
+ # string. Otherwise, it will represented as a ASCII-8BIT string.
609
+ #
610
+ # If the qualifier is not a valid BigQuery field identifier (does
611
+ # not match `[a-zA-Z][a-zA-Z0-9_]*`) a valid identifier must be
612
+ # provided as `field_name`.
613
+ #
614
+ # @return [String]
615
+ #
616
+ # @example
617
+ # require "google/cloud/bigquery"
618
+ #
619
+ # bigquery = Google::Cloud::Bigquery.new
620
+ #
621
+ # bigtable_url = "https://googleapis.com/bigtable/projects/..."
622
+ # bigtable_table = bigquery.external bigtable_url do |bt|
623
+ # bt.add_family "user" do |u|
624
+ # u.add_string "name" do |col|
625
+ # col.qualifier # "user"
626
+ # col.qualifier = "User"
627
+ # col.qualifier # "User"
628
+ # end
629
+ # end
630
+ # end
631
+ #
632
+ def qualifier
633
+ @gapi.qualifier_string || Base64.strict_decode64(@gapi.qualifier_encoded.to_s)
634
+ end
635
+
636
+ ##
637
+ # Set the qualifier of the column. Columns in the parent column
638
+ # family that has this exact qualifier are exposed as `.` field.
639
+ # Values that are valid UTF-8 strings will be treated as such. All
640
+ # other values will be treated as `BINARY`.
641
+ #
642
+ # @param [String] new_qualifier New qualifier value
643
+ #
644
+ # @example
645
+ # require "google/cloud/bigquery"
646
+ #
647
+ # bigquery = Google::Cloud::Bigquery.new
648
+ #
649
+ # bigtable_url = "https://googleapis.com/bigtable/projects/..."
650
+ # bigtable_table = bigquery.external bigtable_url do |bt|
651
+ # bt.add_family "user" do |u|
652
+ # u.add_string "name" do |col|
653
+ # col.qualifier # "user"
654
+ # col.qualifier = "User"
655
+ # col.qualifier # "User"
656
+ # end
657
+ # end
658
+ # end
659
+ #
660
+ def qualifier= new_qualifier
661
+ frozen_check!
662
+ raise ArgumentError if new_qualifier.nil?
663
+
664
+ utf8_qualifier = new_qualifier.encode Encoding::UTF_8
665
+ if utf8_qualifier.valid_encoding?
666
+ @gapi.qualifier_string = utf8_qualifier
667
+ if @gapi.instance_variables.include? :@qualifier_encoded
668
+ @gapi.remove_instance_variable :@qualifier_encoded
669
+ end
670
+ else
671
+ @gapi.qualifier_encoded = Base64.strict_encode64 new_qualifier
672
+ if @gapi.instance_variables.include? :@qualifier_string
673
+ @gapi.remove_instance_variable :@qualifier_string
674
+ end
675
+ end
676
+ rescue EncodingError
677
+ @gapi.qualifier_encoded = Base64.strict_encode64 new_qualifier
678
+ @gapi.remove_instance_variable :@qualifier_string if @gapi.instance_variables.include? :@qualifier_string
679
+ end
680
+
681
+ ##
682
+ # The encoding of the values when the type is not `STRING`.
683
+ #
684
+ # @return [String]
685
+ #
686
+ # @example
687
+ # require "google/cloud/bigquery"
688
+ #
689
+ # bigquery = Google::Cloud::Bigquery.new
690
+ #
691
+ # bigtable_url = "https://googleapis.com/bigtable/projects/..."
692
+ # bigtable_table = bigquery.external bigtable_url do |bt|
693
+ # bt.add_family "user" do |u|
694
+ # u.add_bytes "name" do |col|
695
+ # col.encoding = "TEXT"
696
+ # col.encoding # "TEXT"
697
+ # end
698
+ # end
699
+ # end
700
+ #
701
+ def encoding
702
+ @gapi.encoding
703
+ end
704
+
705
+ ##
706
+ # Set the encoding of the values when the type is not `STRING`.
707
+ # Acceptable encoding values are:
708
+ #
709
+ # * `TEXT` - indicates values are alphanumeric text strings.
710
+ # * `BINARY` - indicates values are encoded using HBase
711
+ # `Bytes.toBytes` family of functions. This can be overridden on a
712
+ # column.
713
+ #
714
+ # @param [String] new_encoding New encoding value
715
+ #
716
+ # @example
717
+ # require "google/cloud/bigquery"
718
+ #
719
+ # bigquery = Google::Cloud::Bigquery.new
720
+ #
721
+ # bigtable_url = "https://googleapis.com/bigtable/projects/..."
722
+ # bigtable_table = bigquery.external bigtable_url do |bt|
723
+ # bt.add_family "user" do |u|
724
+ # u.add_bytes "name" do |col|
725
+ # col.encoding = "TEXT"
726
+ # col.encoding # "TEXT"
727
+ # end
728
+ # end
729
+ # end
730
+ #
731
+ def encoding= new_encoding
732
+ frozen_check!
733
+ @gapi.encoding = new_encoding
734
+ end
735
+
736
+ ##
737
+ # If the qualifier is not a valid BigQuery field identifier (does
738
+ # not match `[a-zA-Z][a-zA-Z0-9_]*`) a valid identifier must be
739
+ # provided as the column field name and is used as field name in
740
+ # queries.
741
+ #
742
+ # @return [String]
743
+ #
744
+ # @example
745
+ # require "google/cloud/bigquery"
746
+ #
747
+ # bigquery = Google::Cloud::Bigquery.new
748
+ #
749
+ # bigtable_url = "https://googleapis.com/bigtable/projects/..."
750
+ # bigtable_table = bigquery.external bigtable_url do |bt|
751
+ # bt.add_family "user" do |u|
752
+ # u.add_string "001_name", as: "user" do |col|
753
+ # col.field_name # "user"
754
+ # col.field_name = "User"
755
+ # col.field_name # "User"
756
+ # end
757
+ # end
758
+ # end
759
+ #
760
+ def field_name
761
+ @gapi.field_name
762
+ end
763
+
764
+ ##
765
+ # Sets the identifier to be used as the column field name in queries
766
+ # when the qualifier is not a valid BigQuery field identifier (does
767
+ # not match `[a-zA-Z][a-zA-Z0-9_]*`).
768
+ #
769
+ # @param [String] new_field_name New field_name value
770
+ #
771
+ # @example
772
+ # require "google/cloud/bigquery"
773
+ #
774
+ # bigquery = Google::Cloud::Bigquery.new
775
+ #
776
+ # bigtable_url = "https://googleapis.com/bigtable/projects/..."
777
+ # bigtable_table = bigquery.external bigtable_url do |bt|
778
+ # bt.add_family "user" do |u|
779
+ # u.add_string "001_name", as: "user" do |col|
780
+ # col.field_name # "user"
781
+ # col.field_name = "User"
782
+ # col.field_name # "User"
783
+ # end
784
+ # end
785
+ # end
786
+ #
787
+ def field_name= new_field_name
788
+ frozen_check!
789
+ @gapi.field_name = new_field_name
790
+ end
791
+
792
+ ##
793
+ # Whether only the latest version of value in this column are
794
+ # exposed. Can also be set at the column family level. However, this
795
+ # value takes precedence when set at both levels.
796
+ #
797
+ # @return [Boolean]
798
+ #
799
+ # @example
800
+ # require "google/cloud/bigquery"
801
+ #
802
+ # bigquery = Google::Cloud::Bigquery.new
803
+ #
804
+ # bigtable_url = "https://googleapis.com/bigtable/projects/..."
805
+ # bigtable_table = bigquery.external bigtable_url do |bt|
806
+ # bt.add_family "user" do |u|
807
+ # u.add_string "name" do |col|
808
+ # col.latest = true
809
+ # col.latest # true
810
+ # end
811
+ # end
812
+ # end
813
+ #
814
+ def latest
815
+ @gapi.only_read_latest
816
+ end
817
+
818
+ ##
819
+ # Set whether only the latest version of value in this column are
820
+ # exposed. Can also be set at the column family level. However, this
821
+ # value takes precedence when set at both levels.
822
+ #
823
+ # @param [Boolean] new_latest New latest value
824
+ #
825
+ # @example
826
+ # require "google/cloud/bigquery"
827
+ #
828
+ # bigquery = Google::Cloud::Bigquery.new
829
+ #
830
+ # bigtable_url = "https://googleapis.com/bigtable/projects/..."
831
+ # bigtable_table = bigquery.external bigtable_url do |bt|
832
+ # bt.add_family "user" do |u|
833
+ # u.add_string "name" do |col|
834
+ # col.latest = true
835
+ # col.latest # true
836
+ # end
837
+ # end
838
+ # end
839
+ #
840
+ def latest= new_latest
841
+ frozen_check!
842
+ @gapi.only_read_latest = new_latest
843
+ end
844
+
845
+ ##
846
+ # The type to convert the value in cells of this column. The values
847
+ # are expected to be encoded using HBase `Bytes.toBytes` function
848
+ # when using the `BINARY` encoding value. The following BigQuery
849
+ # types are allowed:
850
+ #
851
+ # * `BYTES`
852
+ # * `STRING`
853
+ # * `INTEGER`
854
+ # * `FLOAT`
855
+ # * `BOOLEAN`
856
+ #
857
+ # Default type is `BYTES`. Can also be set at the column family
858
+ # level. However, this value takes precedence when set at both
859
+ # levels.
860
+ #
861
+ # @return [String]
862
+ #
863
+ # @example
864
+ # require "google/cloud/bigquery"
865
+ #
866
+ # bigquery = Google::Cloud::Bigquery.new
867
+ #
868
+ # bigtable_url = "https://googleapis.com/bigtable/projects/..."
869
+ # bigtable_table = bigquery.external bigtable_url do |bt|
870
+ # bt.add_family "user" do |u|
871
+ # u.add_string "name" do |col|
872
+ # col.type # "STRING"
873
+ # end
874
+ # end
875
+ # end
876
+ #
877
+ def type
878
+ @gapi.type
879
+ end
880
+
881
+ ##
882
+ # Set the type to convert the value in cells of this column. The
883
+ # values are expected to be encoded using HBase `Bytes.toBytes`
884
+ # function when using the `BINARY` encoding value. The following
885
+ # BigQuery types are allowed:
886
+ #
887
+ # * `BYTES`
888
+ # * `STRING`
889
+ # * `INTEGER`
890
+ # * `FLOAT`
891
+ # * `BOOLEAN`
892
+ #
893
+ # Default type is `BYTES`. Can also be set at the column family
894
+ # level. However, this value takes precedence when set at both
895
+ # levels.
896
+ #
897
+ # @param [String] new_type New type value
898
+ #
899
+ # @example
900
+ # require "google/cloud/bigquery"
901
+ #
902
+ # bigquery = Google::Cloud::Bigquery.new
903
+ #
904
+ # bigtable_url = "https://googleapis.com/bigtable/projects/..."
905
+ # bigtable_table = bigquery.external bigtable_url do |bt|
906
+ # bt.add_family "user" do |u|
907
+ # u.add_string "name" do |col|
908
+ # col.type # "STRING"
909
+ # col.type = "BYTES"
910
+ # col.type # "BYTES"
911
+ # end
912
+ # end
913
+ # end
914
+ #
915
+ def type= new_type
916
+ frozen_check!
917
+ @gapi.type = new_type
918
+ end
919
+
920
+ ##
921
+ # @private Google API Client object.
922
+ def to_gapi
923
+ @gapi
924
+ end
925
+
926
+ ##
927
+ # @private Google API Client object.
928
+ def self.from_gapi gapi
929
+ new_col = new
930
+ new_col.instance_variable_set :@gapi, gapi
931
+ new_col
932
+ end
933
+
934
+ protected
935
+
936
+ def frozen_check!
937
+ return unless frozen?
938
+ raise ArgumentError, "Cannot modify external data source when frozen"
939
+ end
940
+ end
941
+ end
942
+ end
943
+ end
944
+ end
945
+ end