taps2 0.5.5 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -10,14 +10,14 @@
10
10
  #
11
11
 
12
12
  class ProgressBar
13
- VERSION = "0.9"
13
+ VERSION = '0.9'.freeze
14
14
 
15
- def initialize (title, total, out = STDERR)
15
+ def initialize(title, total, out = STDERR)
16
16
  @title = title
17
17
  @total = total
18
18
  @out = out
19
19
  @terminal_width = 80
20
- @bar_mark = "="
20
+ @bar_mark = '='
21
21
  @current = 0
22
22
  @previous = 0
23
23
  @finished_p = false
@@ -25,7 +25,7 @@ class ProgressBar
25
25
  @previous_time = @start_time
26
26
  @title_width = 14
27
27
  @format = "%-#{@title_width}s %3d%% %s %s"
28
- @format_arguments = [:title, :percentage, :bar, :stat]
28
+ @format_arguments = %i[title percentage bar stat]
29
29
  clear
30
30
  show
31
31
  end
@@ -35,11 +35,12 @@ class ProgressBar
35
35
  attr_accessor :start_time
36
36
 
37
37
  private
38
+
38
39
  def fmt_bar
39
40
  bar_width = do_percentage * @terminal_width / 100
40
- sprintf("|%s%s|",
41
- @bar_mark * bar_width,
42
- " " * (@terminal_width - bar_width))
41
+ format('|%s%s|',
42
+ @bar_mark * bar_width,
43
+ ' ' * (@terminal_width - bar_width))
43
44
  end
44
45
 
45
46
  def fmt_percentage
@@ -47,68 +48,68 @@ class ProgressBar
47
48
  end
48
49
 
49
50
  def fmt_stat
50
- if @finished_p then elapsed else eta end
51
+ @finished_p ? elapsed : eta
51
52
  end
52
53
 
53
54
  def fmt_stat_for_file_transfer
54
- if @finished_p then
55
- sprintf("%s %s %s", bytes, transfer_rate, elapsed)
55
+ if @finished_p
56
+ format('%s %s %s', bytes, transfer_rate, elapsed)
56
57
  else
57
- sprintf("%s %s %s", bytes, transfer_rate, eta)
58
+ format('%s %s %s', bytes, transfer_rate, eta)
58
59
  end
59
60
  end
60
61
 
61
62
  def fmt_title
62
- @title[0,(@title_width - 1)] + ":"
63
+ @title[0, (@title_width - 1)] + ':'
63
64
  end
64
65
 
65
- def convert_bytes (bytes)
66
+ def convert_bytes(bytes)
66
67
  if bytes < 1024
67
- sprintf("%6dB", bytes)
68
+ format('%6dB', bytes)
68
69
  elsif bytes < 1024 * 1000 # 1000kb
69
- sprintf("%5.1fKB", bytes.to_f / 1024)
70
- elsif bytes < 1024 * 1024 * 1000 # 1000mb
71
- sprintf("%5.1fMB", bytes.to_f / 1024 / 1024)
70
+ format('%5.1fKB', bytes.to_f / 1024)
71
+ elsif bytes < 1024 * 1024 * 1000 # 1000mb
72
+ format('%5.1fMB', bytes.to_f / 1024 / 1024)
72
73
  else
73
- sprintf("%5.1fGB", bytes.to_f / 1024 / 1024 / 1024)
74
+ format('%5.1fGB', bytes.to_f / 1024 / 1024 / 1024)
74
75
  end
75
76
  end
76
77
 
77
78
  def transfer_rate
78
79
  bytes_per_second = @current.to_f / (Time.now - @start_time)
79
- sprintf("%s/s", convert_bytes(bytes_per_second))
80
+ format('%s/s', convert_bytes(bytes_per_second))
80
81
  end
81
82
 
82
83
  def bytes
83
84
  convert_bytes(@current)
84
85
  end
85
86
 
86
- def format_time (t)
87
+ def format_time(t)
87
88
  t = t.to_i
88
89
  sec = t % 60
89
90
  min = (t / 60) % 60
90
91
  hour = t / 3600
91
- sprintf("%02d:%02d:%02d", hour, min, sec);
92
+ format('%02d:%02d:%02d', hour, min, sec)
92
93
  end
93
94
 
94
95
  # ETA stands for Estimated Time of Arrival.
95
96
  def eta
96
97
  if @current == 0
97
- "ETA: --:--:--"
98
+ 'ETA: --:--:--'
98
99
  else
99
100
  elapsed = Time.now - @start_time
100
- eta = elapsed * @total / @current - elapsed;
101
- sprintf("ETA: %s", format_time(eta))
101
+ eta = elapsed * @total / @current - elapsed
102
+ format('ETA: %s', format_time(eta))
102
103
  end
