bigquery_migration 0.2.0.pre2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/CHANGELOG.md +12 -1
- data/lib/bigquery_migration/bigquery_wrapper.rb +1 -1
- data/lib/bigquery_migration/table_data.rb +79 -50
- data/lib/bigquery_migration/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ee06c260e388082cdec0d3e4f3a72577952acfb8
|
4
|
+
data.tar.gz: 225387ac8df6a0fda1b723bc4f10ca6955fd9025
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 77326f487936158701a52e0a74f0d2241d2375ca5f96cb6803e7b85cec1b3206fa7728a699eae10a6b351adfb595242fa83ac742d257179128df157ec082b49f
|
7
|
+
data.tar.gz: a1b0e5a6418c43383b3c8b4d36deed62d9af9f823d9b1e6e333c9066f4e879d09214850b00a85238c0b8826392744da92dd9794edca97a67f80a8d794069445d
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -4,11 +4,22 @@ Enhancements:
|
|
4
4
|
|
5
5
|
* Support migrate_partitioned_table
|
6
6
|
|
7
|
+
Fixes:
|
8
|
+
|
9
|
+
* Fix list_table_data for when a value is an empty hash
|
10
|
+
|
11
|
+
# 0.1.7 (2016/09/17)
|
12
|
+
|
13
|
+
Fixes:
|
14
|
+
|
15
|
+
* Prohibit to create a table with empty columns
|
16
|
+
* Create a table only if a table does not exist
|
17
|
+
|
7
18
|
# 0.1.6 (2016/07/26)
|
8
19
|
|
9
20
|
Fixes:
|
10
21
|
|
11
|
-
* Fix empty hash to nil
|
22
|
+
* Fix empty hash to nil for list table data
|
12
23
|
|
13
24
|
# 0.1.5 (2016/07/25)
|
14
25
|
|
@@ -1,39 +1,76 @@
|
|
1
|
-
#
|
1
|
+
# This codes are translated from BigQuery Web console's JavaScript
|
2
2
|
require_relative 'error'
|
3
3
|
|
4
4
|
class BigqueryMigration
|
5
5
|
class TableData
|
6
|
-
attr_reader :rows
|
7
|
-
attr_reader :columns
|
6
|
+
attr_reader :rows, :columns
|
8
7
|
|
9
8
|
def logger
|
10
9
|
BigqueryMigration.logger
|
11
10
|
end
|
12
11
|
|
13
12
|
def initialize(columns, rows)
|
14
|
-
@columns = columns || raise(
|
15
|
-
@rows = rows || raise(
|
13
|
+
@columns = columns || raise(Error, '`columns` is required.')
|
14
|
+
@rows = rows || raise(Error, '`rows` is required.')
|
16
15
|
end
|
17
16
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
17
|
+
# format list_table_data response rows which is like
|
18
|
+
#
|
19
|
+
# [
|
20
|
+
# { f: [
|
21
|
+
# { v: "foo" },
|
22
|
+
# { v: "1" },
|
23
|
+
# { v: [] },
|
24
|
+
# { v: "1.1" },
|
25
|
+
# { v: "true" },
|
26
|
+
# { v: "1.444435200E9" }
|
27
|
+
# ] },
|
28
|
+
# { f: [
|
29
|
+
# { v: "foo" },
|
30
|
+
# { v: "2" },
|
31
|
+
# { v: [
|
32
|
+
# { v: "foo" },
|
33
|
+
# { v: "bar" }
|
34
|
+
# ] },
|
35
|
+
# { v: "2.2" },
|
36
|
+
# { v: "false" },
|
37
|
+
# { v: "1.444435200E9" }
|
38
|
+
# ] }
|
39
|
+
# ]
|
40
|
+
#
|
41
|
+
# into
|
42
|
+
#
|
43
|
+
# [
|
44
|
+
# # first row
|
45
|
+
# [
|
46
|
+
# [ "foo", "1", nil, "1.1", "true", "1.444435200E9" ]
|
47
|
+
# ],
|
48
|
+
# # second row
|
49
|
+
# [
|
50
|
+
# [ "foo", "2", "foo", "2.2", "false", "1.444435200E9" ],
|
51
|
+
# [ nil, nil, "bar", nil, nil, nil ],
|
52
|
+
# ],
|
53
|
+
# ]
|
54
|
+
def values
|
55
|
+
values = @rows.map do |row|
|
56
|
+
repeated_count = repeated_count(columns: @columns, rows: row)
|
57
|
+
formatted_row = []
|
58
|
+
repeated_count.times do |count|
|
59
|
+
formatted_row << format_row(columns: @columns, rows: row, count: count)
|
24
60
|
end
|
25
|
-
|
61
|
+
formatted_row
|
26
62
|
end
|
27
|
-
#
|
28
|
-
|
29
|
-
max_row_count > 1 ? rows : rows.map(&:flatten)
|
63
|
+
# flattern if there is no repeated column for backward compatibility
|
64
|
+
values.map(&:length).max > 1 ? values : values.flatten(1)
|
30
65
|
end
|
31
66
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
67
|
+
private
|
68
|
+
|
69
|
+
# Count maximum number of rows on repeated columns
|
70
|
+
#
|
71
|
+
# This method called recursively, rows must be a hash and hash has key f:
|
72
|
+
def repeated_count(columns: nil, rows: nil)
|
73
|
+
return 1 if (rows.nil? || rows.empty?)
|
37
74
|
validate_rows!(rows)
|
38
75
|
rows[:f].zip(columns).map do |row, column|
|
39
76
|
if column[:type] == 'RECORD'
|
@@ -41,84 +78,76 @@ class BigqueryMigration
|
|
41
78
|
if row[:v].length == 0
|
42
79
|
1
|
43
80
|
else
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
v[:repeated_count] = repeated_count
|
48
|
-
end
|
49
|
-
recursive_repeated_counts.inject(0) { |acc, n| acc + n }
|
81
|
+
row[:v].map do |v|
|
82
|
+
v[:repeated_count] = repeated_count(columns: column[:fields], rows: v[:v])
|
83
|
+
end.inject(:+)
|
50
84
|
end
|
51
85
|
else
|
52
|
-
|
53
|
-
_repeated_counts.inject(0) { |acc, n| [acc, n].max }
|
86
|
+
repeated_count(columns: column[:fields], rows: row[:v])
|
54
87
|
end
|
55
88
|
elsif column[:mode] == 'REPEATED'
|
56
89
|
[(row[:v] || []).length, 1].max
|
57
90
|
else
|
58
91
|
1
|
59
92
|
end
|
60
|
-
end
|
93
|
+
end.max
|
61
94
|
end
|
62
95
|
|
63
96
|
# This method called recursively.
|
64
97
|
# So, rows must be a hash and hash has key f:.
|
65
|
-
|
66
|
-
|
67
|
-
value = []
|
98
|
+
def format_row(columns: nil, rows: nil, count: nil)
|
99
|
+
formatted_row = []
|
68
100
|
return [nil] if (rows.nil? || rows.empty?)
|
69
101
|
validate_rows!(rows)
|
70
102
|
rows[:f].zip(columns).each do |row, column|
|
71
103
|
if column[:type] == 'RECORD'
|
72
104
|
if column[:mode] == 'REPEATED'
|
73
105
|
recursive = false
|
74
|
-
# Fixme: would like to avoid using the index counter
|
75
106
|
current = 0
|
76
107
|
row[:v].each do |v|
|
77
108
|
repeated_count = v[:repeated_count]
|
78
109
|
if current <= count && count < (current + repeated_count)
|
79
|
-
|
80
|
-
value.concat(generated_values)
|
110
|
+
formatted_row.concat format_row(columns: column[:fields], rows: v[:v], count: count - current)
|
81
111
|
recursive = true
|
82
112
|
end
|
83
113
|
current = current + repeated_count
|
84
114
|
end
|
85
115
|
unless recursive
|
86
|
-
nil_count =
|
87
|
-
|
116
|
+
nil_count = get_nil_count(column[:fields])
|
117
|
+
formatted_row.concat(Array.new(nil_count))
|
88
118
|
end
|
89
119
|
elsif row[:v].nil?
|
90
|
-
nil_count =
|
91
|
-
|
120
|
+
nil_count = get_nil_count(column[:fields])
|
121
|
+
formatted_row.concat(Array.new(nil_count))
|
92
122
|
else
|
93
|
-
|
94
|
-
value.concat(generated_values)
|
123
|
+
formatted_row.concat format_row(columns: column[:fields], rows: row[:v], count: count)
|
95
124
|
end
|
96
125
|
elsif column[:mode] == 'REPEATED'
|
97
126
|
v = row[:v]
|
98
|
-
count < v.length ?
|
127
|
+
count < v.length ? formatted_row.push(normalize_value(v[count][:v])) : formatted_row.push(nil)
|
99
128
|
elsif count == 0
|
100
|
-
|
129
|
+
formatted_row.push((normalize_value(row[:v])))
|
101
130
|
else
|
102
|
-
|
131
|
+
formatted_row.push(nil)
|
103
132
|
end
|
104
133
|
end
|
105
|
-
|
134
|
+
formatted_row
|
106
135
|
end
|
107
136
|
|
108
137
|
# special treatment empty hash.
|
109
138
|
# nil is converted into {} by to_h
|
110
|
-
|
139
|
+
def normalize_value(v)
|
111
140
|
v.is_a?(Hash) && v.empty? ? nil : v
|
112
141
|
end
|
113
142
|
|
114
|
-
|
143
|
+
def get_nil_count(fields)
|
115
144
|
fields.inject(0) do |acc, f|
|
116
|
-
f[:type] == 'RECORD' ? acc +
|
145
|
+
f[:type] == 'RECORD' ? acc + get_nil_count(f[:fields]) : acc + 1
|
117
146
|
end
|
118
147
|
end
|
119
148
|
|
120
|
-
|
121
|
-
raise
|
149
|
+
def validate_rows!(rows)
|
150
|
+
raise Error, '`rows` must be a hash and hash has key `:f`.' if !rows.is_a?(Hash) || !rows.has_key?(:f)
|
122
151
|
end
|
123
152
|
end
|
124
153
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bigquery_migration
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.0
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Naotoshi Seo
|
@@ -180,9 +180,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
180
180
|
version: '0'
|
181
181
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
182
182
|
requirements:
|
183
|
-
- - "
|
183
|
+
- - ">="
|
184
184
|
- !ruby/object:Gem::Version
|
185
|
-
version:
|
185
|
+
version: '0'
|
186
186
|
requirements: []
|
187
187
|
rubyforge_project:
|
188
188
|
rubygems_version: 2.5.1
|