td 0.11.9 → 0.11.10

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.
data/ChangeLog CHANGED
@@ -1,3 +1,16 @@
1
+ == 2015-05-19 version 0.11.10
2
+
3
+ * Updated 'td-client' gem dependency to 0.8.70. The new gem removed client
4
+ side validation for connector commands to allow additional plugin configs
5
+ we're going to add in the future.
6
+ * connector:guess dumps configuration file to stdout that is guessed by the
7
+ server to check the config file easier.
8
+ * connector:preview shows full column name (not truncated) in the table.
9
+ * add --pool-name option to job registration.
10
+ * add sched:result command to show job results for a saved query.
11
+ * save to temporary file while downloading job result in job:show.
12
+ * show job duration in job list.
13
+
1
14
  == 2015-04-17 version 0.11.9
2
15
 
3
16
  * add connector commands.
@@ -41,10 +41,10 @@ module Command
41
41
  end
42
42
  end
43
43
 
44
- puts "Enter your Treasure Data credentials."
44
+ $stdout.puts "Enter your Treasure Data credentials."
45
45
  unless user_name
46
46
  begin
47
- print "Email: "
47
+ $stdout.print "Email: "
48
48
  line = STDIN.gets || ""
49
49
  user_name = line.strip
50
50
  rescue Interrupt
@@ -62,14 +62,14 @@ module Command
62
62
 
63
63
  3.times do
64
64
  begin
65
- print "Password (typing will be hidden): "
65
+ $stdout.print "Password (typing will be hidden): "
66
66
  password = get_password
67
67
  rescue Interrupt
68
68
  $stderr.print "\ncanceled."
69
69
  exit 1
70
70
  ensure
71
71
  system "stty echo" # TODO termios
72
- print "\n"
72
+ $stdout.print "\n"
73
73
  end
74
74
 
75
75
  if password.empty?
@@ -91,7 +91,7 @@ module Command
91
91
  end
92
92
  return unless client
93
93
 
94
- puts "Authenticated successfully."
94
+ $stdout.puts "Authenticated successfully."
95
95
 
96
96
  conf ||= Config.new
97
97
  conf["account.user"] = user_name
@@ -14,7 +14,7 @@ module Command
14
14
  rows << {:Subject => ac.subject, :Action => ac.action, :Scope => ac.scope, :"Grant option" => ac.grant_option}
15
15
  }
16
16
 
17
- puts cmd_render_table(rows, :fields => [:Subject, :Action, :Scope, :"Grant option"])
17
+ $stdout.puts cmd_render_table(rows, :fields => [:Subject, :Action, :Scope, :"Grant option"])
18
18
 
19
19
  if rows.empty?
20
20
  $stderr.puts "There are no access controls."
@@ -4,7 +4,7 @@ module Command
4
4
 
5
5
  def apikey_show(op)
6
6
  if Config.apikey
7
- puts Config.apikey
7
+ $stdout.puts Config.apikey
8
8
  return
9
9
  end
10
10
 
@@ -20,7 +20,7 @@ module Command
20
20
  exit 1
21
21
  end
22
22
 
23
- puts conf['account.apikey']
23
+ $stdout.puts conf['account.apikey']
24
24
  end
25
25
 
26
26
  def apikey_set(op)
@@ -55,8 +55,8 @@ module Command
55
55
  conf["account.apikey"] = apikey
56
56
  conf.save
57
57
 
58
- puts "API key is set."
59
- puts "Use '#{$prog} db:create <db_name>' to create a database."
58
+ $stdout.puts "API key is set."
59
+ $stdout.puts "Use '#{$prog} db:create <db_name>' to create a database."
60
60
  end
61
61
 
62
62
  end
@@ -16,7 +16,7 @@ module Command
16
16
  rows << {:Name=>bi.name, :Table=>"#{bi.database}.#{bi.table}", :Status=>bi.status.to_s.capitalize, :Frozen=>bi.upload_frozen? ? 'Frozen' : '', :JobID=>bi.job_id, :"Valid Parts"=>bi.valid_parts, :"Error Parts"=>bi.error_parts, :"Valid Records"=>bi.valid_records, :"Error Records"=>bi.error_records}
