td-client 0.8.83 → 0.8.84
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/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
|