td 0.11.2 → 0.11.3

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.
@@ -84,13 +84,14 @@ module Command
84
84
  :Start => (start ? start.localtime : ''),
85
85
  :Elapsed => elapsed.rjust(11),
86
86
  :CPUTime => cpu_time.rjust(17),
87
+ :ResultSize => (job.result_size ? Command.humanize_bytesize(job.result_size, 2) : ""),
87
88
  :Priority => priority,
88
89
  :Result => job.result_url
89
90
  }
90
91
  }
91
92
 
92
93
  puts cmd_render_table(rows,
93
- :fields => [:JobID, :Status, :Start, :Elapsed, :CPUTime, :Priority, :Result, :Type, :Database, :Query],
94
+ :fields => [:JobID, :Status, :Start, :Elapsed, :CPUTime, :ResultSize, :Priority, :Result, :Type, :Database, :Query],
94
95
  :max_width => 1000,
95
96
  :render_format => op.render_format
96
97
  )
@@ -180,8 +181,13 @@ module Command
180
181
  puts "Destination : #{job.query}"
181
182
  end
182
183
  # if the job is done and is of type hive, show the Map-Reduce cumulated CPU time
183
- if job.finished? && [:hive].include?(job.type)
184
- puts "CPU time : #{Command.humanize_time(job.cpu_time, true)}"
184
+ if job.finished?
185
+ if [:hive].include?(job.type)
186
+ puts "CPU time : #{Command.humanize_time(job.cpu_time, true)}"
187
+ end
188
+ if [:hive, :pig, :impala, :presto].include?(job.type)
189
+ puts "Result size : #{Command.humanize_bytesize(job.result_size, 2)}"
190
+ end
185
191
  end
186
192
 
187
193
  if wait && !job.finished?
@@ -285,7 +291,7 @@ module Command
285
291
  def show_result(job, output, limit, format, render_opts={})
286
292
  if output
287
293
  write_result(job, output, limit, format, render_opts)
288
- puts "written to #{output} in #{format} format"
294
+ puts "\rwritten to #{output} in #{format} format" + " " * 50
289
295
  else
290
296
  # every format that is allowed on stdout
291
297
  render_result(job, limit, format, render_opts)
