kura 0.1.5 → 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/kura.gemspec +1 -1
- data/lib/kura/client.rb +147 -154
- data/lib/kura/version.rb +1 -1
- data/lib/kura.rb +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7e158696726d53d4f57682c7074342b353ec867d
|
4
|
+
data.tar.gz: 1a52d2b10903e57608ce0dbfdc0ae25c2a00f33a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c4785e4b3bf7e51d0dac054eb8b88cf79155c56bfc1cf285a41f7c9edf5f438e9f3559a3a7329c2fe774a746fb42fe4caee7b9d6ba66c4295ff902eeca6b2027
|
7
|
+
data.tar.gz: 9f4ab700c948f13dda3e11fcdd0ac1dda6494ef78e284f59f0566d7a996b54d6976cfa686150cb6e97204e7094e13d0fda7b96c61c5313a2bb6d034fb16a1457
|
data/kura.gemspec
CHANGED
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
|
|
22
22
|
|
23
23
|
spec.required_ruby_version = '>= 2.1'
|
24
24
|
|
25
|
-
spec.add_runtime_dependency "google-api-client", "~> 0.
|
25
|
+
spec.add_runtime_dependency "google-api-client", "~> 0.9.pre3"
|
26
26
|
|
27
27
|
spec.add_development_dependency "bundler", "~> 1.10"
|
28
28
|
spec.add_development_dependency "rake", "~> 10.0"
|
data/lib/kura/client.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
|
3
|
-
require "google/
|
3
|
+
require "google/apis/bigquery_v2"
|
4
|
+
require "googleauth"
|
4
5
|
require "kura/version"
|
5
6
|
|
6
7
|
module Kura
|
7
8
|
class Client
|
8
|
-
def initialize(default_project_id: nil, email_address: nil, private_key: nil, http_options: {
|
9
|
+
def initialize(default_project_id: nil, email_address: nil, private_key: nil, http_options: {timeout: 60}, default_retries: 5)
|
9
10
|
@default_project_id = default_project_id
|
10
11
|
@scope = "https://www.googleapis.com/auth/bigquery"
|
11
12
|
@email_address = email_address
|
@@ -17,140 +18,116 @@ module Kura
|
|
17
18
|
scope: @scope,
|
18
19
|
issuer: @email_address,
|
19
20
|
signing_key: @private_key)
|
21
|
+
# MEMO: signet-0.6.1 depend on Farady.default_connection
|
22
|
+
Faraday.default_connection.options.timeout = 60
|
23
|
+
auth.fetch_access_token!
|
20
24
|
else
|
21
|
-
auth = Google::
|
25
|
+
auth = Google::Auth.get_application_default([@scope])
|
26
|
+
auth.fetch_access_token!
|
22
27
|
end
|
23
|
-
|
24
|
-
|
25
|
-
@
|
28
|
+
Google::Apis::RequestOptions.default.retries = default_retries
|
29
|
+
Google::Apis::RequestOptions.default.timeout_sec = http_options[:timeout]
|
30
|
+
@api = Google::Apis::BigqueryV2::BigqueryService.new
|
31
|
+
@api.authorization = auth
|
26
32
|
|
27
33
|
if @default_project_id.nil?
|
28
34
|
@default_project_id = self.projects.first.id
|
29
35
|
end
|
30
36
|
end
|
31
37
|
|
32
|
-
def
|
33
|
-
|
34
|
-
|
35
|
-
error =
|
38
|
+
def process_error(err)
|
39
|
+
if err.respond_to?(:body)
|
40
|
+
jobj = JSON.parse(err.body)
|
41
|
+
error = jobj["error"]
|
42
|
+
error = error["errors"][0]
|
36
43
|
raise Kura::ApiError.new(error["reason"], error["message"])
|
44
|
+
else
|
45
|
+
raise err
|
37
46
|
end
|
38
|
-
|
47
|
+
end
|
48
|
+
private :process_error
|
49
|
+
|
50
|
+
def projects(limit: 1000)
|
51
|
+
result = @api.list_projects(max_results: limit)
|
52
|
+
result.projects
|
53
|
+
rescue
|
54
|
+
process_error($!)
|
39
55
|
end
|
40
56
|
|
41
57
|
def datasets(project_id: @default_project_id, all: false, limit: 1000)
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
end
|
47
|
-
r.data.datasets
|
58
|
+
result = @api.list_datasets(project_id, all: all, max_results: limit)
|
59
|
+
result.datasets
|
60
|
+
rescue
|
61
|
+
process_error($!)
|
48
62
|
end
|
49
63
|
|
50
64
|
def dataset(dataset_id, project_id: @default_project_id)
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
else
|
56
|
-
error = r.data["error"]["errors"][0]
|
57
|
-
raise Kura::ApiError.new(error["reason"], error["message"])
|
58
|
-
end
|
59
|
-
end
|
60
|
-
r.data
|
65
|
+
@api.get_dataset(project_id, dataset_id)
|
66
|
+
rescue
|
67
|
+
return nil if $!.respond_to?(:status_code) and $!.status_code == 404
|
68
|
+
process_error($!)
|
61
69
|
end
|
62
70
|
|
63
71
|
def insert_dataset(dataset_id, project_id: @default_project_id)
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
end
|
69
|
-
r.data
|
72
|
+
obj = Google::Apis::BigqueryV2::Dataset.new(dataset_reference: Google::Apis::BigqueryV2::DatasetReference.new(project_id: project_id, dataset_id: dataset_id))
|
73
|
+
@api.insert_dataset(project_id, obj)
|
74
|
+
rescue
|
75
|
+
process_error($!)
|
70
76
|
end
|
71
77
|
|
72
78
|
def delete_dataset(dataset_id, project_id: @default_project_id, delete_contents: false)
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
end
|
78
|
-
r.data
|
79
|
+
@api.delete_dataset(project_id, dataset_id, delete_contents: delete_contents)
|
80
|
+
rescue
|
81
|
+
return nil if $!.respond_to?(:status_code) and $!.status_code == 404
|
82
|
+
process_error($!)
|
79
83
|
end
|
80
84
|
|
81
85
|
def patch_dataset(dataset_id, project_id: @default_project_id, access: nil, description: nil, default_table_expiration_ms: nil, friendly_name: nil )
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
raise Kura::ApiError.new(error["reason"], error["message"])
|
91
|
-
end
|
92
|
-
r.data
|
86
|
+
obj = Google::Apis::BigqueryV2::Dataset.new(dataset_reference: Google::Apis::BigqueryV2::DatasetReference.new(project_id: project_id, dataset_id: dataset_id))
|
87
|
+
obj.access = access if access
|
88
|
+
obj.default_table_expiration_ms = default_table_expiration_ms if default_table_expiration_ms
|
89
|
+
obj.description = description if description
|
90
|
+
obj.friendly_name = friendly_name if friendly_name
|
91
|
+
@api.patch_dataset(project_id, dataset_id, obj)
|
92
|
+
rescue
|
93
|
+
process_error($!)
|
93
94
|
end
|
94
95
|
|
95
96
|
def tables(dataset_id, project_id: @default_project_id, limit: 1000)
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
raise Kura::ApiError.new(error["reason"], error["message"])
|
101
|
-
end
|
102
|
-
r.data.tables
|
97
|
+
result = @api.list_tables(project_id, dataset_id, max_results: limit)
|
98
|
+
result.tables
|
99
|
+
rescue
|
100
|
+
process_error($!)
|
103
101
|
end
|
104
102
|
|
105
103
|
def table(dataset_id, table_id, project_id: @default_project_id)
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
return nil
|
111
|
-
else
|
112
|
-
error = r.data["error"]["errors"][0]
|
113
|
-
raise Kura::ApiError.new(error["reason"], error["message"])
|
114
|
-
end
|
115
|
-
end
|
116
|
-
r.data
|
104
|
+
@api.get_table(project_id, dataset_id, table_id)
|
105
|
+
rescue
|
106
|
+
return nil if $!.respond_to?(:status_code) and $!.status_code == 404
|
107
|
+
process_error($!)
|
117
108
|
end
|
118
109
|
|
119
110
|
def delete_table(dataset_id, table_id, project_id: @default_project_id)
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
return nil
|
125
|
-
else
|
126
|
-
error = r.data["error"]["errors"][0]
|
127
|
-
raise Kura::ApiError.new(error["reason"], error["message"])
|
128
|
-
end
|
129
|
-
end
|
130
|
-
r.data
|
111
|
+
@api.delete_table(project_id, dataset_id, table_id)
|
112
|
+
rescue
|
113
|
+
return nil if $!.respond_to?(:status_code) and $!.status_code == 404
|
114
|
+
process_error($!)
|
131
115
|
end
|
132
116
|
|
133
117
|
def list_tabledata(dataset_id, table_id, project_id: @default_project_id, start_index: 0, max_result: 100, page_token: nil, schema: nil)
|
134
118
|
schema ||= table(dataset_id, table_id, project_id: project_id).schema.fields
|
135
|
-
field_names = schema.map{|f| f["name"] }
|
136
|
-
|
137
|
-
|
138
|
-
params[:pageToken] = page_token
|
139
|
-
else
|
140
|
-
params[:startIndex] = start_index
|
141
|
-
end
|
142
|
-
r = @api.execute(api_method: @bigquery_api.tabledata.list, parameters: params)
|
143
|
-
unless r.success?
|
144
|
-
error = r.data["error"]["errors"][0]
|
145
|
-
raise Kura::ApiError.new(error["reason"], error["message"])
|
146
|
-
end
|
119
|
+
field_names = schema.map{|f| f.respond_to?(:[]) ? (f["name"] || f[:name]) : f.name }
|
120
|
+
|
121
|
+
r = @api.list_table_data(project_id, dataset_id, table_id, max_results: max_result, start_index: start_index, page_token: page_token)
|
147
122
|
{
|
148
|
-
total_rows: r.
|
149
|
-
next_token: r.
|
150
|
-
rows: r.
|
123
|
+
total_rows: r.total_rows.to_i,
|
124
|
+
next_token: r.page_token,
|
125
|
+
rows: r.rows.map do |row|
|
151
126
|
row.f.zip(field_names).each_with_object({}) do |(v, fn), tbl| tbl[fn] = v.v end
|
152
127
|
end
|
153
128
|
}
|
129
|
+
rescue
|
130
|
+
process_error($!)
|
154
131
|
end
|
155
132
|
|
156
133
|
def mode_to_write_disposition(mode)
|
@@ -162,21 +139,17 @@ module Kura
|
|
162
139
|
private :mode_to_write_disposition
|
163
140
|
|
164
141
|
def insert_job(configuration, project_id: @default_project_id, media: nil, wait: nil)
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
body = { configuration: configuration }
|
170
|
-
r = @api.execute(api_method: @bigquery_api.jobs.insert, parameters: params, body_object: body, media: media)
|
171
|
-
unless r.success?
|
172
|
-
error = r.data["error"]["errors"][0]
|
173
|
-
raise Kura::ApiError.new(error["reason"], error["message"])
|
174
|
-
end
|
142
|
+
job_object = Google::Apis::BigqueryV2::Job.new
|
143
|
+
job_object.configuration = configuration
|
144
|
+
result = @api.insert_job(project_id, job_object, upload_source: media)
|
145
|
+
job_id = result.job_reference.job_id
|
175
146
|
if wait
|
176
|
-
wait_job(
|
147
|
+
wait_job(job_id, wait, project_id: project_id)
|
177
148
|
else
|
178
|
-
|
149
|
+
job_id
|
179
150
|
end
|
151
|
+
rescue
|
152
|
+
process_error($!)
|
180
153
|
end
|
181
154
|
|
182
155
|
def query(sql, mode: :truncate,
|
@@ -193,19 +166,45 @@ module Kura
|
|
193
166
|
configuration = {
|
194
167
|
query: {
|
195
168
|
query: sql,
|
196
|
-
|
197
|
-
|
198
|
-
|
169
|
+
write_disposition: write_disposition,
|
170
|
+
allow_large_results: allow_large_results,
|
171
|
+
flatten_results: flatten_results,
|
199
172
|
priority: priority,
|
200
|
-
|
173
|
+
use_query_cache: use_query_cache,
|
201
174
|
}
|
202
175
|
}
|
203
176
|
if dataset_id and table_id
|
204
|
-
configuration[:query][:
|
177
|
+
configuration[:query][:destination_table] = { project_id: project_id, dataset_id: dataset_id, table_id: table_id }
|
205
178
|
end
|
206
179
|
insert_job(configuration, wait: wait, project_id: job_project_id)
|
207
180
|
end
|
208
181
|
|
182
|
+
def normalize_schema(schema)
|
183
|
+
schema.map do |s|
|
184
|
+
if s.respond_to?(:[])
|
185
|
+
f = {
|
186
|
+
name: (s[:name] || s["name"]),
|
187
|
+
type: (s[:type] || s["type"]),
|
188
|
+
mode: (s[:mode] || s["mode"]),
|
189
|
+
}
|
190
|
+
if (sub_fields = (s[:fields] || s["fields"]))
|
191
|
+
f[:fields] = normalize_schema(sub_fields)
|
192
|
+
end
|
193
|
+
else
|
194
|
+
f = {
|
195
|
+
name: s.name,
|
196
|
+
type: s.type,
|
197
|
+
mode: s.mode,
|
198
|
+
}
|
199
|
+
if (sub_fields = f.fields)
|
200
|
+
f[:fields] = normalize_schema(sub_fields)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
f
|
204
|
+
end
|
205
|
+
end
|
206
|
+
private :normalize_schema
|
207
|
+
|
209
208
|
def load(dataset_id, table_id, source_uris=nil,
|
210
209
|
schema: nil, delimiter: ",", field_delimiter: delimiter, mode: :append,
|
211
210
|
allow_jagged_rows: false, max_bad_records: 0,
|
@@ -220,31 +219,29 @@ module Kura
|
|
220
219
|
source_uris = [source_uris] if source_uris.is_a?(String)
|
221
220
|
configuration = {
|
222
221
|
load: {
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
222
|
+
destination_table: {
|
223
|
+
project_id: project_id,
|
224
|
+
dataset_id: dataset_id,
|
225
|
+
table_id: table_id,
|
227
226
|
},
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
227
|
+
write_disposition: write_disposition,
|
228
|
+
allow_jagged_rows: allow_jagged_rows,
|
229
|
+
max_bad_records: max_bad_records,
|
230
|
+
ignore_unknown_values: ignore_unknown_values,
|
231
|
+
source_format: source_format,
|
233
232
|
}
|
234
233
|
}
|
235
234
|
if schema
|
236
|
-
configuration[:load][:schema] = { fields: schema }
|
235
|
+
configuration[:load][:schema] = { fields: normalize_schema(schema) }
|
237
236
|
end
|
238
237
|
if source_format == "CSV"
|
239
|
-
configuration[:load][:
|
240
|
-
configuration[:load][:
|
238
|
+
configuration[:load][:field_delimiter] = field_delimiter
|
239
|
+
configuration[:load][:allow_quoted_newlines] = allow_quoted_newlines
|
241
240
|
configuration[:load][:quote] = quote
|
242
|
-
configuration[:load][:
|
241
|
+
configuration[:load][:skip_leading_rows] = skip_leading_rows
|
243
242
|
end
|
244
|
-
|
245
|
-
|
246
|
-
else
|
247
|
-
configuration[:load][:sourceUris] = source_uris
|
243
|
+
unless file
|
244
|
+
configuration[:load][:source_uris] = source_uris
|
248
245
|
end
|
249
246
|
insert_job(configuration, media: file, wait: wait, project_id: job_project_id)
|
250
247
|
end
|
@@ -261,18 +258,18 @@ module Kura
|
|
261
258
|
configuration = {
|
262
259
|
extract: {
|
263
260
|
compression: compression,
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
261
|
+
destination_format: destination_format,
|
262
|
+
source_table: {
|
263
|
+
project_id: project_id,
|
264
|
+
dataset_id: dataset_id,
|
265
|
+
table_id: table_id,
|
269
266
|
},
|
270
|
-
|
267
|
+
destination_uris: dest_uris,
|
271
268
|
}
|
272
269
|
}
|
273
270
|
if destination_format == "CSV"
|
274
|
-
configuration[:extract][:
|
275
|
-
configuration[:extract][:
|
271
|
+
configuration[:extract][:field_delimiter] = field_delimiter
|
272
|
+
configuration[:extract][:print_header] = print_header
|
276
273
|
end
|
277
274
|
insert_job(configuration, wait: wait, project_id: job_project_id)
|
278
275
|
end
|
@@ -286,36 +283,32 @@ module Kura
|
|
286
283
|
write_disposition = mode_to_write_disposition(mode)
|
287
284
|
configuration = {
|
288
285
|
copy: {
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
286
|
+
destination_table: {
|
287
|
+
project_id: dest_project_id,
|
288
|
+
dataset_id: dest_dataset_id,
|
289
|
+
table_id: dest_table_id,
|
293
290
|
},
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
291
|
+
source_table: {
|
292
|
+
project_id: src_project_id,
|
293
|
+
dataset_id: src_dataset_id,
|
294
|
+
table_id: src_table_id,
|
298
295
|
},
|
299
|
-
|
296
|
+
write_disposition: write_disposition,
|
300
297
|
}
|
301
298
|
}
|
302
299
|
insert_job(configuration, wait: wait, project_id: job_project_id)
|
303
300
|
end
|
304
301
|
|
305
302
|
def job(job_id, project_id: @default_project_id)
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
error = r.data["error"]["errors"][0]
|
310
|
-
raise Kura::ApiError.new(error["reason"], error["message"])
|
311
|
-
end
|
312
|
-
r.data
|
303
|
+
@api.get_job(project_id, job_id)
|
304
|
+
rescue
|
305
|
+
process_error($!)
|
313
306
|
end
|
314
307
|
|
315
308
|
def job_finished?(r)
|
316
309
|
if r.status.state == "DONE"
|
317
|
-
if r.status
|
318
|
-
raise Kura::ApiError.new(r.status.
|
310
|
+
if r.status.error_result
|
311
|
+
raise Kura::ApiError.new(r.status.error_result.reason, r.status.error_result.message)
|
319
312
|
end
|
320
313
|
return true
|
321
314
|
end
|
data/lib/kura/version.rb
CHANGED
data/lib/kura.rb
CHANGED
@@ -34,7 +34,7 @@ module Kura
|
|
34
34
|
private_key
|
35
35
|
end
|
36
36
|
|
37
|
-
def self.client(project_id=nil, email_address=nil, private_key=nil, http_options: {
|
37
|
+
def self.client(project_id=nil, email_address=nil, private_key=nil, http_options: {timeout: 60})
|
38
38
|
if private_key
|
39
39
|
private_key = get_private_key(private_key)
|
40
40
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kura
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chikanaga Tomoyuki
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-08-
|
11
|
+
date: 2015-08-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: google-api-client
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.
|
19
|
+
version: 0.9.pre3
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.
|
26
|
+
version: 0.9.pre3
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -147,7 +147,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
147
147
|
version: '0'
|
148
148
|
requirements: []
|
149
149
|
rubyforge_project:
|
150
|
-
rubygems_version: 2.4.5
|
150
|
+
rubygems_version: 2.4.5.1
|
151
151
|
signing_key:
|
152
152
|
specification_version: 4
|
153
153
|
summary: Interface to BigQuery API v2.
|