kura 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ChangeLog.md +40 -0
- data/lib/kura/client.rb +107 -26
- data/lib/kura/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d152cd817d2c2b1d5ca66756310e5af0a4a1d338
|
4
|
+
data.tar.gz: a18b967e4fec4f97b1d22937590ef5e9866f4f96
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a834c80e7c6eec7e1aea2c32a37616e4adbbdfc44509df5f49c3e5859eedce046d69b256d3919d1fb38267de61734e59f496a52a35a3910a7eebcfb582b8f180
|
7
|
+
data.tar.gz: dd055673db99ecd8c38bf2810c7d44c53ee449292e08bd0a53206bc3a9072b372bc1bdf3accc2e5ed15b48b266e350df38af60891b0758487004891b45be815d
|
data/ChangeLog.md
CHANGED
@@ -1,3 +1,43 @@
|
|
1
|
+
# 0.1.2
|
2
|
+
|
3
|
+
## Incompatible Changes
|
4
|
+
|
5
|
+
* Kura::Client#load: 3rd argument `source_uris` is now optional (default value is nil)
|
6
|
+
because is is not required on multipart upload. `source_uris` and keyworkd argument `file` is exclusive.
|
7
|
+
* Kura::Client#load: 4th argument `schema` become keyword argument. It is marked as [Optional] in
|
8
|
+
[API Reference](https://cloud.google.com/bigquery/docs/reference/v2/jobs#configuration.load.schema)
|
9
|
+
* Kura::Client#query: 1st and 2nd argument `dataset_id`, `table_id` become keyord argument.
|
10
|
+
destinationTable is an [Optional] parameter.
|
11
|
+
|
12
|
+
## Enhancements
|
13
|
+
|
14
|
+
* Kura::Client#load support keyword argument `file` for multipart upload.
|
15
|
+
* Add optional keyword arguments of Kura::Client#load.
|
16
|
+
* `field_delimiter`
|
17
|
+
* `allow_jagged_rows`
|
18
|
+
* `max_bad_records`
|
19
|
+
* `ignore_unknown_values`
|
20
|
+
* `allow_quoted_newlines`
|
21
|
+
* `quote`
|
22
|
+
* `skip_leading_rows`
|
23
|
+
* `source_format`
|
24
|
+
* Kura::Client#load keyword argument `delimiter` is deprecated. It is alias of `field_delimiter` now.
|
25
|
+
* Add optional keyword arguments of Kura::Client#query.
|
26
|
+
* `flatten_results`
|
27
|
+
* `priority`
|
28
|
+
* `use_query_cache`
|
29
|
+
* Kura::Client#query keyword argument `allow_large_result` is deprecated. It is alias of `allow_large_results` now.
|
30
|
+
* Add optional keyword arguments of Kura::Client#extract.
|
31
|
+
* `compression`
|
32
|
+
* `destination_format`
|
33
|
+
* `field_delimiter`
|
34
|
+
* `print_header`
|
35
|
+
* Fix error handling. Kura::ApiError#reason was missing.
|
36
|
+
* Add Kura::Client#list_tabledata API.
|
37
|
+
|
1
38
|
# 0.1.1
|
39
|
+
|
40
|
+
## Enhancements
|
41
|
+
|
2
42
|
* Add Kura::Client#tables API.
|
3
43
|
* Kura::Client#wait_job yield block every second if block was passed.
|
data/lib/kura/client.rb
CHANGED
@@ -24,7 +24,8 @@ module Kura
|
|
24
24
|
def datasets(project_id: @project_id, all: false, limit: 1000)
|
25
25
|
r = @api.execute(api_method: @bigquery_api.datasets.list, parameters: { projectId: project_id, all: all, maxResult: limit })
|
26
26
|
unless r.success?
|
27
|
-
|
27
|
+
error = r.data["error"]["errors"][0]
|
28
|
+
raise Kura::ApiError.new(error["reason"], error["message"])
|
28
29
|
end
|
29
30
|
r.data.datasets
|
30
31
|
end
|
@@ -35,7 +36,8 @@ module Kura
|
|
35
36
|
if r.data.error["code"] == 404
|
36
37
|
return nil
|
37
38
|
else
|
38
|
-
|
39
|
+
error = r.data["error"]["errors"][0]
|
40
|
+
raise Kura::ApiError.new(error["reason"], error["message"])
|
39
41
|
end
|
40
42
|
end
|
41
43
|
r.data
|
@@ -44,7 +46,8 @@ module Kura
|
|
44
46
|
def insert_dataset(dataset_id)
|
45
47
|
r = @api.execute(api_method: @bigquery_api.datasets.insert, parameters: { projectId: @project_id }, body_object: { datasetReference: { datasetId: dataset_id } })
|
46
48
|
unless r.success?
|
47
|
-
|
49
|
+
error = r.data["error"]["errors"][0]
|
50
|
+
raise Kura::ApiError.new(error["reason"], error["message"])
|
48
51
|
end
|
49
52
|
r.data
|
50
53
|
end
|
@@ -52,7 +55,8 @@ module Kura
|
|
52
55
|
def delete_dataset(dataset_id, delete_contents: false)
|
53
56
|
r = @api.execute(api_method: @bigquery_api.datasets.delete, parameters: { projectId: @project_id, datasetId: dataset_id, deleteContents: delete_contents })
|
54
57
|
unless r.success?
|
55
|
-
|
58
|
+
error = r.data["error"]["errors"][0]
|
59
|
+
raise Kura::ApiError.new(error["reason"], error["message"])
|
56
60
|
end
|
57
61
|
r.data
|
58
62
|
end
|
@@ -65,7 +69,8 @@ module Kura
|
|
65
69
|
body["friendlyName"] = friendly_name if friendly_name
|
66
70
|
r = @api.execute(api_method: @bigquery_api.datasets.patch, parameters: { projectId: project_id, datasetId: dataset_id }, body_object: body)
|
67
71
|
unless r.success?
|
68
|
-
|
72
|
+
error = r.data["error"]["errors"][0]
|
73
|
+
raise Kura::ApiError.new(error["reason"], error["message"])
|
69
74
|
end
|
70
75
|
r.data
|
71
76
|
end
|
@@ -74,7 +79,8 @@ module Kura
|
|
74
79
|
params = { projectId: project_id, datasetId: dataset_id, maxResult: limit }
|
75
80
|
r = @api.execute(api_method: @bigquery_api.tables.list, parameters: params)
|
76
81
|
unless r.success?
|
77
|
-
|
82
|
+
error = r.data["error"]["errors"][0]
|
83
|
+
raise Kura::ApiError.new(error["reason"], error["message"])
|
78
84
|
end
|
79
85
|
r.data.tables
|
80
86
|
end
|
@@ -86,7 +92,8 @@ module Kura
|
|
86
92
|
if r.data["error"]["code"] == 404
|
87
93
|
return nil
|
88
94
|
else
|
89
|
-
|
95
|
+
error = r.data["error"]["errors"][0]
|
96
|
+
raise Kura::ApiError.new(error["reason"], error["message"])
|
90
97
|
end
|
91
98
|
end
|
92
99
|
r.data
|
@@ -99,12 +106,36 @@ module Kura
|
|
99
106
|
if r.data["error"]["code"] == 404
|
100
107
|
return nil
|
101
108
|
else
|
102
|
-
|
109
|
+
error = r.data["error"]["errors"][0]
|
110
|
+
raise Kura::ApiError.new(error["reason"], error["message"])
|
103
111
|
end
|
104
112
|
end
|
105
113
|
r.data
|
106
114
|
end
|
107
115
|
|
116
|
+
def list_tabledata(dataset_id, table_id, project_id: @project_id, start_index: 0, max_result: 100, page_token: nil, schema: nil)
|
117
|
+
schema ||= table(dataset_id, table_id, project_id: project_id).schema.fields
|
118
|
+
field_names = schema.map{|f| f["name"] }
|
119
|
+
params = { projectId: project_id, datasetId: dataset_id, tableId: table_id, maxResults: max_result }
|
120
|
+
if page_token
|
121
|
+
params[:pageToken] = page_token
|
122
|
+
else
|
123
|
+
params[:startIndex] = start_index
|
124
|
+
end
|
125
|
+
r = @api.execute(api_method: @bigquery_api.tabledata.list, parameters: params)
|
126
|
+
unless r.success?
|
127
|
+
error = r.data["error"]["errors"][0]
|
128
|
+
raise Kura::ApiError.new(error["reason"], error["message"])
|
129
|
+
end
|
130
|
+
{
|
131
|
+
total_rows: r.data.totalRows,
|
132
|
+
next_token: r.data["pageToken"],
|
133
|
+
rows: r.data.rows.map do |row|
|
134
|
+
row.f.zip(field_names).each_with_object({}) do |(v, fn), tbl| tbl[fn] = v.v end
|
135
|
+
end
|
136
|
+
}
|
137
|
+
end
|
138
|
+
|
108
139
|
def mode_to_write_disposition(mode)
|
109
140
|
unless %i{ append truncate empty }.include?(mode)
|
110
141
|
raise "mode option should be one of :append, :truncate, :empty but #{mode}"
|
@@ -113,12 +144,16 @@ module Kura
|
|
113
144
|
end
|
114
145
|
private :mode_to_write_disposition
|
115
146
|
|
116
|
-
def insert_job(configuration, wait: nil)
|
147
|
+
def insert_job(configuration, media: nil, wait: nil)
|
117
148
|
params = { projectId: @project_id }
|
149
|
+
if media
|
150
|
+
params["uploadType"] = "multipart"
|
151
|
+
end
|
118
152
|
body = { configuration: configuration }
|
119
|
-
r = @api.execute(api_method: @bigquery_api.jobs.insert, parameters: params, body_object: body)
|
153
|
+
r = @api.execute(api_method: @bigquery_api.jobs.insert, parameters: params, body_object: body, media: media)
|
120
154
|
unless r.success?
|
121
|
-
|
155
|
+
error = r.data["error"]["errors"][0]
|
156
|
+
raise Kura::ApiError.new(error["reason"], error["message"])
|
122
157
|
end
|
123
158
|
if wait
|
124
159
|
wait_job(r.data.jobReference.jobId, wait)
|
@@ -127,42 +162,83 @@ module Kura
|
|
127
162
|
end
|
128
163
|
end
|
129
164
|
|
130
|
-
def query(
|
165
|
+
def query(sql, mode: :truncate,
|
166
|
+
dataset_id: nil, table_id: nil,
|
167
|
+
allow_large_result: true, # for backward compatibility
|
168
|
+
allow_large_results: allow_large_result,
|
169
|
+
flatten_results: true,
|
170
|
+
priority: "INTERACTIVE",
|
171
|
+
use_query_cache: true,
|
172
|
+
wait: nil)
|
131
173
|
write_disposition = mode_to_write_disposition(mode)
|
132
174
|
configuration = {
|
133
175
|
query: {
|
134
176
|
query: sql,
|
135
|
-
destinationTable: { projectId: @project_id, datasetId: dataset_id, tableId: table_id },
|
136
177
|
writeDisposition: write_disposition,
|
137
|
-
allowLargeResults:
|
178
|
+
allowLargeResults: allow_large_results,
|
179
|
+
flattenResults: flatten_results,
|
180
|
+
priority: priority,
|
181
|
+
useQueryCache: use_query_cache,
|
138
182
|
}
|
139
183
|
}
|
184
|
+
if dataset_id and table_id
|
185
|
+
configuration[:query][:destinationTable] = { projectId: @project_id, datasetId: dataset_id, tableId: table_id }
|
186
|
+
end
|
140
187
|
insert_job(configuration, wait: wait)
|
141
188
|
end
|
142
189
|
|
143
|
-
def load(dataset_id, table_id, source_uris,
|
190
|
+
def load(dataset_id, table_id, source_uris=nil,
|
191
|
+
schema: nil, delimiter: ",", field_delimiter: delimiter, mode: :append,
|
192
|
+
allow_jagged_rows: false, max_bad_records: 0,
|
193
|
+
ignore_unknown_values: false,
|
194
|
+
allow_quoted_newlines: false,
|
195
|
+
quote: '"', skip_leading_rows: 0,
|
196
|
+
source_format: "CSV",
|
197
|
+
file: nil, wait: nil)
|
144
198
|
write_disposition = mode_to_write_disposition(mode)
|
145
199
|
source_uris = [source_uris] if source_uris.is_a?(String)
|
146
200
|
configuration = {
|
147
201
|
load: {
|
148
|
-
sourceUris: source_uris,
|
149
202
|
destinationTable: {
|
150
203
|
projectId: @project_id,
|
151
204
|
datasetId: dataset_id,
|
152
205
|
tableId: table_id,
|
153
206
|
},
|
154
|
-
fieldDelimiter: delimiter,
|
155
207
|
writeDisposition: write_disposition,
|
156
|
-
|
208
|
+
allowJaggedRows: allow_jagged_rows,
|
209
|
+
maxBadRecords: max_bad_records,
|
210
|
+
ignoreUnknownValues: ignore_unknown_values,
|
211
|
+
sourceFormat: source_format,
|
157
212
|
}
|
158
213
|
}
|
159
|
-
|
214
|
+
if schema
|
215
|
+
configuration[:load][:schema] = { fields: schema }
|
216
|
+
end
|
217
|
+
if source_format == "CSV"
|
218
|
+
configuration[:load][:fieldDelimiter] = field_delimiter
|
219
|
+
configuration[:load][:allowQuotedNewlines] = allow_quoted_newlines
|
220
|
+
configuration[:load][:quote] = quote
|
221
|
+
configuration[:load][:skipLeadingRows] = skip_leading_rows
|
222
|
+
end
|
223
|
+
if file
|
224
|
+
file = Google::APIClient::UploadIO.new(file, "application/octet-stream")
|
225
|
+
else
|
226
|
+
configuration[:load][:sourceUris] = source_uris
|
227
|
+
end
|
228
|
+
insert_job(configuration, media: file, wait: wait)
|
160
229
|
end
|
161
230
|
|
162
|
-
def extract(dataset_id, table_id, dest_uris,
|
231
|
+
def extract(dataset_id, table_id, dest_uris,
|
232
|
+
compression: "NONE",
|
233
|
+
destination_format: "CSV",
|
234
|
+
field_delimiter: ",",
|
235
|
+
print_header: true,
|
236
|
+
wait: nil)
|
163
237
|
dest_uris = [ dest_uris ] if dest_uris.is_a?(String)
|
164
238
|
configuration = {
|
165
239
|
extract: {
|
240
|
+
compression: compression,
|
241
|
+
destinationFormat: destination_format,
|
166
242
|
sourceTable: {
|
167
243
|
projectId: @project_id,
|
168
244
|
datasetId: dataset_id,
|
@@ -171,6 +247,10 @@ module Kura
|
|
171
247
|
destinationUris: dest_uris,
|
172
248
|
}
|
173
249
|
}
|
250
|
+
if destination_format == "CSV"
|
251
|
+
configuration[:extract][:fieldDelimiter] = field_delimiter
|
252
|
+
configuration[:extract][:printHeader] = print_header
|
253
|
+
end
|
174
254
|
insert_job(configuration, wait: wait)
|
175
255
|
end
|
176
256
|
|
@@ -198,13 +278,13 @@ module Kura
|
|
198
278
|
params = { projectId: @project_id, jobId: job_id }
|
199
279
|
r = @api.execute(api_method: @bigquery_api.jobs.get, parameters: params)
|
200
280
|
unless r.success?
|
201
|
-
|
281
|
+
error = r.data["error"]["errors"][0]
|
282
|
+
raise Kura::ApiError.new(error["reason"], error["message"])
|
202
283
|
end
|
203
284
|
r.data
|
204
285
|
end
|
205
286
|
|
206
|
-
def job_finished?(
|
207
|
-
r = job(job_id)
|
287
|
+
def job_finished?(r)
|
208
288
|
if r.status.state == "DONE"
|
209
289
|
if r.status["errorResult"]
|
210
290
|
raise Kura::ApiError.new(r.status.errorResult.reason, r.status.errorResult.message)
|
@@ -217,11 +297,12 @@ module Kura
|
|
217
297
|
def wait_job(job_id, timeout=60*10)
|
218
298
|
expire = Time.now + timeout
|
219
299
|
while expire > Time.now
|
220
|
-
|
221
|
-
|
300
|
+
j = job(job_id)
|
301
|
+
if job_finished?(j)
|
302
|
+
return j
|
222
303
|
end
|
223
304
|
if block_given?
|
224
|
-
yield
|
305
|
+
yield j
|
225
306
|
end
|
226
307
|
sleep 1
|
227
308
|
end
|
data/lib/kura/version.rb
CHANGED
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.1.
|
4
|
+
version: 0.1.2
|
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-07-
|
11
|
+
date: 2015-07-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: google-api-client
|