td-client 0.8.83 → 0.8.84
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/td/client/api.rb +18 -9
- data/lib/td/client/api/import.rb +3 -2
- data/lib/td/client/model.rb +18 -16
- data/lib/td/client/version.rb +1 -1
- data/spec/spec_helper.rb +3 -3
- data/spec/td/client/bulk_import_spec.rb +4 -2
- data/spec/td/client/import_api_spec.rb +82 -7
- data/spec/td/client/model_job_spec.rb +5 -2
- data/spec/td/client/model_schema_spec.rb +134 -0
- metadata +11 -61
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3cf8a70e24c1afadf7756f4b7e97f05b194b9e02
|
4
|
+
data.tar.gz: 19cd3b2d119d5cfd45ed275047d698345cb99047
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c729351e09ef71b1b67dec38d4ea413831de6936248e9784d29138fe82f0cda1adf203fc503ce048baf7b9990b28f2c79cad1c456155e421a0c0e44e27aa1a20
|
7
|
+
data.tar.gz: 76ab4a900d117a2fe0b5c500f544287615d453770ec10211f69756f4b2b607a8ccfb6942bc662b758053e44d26ab6ab1554d4fdf9eddfcec753247f712c6d857
|
data/lib/td/client/api.rb
CHANGED
@@ -36,16 +36,19 @@ class API
|
|
36
36
|
include API::Table
|
37
37
|
include API::User
|
38
38
|
|
39
|
-
DEFAULT_ENDPOINT = 'api.
|
40
|
-
DEFAULT_IMPORT_ENDPOINT = 'api-import.
|
39
|
+
DEFAULT_ENDPOINT = 'api.treasuredata.com'
|
40
|
+
DEFAULT_IMPORT_ENDPOINT = 'api-import.treasuredata.com'
|
41
41
|
|
42
|
-
|
43
|
-
|
42
|
+
# Deprecated. Use DEFAULT_ENDPOINT and DEFAULT_IMPORT_ENDPOINT instead
|
43
|
+
NEW_DEFAULT_ENDPOINT = DEFAULT_ENDPOINT
|
44
|
+
NEW_DEFAULT_IMPORT_ENDPOINT = DEFAULT_IMPORT_ENDPOINT
|
45
|
+
OLD_ENDPOINT = 'api.treasure-data.com'
|
44
46
|
|
45
47
|
class IncompleteError < APIError; end
|
46
48
|
|
47
49
|
# @param [String] apikey
|
48
50
|
# @param [Hash] opts
|
51
|
+
# for backward compatibility
|
49
52
|
def initialize(apikey, opts={})
|
50
53
|
require 'json'
|
51
54
|
require 'time'
|
@@ -92,12 +95,18 @@ class API
|
|
92
95
|
# generic URI
|
93
96
|
@host, @port = endpoint.split(':', 2)
|
94
97
|
@port = @port.to_i
|
95
|
-
if opts[:ssl]
|
96
|
-
|
97
|
-
|
98
|
-
|
98
|
+
if opts[:ssl] === false || @host == TreasureData::API::OLD_ENDPOINT
|
99
|
+
# for backward compatibility, old endpoint specified without ssl option, use http
|
100
|
+
#
|
101
|
+
# opts[:ssl] would be nil if user doesn't specify ssl options,
|
102
|
+
# but connecting to https is the new default behavior (since 0.9)
|
103
|
+
# so check ssl option by `if opts[:ssl] === false` instead of `if opts[:ssl]`
|
104
|
+
# that means if user desire to use http, give `:ssl => false` for initializer such as API.new("APIKEY", :ssl => false)
|
99
105
|
@port = 80 if @port == 0
|
100
106
|
@ssl = false
|
107
|
+
else
|
108
|
+
@port = 443 if @port == 0
|
109
|
+
@ssl = true
|
101
110
|
end
|
102
111
|
@base_path = ''
|
103
112
|
end
|
@@ -296,7 +305,7 @@ private
|
|
296
305
|
retry_delay *= 2
|
297
306
|
redo # restart from beginning of do-while loop
|
298
307
|
end
|
299
|
-
rescue Errno::ECONNREFUSED, Errno::ECONNRESET, Timeout::Error, EOFError, OpenSSL::SSL::SSLError, SocketError, IncompleteError => e
|
308
|
+
rescue Errno::ECONNREFUSED, Errno::ECONNRESET, Timeout::Error, EOFError, OpenSSL::SSL::SSLError, SocketError, IncompleteError, HTTPClient::TimeoutError => e
|
300
309
|
if block_given?
|
301
310
|
raise e
|
302
311
|
end
|
data/lib/td/client/api/import.rb
CHANGED
@@ -21,8 +21,9 @@ module Import
|
|
21
21
|
opts = {}
|
22
22
|
if @host == DEFAULT_ENDPOINT
|
23
23
|
opts[:host] = DEFAULT_IMPORT_ENDPOINT
|
24
|
-
elsif @host ==
|
25
|
-
opts[:host] =
|
24
|
+
elsif @host == TreasureData::API::OLD_ENDPOINT # backward compatibility
|
25
|
+
opts[:host] = 'api-import.treasure-data.com'
|
26
|
+
opts[:ssl] = false
|
26
27
|
end
|
27
28
|
code, body, res = put(path, stream, size, opts)
|
28
29
|
if code[0] != ?2
|
data/lib/td/client/model.rb
CHANGED
@@ -305,7 +305,7 @@ class Schema
|
|
305
305
|
def self.parse(columns)
|
306
306
|
schema = Schema.new
|
307
307
|
columns.each {|column|
|
308
|
-
unless /\A(?<name>.*)(?::(?<type>[
|
308
|
+
unless /\A(?<name>.*)(?::(?<type>[^:@]+))(?:@(?<sql_alias>[^:@]+))?\z/ =~ column
|
309
309
|
raise ParameterValidationError, "type must be specified"
|
310
310
|
end
|
311
311
|
schema.add_field(name, type, sql_alias)
|
@@ -437,25 +437,27 @@ class Job < Model
|
|
437
437
|
attr_reader :priority, :retry_limit, :org_name, :db_name
|
438
438
|
attr_reader :duration
|
439
439
|
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
440
|
+
# @option timeout [Integer,nil] timeout in second
|
441
|
+
# @option wait_interval [Integer,nil] interval in second of polling the job status
|
442
|
+
# @param detail [Boolean] update job detail or not
|
443
|
+
# @param verbose [Boolean] out retry log to stderr or not
|
444
|
+
def wait(timeout=nil, wait_interval=2, detail: false, verbose: ENV['TD_CLIENT_DEBUG'])
|
445
|
+
deadline = Process.clock_gettime(Process::CLOCK_MONOTONIC) + timeout if timeout
|
446
|
+
timeout_klass = Class.new(Exception)
|
447
|
+
begin
|
448
448
|
if timeout
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
timeout -= d if d > 0
|
453
|
-
raise Timeout::Error, "timeout=#{orig_timeout} wait_interval=#{wait_interval}" if timeout <= 0
|
449
|
+
if deadline <= Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
450
|
+
raise timeout_klass, "timeout (#{timeout}) exceeded wait_interval=#{wait_interval}"
|
451
|
+
end
|
454
452
|
end
|
455
453
|
sleep wait_interval
|
456
454
|
yield self if block_given?
|
457
|
-
|
458
|
-
|
455
|
+
detail ? update_status! : update_progress!
|
456
|
+
rescue timeout_klass
|
457
|
+
raise Timeout::Error, $!.message
|
458
|
+
rescue Timeout::Error, SystemCallError, EOFError, SocketError, HTTPClient::ConnectTimeoutError
|
459
|
+
$stderr.puts "ignore network error (#{$!}); retry..." if verbose
|
460
|
+
end until finished?
|
459
461
|
end
|
460
462
|
|
461
463
|
def kill!
|
data/lib/td/client/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -48,13 +48,13 @@ shared_context 'common helper' do
|
|
48
48
|
end
|
49
49
|
|
50
50
|
def stub_api_request(method, path, opts = nil)
|
51
|
-
scheme = '
|
51
|
+
scheme = 'https'
|
52
52
|
with_opts = {:headers => headers}
|
53
53
|
if opts
|
54
|
-
scheme = '
|
54
|
+
scheme = 'http' if opts[:ssl] == false
|
55
55
|
with_opts[:query] = opts[:query] if opts[:query]
|
56
56
|
end
|
57
|
-
stub_request(method, "#{scheme}://api.
|
57
|
+
stub_request(method, "#{scheme}://api.treasuredata.com#{path}").with(with_opts)
|
58
58
|
end
|
59
59
|
|
60
60
|
def e(s)
|
@@ -24,6 +24,8 @@ describe 'BulkImport API' do
|
|
24
24
|
s.string
|
25
25
|
end
|
26
26
|
|
27
|
+
let(:endpoint_domain) { TreasureData::API::DEFAULT_IMPORT_ENDPOINT }
|
28
|
+
|
27
29
|
describe 'create_bulk_import' do
|
28
30
|
it 'should create a new bulk_import' do
|
29
31
|
stub_api_request(:post, "/v3/bulk_import/create/#{e(bi_name)}/#{e(db_name)}/#{e(table_name)}").
|
@@ -106,7 +108,7 @@ describe 'BulkImport API' do
|
|
106
108
|
File.open(t.path, 'w') do |f|
|
107
109
|
f << '12345'
|
108
110
|
end
|
109
|
-
stub_request(:put,
|
111
|
+
stub_request(:put, "https://#{TreasureData::API::DEFAULT_ENDPOINT}/v3/bulk_import/upload_part/name/part").
|
110
112
|
with(:body => '12345')
|
111
113
|
File.open(t.path) do |f|
|
112
114
|
expect(api.bulk_import_upload_part('name', 'part', f, 5)).to eq(nil)
|
@@ -119,7 +121,7 @@ describe 'BulkImport API' do
|
|
119
121
|
File.open(t.path, 'w') do |f|
|
120
122
|
f << '12345'
|
121
123
|
end
|
122
|
-
stub_request(:put,
|
124
|
+
stub_request(:put, "https://#{TreasureData::API::DEFAULT_ENDPOINT}/v3/bulk_import/upload_part/name/" + CGI.escape('日本語(Japanese)'.encode('UTF-8'))).
|
123
125
|
with(:body => '12345')
|
124
126
|
File.open(t.path) do |f|
|
125
127
|
expect(api.bulk_import_upload_part('name', '日本語(Japanese)'.encode('Windows-31J'), f, 5)).to eq(nil)
|
@@ -8,20 +8,43 @@ describe 'Import API' do
|
|
8
8
|
include_context 'common helper'
|
9
9
|
|
10
10
|
let :api do
|
11
|
-
API.new(nil, :endpoint =>
|
11
|
+
API.new(nil, :endpoint => endpoint)
|
12
12
|
end
|
13
13
|
|
14
14
|
let :api_old do
|
15
|
-
API.new(nil, :endpoint =>
|
15
|
+
API.new(nil, :endpoint => endpoint_old)
|
16
16
|
end
|
17
17
|
|
18
|
+
let :api_default do
|
19
|
+
API.new(nil)
|
20
|
+
end
|
21
|
+
|
22
|
+
let :api_default_http do
|
23
|
+
API.new(nil, :ssl => false)
|
24
|
+
end
|
25
|
+
|
26
|
+
let :api_unknown_host do
|
27
|
+
API.new(nil, :endpoint => endpoint_unknown)
|
28
|
+
end
|
29
|
+
|
30
|
+
let :api_unknown_host_http do
|
31
|
+
API.new(nil, :endpoint => endpoint_unknown, :ssl => false)
|
32
|
+
end
|
33
|
+
|
34
|
+
let(:endpoint) { 'api.treasuredata.com' }
|
35
|
+
let(:endpoint_old) { TreasureData::API::OLD_ENDPOINT }
|
36
|
+
let(:endpoint_unknown) { "example.com" }
|
37
|
+
let(:endpoint_import) { "api-import.treasuredata.com" }
|
38
|
+
let(:endpoint_import_old) { "api-import.treasure-data.com" }
|
39
|
+
let(:endpoint_import_unknown) { endpoint_unknown }
|
40
|
+
|
18
41
|
describe 'import' do
|
19
42
|
it 'runs with unique_id' do
|
20
43
|
t = Tempfile.new('import_api_spec')
|
21
44
|
File.open(t.path, 'w') do |f|
|
22
45
|
f << '12345'
|
23
46
|
end
|
24
|
-
stub_request(:put, "https
|
47
|
+
stub_request(:put, "https://#{endpoint_import}/v3/table/import_with_id/db/table/unique_id/format").
|
25
48
|
with(:body => '12345').
|
26
49
|
to_return(:body => '{"elapsed_time":"1.23"}')
|
27
50
|
File.open(t.path) do |f|
|
@@ -34,7 +57,7 @@ describe 'Import API' do
|
|
34
57
|
File.open(t.path, 'w') do |f|
|
35
58
|
f << '12345'
|
36
59
|
end
|
37
|
-
stub_request(:put, "https
|
60
|
+
stub_request(:put, "https://#{endpoint_import}/v3/table/import/db/table/format").
|
38
61
|
with(:body => '12345').
|
39
62
|
to_return(:body => '{"elapsed_time":"1.23"}')
|
40
63
|
File.open(t.path) do |f|
|
@@ -42,12 +65,12 @@ describe 'Import API' do
|
|
42
65
|
end
|
43
66
|
end
|
44
67
|
|
45
|
-
it 'runs for old endpoint' do
|
68
|
+
it 'runs for old endpoint (force "http" instead of "https" for compatibility)' do
|
46
69
|
t = Tempfile.new('import_api_spec')
|
47
70
|
File.open(t.path, 'w') do |f|
|
48
71
|
f << '12345'
|
49
72
|
end
|
50
|
-
stub_request(:put, "http
|
73
|
+
stub_request(:put, "http://#{endpoint_import_old}/v3/table/import/db/table/format").
|
51
74
|
with(:body => '12345').
|
52
75
|
to_return(:body => '{"elapsed_time":"1.23"}')
|
53
76
|
File.open(t.path) do |f|
|
@@ -55,12 +78,64 @@ describe 'Import API' do
|
|
55
78
|
end
|
56
79
|
end
|
57
80
|
|
81
|
+
it 'runs for no endpoint specified (default behavior)' do
|
82
|
+
t = Tempfile.new('import_api_spec')
|
83
|
+
File.open(t.path, 'w') do |f|
|
84
|
+
f << '12345'
|
85
|
+
end
|
86
|
+
stub_request(:put, "https://#{endpoint_import}/v3/table/import/db/table/format").
|
87
|
+
with(:body => '12345').
|
88
|
+
to_return(:body => '{"elapsed_time":"1.23"}')
|
89
|
+
File.open(t.path) do |f|
|
90
|
+
expect(api_default.import('db', 'table', 'format', f, 5)).to eq 1.23
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'runs for no endpoint specified with ssl: false' do
|
95
|
+
t = Tempfile.new('import_api_spec')
|
96
|
+
File.open(t.path, 'w') do |f|
|
97
|
+
f << '12345'
|
98
|
+
end
|
99
|
+
stub_request(:put, "http://#{endpoint_import}/v3/table/import/db/table/format").
|
100
|
+
with(:body => '12345').
|
101
|
+
to_return(:body => '{"elapsed_time":"1.23"}')
|
102
|
+
File.open(t.path) do |f|
|
103
|
+
expect(api_default_http.import('db', 'table', 'format', f, 5)).to eq 1.23
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'runs for unknown endpoint specified' do
|
108
|
+
t = Tempfile.new('import_api_spec')
|
109
|
+
File.open(t.path, 'w') do |f|
|
110
|
+
f << '12345'
|
111
|
+
end
|
112
|
+
stub_request(:put, "https://#{endpoint_unknown}/v3/table/import/db/table/format").
|
113
|
+
with(:body => '12345').
|
114
|
+
to_return(:body => '{"elapsed_time":"1.23"}')
|
115
|
+
File.open(t.path) do |f|
|
116
|
+
expect(api_unknown_host.import('db', 'table', 'format', f, 5)).to eq 1.23
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'runs for unknown endpoint with ssl=false specified' do
|
121
|
+
t = Tempfile.new('import_api_spec')
|
122
|
+
File.open(t.path, 'w') do |f|
|
123
|
+
f << '12345'
|
124
|
+
end
|
125
|
+
stub_request(:put, "http://#{endpoint_unknown}/v3/table/import/db/table/format").
|
126
|
+
with(:body => '12345').
|
127
|
+
to_return(:body => '{"elapsed_time":"1.23"}')
|
128
|
+
File.open(t.path) do |f|
|
129
|
+
expect(api_unknown_host_http.import('db', 'table', 'format', f, 5)).to eq 1.23
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
58
133
|
it 'raises APIError' do
|
59
134
|
t = Tempfile.new('import_api_spec')
|
60
135
|
File.open(t.path, 'w') do |f|
|
61
136
|
f << '12345'
|
62
137
|
end
|
63
|
-
stub_request(:put, "https
|
138
|
+
stub_request(:put, "https://#{endpoint_import}/v3/table/import/db/table/format").
|
64
139
|
with(:body => '12345').
|
65
140
|
to_return(:status => 500)
|
66
141
|
File.open(t.path) do |f|
|
@@ -90,12 +90,15 @@ describe 'Job Model' do
|
|
90
90
|
end
|
91
91
|
|
92
92
|
it 'calls a given block in every wait_interval second' do
|
93
|
+
now = 1_400_000_000
|
94
|
+
allow(self).to receive(:sleep){|arg| now += arg }
|
95
|
+
allow(Process).to receive(:clock_gettime){ now }
|
93
96
|
expect { |b|
|
94
97
|
begin
|
95
98
|
thread = Thread.start {
|
96
|
-
job.wait(nil,
|
99
|
+
job.wait(nil, 2, &b)
|
97
100
|
}
|
98
|
-
sleep
|
101
|
+
sleep 6
|
99
102
|
change_job_status(Job::STATUS_SUCCESS)
|
100
103
|
thread.join(1)
|
101
104
|
expect(thread).to be_stop
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'td/client/spec_resources'
|
3
|
+
|
4
|
+
describe 'TreasureData::Schema::Field' do
|
5
|
+
describe '.new' do
|
6
|
+
context 'name="v"' do
|
7
|
+
it 'raises ParameterValidationError' do
|
8
|
+
expect{ Schema::Field.new('v', 'int') }.to raise_error(ParameterValidationError)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
context 'name="time"' do
|
12
|
+
it 'raises ParameterValidationError' do
|
13
|
+
expect{ Schema::Field.new('time', 'int') }.to raise_error(ParameterValidationError)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
context 'name with UTF-8' do
|
17
|
+
it 'works' do
|
18
|
+
name = "\u3042\u3044\u3046"
|
19
|
+
f = Schema::Field.new(name, 'int')
|
20
|
+
expect(f.name).to eq name
|
21
|
+
expect(f.type).to eq 'int'
|
22
|
+
expect(f.sql_alias).to be_nil
|
23
|
+
end
|
24
|
+
end
|
25
|
+
context 'with sql_alias' do
|
26
|
+
it 'raises' do
|
27
|
+
f = Schema::Field.new('t:t', 'int', 'alice')
|
28
|
+
expect(f.name).to eq 't:t'
|
29
|
+
expect(f.type).to eq 'int'
|
30
|
+
expect(f.sql_alias).to eq 'alice'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
context 'with invalid sql_alias' do
|
34
|
+
it 'raises' do
|
35
|
+
expect{ Schema::Field.new('t:t', 'int', 't:t') }.to raise_error(ParameterValidationError)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe 'TreasureData::Schema' do
|
42
|
+
describe '.parse' do
|
43
|
+
let(:columns){ ["foo:int", "BAR\u3070\u30FC:string@bar", "baz:baz!:array<double>@baz"] }
|
44
|
+
it do
|
45
|
+
sc = Schema.parse(columns)
|
46
|
+
expect(sc.fields.size).to eq 3
|
47
|
+
expect(sc.fields[0].name).to eq 'foo'
|
48
|
+
expect(sc.fields[0].type).to eq 'int'
|
49
|
+
expect(sc.fields[0].sql_alias).to be_nil
|
50
|
+
expect(sc.fields[1].name).to eq "BAR\u3070\u30FC"
|
51
|
+
expect(sc.fields[1].type).to eq 'string'
|
52
|
+
expect(sc.fields[1].sql_alias).to eq 'bar'
|
53
|
+
expect(sc.fields[2].name).to eq 'baz:baz!'
|
54
|
+
expect(sc.fields[2].type).to eq 'array<double>'
|
55
|
+
expect(sc.fields[2].sql_alias).to eq 'baz'
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe '.new' do
|
60
|
+
it do
|
61
|
+
f = Schema::Field.new('a', 'int')
|
62
|
+
sc = Schema.new([f])
|
63
|
+
expect(sc.fields[0]).to eq f
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe '#fields' do
|
68
|
+
it do
|
69
|
+
f = Schema::Field.new('a', 'int')
|
70
|
+
sc = Schema.new([f])
|
71
|
+
expect(sc.fields[0]).to eq f
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe '#add_field' do
|
76
|
+
it do
|
77
|
+
f = Schema::Field.new('a', 'int')
|
78
|
+
sc = Schema.new([f])
|
79
|
+
sc.add_field('b', 'double', 'bb')
|
80
|
+
expect(sc.fields[1].name).to eq 'b'
|
81
|
+
end
|
82
|
+
it 'raises ParameterValidationError if name is duplicated' do
|
83
|
+
f = Schema::Field.new('a', 'int')
|
84
|
+
sc = Schema.new([f])
|
85
|
+
expect{ sc.add_field('a', 'double') }.to raise_error(ParameterValidationError)
|
86
|
+
end
|
87
|
+
it 'raises ParameterValidationError if sql_alias is duplicated' do
|
88
|
+
f = Schema::Field.new('a', 'int')
|
89
|
+
sc = Schema.new([f])
|
90
|
+
expect{ sc.add_field('abc', 'double', 'a') }.to raise_error(ParameterValidationError)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe '#merge' do
|
95
|
+
it do
|
96
|
+
sc1 = Schema.parse(['foo:int', 'bar:float'])
|
97
|
+
sc2 = Schema.parse(['bar:double', 'baz:string'])
|
98
|
+
sc3 = sc1.merge(sc2)
|
99
|
+
expect(sc3.fields.size).to eq 3
|
100
|
+
expect(sc3.fields[0].name).to eq 'foo'
|
101
|
+
expect(sc3.fields[0].type).to eq 'int'
|
102
|
+
expect(sc3.fields[1].name).to eq 'bar'
|
103
|
+
expect(sc3.fields[1].type).to eq 'double'
|
104
|
+
expect(sc3.fields[2].name).to eq 'baz'
|
105
|
+
expect(sc3.fields[2].type).to eq 'string'
|
106
|
+
end
|
107
|
+
it do
|
108
|
+
sc1 = Schema.parse(['foo:int', 'bar:float'])
|
109
|
+
sc2 = Schema.parse(['bar:double@foo'])
|
110
|
+
expect{ sc1.merge(sc2) }.to raise_error(ArgumentError)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe '#to_json' do
|
115
|
+
it do
|
116
|
+
sc = Schema.parse(['foo:int', 'bar:float@baz'])
|
117
|
+
expect(sc.to_json).to eq '[["foo","int"],["bar","float","baz"]]'
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
describe '#from_json' do
|
122
|
+
it do
|
123
|
+
sc = Schema.new
|
124
|
+
sc.from_json [["foo","int"],["bar","float","baz"]]
|
125
|
+
expect(sc.fields.size).to eq 2
|
126
|
+
expect(sc.fields[0].name).to eq 'foo'
|
127
|
+
expect(sc.fields[0].type).to eq 'int'
|
128
|
+
expect(sc.fields[0].sql_alias).to be_nil
|
129
|
+
expect(sc.fields[1].name).to eq 'bar'
|
130
|
+
expect(sc.fields[1].type).to eq 'float'
|
131
|
+
expect(sc.fields[1].sql_alias).to eq 'baz'
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
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.
|
4
|
+
version: 0.8.84
|
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-
|
11
|
+
date: 2016-10-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: msgpack
|
@@ -16,44 +16,20 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.
|
20
|
-
- - "!="
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version: 0.5.0
|
23
|
-
- - "!="
|
24
|
-
- !ruby/object:Gem::Version
|
25
|
-
version: 0.5.1
|
26
|
-
- - "!="
|
27
|
-
- !ruby/object:Gem::Version
|
28
|
-
version: 0.5.2
|
29
|
-
- - "!="
|
30
|
-
- !ruby/object:Gem::Version
|
31
|
-
version: 0.5.3
|
19
|
+
version: 0.5.6
|
32
20
|
- - "<"
|
33
21
|
- !ruby/object:Gem::Version
|
34
|
-
version:
|
22
|
+
version: '2'
|
35
23
|
type: :runtime
|
36
24
|
prerelease: false
|
37
25
|
version_requirements: !ruby/object:Gem::Requirement
|
38
26
|
requirements:
|
39
27
|
- - ">="
|
40
28
|
- !ruby/object:Gem::Version
|
41
|
-
version: 0.
|
42
|
-
- - "!="
|
43
|
-
- !ruby/object:Gem::Version
|
44
|
-
version: 0.5.0
|
45
|
-
- - "!="
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: 0.5.1
|
48
|
-
- - "!="
|
49
|
-
- !ruby/object:Gem::Version
|
50
|
-
version: 0.5.2
|
51
|
-
- - "!="
|
52
|
-
- !ruby/object:Gem::Version
|
53
|
-
version: 0.5.3
|
29
|
+
version: 0.5.6
|
54
30
|
- - "<"
|
55
31
|
- !ruby/object:Gem::Version
|
56
|
-
version:
|
32
|
+
version: '2'
|
57
33
|
- !ruby/object:Gem::Dependency
|
58
34
|
name: json
|
59
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -72,14 +48,14 @@ dependencies:
|
|
72
48
|
name: httpclient
|
73
49
|
requirement: !ruby/object:Gem::Requirement
|
74
50
|
requirements:
|
75
|
-
- - "
|
51
|
+
- - ">="
|
76
52
|
- !ruby/object:Gem::Version
|
77
53
|
version: '2.7'
|
78
54
|
type: :runtime
|
79
55
|
prerelease: false
|
80
56
|
version_requirements: !ruby/object:Gem::Requirement
|
81
57
|
requirements:
|
82
|
-
- - "
|
58
|
+
- - ">="
|
83
59
|
- !ruby/object:Gem::Version
|
84
60
|
version: '2.7'
|
85
61
|
- !ruby/object:Gem::Dependency
|
@@ -96,34 +72,6 @@ dependencies:
|
|
96
72
|
- - "~>"
|
97
73
|
- !ruby/object:Gem::Version
|
98
74
|
version: '3.0'
|
99
|
-
- !ruby/object:Gem::Dependency
|
100
|
-
name: mime-types
|
101
|
-
requirement: !ruby/object:Gem::Requirement
|
102
|
-
requirements:
|
103
|
-
- - '='
|
104
|
-
- !ruby/object:Gem::Version
|
105
|
-
version: '1.25'
|
106
|
-
type: :development
|
107
|
-
prerelease: false
|
108
|
-
version_requirements: !ruby/object:Gem::Requirement
|
109
|
-
requirements:
|
110
|
-
- - '='
|
111
|
-
- !ruby/object:Gem::Version
|
112
|
-
version: '1.25'
|
113
|
-
- !ruby/object:Gem::Dependency
|
114
|
-
name: rest-client
|
115
|
-
requirement: !ruby/object:Gem::Requirement
|
116
|
-
requirements:
|
117
|
-
- - '='
|
118
|
-
- !ruby/object:Gem::Version
|
119
|
-
version: 1.6.8
|
120
|
-
type: :development
|
121
|
-
prerelease: false
|
122
|
-
version_requirements: !ruby/object:Gem::Requirement
|
123
|
-
requirements:
|
124
|
-
- - '='
|
125
|
-
- !ruby/object:Gem::Version
|
126
|
-
version: 1.6.8
|
127
75
|
- !ruby/object:Gem::Dependency
|
128
76
|
name: coveralls
|
129
77
|
requirement: !ruby/object:Gem::Requirement
|
@@ -237,6 +185,7 @@ files:
|
|
237
185
|
- spec/td/client/job_api_spec.rb
|
238
186
|
- spec/td/client/model_job_spec.rb
|
239
187
|
- spec/td/client/model_schedule_spec.rb
|
188
|
+
- spec/td/client/model_schema_spec.rb
|
240
189
|
- spec/td/client/partial_delete_api_spec.rb
|
241
190
|
- spec/td/client/result_api_spec.rb
|
242
191
|
- spec/td/client/sched_api_spec.rb
|
@@ -257,7 +206,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
257
206
|
requirements:
|
258
207
|
- - ">="
|
259
208
|
- !ruby/object:Gem::Version
|
260
|
-
version: 2.
|
209
|
+
version: '2.1'
|
261
210
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
262
211
|
requirements:
|
263
212
|
- - ">="
|
@@ -283,6 +232,7 @@ test_files:
|
|
283
232
|
- spec/td/client/job_api_spec.rb
|
284
233
|
- spec/td/client/model_job_spec.rb
|
285
234
|
- spec/td/client/model_schedule_spec.rb
|
235
|
+
- spec/td/client/model_schema_spec.rb
|
286
236
|
- spec/td/client/partial_delete_api_spec.rb
|
287
237
|
- spec/td/client/result_api_spec.rb
|
288
238
|
- spec/td/client/sched_api_spec.rb
|