kura 0.1.1 → 0.1.2
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/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
|