td-client 0.8.82 → 0.8.83

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: bf42a2c04e997054b7071bd6dc6038738a8857a6
4
- data.tar.gz: 360933ff5ee21f22dbb9fce7b5acab14a23006f4
3
+ metadata.gz: d3662e5e2dfaa4e0eef6afb81bee1ba5eda81b2f
4
+ data.tar.gz: 4863761d3f0b4851a94348f776a09d923cec2e85
5
5
  SHA512:
6
- metadata.gz: ab861c2082d0eb19039a928c59e18414f64d31b15303ab4e11144f3290eeb9b29bacbd26ec721d2eb85f25b8935c571c3b0a27ae660885454756fddfae37fbdc
7
- data.tar.gz: d562b950d3c9c09d2bf25cef45d2397212a5ea654fc7ca6bf002c403dd9cc76022a0a8db6203f9218ccf40457bfd4fe8c7134592d71875993a5c40181db1e6b4
6
+ metadata.gz: 4c40f28abe243f4ad108595155324da7c93f56e57ac81564ffcc7dfba6f310a3a22abae62ae8447eb5a9753e0abdad3cfc0611410606d8ba485e9e173f44d2eb
7
+ data.tar.gz: d5a1d2e957400ab340b0a5ba91634575f08d27029eb363bc8c9d57ba41a55cbf64b2b87e3846a6f200ea846d99371c8b9a9f80dff513a854c584eac050e455fa
@@ -574,9 +574,9 @@ class Client
574
574
  @api.bulk_load_show(name)
575
575
  end
576
576
 
577
- # name: String, job: BulkLoad -> BulkLoad
578
- def bulk_load_update(name, job)
579
- @api.bulk_load_update(name, job)
577
+ # name: String, settings: Hash -> BulkLoad
578
+ def bulk_load_update(name, settings)
579
+ @api.bulk_load_update(name, settings)
580
580
  end
581
581
 
582
582
  # name: String -> BulkLoad
@@ -174,7 +174,26 @@ class API
174
174
 
175
175
  # @param [String] name
176
176
  def self.validate_column_name(name)
177
- validate_name("column", 1, 255, name)
177
+ target = 'column'
178
+ min_len = 1
179
+ max_len = 128
180
+ name = name.to_s
181
+ if name.empty?
182
+ raise ParameterValidationError,
183
+ "Empty #{target} name is not allowed"
184
+ end
185
+ if name.length < min_len || name.length > max_len
186
+ raise ParameterValidationError,
187
+ "#{target.capitalize} name must be between #{min_len} and #{max_len} characters long. Got #{name.length} " +
188
+ (name.length == 1 ? "character" : "characters") + "."
189
+ end
190
+
191
+ name
192
+ end
193
+
194
+ # @param [String] name
195
+ def self.validate_sql_alias_name(name)
196
+ validate_name("sql_alias", 1, 128, name)
178
197
  end
179
198
 
180
199
  # @param [String] name
@@ -199,25 +218,6 @@ class API
199
218
  normalize_database_name(name)
200
219
  end
201
220
 
202
- # TODO support array types
203
- # @param [String] name
204
- def self.normalize_type_name(name)
205
- case name
206
- when /int/i, /integer/i
207
- "int"
208
- when /long/i, /bigint/i
209
- "long"
210
- when /string/i
211
- "string"
212
- when /float/i
213
- "float"
214
- when /double/i
215
- "double"
216
- else
217
- raise "Type name must either of int, long, string float or double"
218
- end
219
- end
220
-
221
221
  # for fluent-plugin-td / td command to check table existence with import onlt user
222
222
  # @return [String]
223
223
  def self.create_empty_gz_data
@@ -116,10 +116,10 @@ module BulkLoad
116
116
  JSON.load(res.body)
117
117
  end
118
118
 
119
- # name: String, job: Hash -> Hash
120
- def bulk_load_update(name, job)
119
+ # name: String, settings: Hash -> Hash
120
+ def bulk_load_update(name, settings)
121
121
  path = session_path(name)
122
- res = api { put(path, job.to_json) }
122
+ res = api { put(path, settings.to_json) }
123
123
  unless res.ok?
124
124
  raise_error("BulkLoadSession: #{name} update failed", res)
125
125
  end
@@ -269,36 +269,62 @@ class Table < Model
269
269
  def update_database!
270
270
  @database = @client.database(@db_name)
271
271
  end