17
17
  }
18
18
 
19
- puts cmd_render_table(rows, :fields => [:Name, :Table, :Status, :Frozen, :JobID, :"Valid Parts", :"Error Parts", :"Valid Records", :"Error Records"], :max_width=>200, :render_format => op.render_format)
19
+ $stdout.puts cmd_render_table(rows, :fields => [:Name, :Table, :Status, :Frozen, :JobID, :"Valid Parts", :"Error Parts", :"Valid Records", :"Error Records"], :max_width=>200, :render_format => op.render_format)
20
20
 
21
21
  if rows.empty?
22
22
  $stderr.puts "There are no bulk import sessions."
@@ -75,7 +75,7 @@ module Command
75
75
 
76
76
  list = client.list_bulk_import_parts(name)
77
77
  list.each {|name|
78
- puts " #{name}"
78
+ $stdout.puts " #{name}"
79
79
  }
80
80
  end
81
81
 
@@ -100,6 +100,7 @@ module Command
100
100
  part_prefix = ""
101
101
  auto_perform = false
102
102
  parallel = 2
103
+ pool_name = nil
103
104
 
104
105
  op.on('-P', '--prefix NAME', 'add prefix to parts name') {|s|
105
106
  part_prefix = s
@@ -113,6 +114,9 @@ module Command
113
114
  op.on('--parallel NUM', 'perform uploading in parallel (default: 2; max 8)', Integer) {|i|
114
115
  parallel = i
115
116
  }
117
+ op.on('-O', '--pool-name NAME', 'specify resource pool by name') {|s|
118
+ pool_name = s
119
+ }
116
120
 
117
121
  name, *files = op.cmd_parse
118
122
 
@@ -176,8 +180,10 @@ module Command
176
180
  $stderr.puts "done."
177
181
 
178
182
  if auto_perform
183
+ opts = {}
184
+ opts['pool_name'] = pool_name if pool_name
179
185
  client = get_client
180
- job = client.perform_bulk_import(name)
186
+ job = client.perform_bulk_import(name, opts)
181
187
 
182
188
  $stderr.puts "Job #{job.job_id} is queued."
183
189
  $stderr.puts "Use '#{$prog} " + Config.cl_options_string + "job:show [-w] #{job.job_id}' to show the status."
@@ -185,7 +191,7 @@ module Command
185
191
  end
186
192
 
187
193
  def bulk_import_upload_parts2(op)
188
- puts "This command is moved to 'td import:upload' since 0.10.85."
194
+ $stdout.puts "This command is moved to 'td import:upload' since 0.10.85."
189
195
  end
190
196
 
191
197
  # obsoleted
@@ -223,6 +229,7 @@ module Command
223
229
  def bulk_import_perform(op)
224
230
  wait = false
225
231
  force = false
232
+ pool_name = nil
226
233
 
227
234
  op.on('-w', '--wait', 'wait for finishing the job', TrueClass) {|b|
228
235
  wait = b
@@ -230,6 +237,9 @@ module Command
230
237
  op.on('-f', '--force', 'force start performing', TrueClass) {|b|
231
238
  force = b
232
239
  }
240
+ op.on('-O', '--pool-name NAME', 'specify resource pool by name') {|s|
241
+ pool_name = s
242
+ }
233
243
 
234
244
  name = op.cmd_parse
235
245
 
@@ -252,7 +262,9 @@ module Command
252
262
  end
253
263
  end
254
264
 
255
- job = client.perform_bulk_import(name)
265
+ opts = {}
266
+ opts['pool_name'] = pool_name if pool_name
267
+ job = client.perform_bulk_import(name, opts)
256
268
 
257
269
  $stderr.puts "Job #{job.job_id} is queued."
258
270
  $stderr.puts "Use '#{$prog} " + Config.cl_options_string + "job:show [-w] #{job.job_id}' to show the status."
@@ -338,7 +350,7 @@ module Command
338
350
 
339
351
  require 'yajl'
340
352
  client.bulk_import_error_records(name) {|r|
341
- puts Yajl.dump(r)
353
+ $stdout.puts Yajl.dump(r)
342
354
  }
343
355
  end
344
356
 
@@ -459,7 +471,7 @@ module Command
459
471
  end
460
472
 
461
473
  def bulk_import_prepare_parts2(op)
462
- puts "This command is moved to 'td import:prepare' since 0.10.85."
474
+ $stdout.puts "This command is moved to 'td import:prepare' since 0.10.85."
463
475
  end
464
476
 
465
477
  private
@@ -2,6 +2,8 @@ require 'td/version'
2
2
 
3
3
  module TreasureData
4
4
 
5
+ require "td/config"
6
+
5
7
  autoload :API, 'td/client/api'
6
8
  autoload :Client, 'td/client'
7
9
  autoload :Database, 'td/client'
@@ -249,7 +251,7 @@ EOS
249
251
  3.times do
250
252
  begin
251
253
  system "stty -echo" # TODO termios
252
- print "Password (typing will be hidden): "
254
+ $stdout.print "Password (typing will be hidden): "
253
255
  password = STDIN.gets || ""
254
256
  password = password[0..-2] # strip \n
255
257
  rescue Interrupt
@@ -257,7 +259,7 @@ EOS
257
259
  exit 1
258
260
  ensure
259
261
  system "stty echo" # TODO termios
260
- print "\n"
262
+ $stdout.print "\n"
261
263
  end
262
264
 
263
265
  if password.empty?
@@ -328,7 +330,7 @@ EOS
328
330
  class DownloadProgressIndicator
329
331
  def initialize(msg)
330
332
  @base_msg = msg
331
- print @base_msg + " " * 10
333
+ $stdout.print @base_msg + " " * 10
332
334
  end
333
335
  end
334
336
 
@@ -343,8 +345,8 @@ EOS
343
345
  def update
344
346
  if (time = Time.now.to_i) - @last_time >= @periodicity
345
347
  msg = "\r#{@base_msg}: #{Command.humanize_elapsed_time(@start_time, time)} elapsed"
346
- print "\r" + " " * (msg.length + 10)
347
- print msg
348
+ $stdout.print "\r" + " " * (msg.length + 10)
349
+ $stdout.print msg
348
350
  @last_time = time
349
351
  true
350
352
  else
@@ -353,7 +355,7 @@ EOS
353
355
  end
354
356
 
355
357
  def finish
356
- puts "\r#{@base_msg}...done" + " " * 20
358
+ $stdout.puts "\r#{@base_msg}...done" + " " * 20
357
359
  end
358
360
  end
359
361
 
@@ -378,15 +380,15 @@ EOS
378
380
  def update(curr_size)
379
381
  if @size.nil? || @size == 0
380
382
  msg = "\r#{@base_msg}: #{Command.humanize_bytesize(curr_size)}"
381
- print msg
383
+ $stdout.print msg
382
384
  true
383
385
  else
384
386
  ratio = (curr_size.to_f * 100 / @size).round(1)
385
387
  if ratio >= (@last_perc_step + @perc_step) &&
386
388
  (!@min_periodicity || (time = Time.now.to_i) - @last_time >= @min_periodicity)
387
389
  msg = "\r#{@base_msg}: #{Command.humanize_bytesize(curr_size)} / #{ratio}%"
388
- print "\r" + " " * (msg.length + 10)
389
- print msg
390
+ $stdout.print "\r" + " " * (msg.length + 10)
391
+ $stdout.print msg
390
392
  @last_perc_step = ratio
391
393
  @last_time = time
392
394
  true
@@ -397,7 +399,7 @@ EOS
397
399
  end
398
400
 
399
401
  def finish
400
- print "\r#{@base_msg}...done" + " " * 20
402
+ $stdout.print "\r#{@base_msg}...done" + " " * 20
401
403
  end
402
404
  end
403
405
 
@@ -40,7 +40,7 @@ module Command
40
40
  bucket = path_components.shift.sub(/\//, '')
41
41
  path_prefix = path_components.join.sub(/\//, '')
42
42
 
43
- job = API::BulkLoad::BulkLoad.from_hash(
43
+ job = {
44
44
  :config => {
45
45
  :type => type,
46
46
  :access_key_id => id,
@@ -49,7 +49,7 @@ module Command
49
49
  :bucket => bucket,
50
50
  :path_prefix => path_prefix,
51
51
  }
52
- ).validate
52
+ }
53
53
  end
54
54
 
55
55
  client = get_client
@@ -57,16 +57,20 @@ module Command
57
57
 
58
58
  create_bulkload_job_file_backup(out)
59
59
  if /\.json\z/ =~ out
60
- config_str = JSON.pretty_generate(job.to_h)
60
+ config_str = JSON.pretty_generate(job)
61
61
  else
62
- config_str = YAML.dump(job.to_h)
62
+ config_str = YAML.dump(job)
63
63
  end
64
64
  File.open(out, 'w') do |f|
65
65
  f << config_str
66
66
  end
67
67
 
68
- puts "Created #{out} file."
69
- puts "Use '#{$prog} " + Config.cl_options_string + "connector:preview #{out}' to see bulk load preview."
68
+ $stdout.puts "Guessed configuration:"
69
+ $stdout.puts
70
+ $stdout.puts config_str
71
+ $stdout.puts
72
+ $stdout.puts "Created #{out} file."
73
+ $stdout.puts "Use '#{$prog} " + Config.cl_options_string + "connector:preview #{out}' to see bulk load preview."
70
74
  end
71
75
 
72
76
  def connector_preview(op)
@@ -76,23 +80,23 @@ module Command
76
80
  client = get_client()
77
81
  preview = client.bulk_load_preview(job)
78
82
 
79
- cols = preview.schema.sort_by { |col|
83
+ cols = preview['schema'].sort_by { |col|
80
84
  col['index']
81
85
  }
82
86
  fields = cols.map { |col| col['name'] + ':' + col['type'] }
83
87
  types = cols.map { |col| col['type'] }
84
- rows = preview.records.map { |row|
88
+ rows = preview['records'].map { |row|
85
89
  cols = {}
86
90
  row.each_with_index do |col, idx|
87
91
  cols[fields[idx]] = col.inspect
88
92
  end
89
93
  cols
90
- }
94
+ }
91
95
 
92
- puts cmd_render_table(rows, :fields => fields, :render_format => op.render_format)
96
+ $stdout.puts cmd_render_table(rows, :fields => fields, :render_format => op.render_format, :resize => false)
93
97
 
94
- puts "Update #{config_file} and use '#{$prog} " + Config.cl_options_string + "connector:preview #{config_file}' to preview again."
95
- puts "Use '#{$prog} " + Config.cl_options_string + "connector:issue #{config_file}' to run Server-side bulk load."
98
+ $stdout.puts "Update #{config_file} and use '#{$prog} " + Config.cl_options_string + "connector:preview #{config_file}' to preview again."
99
+ $stdout.puts "Use '#{$prog} " + Config.cl_options_string + "connector:issue #{config_file}' to run Server-side bulk load."
96
100
  end
97
101
 
98
102
  def connector_issue(op)
@@ -116,8 +120,8 @@ module Command
116
120
  client = get_client()
117
121
  job_id = client.bulk_load_issue(database, table, job)
118
122
 
119
- puts "Job #{job_id} is queued."
120
- puts "Use '#{$prog} " + Config.cl_options_string + "job:show #{job_id}' to show the status."
123
+ $stdout.puts "Job #{job_id} is queued."
124
+ $stdout.puts "Use '#{$prog} " + Config.cl_options_string + "job:show #{job_id}' to show the status."
121
125
 
122
126
  if wait
123
127
  wait_connector_job(client, job_id, exclude)
@@ -135,10 +139,10 @@ module Command
135
139
  rows = client.bulk_load_list().sort_by { |e|
136
140
  e['name']
137
141
  }.map { |e|
138
- Hash[fields.zip(e.to_h.values_at(*keys))]
142
+ Hash[fields.zip(e.values_at(*keys))]
139
143
  }
140
144
 
141
- puts cmd_render_table(rows, :fields => fields, :render_format => op.render_format)
145
+ $stdout.puts cmd_render_table(rows, :fields => fields, :render_format => op.render_format)
142
146
  end
143
147
 
144
148
  def connector_create(op)
@@ -195,8 +199,8 @@ module Command
195
199
 
196
200
  client = get_client()
197
201
  session = client.bulk_load_delete(name)
198
- puts 'Deleted session'
199
- puts '--'
202
+ $stdout.puts 'Deleted session'
203
+ $stdout.puts '--'
200
204
  dump_connector_session(session)
201
205
  end
202
206
 
@@ -219,7 +223,7 @@ module Command
219
223
  :Duration => (e.end_at.nil? ? Time.now.to_i : e.end_at) - e.start_at,
220
224
  }
221
225
  }
222
- puts cmd_render_table(rows, :fields => fields, :render_format => op.render_format)
226
+ $stdout.puts cmd_render_table(rows, :fields => fields, :render_format => op.render_format)
223
227
  end
224
228
 
225
229
  def connector_run(op)
@@ -231,8 +235,8 @@ module Command
231
235
 
232
236
  client = get_client()
233
237
  job_id = client.bulk_load_run(name)
234
- puts "Job #{job_id} is queued."
235
- puts "Use '#{$prog} " + Config.cl_options_string + "job:show #{job_id}' to show the status."
238
+ $stdout.puts "Job #{job_id} is queued."
239
+ $stdout.puts "Use '#{$prog} " + Config.cl_options_string + "job:show #{job_id}' to show the status."
236
240
 
237
241
  if wait
238
242
  wait_connector_job(client, job_id, exclude)
@@ -263,7 +267,7 @@ private
263
267
  if file_type(config_str) == :yaml
264
268
  config_str = JSON.pretty_generate(YAML.load(config_str))
265
269
  end
266
- API::BulkLoad::BulkLoad.from_json(config_str)
270
+ JSON.load(config_str)
267
271
  end
268
272
 
269
273
  def create_bulkload_job_file_backup(out)
@@ -279,20 +283,20 @@ private
279
283
  end
280
284
 
281
285
  def dump_connector_session(session)
282
- puts "Name : #{session.name}"
283
- puts "Cron : #{session.cron}"
284
- puts "Timezone : #{session.timezone}"
285
- puts "Delay : #{session.delay}"
286
- puts "Database : #{session.database}"
287
- puts "Table : #{session.table}"
288
- puts "Config"
289
- puts YAML.dump(session.config.to_h)
286
+ $stdout.puts "Name : #{session.name}"
287
+ $stdout.puts "Cron : #{session.cron}"
288
+ $stdout.puts "Timezone : #{session.timezone}"
289
+ $stdout.puts "Delay : #{session.delay}"
290
+ $stdout.puts "Database : #{session.database}"
291
+ $stdout.puts "Table : #{session.table}"
292
+ $stdout.puts "Config"
293
+ $stdout.puts YAML.dump(session.config)
290
294
  end
291
295
 
292
296
  def wait_connector_job(client, job_id, exclude)
293
297
  job = client.job(job_id)
294
298
  wait_job(job, true)
295
- puts "Status : #{job.status}"
299
+ $stdout.puts "Status : #{job.status}"
296
300
  end
297
301
 
298
302
  end
data/lib/td/command/db.rb CHANGED
@@ -22,7 +22,7 @@ module Command
22
22
  [map[:Type].size, map[:Table]]
23
23
  }
24
24
 
25
- puts cmd_render_table(rows, :fields => [:Table, :Type, :Count, :Schema], :render_format => op.render_format)
25
+ $stdout.puts cmd_render_table(rows, :fields => [:Table, :Type, :Count, :Schema], :render_format => op.render_format)
26
26
  end
27
27
 
28
28
  def db_list(op)
@@ -37,7 +37,7 @@ module Command
37
37
  dbs.each {|db|
38
38
  rows << {:Name=>db.name, :Count=>db.count}
39
39
  }
40
- puts cmd_render_table(rows, :fields => [:Name, :Count], :render_format => op.render_format)
40
+ $stdout.puts cmd_render_table(rows, :fields => [:Name, :Count], :render_format => op.render_format)
41
41
 
42
42
  if dbs.empty?
43
43
  $stderr.puts "There are no databases."
@@ -12,6 +12,7 @@ module Command
12
12
  aws_secret_access_key = nil
13
13
  file_prefix = nil
14
14
  file_format = "json.gz" # default
15
+ pool_name = nil
15
16
 
16
17
  op.on('-w', '--wait', 'wait until the job is completed', TrueClass) {|b|
17
18
  wait = b
@@ -38,6 +39,9 @@ module Command
38
39
  raise ArgumentError, "#{s} is not a supported file format" unless SUPPORTED_FORMATS.include?(s)
39
40
  file_format = s
40
41
  }
42
+ op.on('-O', '--pool-name NAME', 'specify resource pool by name') {|s|
43
+ pool_name = s
44
+ }
41
45
 
42
46
  db_name, table_name = op.cmd_parse
43
47
 
@@ -70,6 +74,7 @@ module Command
70
74
  s3_opts['bucket'] = s3_bucket
71
75
  s3_opts['access_key_id'] = aws_access_key_id
72
76
  s3_opts['secret_access_key'] = aws_secret_access_key
77
+ s3_opts['pool_name'] = pool_name if pool_name
73
78
 
74
79
  job = client.export(db_name, table_name, "s3", s3_opts)
75
80
 
@@ -78,7 +83,7 @@ module Command
78
83
 
79
84
  if wait && !job.finished?
80
85
  wait_job(job)
81
- puts "Status : #{job.status}"
86
+ $stdout.puts "Status : #{job.status}"
82
87
  end
83
88
  end
84
89
 
@@ -13,7 +13,7 @@ module Command
13
13
 
14
14
  elsif c.name != cmd && c.group == cmd
15
15
  # group command
16
- puts List.cmd_usage(cmd)
16
+ $stdout.puts List.cmd_usage(cmd)
17
17
  exit 1
18
18
 
19
19
  else
@@ -26,8 +26,8 @@ module Command
26
26
  cmd = op.cmd_parse
27
27
 
28
28
  TreasureData::Command::List.show_help(op.summary_indent)
29
- puts ""
30
- puts "Type '#{$prog} help COMMAND' for more information on a specific command."
29
+ $stdout.puts ""
30
+ $stdout.puts "Type '#{$prog} help COMMAND' for more information on a specific command."
31
31
  end
32
32
 
33
33
  end
@@ -27,7 +27,7 @@ module Command
27
27
  def import_jar_version(op)
28
28
  op.cmd_parse
29
29
  version = find_version_file
30
- puts "td-import-java #{File.open(version, 'r').read}"
30
+ $stdout.puts "td-import-java #{File.open(version, 'r').read}"
31
31
  end
32
32
 
33
33
  def import_jar_update(op)
@@ -90,7 +90,7 @@ module Command
90
90
  if op.cmd_requires_connectivity
91
91
  raise e
92
92
  else
93
- puts "Warning: JAR update skipped for connectivity issues"
93
+ $stdout.puts "Warning: JAR update skipped for connectivity issues"
94
94
  end
95
95
  end
96
96
 
@@ -303,7 +303,7 @@ module Command
303
303
  installed_path = File.join(File.expand_path('../../..', File.dirname(__FILE__)), 'java')
304
304
  config = Command.find_files("logging.properties", [Updater.jarfile_dest_path, installed_path])
305
305
  if config.empty?
306
- puts "Cannot find 'logging.properties' file in '#{Updater.jarfile_dest_path}' or " +
306
+ $stdout.puts "Cannot find 'logging.properties' file in '#{Updater.jarfile_dest_path}' or " +
307
307
  "'#{installed_path}'." unless ENV['TD_TOOLBELT_DEBUG'].nil?
308
308
  []
309
309
  else