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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a3b3f01fed1dd8a0b55be71b85f918308f6a9362
4
- data.tar.gz: 72e91b8d8eca47315fb73a3cd98b48d04bf80a8b
3
+ metadata.gz: d152cd817d2c2b1d5ca66756310e5af0a4a1d338
4
+ data.tar.gz: a18b967e4fec4f97b1d22937590ef5e9866f4f96
5
5
  SHA512:
6
- metadata.gz: 1d863fa3c9d9c6463d292863285ee5843a372ef0587e4ed2c77d7be59138d310fe9ea66a32334a5b386d22d3805b8b9bec11ff3d012fb9dd4ed171855068c942
7
- data.tar.gz: 4c84a956904d442888657c43c196bfa6221a31dc0a415d1c77543a6f1755abe614c9de5ad926f0e3d988afa0dc714657e326d55e380afe134f7422cdebbcc19f
6
+ metadata.gz: a834c80e7c6eec7e1aea2c32a37616e4adbbdfc44509df5f49c3e5859eedce046d69b256d3919d1fb38267de61734e59f496a52a35a3910a7eebcfb582b8f180
7
+ data.tar.gz: dd055673db99ecd8c38bf2810c7d44c53ee449292e08bd0a53206bc3a9072b372bc1bdf3accc2e5ed15b48b266e350df38af60891b0758487004891b45be815d
@@ -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.
@@ -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
- raise Kura::ApiError.new(r.data["error"]["reason"], r.data["error"]["message"])
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
- raise Kura::ApiError.new(r.data.error["reason"], r.data.error["message"])
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
- raise Kura::ApiError.new(r.data["error"]["reason"], r.data["error"]["message"])
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
- raise Kura::ApiError.new(r.data["error"]["reason"], r.data["error"]["message"])
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
- raise Kura::ApiError.new(r.data["error"]["reason"], r.data["error"]["message"])
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
- raise Kura::ApiError.new(r.data["error"]["reason"], r.data["error"]["message"])
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
- raise Kura::ApiError.new(r.data["error"]["reason"], r.data["error"]["message"])
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
- raise Kura::ApiError.new(r.data["error"]["reason"], r.data["error"]["message"])
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
- raise Kura::ApiError.new(r.data["error"]["reason"], r.data["error"]["message"])
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(dataset_id, table_id, sql, mode: :truncate, allow_large_result: true, wait: nil)
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: allow_large_result,
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, schema, delimiter: ",", mode: :append, wait: nil)
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
- schema: { fields: schema },
208
+ allowJaggedRows: allow_jagged_rows,
209
+ maxBadRecords: max_bad_records,
210
+ ignoreUnknownValues: ignore_unknown_values,
211
+ sourceFormat: source_format,
157
212
  }
158
213
  }
159
- insert_job(configuration, wait: wait)
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, wait: nil)
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
- raise Kura::ApiError.new(r.data["error"]["reason"], r.data["error"]["message"])
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?(job_id)
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
- if job_finished?(job_id)
221
- return true
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
@@ -1,3 +1,3 @@
1
1
  module Kura
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  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.1.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-14 00:00:00.000000000 Z
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