@@ -302,13 +308,20 @@ module Command
302
308
  open_file(output, "w") {|f|
303
309
  f.write "["
304
310
  n_rows = 0
305
- job.result_each {|row|
311
+ unless output.nil?
312
+ indicator = Command::SizeBasedDownloadProgressIndicator.new(
313
+ "NOTE: the job result is being written to #{output} in json format",
314
+ job.result_size, 0.1, 1)
315
+ end
316
+ job.result_each_with_compr_size {|row, compr_size|
317
+ indicator.update(compr_size) unless output.nil?
306
318
  f.write ",\n" if n_rows > 0
307
319
  f.write Yajl.dump(row)
308
320
  n_rows += 1
309
321
  break if output.nil? and !limit.nil? and n_rows == limit
310
322
  }
311
323
  f.write "]"
324
+ indicator.finish unless output.nil?
312
325
  }
313
326
  puts if output.nil?
314
327
 
@@ -318,15 +331,21 @@ module Command
318
331
 
319
332
  open_file(output, "w") {|f|
320
333
  writer = CSV.new(f)
321
- n_rows = 0
322
334
  # output headers
323
335
  if render_opts[:header] && job.hive_result_schema
324
- writer << job.hive_result_schema.map {|name,type|
336
+ writer << job.hive_result_schema.map {|name, type|
325
337
  name
326
338
  }
327
339
  end
328
340
  # output data
329
- job.result_each {|row|
341
+ n_rows = 0
342
+ unless output.nil?
343
+ indicator = Command::SizeBasedDownloadProgressIndicator.new(
344
+ "NOTE: the job result is being written to #{output} in csv format",
345
+ job.result_size, 0.1, 1)
346
+ end
347
+ job.result_each_with_compr_size {|row, compr_size|
348
+ indicator.update(compr_size) unless output.nil?
330
349
  # TODO limit the # of columns
331
350
  writer << row.map {|col|
332
351
  dump_column(col)
@@ -335,6 +354,7 @@ module Command
335
354
  writer.flush if n_rows % 100 == 0 # flush every 100 recods
336
355
  break if output.nil? and !limit.nil? and n_rows == limit
337
356
  }
357
+ indicator.finish unless output.nil?
338
358
  }
339
359
 
340
360
  when 'tsv'
@@ -350,7 +370,13 @@ module Command
350
370
  end
351
371
  # output data
352
372
  n_rows = 0
353
- job.result_each {|row|
373
+ unless output.nil?
374
+ indicator = Command::SizeBasedDownloadProgressIndicator.new(
375
+ "NOTE: the job result is being written to #{output} in tsv format",
376
+ job.result_size, 0.1, 1)
377
+ end
378
+ job.result_each_with_compr_size {|row, compr_size|
379
+ indicator.update(compr_size) unless output.nil?
354
380
  n_cols = 0
355
381
  row.each {|col|
356
382
  f.write "\t" if n_cols > 0
@@ -363,6 +389,7 @@ module Command
363
389
  f.flush if n_rows % 100 == 0 # flush every 100 recods
364
390
  break if output.nil? and !limit.nil? and n_rows == limit
365
391
  }
392
+ indicator.finish unless output.nil?
366
393
  }
367
394
 
368
395
  # these last 2 formats are only valid if writing the result to file through the -o/--output option.
@@ -373,7 +400,13 @@ module Command
373
400
  "Format 'msgpack' does not support writing to stdout"
374
401
  end
375
402
  open_file(output, "wb") {|f|
376
- job.result_format('msgpack', f)
403
+ indicator = Command::SizeBasedDownloadProgressIndicator.new(
404
+ "NOTE: the job result is being written to #{output} in msgpack format",
405
+ job.result_size, 0.1, 1)
406
+ job.result_format('msgpack', f) {|compr_size|
407
+ indicator.update(compr_size)
408
+ }
409
+ indicator.finish
377
410
  }
378
411
 
379
412
  when 'msgpack.gz'
@@ -382,7 +415,13 @@ module Command
382
415
  "Format 'msgpack' does not support writing to stdout"
383
416
  end
384
417
  open_file(output, "wb") {|f|
385
- job.result_format('msgpack.gz', f)
418
+ indicator = Command::SizeBasedDownloadProgressIndicator.new(
419
+ "NOTE: the job result is being written to #{output} in msgpack.gz format",
420
+ job.result_size, 0.1, 1)
421
+ job.result_format('msgpack.gz', f) {|compr_size|
422
+ indicator.update(compr_size)
423
+ }
424
+ indicator.finish
386
425
  }
387
426
 
388
427
  else
@@ -411,9 +450,11 @@ module Command
411
450
  # display result in tabular format
412
451
  rows = []
413
452
  n_rows = 0
414
- print "WARNING: the query result is being downloaded...\r"
415
- job.result_each {|row|
416
- # TODO limit number of rows to show
453
+
454
+ indicator = Command::SizeBasedDownloadProgressIndicator.new(
455
+ "WARNING: the job result is being downloaded...", job.result_size, 0.1, 1)
456
+ job.result_each_with_compr_size {|row, compr_size|
457
+ indicator.update(compr_size)
417
458
  rows << row.map {|v|
418
459
  dump_column(v)
419
460
  }
@@ -427,7 +468,8 @@ module Command
427
468
  render_opts[:change_fields] = job.hive_result_schema.map { |name,type| name }
428
469
  end
429
470
 
430
- puts cmd_render_table(rows, render_opts)
471
+ print "\r" + " " * 50
472
+ puts "\r" + cmd_render_table(rows, render_opts)
431
473
  else
432
474
  # display result in any of: json, csv, tsv.
433
475
  # msgpack and mspgpack.gz are not supported for stdout output
@@ -3,17 +3,19 @@ module Command
3
3
  module List
4
4
 
5
5
  class CommandParser < OptionParser
6
- def initialize(name, req_args, opt_args, varlen, argv)
6
+ def initialize(name, req_args, opt_args, varlen, argv, req_conn)
7
7
  super()
8
+ @name = name
8
9
  @req_args = req_args
9
10
  @opt_args = opt_args
10
11
  @varlen = varlen
11
12
  @argv = argv
12
13
  @has_options = false
13
14
  @message = ''
15
+ @cmd_requires_connectivity = req_conn
14
16
  end
15
17
 
16
- attr_accessor :message
18
+ attr_accessor :message, :name, :cmd_requires_connectivity
17
19
 
18
20
  def on(*argv)
19
21
  @has_options = true
@@ -51,15 +53,16 @@ module List
51
53
  end
52
54
 
53
55
  class CommandOption
54
- def initialize(name, args, description, examples)
56
+ def initialize(name, args, description, examples = [], req_conn = true)
55
57
  @name = name
56
58
  @args = args
57
59
  @description = description.to_s
58
60
  @examples = examples
61
+ @req_conn = req_conn
59
62
  @override_message = nil
60
63
  end
61
64
 
62
- attr_reader :name, :args, :description, :examples
65
+ attr_reader :name, :args, :description, :examples, :req_conn
63
66
  attr_accessor :override_message
64
67
 
65
68
  def compile!
@@ -84,7 +87,7 @@ module List
84
87
 
85
88
  def create_optparse(argv)
86
89
  compile!
87
- op = CommandParser.new(@name, @req_args, @opt_args, @varlen, argv)
90
+ op = CommandParser.new(@name, @req_args, @opt_args, @varlen, argv, @req_conn)
88
91
 
89
92
  message = "usage:\n"
90
93
  message << " $ #{File.basename($0)} #{@usage_args}\n"
@@ -129,8 +132,8 @@ module List
129
132
  HELP_EXCLUDE = [/^help/, /^account/, /^update/, /^user/, /^acl/]
130
133
  USAGE_EXCLUDE = [/bulk_import:upload_part\z/, /bulk_import:delete_part\z/]
131
134
 
132
- def self.add_list(name, args, description, *examples)
133
- LIST << COMMAND[name] = CommandOption.new(name, args, description, examples)
135
+ def self.add_list(name, args, description, examples = [], cmd_req_conn = true)
136
+ LIST << COMMAND[name] = CommandOption.new(name, args, description, examples, cmd_req_conn)
134
137
  end
135
138
 
136
139
  def self.add_alias(new_cmd, old_cmd)
@@ -157,7 +160,7 @@ module List
157
160
  require "td/command/#{group}"
158
161
  cmd = name.gsub(/[\:\-]/, '_')
159
162
  m = Object.new.extend(Command).method(cmd)
160
- return Proc.new {|args| m.call(c.create_optparse(args)) }
163
+ return Proc.new { |args| m.call(c.create_optparse(args)) }, c.req_conn
161
164
  end
162
165
  nil
163
166
  end
@@ -213,85 +216,85 @@ module List
213
216
  }
214
217
  end
215
218
 
216
- add_list 'db:list', %w[], 'Show list of tables in a database', 'db:list', 'dbs'
217
- add_list 'db:show', %w[db], 'Describe information of a database', 'db example_db'
218
- add_list 'db:create', %w[db], 'Create a database', 'db:create example_db'
219
- add_list 'db:delete', %w[db], 'Delete a database', 'db:delete example_db'
220
-
221
- add_list 'table:list', %w[db?], 'Show list of tables', 'table:list', 'table:list example_db', 'tables'
222
- add_list 'table:show', %w[db table], 'Describe information of a table', 'table example_db table1'
223
- add_list 'table:create', %w[db table], 'Create a table', 'table:create example_db table1'
224
- add_list 'table:delete', %w[db table], 'Delete a table', 'table:delete example_db table1'
225
- add_list 'table:import', %w[db table files_], 'Parse and import files to a table', 'table:import example_db table1 --apache access.log', 'table:import example_db table1 --json -t time - < test.json'
226
- add_list 'table:export', %w[db table], 'Dump logs in a table to the specified storage', 'table:export example_db table1 --s3-bucket mybucket -k KEY_ID -s SECRET_KEY'
227
- add_list 'table:swap', %w[db table1 table2], 'Swap names of two tables', 'table:swap example_db table1 table2'
228
- add_list 'table:tail', %w[db table], 'Get recently imported logs', 'table:tail example_db table1', 'table:tail example_db table1 -t "2011-01-02 03:04:05" -n 30'
229
- add_list 'table:partial_delete', %w[db table], 'Delete logs from the table within the specified time range', 'table:partial_delete example_db table1 --from 1341000000 --to 1341003600'
230
- add_list 'table:expire', %w[db table expire_days], 'Expire data in table after specified number of days', 'table:expire example_db table1 30'
231
-
232
- add_list 'bulk_import:list', %w[], 'List bulk import sessions', 'bulk_import:list'
233
- add_list 'bulk_import:show', %w[name], 'Show list of uploaded parts', 'bulk_import:show'
234
- add_list 'bulk_import:create', %w[name db table], 'Create a new bulk import session to the the table', 'bulk_import:create logs_201201 example_db event_logs'
235
- add_list 'bulk_import:prepare_parts', %w[files_], 'Convert files into part file format', 'bulk_import:prepare_parts logs/*.csv --format csv --columns time,uid,price,count --time-column "time" -o parts/'
236
- add_list 'bulk_import:upload_part', %w[name id path.msgpack.gz], 'Upload or re-upload a file into a bulk import session', 'bulk_import:upload_part logs_201201 01h data-201201-01.msgpack.gz'
237
- add_list 'bulk_import:upload_parts', %w[name files_], 'Upload or re-upload files into a bulk import session', 'bulk_import:upload_parts parts/* --parallel 4'
238
- add_list 'bulk_import:delete_part', %w[name id], 'Delete a uploaded file from a bulk import session', 'bulk_import:delete_part logs_201201 01h'
239
- add_list 'bulk_import:delete_parts', %w[name ids_], 'Delete uploaded files from a bulk import session', 'bulk_import:delete_parts logs_201201 01h 02h 03h'
240
- add_list 'bulk_import:perform', %w[name], 'Start to validate and convert uploaded files', 'bulk_import:perform logs_201201'
241
- add_list 'bulk_import:error_records', %w[name], 'Show records which did not pass validations', 'bulk_import:error_records logs_201201'
242
- add_list 'bulk_import:commit', %w[name], 'Start to commit a performed bulk import session', 'bulk_import:commit logs_201201'
243
- add_list 'bulk_import:delete', %w[name], 'Delete a bulk import session', 'bulk_import:delete logs_201201'
244
- add_list 'bulk_import:freeze', %w[name], 'Reject succeeding uploadings to a bulk import session', 'bulk_import:freeze logs_201201'
245
- add_list 'bulk_import:unfreeze', %w[name], 'Unfreeze a frozen bulk import session', 'bulk_import:unfreeze logs_201201'
246
-
247
- add_list 'import:list', %w[], 'List bulk import sessions', 'import:list'
248
- add_list 'import:show', %w[name], 'Show list of uploaded parts', 'import:show'
249
- add_list 'import:create', %w[name db table], 'Create a new bulk import session to the the table', 'import:create logs_201201 example_db event_logs'
250
- add_list 'import:jar_version', %w[], 'Show import jar version', 'import:jar_version'
251
- add_list 'import:jar_update', %w[], 'Update import jar to the latest version', 'import:jar_update'
252
- add_list 'import:prepare', %w[files_], 'Convert files into part file format', 'import:prepare logs/*.csv --format csv --columns time,uid,price,count --time-column "time" -o parts/'
253
- add_list 'import:upload', %w[name files_], 'Upload or re-upload files into a bulk import session', 'import:upload parts/* --parallel 4'
254
- add_list 'import:auto', %w[name files_], 'Upload files and automatically perform and commit the data', 'import:auto parts/* --parallel 4'
255
- add_list 'import:perform', %w[name], 'Start to validate and convert uploaded files', 'import:perform logs_201201'
256
- add_list 'import:error_records', %w[name], 'Show records which did not pass validations', 'import:error_records logs_201201'
257
- add_list 'import:commit', %w[name], 'Start to commit a performed bulk import session', 'import:commit logs_201201'
258
- add_list 'import:delete', %w[name], 'Delete a bulk import session', 'import:delete logs_201201'
259
- add_list 'import:freeze', %w[name], 'Reject succeeding uploadings to a bulk import session', 'import:freeze logs_201201'
260
- add_list 'import:unfreeze', %w[name], 'Unfreeze a frozen bulk import session', 'import:unfreeze logs_201201'
261
-
262
- add_list 'result:list', %w[], 'Show list of result URLs', 'result:list', 'results'
263
- add_list 'result:show', %w[name], 'Describe information of a result URL', 'result name'
264
- add_list 'result:create', %w[name URL], 'Create a result URL', 'result:create name mysql://my-server/mydb'
265
- add_list 'result:delete', %w[name], 'Delete a result URL', 'result:delete name'
266
-
267
- add_list 'status', %w[], 'Show schedules, jobs, tables and results', 'status', 's'
268
-
269
- add_list 'schema:show', %w[db table], 'Show schema of a table', 'schema example_db table1'
270
- add_list 'schema:set', %w[db table columns_?], 'Set new schema on a table', 'schema:set example_db table1 user:string size:int'
271
- add_list 'schema:add', %w[db table columns_], 'Add new columns to a table', 'schema:add example_db table1 user:string size:int'
272
- add_list 'schema:remove', %w[db table columns_], 'Remove columns from a table', 'schema:remove example_db table1 user size'
273
-
274
- add_list 'sched:list', %w[], 'Show list of schedules', 'sched:list', 'scheds'
275
- add_list 'sched:create', %w[name cron sql?], 'Create a schedule', 'sched:create sched1 "0 * * * *" -d example_db "select count(*) from table1" -r rset1',
276
- 'sched:create sched1 "0 * * * *" -d example_db -q query.txt -r rset2'
277
- add_list 'sched:delete', %w[name], 'Delete a schedule', 'sched:delete sched1'
278
- add_list 'sched:update', %w[name], 'Modify a schedule', 'sched:update sched1 -s "0 */2 * * *" -d my_db -t "Asia/Tokyo" -D 3600'
279
- add_list 'sched:history', %w[name max?], 'Show history of scheduled queries', 'sched sched1 --page 1'
280
- add_list 'sched:run', %w[name time], 'Run scheduled queries for the specified time', 'sched:run sched1 "2013-01-01 00:00:00" -n 6'
281
-
282
- add_list 'query', %w[sql?], 'Issue a query', 'query -d example_db -w -r rset1 "select count(*) from table1"',
283
- 'query -d example_db -w -r rset1 -q query.txt'
284
-
285
- add_list 'job:show', %w[job_id], 'Show status and result of a job', 'job:show 1461'
286
- add_list 'job:status', %w[job_id], 'Show status progress of a job', 'job:status 1461'
287
- add_list 'job:list', %w[max?], 'Show list of jobs', 'jobs', 'jobs --page 1'
288
- add_list 'job:kill', %w[job_id], 'Kill or cancel a job', 'job:kill 1461'
219
+ add_list 'db:list', %w[], 'Show list of tables in a database', ['db:list', 'dbs']
220
+ add_list 'db:show', %w[db], 'Describe information of a database', ['db example_db']
221
+ add_list 'db:create', %w[db], 'Create a database', ['db:create example_db']
222
+ add_list 'db:delete', %w[db], 'Delete a database', ['db:delete example_db']
223
+
224
+ add_list 'table:list', %w[db?], 'Show list of tables', ['table:list', 'table:list example_db', 'tables']
225
+ add_list 'table:show', %w[db table], 'Describe information of a table', ['table example_db table1']
226
+ add_list 'table:create', %w[db table], 'Create a table', ['table:create example_db table1']
227
+ add_list 'table:delete', %w[db table], 'Delete a table', ['table:delete example_db table1']
228
+ add_list 'table:import', %w[db table files_], 'Parse and import files to a table', ['table:import example_db table1 --apache access.log', 'table:import example_db table1 --json -t time - < test.json']
229
+ add_list 'table:export', %w[db table], 'Dump logs in a table to the specified storage', ['table:export example_db table1 --s3-bucket mybucket -k KEY_ID -s SECRET_KEY']
230
+ add_list 'table:swap', %w[db table1 table2], 'Swap names of two tables', ['table:swap example_db table1 table2']
231
+ add_list 'table:tail', %w[db table], 'Get recently imported logs', ['table:tail example_db table1', 'table:tail example_db table1 -t "2011-01-02 03:04:05" -n 30']
232
+ add_list 'table:partial_delete', %w[db table], 'Delete logs from the table within the specified time range', ['table:partial_delete example_db table1 --from 1341000000 --to 1341003600']
233
+ add_list 'table:expire', %w[db table expire_days], 'Expire data in table after specified number of days', ['table:expire example_db table1 30']
234
+
235
+ add_list 'bulk_import:list', %w[], 'List bulk import sessions', ['bulk_import:list']
236
+ add_list 'bulk_import:show', %w[name], 'Show list of uploaded parts', ['bulk_import:show']
237
+ add_list 'bulk_import:create', %w[name db table], 'Create a new bulk import session to the the table', ['bulk_import:create logs_201201 example_db event_logs']
238
+ add_list 'bulk_import:prepare_parts', %w[files_], 'Convert files into part file format', ['bulk_import:prepare_parts logs/*.csv --format csv --columns time,uid,price,count --time-column "time" -o parts/']
239
+ add_list 'bulk_import:upload_part', %w[name id path.msgpack.gz], 'Upload or re-upload a file into a bulk import session', ['bulk_import:upload_part logs_201201 01h data-201201-01.msgpack.gz']
240
+ add_list 'bulk_import:upload_parts', %w[name files_], 'Upload or re-upload files into a bulk import session', ['bulk_import:upload_parts parts/* --parallel 4']
241
+ add_list 'bulk_import:delete_part', %w[name id], 'Delete a uploaded file from a bulk import session', ['bulk_import:delete_part logs_201201 01h']
242
+ add_list 'bulk_import:delete_parts', %w[name ids_], 'Delete uploaded files from a bulk import session', ['bulk_import:delete_parts logs_201201 01h 02h 03h']
243
+ add_list 'bulk_import:perform', %w[name], 'Start to validate and convert uploaded files', ['bulk_import:perform logs_201201']
244
+ add_list 'bulk_import:error_records', %w[name], 'Show records which did not pass validations', ['bulk_import:error_records logs_201201']
245
+ add_list 'bulk_import:commit', %w[name], 'Start to commit a performed bulk import session', ['bulk_import:commit logs_201201']
246
+ add_list 'bulk_import:delete', %w[name], 'Delete a bulk import session', ['bulk_import:delete logs_201201']
247
+ add_list 'bulk_import:freeze', %w[name], 'Reject succeeding uploadings to a bulk import session', ['bulk_import:freeze logs_201201']
248
+ add_list 'bulk_import:unfreeze', %w[name], 'Unfreeze a frozen bulk import session', ['bulk_import:unfreeze logs_201201']
249
+
250
+ add_list 'import:list', %w[], 'List bulk import sessions', ['import:list']
251
+ add_list 'import:show', %w[name], 'Show list of uploaded parts', ['import:show']
252
+ add_list 'import:create', %w[name db table], 'Create a new bulk import session to the the table', ['import:create logs_201201 example_db event_logs']
253
+ add_list 'import:jar_version', %w[], 'Show import jar version', ['import:jar_version'], false
254
+ add_list 'import:jar_update', %w[], 'Update import jar to the latest version', ['import:jar_update']
255
+ add_list 'import:prepare', %w[files_], 'Convert files into part file format', ['import:prepare logs/*.csv --format csv --columns time,uid,price,count --time-column "time" -o parts/'], false
256
+ add_list 'import:upload', %w[name files_], 'Upload or re-upload files into a bulk import session', ['import:upload parts/* --parallel 4']
257
+ add_list 'import:auto', %w[name files_], 'Upload files and automatically perform and commit the data', ['import:auto parts/* --parallel 4']
258
+ add_list 'import:perform', %w[name], 'Start to validate and convert uploaded files', ['import:perform logs_201201']
259
+ add_list 'import:error_records', %w[name], 'Show records which did not pass validations', ['import:error_records logs_201201']
260
+ add_list 'import:commit', %w[name], 'Start to commit a performed bulk import session', ['import:commit logs_201201']
261
+ add_list 'import:delete', %w[name], 'Delete a bulk import session', ['import:delete logs_201201']
262
+ add_list 'import:freeze', %w[name], 'Reject succeeding uploadings to a bulk import session', ['import:freeze logs_201201']
263
+ add_list 'import:unfreeze', %w[name], 'Unfreeze a frozen bulk import session', ['import:unfreeze logs_201201']
264
+
265
+ add_list 'result:list', %w[], 'Show list of result URLs', ['result:list', 'results']
266
+ add_list 'result:show', %w[name], 'Describe information of a result URL', ['result name']
267
+ add_list 'result:create', %w[name URL], 'Create a result URL', ['result:create name mysql://my-server/mydb']
268
+ add_list 'result:delete', %w[name], 'Delete a result URL', ['result:delete name']
269
+
270
+ add_list 'status', %w[], 'Show schedules, jobs, tables and results', ['status', 's']
271
+
272
+ add_list 'schema:show', %w[db table], 'Show schema of a table', ['schema example_db table1']
273
+ add_list 'schema:set', %w[db table columns_?], 'Set new schema on a table', ['schema:set example_db table1 user:string size:int']
274
+ add_list 'schema:add', %w[db table columns_], 'Add new columns to a table', ['schema:add example_db table1 user:string size:int']
275
+ add_list 'schema:remove', %w[db table columns_], 'Remove columns from a table', ['schema:remove example_db table1 user size']
276
+
277
+ add_list 'sched:list', %w[], 'Show list of schedules', ['sched:list', 'scheds']
278
+ add_list 'sched:create', %w[name cron sql?], 'Create a schedule', ['sched:create sched1 "0 * * * *" -d example_db "select count(*) from table1" -r rset1',
279
+ 'sched:create sched1 "0 * * * *" -d example_db -q query.txt -r rset2']
280
+ add_list 'sched:delete', %w[name], 'Delete a schedule', ['sched:delete sched1']
281
+ add_list 'sched:update', %w[name], 'Modify a schedule', ['sched:update sched1 -s "0 */2 * * *" -d my_db -t "Asia/Tokyo" -D 3600']
282
+ add_list 'sched:history', %w[name max?], 'Show history of scheduled queries', ['sched sched1 --page 1']
283
+ add_list 'sched:run', %w[name time], 'Run scheduled queries for the specified time', ['sched:run sched1 "2013-01-01 00:00:00" -n 6']
284
+
285
+ add_list 'query', %w[sql?], 'Issue a query', ['query -d example_db -w -r rset1 "select count(*) from table1"',
286
+ 'query -d example_db -w -r rset1 -q query.txt']
287
+
288
+ add_list 'job:show', %w[job_id], 'Show status and result of a job', ['job:show 1461']
289
+ add_list 'job:status', %w[job_id], 'Show status progress of a job', ['job:status 1461']
290
+ add_list 'job:list', %w[max?], 'Show list of jobs', ['jobs', 'jobs --page 1']
291
+ add_list 'job:kill', %w[job_id], 'Kill or cancel a job', ['job:kill 1461']
289
292
 
290
293
  add_list 'account', %w[user_name?], 'Setup a Treasure Data account'
291
294
  add_list 'account:usage', %w[user_name?], 'Show resource usage information'
292
295
  add_list 'password:change', %w[], 'Change password'
293
- add_list 'apikey:show', %w[], 'Show Treasure Data API key'
294
- add_list 'apikey:set', %w[apikey], 'Set Treasure Data API key'
296
+ add_list 'apikey:show', %w[], 'Show Treasure Data API key', [], false
297
+ add_list 'apikey:set', %w[apikey], 'Set Treasure Data API key', [], false
295
298
 
296
299
  add_list 'user:list', %w[], 'Show list of users'
297
300
  add_list 'user:show', %w[name], 'Show an user'
@@ -308,12 +311,12 @@ module List
308
311
  # TODO acl:test
309
312
 
310
313
  add_list 'server:status', %w[], 'Show status of the Treasure Data server'
311
- add_list 'server:endpoint', %w[api_endpoint], "Set the Treasure Data API server's endpoint (must be a valid URI)", "td server:endpoint 'https://api.treasuredata.com'"
314
+ add_list 'server:endpoint', %w[api_endpoint], "Set the Treasure Data API server's endpoint (must be a valid URI)", ["td server:endpoint 'https://api.treasuredata.com'"]
312
315
 
313
- add_list 'sample:apache', %w[path.json], 'Create a sample log file'
316
+ add_list 'sample:apache', %w[path.json], 'Create a sample log file', [], false
314
317
 
315
- add_list 'help:all', %w[], 'Show usage of all commands'
316
- add_list 'help', %w[command], 'Show usage of a command'
318
+ add_list 'help:all', %w[], 'Show usage of all commands', [], false
319
+ add_list 'help', %w[command], 'Show usage of a command', [], false
317
320
 
318
321
  add_list 'update', %w[], 'Update td and related libraries for TreasureData toolbelt'
319
322
 
@@ -59,9 +59,9 @@ Type 'td help COMMAND' for more information on a specific command.
59
59
  EOF
60
60
  if errmsg
61
61
  puts "Error: #{errmsg}"
62
- exit 1
62
+ return 1
63
63
  else
64
- exit 0
64
+ return 0
65
65
  end
66
66
  end
67
67
  end
@@ -104,17 +104,17 @@ EOF
104
104
  #}
105
105
 
106
106
  op.on('-h', '--help', "show help") {
107
- usage nil
107
+ return usage nil
108
108
  }
109
109
 
110
110
  op.on('--version', "show version") {
111
111
  puts op.version
112
- exit
112
+ return 0
113
113
  }
114
114
 
115
115
  begin
116
116
  op.order!(argv)
117
- usage nil if argv.empty?
117
+ return usage nil if argv.empty?
118
118
  cmd = argv.shift
119
119
 
120
120
  # NOTE: these information are loaded from by each command through
@@ -135,7 +135,7 @@ EOF
135
135
  Config.secure = false
136
136
  end
137
137
  rescue
138
- usage $!.to_s
138
+ return usage $!.to_s
139
139
  end
140
140
 
141
141
  require 'td/command/list'
@@ -144,37 +144,49 @@ EOF
144
144
  Encoding.default_external = 'UTF-8' if Encoding.respond_to?(:default_external)
145
145
  end
146
146
 
147
- method = Command::List.get_method(cmd)
147
+ method, cmd_req_connectivity = Command::List.get_method(cmd)
148
148
  unless method
149
149
  $stderr.puts "'#{cmd}' is not a td command. Run '#{$prog}' to show the list."
150
150
  Command::List.show_guess(cmd)
151
- exit 1
151
+ return 1
152
152
  end
153
153
 
154
154
  begin
155
+ # test the connectivity with the API endpoint
156
+ if cmd_req_connectivity && Config.cl_endpoint
157
+ Command.test_api_endpoint(Config.endpoint)
158
+ end
155
159
  method.call(argv)
156
160
  rescue ConfigError
157
161
  $stderr.puts "TreasureData account is not configured yet."
158
162
  $stderr.puts "Run '#{$prog} account' first."
159
163
  rescue => e
160
- # work in progress look ahead development: new exceptions are rendered as simple
161
- # error messages unless the TD_TOOLBELT_DEBUG variable is not empty.
162
- # List of new exceptions:
163
- # => ParameterConfigurationError
164
- # => BulkImportExecutionError
165
- # => UpUpdateError
164
+ # known exceptions are rendered as simple error messages unless the
165
+ # TD_TOOLBELT_DEBUG variable is set or the -v / --verbose option is used.
166
+ # List of known exceptions:
167
+ # => ParameterConfigurationError
168
+ # => BulkImportExecutionError
169
+ # => UpUpdateError
170
+ # => ImportError
166
171
  require 'td/client/api'
167
- # => APIError
168
- unless [ParameterConfigurationError, BulkImportExecutionError, UpdateError,
169
- APIError]
170
- .include?(e.class) && ENV['TD_TOOLBELT_DEBUG'].nil?
172
+ # => APIError
173
+ # => ForbiddenError
174
+ # => NotFoundError
175
+ # => AuthError
176
+ if ![ParameterConfigurationError, BulkImportExecutionError, UpdateError, ImportError,
177
+ APIError, ForbiddenError, NotFoundError, AuthError].include?(e.class) ||
178
+ !ENV['TD_TOOLBELT_DEBUG'].nil? || $verbose
171
179
  $stderr.puts "Error #{$!.class}: backtrace:"
172
- $!.backtrace.each {|b|
173
- $stderr.puts " #{b}"
180
+ $!.backtrace.each {|bt|
181
+ $stderr.puts " #{bt}"
174
182
  }
175
183
  puts ""
176
184
  end
177
- puts "Error: " + $!.to_s
185
+ print "Error: "
186
+ if [ForbiddenError, NotFoundError, AuthError].include?(e.class)
187
+ print "#{e.class} - "
188
+ end
189
+ puts $!.to_s
178
190
 
179
191
  require 'socket'
180
192
  if e.is_a?(::SocketError)
@@ -136,6 +136,7 @@ module Command
136
136
  def sched_update(op)
137
137
  require 'td/command/job' # job_priority_id_of
138
138
 
139
+ newname = nil
139
140
  cron = nil
140
141
  sql = nil
141
142
  db_name = nil
@@ -146,6 +147,9 @@ module Command
146
147
  retry_limit = nil
147
148
  type = nil
148
149
 
150
+ op.on('-n', '--newname NAME', 'change the schedule\'s name') {|n|
151
+ newname = n
152
+ }
149
153
  op.on('-s', '--schedule CRON', 'change the schedule') {|s|
150
154
  cron = s
151
155
  }
@@ -183,10 +187,10 @@ module Command
183
187
  type = s
184
188
  }
185
189
 
186
-
187
- name = op.cmd_parse
190
+ curname = op.cmd_parse
188
191
 
189
192
  params = {}
193
+ params['name'] = newname if newname
190
194
  params['cron'] = cron if cron
191
195
  params['query'] = sql if sql
192
196
  params['database'] = db_name if db_name
@@ -205,15 +209,19 @@ module Command
205
209
  client = get_client
206
210
 
207
211
  begin
208
- client.update_schedule(name, params)
212
+ client.update_schedule(curname, params)
209
213
  rescue NotFoundError
210
214
  cmd_debug_error $!
211
- $stderr.puts "Schedule '#{name}' does not exist."
215
+ $stderr.puts "Schedule '#{curname}' does not exist."
212
216
  $stderr.puts "Use '#{$prog} " + Config.cl_options_string + "sched:list' to show list of the schedules."
213
217
  exit 1
214
218
  end
215
219
 
216
- $stderr.puts "Schedule '#{name}' is updated."
220
+ if newname && curname != newname
221
+ puts "Schedule '#{curname}' is updated and its name changed to '#{newname}'."
222
+ else
223
+ puts "Schedule '#{curname}' is updated."
224
+ end
217
225
  end
218
226
 
219
227
  def sched_history(op)
@@ -12,13 +12,16 @@ module Command
12
12
  def server_endpoint(op)
13
13
  endpoint = op.cmd_parse
14
14
 
15
- Command.validate_api_endpoint(endpoint)
16
-
17
15
  if Config.cl_endpoint and endpoint != Config.endpoint
18
16
  raise ParameterConfigurationError,
19
- "You specified the API server endpoint in the command options as well (-e / --endpoint option) but it does not match the value provided to the 'server:endpoint' command. Please remove the option or ensure the endpoints URLs match each other."
17
+ "You specified the API server endpoint in the command options as well (-e / --endpoint " +
18
+ "option) but it does not match the value provided to the 'server:endpoint' command. " +
19
+ "Please remove the option or ensure the endpoints URLs match each other."
20
20
  end
21
21
 
22
+ Command.validate_api_endpoint(endpoint)
23
+ Coomand.test_api_endpoint(endpoint)
24
+
22
25
  conf = nil
23
26
  begin
24
27
  conf = Config.read