103
104
  end
104
105
 
105
106
  def elapsed
106
107
  elapsed = Time.now - @start_time
107
- sprintf("Time: %s", format_time(elapsed))
108
+ format('Time: %s', format_time(elapsed))
108
109
  end
109
110
 
110
111
  def eol
111
- if @finished_p then "\n" else "\r" end
112
+ @finished_p ? "\n" : "\r"
112
113
  end
113
114
 
114
115
  def do_percentage
@@ -124,10 +125,10 @@ class ProgressBar
124
125
  default_width = 80
125
126
  begin
126
127
  tiocgwinsz = 0x5413
127
- data = [0, 0, 0, 0].pack("SSSS")
128
- if @out.ioctl(tiocgwinsz, data) >= 0 then
129
- _, cols = data.unpack("SSSS")
130
- if cols > 0 then cols else default_width end
128
+ data = [0, 0, 0, 0].pack('SSSS')
129
+ if @out.ioctl(tiocgwinsz, data) >= 0
130
+ _, cols = data.unpack('SSSS')
131
+ cols > 0 ? cols : default_width
131
132
  else
132
133
  default_width
133
134
  end
@@ -138,11 +139,11 @@ class ProgressBar
138
139
 
139
140
  def show
140
141
  arguments = @format_arguments.map do |method|
141
- method = sprintf("fmt_%s", method)
142
+ method = format('fmt_%s', method)
142
143
  send(method)
143
144
  end
144
145
 
145
- line = sprintf(@format, *arguments)
146
+ line = format(@format, *arguments)
146
147
 
147
148
  width = get_width
148
149
  if line.length == width - 1
@@ -150,7 +151,7 @@ class ProgressBar
150
151
  @out.flush
151
152
  elsif line.length >= width
152
153
  @terminal_width = [@terminal_width - (line.length - width + 1), 0].max
153
- if @terminal_width == 0 then @out.print(line + eol) else show end
154
+ @terminal_width == 0 ? @out.print(line + eol) : show
154
155
  else # line.length < width - 1
155
156
  @terminal_width += width - line.length + 1
156
157
  show
@@ -169,16 +170,16 @@ class ProgressBar
169
170
 
170
171
  # Use "!=" instead of ">" to support negative changes
171
172
  if cur_percentage != prev_percentage ||
172
- Time.now - @previous_time >= 1 || @finished_p
173
+ Time.now - @previous_time >= 1 || @finished_p
173
174
  show
174
175
  end
175
176
  end
176
177
 
177
- public
178
+ public
178
179
 
179
180
  def clear
180
181
  @out.print "\r"
181
- @out.print(" " * (get_width - 1))
182
+ @out.print(' ' * (get_width - 1))
182
183
  @out.print "\r"
183
184
  end
184
185
 
@@ -193,30 +194,26 @@ public
193
194
  end
194
195
 
195
196
  def file_transfer_mode
196
- @format_arguments = [:title, :percentage, :bar, :stat_for_file_transfer]
197
+ @format_arguments = %i[title percentage bar stat_for_file_transfer]
197
198
  end
198
199
 
199
- def format= (format)
200
- @format = format
201
- end
200
+ attr_writer :format
202
201
 
203
- def format_arguments= (arguments)
204
- @format_arguments = arguments
205
- end
202
+ attr_writer :format_arguments
206
203
 
207
204
  def halt
208
205
  @finished_p = true
209
206
  show
210
207
  end
211
208
 
212
- def inc (step = 1)
209
+ def inc(step = 1)
213
210
  @current += step
214
211
  @current = @total if @current > @total
215
212
  show_if_needed
216
213
  @previous = @current
217
214
  end
218
215
 
219
- def set (count)
216
+ def set(count)
220
217
  if count < 0 || count > @total
221
218
  raise "invalid count: #{count} (total: #{@total})"
222
219
  end
data/lib/taps/schema.rb CHANGED
@@ -9,7 +9,7 @@ module Taps
9
9
 
10
10
  def dump(database_url)
11
11
  db = Sequel.connect(database_url)
12
- db.dump_schema_migration(:indexes => false)
12
+ db.dump_schema_migration(indexes: false)
13
13
  end
14
14
 
15
15
  def dump_table(database_url, table)
@@ -17,7 +17,7 @@ module Taps
17
17
  <<END_MIG
18
18
  Class.new(Sequel::Migration) do
19
19
  def up