272
+
273
+ # @return [String]
274
+ def inspect
275
+ %[#<%s:%#0#{1.size*2}x @db_name="%s" @table_name="%s">] %
276
+ [self.class.name, self.__id__*2, @db_name, @table_name]
277
+ end
272
278
  end
273
279
 
274
280
  class Schema
275
281
  class Field
276
282
  # @param [String] name
277
283
  # @param [String] type
278
- def initialize(name, type)
284
+ # @param [String] sql_alias
285
+ def initialize(name, type, sql_alias=nil)
286
+ if name == 'v' || name == 'time'
287
+ raise ParameterValidationError, "Column name '#{name}' is reserved."
288
+ end
289
+ API.validate_column_name(name)
290
+ API.validate_sql_alias_name(sql_alias) if sql_alias
279
291
  @name = name
280
292
  @type = type
293
+ @sql_alias = sql_alias
281
294
  end
282
295
 
283
296
  # @!attribute [r] name
284
297
  # @!attribute [r] type
285
298
  attr_reader :name
286
299
  attr_reader :type
300
+ attr_reader :sql_alias
287
301
  end
288
302
 
289
- # @param [String] cols
303
+ # @param [String] columns
290
304
  # @return [Schema]
291
- def self.parse(cols)
292
- fields = cols.split(',').map {|col|
293
- name, type, *_ = col.split(':')
294
- Field.new(name, type)
305
+ def self.parse(columns)
306
+ schema = Schema.new
307
+ columns.each {|column|
308
+ unless /\A(?<name>.*)(?::(?<type>[^:]+))(?:@(?<sql_alias>[^:@]+))?\z/ =~ column
309
+ raise ParameterValidationError, "type must be specified"
310
+ end
311
+ schema.add_field(name, type, sql_alias)
295
312
  }
296
- Schema.new(fields)
313
+ schema
297
314
  end
298
315
 
299
316
  # @param [Array] fields
300
317
  def initialize(fields=[])
301
318
  @fields = fields
319
+ @names = {}
320
+ @fields.each do |f|
321
+ raise ArgumentError, "Column name '#{f.name}' is duplicated." if @names.key?(f.name)
322
+ @names[f.name] = true
323
+ if f.sql_alias
324
+ raise ArgumentError, "SQL Column alias '#{f.sql_alias}' is duplicated." if @names.key?(f.sql_alias)
325
+ @names[f.sql_alias] = true
326
+ end
327
+ end
302
328
  end
303
329
 
304
330
  # @!attribute [r] fields
@@ -307,8 +333,16 @@ class Schema
307
333
  # @param [String] name
308
334
  # @param [String] type
309
335
  # @return [Array]
310
- def add_field(name, type)
311
- @fields << Field.new(name, type)
336
+ def add_field(name, type, sql_alias=nil)
337
+ if @names.key?(name)
338
+ raise ParameterValidationError, "Column name '#{name}' is duplicated."
339
+ end
340
+ @names[name] = true
341
+ if sql_alias && @names.key?(sql_alias)
342
+ raise ParameterValidationError, "SQL Column alias '#{sql_alias}' is duplicated."
343
+ end
344
+ @names[sql_alias] = true
345
+ @fields << Field.new(name, type, sql_alias)
312
346
  end
313
347
 
314
348
  # @param [Schema] schema
@@ -327,14 +361,14 @@ class Schema
327
361
 
328
362
  # @return [Array<Field>]
329
363
  def to_json(*args)
330
- @fields.map {|f| [f.name, f.type] }.to_json(*args)
364
+ @fields.map {|f| f.sql_alias ? [f.name, f.type, f.sql_alias] : [f.name, f.type] }.to_json(*args)
331
365
  end
332
366
 
333
367
  # @param [Object] obj
334
368
  # @return [self]
335
369
  def from_json(obj)
336
370
  @fields = obj.map {|f|
337
- Field.new(f[0], f[1])
371
+ Field.new(*f)
338
372
  }
339
373
  self
340
374
  end
@@ -416,7 +450,7 @@ class Job < Model
416
450
  d = t - t1
417
451
  t1 = t
418
452
  timeout -= d if d > 0
419
- raise ::TimeoutError, "timeout=#{orig_timeout} wait_interval=#{wait_interval}" if timeout <= 0
453
+ raise Timeout::Error, "timeout=#{orig_timeout} wait_interval=#{wait_interval}" if timeout <= 0
420
454
  end
421
455
  sleep wait_interval
422
456
  yield self if block_given?
@@ -1,5 +1,5 @@
1
1
  module TreasureData
2
2
  class Client
3
- VERSION = '0.8.82'
3
+ VERSION = '0.8.83'
4
4
  end
5
5
  end
@@ -126,7 +126,7 @@ describe API do
126
126
 
127
127
  describe "'validate_column_name'" do
128
128
  it 'should raise a ParameterValidationError exception' do
129
- ['/', '', 'D'].each { |ng|
129
+ ['', 'a'*129].each { |ng|
130
130
  expect {
131
131
  API.validate_column_name(ng)
132
132
  }.to raise_error(ParameterValidationError)
@@ -137,14 +137,40 @@ describe API do
137
137
  VALID_NAMES.each {|ok|
138
138
  expect(API.validate_column_name(ok)).to eq(ok)
139
139
  }
140
- # columns can be as short as 2 characters
141
- expect(API.validate_column_name('ab')).to eq('ab')
140
+ ['a', 'a'*128].each {|ok|
141
+ expect(API.validate_column_name(ok)).to eq(ok)
142
+ }
142
143
  end
143
144
  end
144
145
 
146
+ describe "'validate_sql_alias_name'" do
147
+ it 'should raise a ParameterValidationError exception' do
148
+ ['', 'a'*129].each { |ng|
149
+ expect{API.validate_sql_alias_name(ng)}.to raise_error(ParameterValidationError)
150
+ }
151
+ valid = ("a".."z").to_a.join<<("0".."9").to_a.join<<"_"
152
+ ("\x00".."\x7F").each { |ng|
153
+ next if valid.include?(ng)
154
+ expect{API.validate_sql_alias_name(ng)}.to raise_error(ParameterValidationError)
155
+ }
156
+ end
157
+
158
+ it 'should return valid data' do
159
+ VALID_NAMES.each {|ok|
160
+ expect(API.validate_sql_alias_name(ok)).to eq(ok)
161
+ }
162
+ ['a', '_a', 'a_', 'a'*128].each {|ok|
163
+ expect(API.validate_sql_alias_name(ok)).to eq(ok)
164
+ }
165
+ end
166
+ end
145
167
 
146
168
  describe "'generic validate_name'" do
147
169
  it 'should raise a ParameterValidationError exception' do
170
+ # wrong target
171
+ expect {
172
+ API.validate_name("", 3, 256, '')
173
+ }.to raise_error(ParameterValidationError)
148
174
  INVALID_NAMES.each_pair {|ng,ok|
149
175
  expect {
150
176
  API.validate_name("generic", 3, 256, ng)
@@ -336,6 +336,31 @@ describe 'BulkImport API' do
336
336
  bulk_load_session
337
337
  )).to eq(bulk_load_session)
338
338
  end
339
+
340
+ it 'returns updated bulk_load_session' do
341
+ updated_bulk_load_session = bulk_load_session.merge({'timezone' => 'America/Los Angeles'})
342
+ stub_api_request(:put, '/v3/bulk_loads/nahi_test_1').
343
+ with(:body => updated_bulk_load_session.to_json).
344
+ to_return(:body => updated_bulk_load_session.to_json)
345
+ expect(api.bulk_load_update(
346
+ 'nahi_test_1',
347
+ updated_bulk_load_session
348
+ )).to eq updated_bulk_load_session
349
+ end
350
+
351
+ it 'can remove the cron schedule ' do
352
+ updated_bulk_load_session = bulk_load_session.merge({'cron' => ''})
353
+ # NOTE: currently the API just ignores an empty 'cron' specification update
354
+ # I am assuming that once fixed, the API will return a nil for cron if unscheduled.
355
+ expected_bulk_load_session = (bulk_load_session['cron'] = nil)
356
+ stub_api_request(:put, '/v3/bulk_loads/nahi_test_1').
357
+ with(:body => updated_bulk_load_session.to_json).
358
+ to_return(:body => expected_bulk_load_session.to_json)
359
+ expect(api.bulk_load_update(
360
+ 'nahi_test_1',
361
+ updated_bulk_load_session
362
+ )).to eq expected_bulk_load_session
363
+ end
339
364
  end
340
365
 
341
366
  describe 'delete' do
@@ -97,7 +97,7 @@ describe 'Job Model' do
97
97
  }
98
98
  sleep 0.3
99
99
  change_job_status(Job::STATUS_SUCCESS)
100
- thread.join(0.5)
100
+ thread.join(1)
101
101
  expect(thread).to be_stop
102
102
  ensure
103
103
  thread.kill # just in case
@@ -108,10 +108,10 @@ describe 'Job Model' do
108
108
 
109
109
  context 'with timeout' do
110
110
  context 'the job running time is too long' do
111
- it 'raise ::TimeoutError' do
111
+ it 'raise Timeout::Error' do
112
112
  expect {
113
113
  job.wait(0.1)
114
- }.to raise_error(::TimeoutError)
114
+ }.to raise_error(Timeout::Error)
115
115
  end
116
116
  end
117
117
 
@@ -121,7 +121,7 @@ describe 'Job Model' do
121
121
  thread = Thread.start {
122
122
  job.wait(0.3, 0.1, &b)
123
123
  }
124
- expect{ thread.value }.to raise_error(::TimeoutError)
124
+ expect{ thread.value }.to raise_error(Timeout::Error)
125
125
  expect(thread).to be_stop
126
126
  ensure
127
127
  thread.kill # just in case
@@ -82,10 +82,10 @@ describe 'Table API' do
82
82
  describe "'tables' Client API" do
83
83
  it 'should return an array of Table objects' do
84
84
  tables = [
85
- ["table_1", "item", "[[\"time\",\"long\"],[\"value\",\"string\"]]", 111, "2013-01-21 01:51:41 UTC", "2014-01-21 01:51:41 UTC"],
86
- ["table_2", "log", "[[\"time\",\"long\"],[\"value\",\"long\"]]", 222, "2013-02-22 02:52:42 UTC", "2014-02-22 02:52:42 UTC"],
87
- ["table_3", "item", "[[\"time\",\"long\"],[\"value\",\"string\"]]", 333, "2013-03-23 03:53:43 UTC", "2014-03-23 03:53:43 UTC"],
88
- ["table_4", "log", "[[\"time\",\"long\"],[\"value\",\"long\"]]", 444, "2013-04-24 04:54:44 UTC", "2014-04-24 04:54:44 UTC"]
85
+ ["table_1", "item", "[[\"value\",\"string\"]]", 111, "2013-01-21 01:51:41 UTC", "2014-01-21 01:51:41 UTC"],
86
+ ["table_2", "log", "[[\"value\",\"long\"]]", 222, "2013-02-22 02:52:42 UTC", "2014-02-22 02:52:42 UTC"],
87
+ ["table_3", "item", "[[\"value\",\"string\"]]", 333, "2013-03-23 03:53:43 UTC", "2014-03-23 03:53:43 UTC"],
88
+ ["table_4", "log", "[[\"value\",\"long\"]]", 444, "2013-04-24 04:54:44 UTC", "2014-04-24 04:54:44 UTC"]
89
89
  ]
90
90
  stub_api_request(:get, "/v3/table/list/#{e db_name}").
91
91
  to_return(:body => {'tables' => [
@@ -138,10 +138,10 @@ describe 'Table API' do
138
138
  describe "'table' Client API" do
139
139
  it 'should return the Table object corresponding to the name' do
140
140
  tables = [
141
- ["table_1", "item", "[[\"time\",\"long\"],[\"value\",\"string\"]]", 111, "2013-01-21 01:51:41 UTC", "2014-01-21 01:51:41 UTC"],
142
- ["table_2", "log", "[[\"time\",\"long\"],[\"value\",\"long\"]]", 222, "2013-02-22 02:52:42 UTC", "2014-02-22 02:52:42 UTC"],
143
- ["table_3", "item", "[[\"time\",\"long\"],[\"value\",\"string\"]]", 333, "2013-03-23 03:53:43 UTC", "2014-03-23 03:53:43 UTC"],
144
- ["table_4", "log", "[[\"time\",\"long\"],[\"value\",\"long\"]]", 444, "2013-04-24 04:54:44 UTC", "2014-04-24 04:54:44 UTC"]
141
+ ["table_1", "item", "[[\"value\",\"string\"]]", 111, "2013-01-21 01:51:41 UTC", "2014-01-21 01:51:41 UTC"],
142
+ ["table_2", "log", "[[\"value\",\"long\"]]", 222, "2013-02-22 02:52:42 UTC", "2014-02-22 02:52:42 UTC"],
143
+ ["table_3", "item", "[[\"value\",\"string\"]]", 333, "2013-03-23 03:53:43 UTC", "2014-03-23 03:53:43 UTC"],
144
+ ["table_4", "log", "[[\"value\",\"long\"]]", 444, "2013-04-24 04:54:44 UTC", "2014-04-24 04:54:44 UTC"]
145
145
  ]
146
146
  stub_api_request(:get, "/v3/table/list/#{e db_name}").
147
147
  to_return(:body => {'tables' => [
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: td-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.82
4
+ version: 0.8.83
5
5
  platform: ruby
6
6
  authors:
7
7
  - Treasure Data, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-07-11 00:00:00.000000000 Z
11
+ date: 2016-09-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: msgpack
@@ -257,7 +257,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
257
257
  requirements:
258
258
  - - ">="
259
259
  - !ruby/object:Gem::Version
260
- version: 1.8.7
260
+ version: 2.0.0
261
261
  required_rubygems_version: !ruby/object:Gem::Requirement
262
262
  requirements:
263
263
  - - ">="
@@ -291,4 +291,3 @@ test_files:
291
291
  - spec/td/client/user_api_spec.rb
292
292
  - spec/td/client_sched_spec.rb
293
293
  - spec/td/client_spec.rb
294
- has_rdoc: false