20
- #{db.extension(:schema_dumper).dump_table_schema(Sequel.identifier(table.to_sym), :indexes => false)}
20
+ #{db.extension(:schema_dumper).dump_table_schema(Sequel.identifier(table.to_sym), indexes: false)}
21
21
  end
22
22
 
23
23
  def down
data/lib/taps/server.rb CHANGED
@@ -12,17 +12,17 @@ module Taps
12
12
 
13
13
  use Rack::Deflater unless ENV['NO_DEFLATE']
14
14
 
15
- set :raise_errors => false
16
- set :show_exceptions => false
15
+ set raise_errors: false
16
+ set show_exceptions: false
17
17
 
18
18
  error do
19
19
  e = request.env['sinatra.error']
20
20
 
21
21
  puts "ERROR: #{e.class}: #{e.message}"
22
22
 
23
- if e.kind_of?(Taps::BaseError)
24
- content_type "application/json"
25
- halt 412, ::OkJson.encode({ 'error_class' => e.class.to_s, 'error_message' => e.message, 'error_backtrace' => e.backtrace.join("\n") })
23
+ if e.is_a?(Taps::BaseError)
24
+ content_type 'application/json'
25
+ halt 412, ::OkJson.encode('error_class' => e.class.to_s, 'error_message' => e.message, 'error_backtrace' => e.backtrace.join("\n"))
26
26
  else
27
27
  "Taps Server Error: #{e}\n#{e.backtrace}"
28
28
  end
@@ -30,8 +30,8 @@ module Taps
30
30
 
31
31
  before do
32
32
  unless request.path_info == '/health'
33
- major, minor = request.env['HTTP_TAPS_VERSION'].split('.') rescue []
34
- unless "#{major}.#{minor}" == Taps.compatible_version
33
+ major, minor = request.env['HTTP_TAPS_VERSION'].to_s.split('.')
34
+ unless Taps.compatible_version == "#{major}.#{minor}"
35
35
  halt 417, "Taps >= v#{Taps.compatible_version}.x is required for this server"
36
36
  end
37
37
  end
@@ -39,29 +39,29 @@ module Taps
39
39
 
40
40
  get '/health' do
41
41
  content_type 'application/json'
42
- ::OkJson.encode({ :ok => true })
42
+ ::OkJson.encode(ok: true)
43
43
  end
44
44
 
45
45
  get '/' do
46
- "hello"
46
+ 'hello'
47
47
  end
48
48
 
49
49
  post '/sessions' do
50
- key = rand(9999999999).to_s
50
+ key = rand(9_999_999_999).to_s
51
51
 
52
- if ENV['NO_DEFAULT_DATABASE_URL']
53
- database_url = request.body.string
54
- else
55
- database_url = Taps::Config.database_url || request.body.string
56
- end
52
+ database_url = if ENV['NO_DEFAULT_DATABASE_URL']
53
+ request.body.string
54
+ else
55
+ Taps::Config.database_url || request.body.string
56
+ end
57
57
 
58
- DbSession.create(:key => key, :database_url => database_url, :started_at => Time.now, :last_access => Time.now)
58
+ DbSession.create(key: key, database_url: database_url, started_at: Time.now, last_access: Time.now)
59
59
 
60
60
  "/sessions/#{key}"
61
61
  end
62
62
 
63
63
  post '/sessions/:key/push/verify_stream' do
64
- session = DbSession.filter(:key => params[:key]).first
64
+ session = DbSession.filter(key: params[:key]).first
65
65
  halt 404 unless session
66
66
 
67
67
  state = DataStream.parse_json(params[:state])
@@ -75,11 +75,11 @@ module Taps
75
75
  end
76
76
 
77
77
  content_type 'application/json'
78
- ::OkJson.encode({ :state => stream.to_hash })
78
+ ::OkJson.encode(state: stream.to_hash)
79
79
  end
80
80
 
81
81
  post '/sessions/:key/push/table' do
82
- session = DbSession.filter(:key => params[:key]).first
82
+ session = DbSession.filter(key: params[:key]).first
83
83
  halt 404 unless session
84
84
 
85
85
  json = DataStream.parse_json(params[:json])
@@ -97,14 +97,14 @@ module Taps
97
97
  end
98
98
 
99
99
  post '/sessions/:key/push/reset_sequences' do
100
- session = DbSession.filter(:key => params[:key]).first
100
+ session = DbSession.filter(key: params[:key]).first
101
101
  halt 404 unless session
102
102
 
103
103
  Taps::Utils.schema_bin(:reset_db_sequences, session.database_url)
104
104
  end
105
105
 
106
106
  post '/sessions/:key/push/schema' do
107
- session = DbSession.filter(:key => params[:key]).first
107
+ session = DbSession.filter(key: params[:key]).first
108
108
  halt 404 unless session
109
109
 
110
110
  schema_data = request.body.read
@@ -112,7 +112,7 @@ module Taps
112
112
  end
113
113
 
114
114
  post '/sessions/:key/push/indexes' do
115
- session = DbSession.filter(:key => params[:key]).first
115
+ session = DbSession.filter(key: params[:key]).first
116
116
  halt 404 unless session
117
117
 
118
118
  index_data = request.body.read
@@ -120,14 +120,14 @@ module Taps
120
120
  end
121
121
 
122
122
  post '/sessions/:key/pull/schema' do
123
- session = DbSession.filter(:key => params[:key]).first
123
+ session = DbSession.filter(key: params[:key]).first
124
124
  halt 404 unless session
125
125
 
126
126
  Taps::Utils.schema_bin(:dump_table, session.database_url, params[:table_name])
127
127
  end
128
128
 
129
129
  get '/sessions/:key/pull/indexes' do
130
- session = DbSession.filter(:key => params[:key]).first
130
+ session = DbSession.filter(key: params[:key]).first
131
131
  halt 404 unless session
132
132
 
133
133
  content_type 'application/json'
@@ -135,7 +135,7 @@ module Taps
135
135
  end
136
136
 
137
137
  get '/sessions/:key/pull/table_names' do
138
- session = DbSession.filter(:key => params[:key]).first
138
+ session = DbSession.filter(key: params[:key]).first
139
139
  halt 404 unless session
140
140
 
141
141
  tables = []
@@ -148,18 +148,18 @@ module Taps
148
148
  end
149
149
 
150
150
  post '/sessions/:key/pull/table_count' do
151
- session = DbSession.filter(:key => params[:key]).first
151
+ session = DbSession.filter(key: params[:key]).first
152
152
  halt 404 unless session
153
153
 
154
154
  count = 0
155
155
  session.conn do |db|
156
- count = db[ params[:table].to_sym.identifier ].count
156
+ count = db[params[:table].to_sym.identifier].count
157
157
  end
158
158
  count.to_s
159
159
  end
160
160
 
161
161
  post '/sessions/:key/pull/table' do
162
- session = DbSession.filter(:key => params[:key]).first
162
+ session = DbSession.filter(key: params[:key]).first
163
163
  halt 404 unless session
164
164
 
165
165
  encoded_data = nil
@@ -172,15 +172,15 @@ module Taps
172
172
  end
173
173
 
174
174
  checksum = Taps::Utils.checksum(encoded_data).to_s
175
- json = ::OkJson.encode({ :checksum => checksum, :state => stream.to_hash })
175
+ json = ::OkJson.encode(checksum: checksum, state: stream.to_hash)
176
176
 
177
177
  content, content_type_value = Taps::Multipart.create do |r|
178
- r.attach :name => :encoded_data,
179
- :payload => encoded_data,
180
- :content_type => 'application/octet-stream'
181
- r.attach :name => :json,
182
- :payload => json,
183
- :content_type => 'application/json'
178
+ r.attach name: :encoded_data,
179
+ payload: encoded_data,
180
+ content_type: 'application/octet-stream'
181
+ r.attach name: :json,
182
+ payload: json,
183
+ content_type: 'application/json'
184
184
  end
185
185
 
186
186
  content_type content_type_value
@@ -188,13 +188,12 @@ module Taps
188
188
  end
189
189
 
190
190
  delete '/sessions/:key' do
191
- session = DbSession.filter(:key => params[:key]).first
191
+ session = DbSession.filter(key: params[:key]).first
192
192
  halt 404 unless session
193
193
 
194
194
  session.destroy
195
195
 
196
- "ok"
196
+ 'ok'
197
197
  end
198
-
199
198
  end
200
199
  end
data/lib/taps/utils.rb CHANGED
@@ -31,45 +31,41 @@ module Taps
31
31
  end
32
32
 
33
33
  def base64encode(data)
34
- [data].pack("m")
34
+ [data].pack('m')
35
35
  end
36
36
 
37
37
  def base64decode(data)
38
- data.unpack("m").first
38
+ data.unpack('m').first
39
39
  end
40
40
 
41
- def format_data(data, opts={})
42
- return {} if data.size == 0
41
+ def format_data(data, opts = {})
42
+ return {} if data.empty?
43
43
  string_columns = opts[:string_columns] || []
44
44
  schema = opts[:schema] || []
45
45
  table = opts[:table]
46
46
 
47
- max_lengths = schema.inject({}) do |hash, (column, meta)|
48
- if meta[:db_type] =~ /^varchar\((\d+)\)/
49
- hash.update(column => $1.to_i)
50
- end
51
- hash
47
+ max_lengths = schema.each_with_object({}) do |(column, meta), hash|
48
+ hash.update(column => Regexp.last_match(1).to_i) if meta[:db_type] =~ /^varchar\((\d+)\)/
52
49
  end
53
50
 
54
51
  header = data[0].keys
55
52
  only_data = data.collect do |row|
56
53
  row = blobs_to_string(row, string_columns)
57
54
  row.each do |column, value|
58
- if value.to_s.length > (max_lengths[column] || value.to_s.length)
59
- raise Taps::InvalidData.new(<<-ERROR)
55
+ next unless value.to_s.length > (max_lengths[column] || value.to_s.length)
56
+ raise Taps::InvalidData, <<-ERROR
60
57
  Detected value that exceeds the length limitation of its column. This is
61
58
  generally due to the fact that SQLite does not enforce length restrictions.
62
59
 
63
60
  Table : #{table}
64
61
  Column : #{column}
65
- Type : #{schema.detect{|s| s.first == column}.last[:db_type]}
62
+ Type : #{schema.detect { |s| s.first == column }.last[:db_type]}
66
63
  Value : #{value}
67
- ERROR
68
- end
64
+ ERROR
69
65
  end
70
66
  header.collect { |h| row[h] }
71
67
  end
72
- { :header => header, :data => only_data }
68
+ { header: header, data: only_data }
73
69
  end
74
70
 
75
71
  # mysql text and blobs fields are handled the same way internally
@@ -87,9 +83,9 @@ ERROR
87
83
  end
88
84
 
89
85
  def blobs_to_string(row, columns)
90
- return row if columns.size == 0
86
+ return row if columns.empty?
91
87
  columns.each do |c|
92
- row[c] = row[c].to_s if row[c].kind_of?(Sequel::SQL::Blob)
88
+ row[c] = row[c].to_s if row[c].is_a?(Sequel::SQL::Blob)
93
89
  end
94
90
  row
95
91
  end
@@ -138,42 +134,43 @@ ERROR
138
134
  end
139
135
 
140
136
  def single_integer_primary_key(db, table)
141
- table = table.to_sym.identifier unless table.kind_of?(Sequel::SQL::Identifier)
137
+ table = table.to_sym.identifier unless table.is_a?(Sequel::SQL::Identifier)
142
138
  keys = db.schema(table).select { |c| c[1][:primary_key] }
143
- not keys.nil? and keys.size == 1 and keys[0][1][:type] == :integer
139
+ !keys.nil? && (keys.size == 1) && (keys[0][1][:type] == :integer)
144
140
  end
145
141
 
146
142
  def order_by(db, table)
147
143
  pkey = primary_key(db, table)
148
144
  if pkey
149
- pkey.kind_of?(Array) ? pkey : [pkey.to_sym]
145
+ pkey.is_a?(Array) ? pkey : [pkey.to_sym]
150
146
  else
151
- table = table.to_sym.identifier unless table.kind_of?(Sequel::SQL::Identifier)
147
+ table = table.to_sym.identifier unless table.is_a?(Sequel::SQL::Identifier)
152
148
  db[table].columns
153
149
  end
154
150
  end
155
151
 
156
-
157
152
  # try to detect server side errors to
158
153
  # give the client a more useful error message
159
- def server_error_handling(&blk)
160
- begin
161
- blk.call
162
- rescue Sequel::DatabaseError => e
163
- if e.message =~ /duplicate key value/i
164
- raise Taps::DuplicatePrimaryKeyError, e.message
165
- else
166
- raise
167
- end
154
+ def server_error_handling
155
+ yield
156
+ rescue Sequel::DatabaseError => e
157
+ if e.message =~ /duplicate key value/i
158
+ raise Taps::DuplicatePrimaryKeyError, e.message
159
+ else
160
+ raise
168
161
  end
169
162
  end
170
163
 
171
164
  def reraise_server_exception(e)
172
- if e.kind_of?(RestClient::Exception)
165
+ if e.is_a?(RestClient::Exception)
173
166
  if e.respond_to?(:response) && e.response.headers[:content_type] == 'application/json'
174
167
  json = ::OkJson.decode(e.response.to_s)
175
- klass = eval(json['error_class']) rescue nil
176
- raise klass.new(json['error_message'], :backtrace => json['error_backtrace']) if klass
168
+ klass = begin
169
+ eval(json['error_class'])
170
+ rescue
171
+ nil
172
+ end
173
+ raise klass.new(json['error_message'], backtrace: json['error_backtrace']) if klass
177
174
  end
178
175
  end
179
176
  raise e