mongify 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.rdoc CHANGED
@@ -1,3 +1,12 @@
1
+ == 0.1.3 / 21 Feb 2011
2
+ * Made all exception stem from MongifyError and system always raises a child of MongifyError.
3
+ * Brought in the progress bar into source
4
+ * Changed behaviour on storing BigDecimal (now converts into String)
5
+ * Added ability to convert BigDecimal to integer via an :at => 'integer, :scale => 2 settings.
6
+ * Improved Progress Bar display, now it gives you a better feel for what's going on.
7
+ * Added an index on pre_mongified_id to speedup lookup times (Making it 42 times faster on import of embedded tables)
8
+ * Fixed bug in importing of polymorphic tables where associations are nil
9
+ * Fixed bug where pre_mongified_id would be a string and not an integer (causing no updates of ref_ids)
1
10
  == 0.1.2 / 14 Feb 2011
2
11
  * More Improvements to README and RDOC
3
12
  * Added ability to :force => true on a mongodb_connection, forcing it to drop database before processing.
data/Gemfile.lock CHANGED
@@ -1,31 +1,31 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- mongify (0.1.2)
4
+ mongify (0.1.3)
5
5
  activerecord (>= 3.0.3)
6
6
  activesupport (>= 3.0.3)
7
7
  bson_ext (>= 1.1.5)
8
+ highline (>= 1.6.1)
8
9
  mongo (>= 1.1.5)
9
10
  mysql2
10
11
  net-ssh (>= 2.0)
11
- progressbar (>= 0.9)
12
12
 
13
13
  GEM
14
14
  remote: http://rubygems.org/
15
15
  specs:
16
- activemodel (3.0.3)
17
- activesupport (= 3.0.3)
16
+ activemodel (3.0.4)
17
+ activesupport (= 3.0.4)
18
18
  builder (~> 2.1.2)
19
19
  i18n (~> 0.4)
20
- activerecord (3.0.3)
21
- activemodel (= 3.0.3)
22
- activesupport (= 3.0.3)
20
+ activerecord (3.0.4)
21
+ activemodel (= 3.0.4)
22
+ activesupport (= 3.0.4)
23
23
  arel (~> 2.0.2)
24
24
  tzinfo (~> 0.3.23)
25
- activesupport (3.0.3)
26
- arel (2.0.7)
27
- bson (1.2.0)
28
- bson_ext (1.2.0)
25
+ activesupport (3.0.4)
26
+ arel (2.0.8)
27
+ bson (1.2.2)
28
+ bson_ext (1.2.2)
29
29
  builder (2.1.2)
30
30
  cucumber (0.10.0)
31
31
  builder (>= 2.1.2)
@@ -36,26 +36,24 @@ GEM
36
36
  diff-lcs (1.1.2)
37
37
  gherkin (2.3.3)
38
38
  json (~> 1.4.6)
39
+ highline (1.6.1)
39
40
  i18n (0.5.0)
40
41
  json (1.4.6)
41
- mocha (0.9.10)
42
- rake
43
- mongo (1.2.0)
44
- bson (>= 1.2.0)
42
+ mocha (0.9.12)
43
+ mongo (1.2.2)
44
+ bson (>= 1.2.2)
45
45
  mysql (2.8.1)
46
46
  mysql2 (0.2.6)
47
47
  net-ssh (2.1.0)
48
- progressbar (0.9.0)
49
- rake (0.8.7)
50
48
  rcov (0.9.9)
51
- rspec (2.4.0)
52
- rspec-core (~> 2.4.0)
53
- rspec-expectations (~> 2.4.0)
54
- rspec-mocks (~> 2.4.0)
55
- rspec-core (2.4.0)
56
- rspec-expectations (2.4.0)
49
+ rspec (2.5.0)
50
+ rspec-core (~> 2.5.0)
51
+ rspec-expectations (~> 2.5.0)
52
+ rspec-mocks (~> 2.5.0)
53
+ rspec-core (2.5.1)
54
+ rspec-expectations (2.5.0)
57
55
  diff-lcs (~> 1.1.2)
58
- rspec-mocks (2.4.0)
56
+ rspec-mocks (2.5.0)
59
57
  sqlite3 (1.3.3)
60
58
  sqlite3-ruby (1.3.3)
61
59
  sqlite3 (>= 1.3.3)
data/README.rdoc CHANGED
@@ -177,6 +177,8 @@ Table Options are as follow:
177
177
  end # Moving records around, renaming records, changing values in row based on
178
178
  end # some values! Checkout Mongify::Database::DataRow to learn more
179
179
 
180
+ More documentation can be found at {Mongify::Database::Table}
181
+
180
182
  === Columns
181
183
 
182
184
  ==== Structure
@@ -194,7 +196,7 @@ Before we cover the options, you need to know what types of columns are supporte
194
196
  :key # Columns that are primary keys need to be marked as :key type
195
197
  :integer # Will be converted to a integer
196
198
  :float # Will be converted to a float
197
- :decimal # Will be converted to a BigDecimal
199
+ :decimal # Will be converted to a string (due to MongoDB Ruby Drivers not supporting BigDecimal, read details in Mongify::Database::Column under Decimal Storage)
198
200
  :string # Will be converted to a string
199
201
  :text # Will be converted to a string
200
202
  :datetime # Will be converted to a Time format (DateTime is not currently supported in the Mongo ruby driver)
@@ -215,6 +217,18 @@ Before we cover the options, you need to know what types of columns are supporte
215
217
  column "surname",
216
218
  :string,
217
219
  :rename_to => 'last_name' # Rename_to allows you to rename the column
220
+
221
+ <em>For decimal columns you can specify a few options:</em>
222
+ column "total", # This is a default conversion setting.
223
+ :decimal,
224
+ :as => 'string'
225
+
226
+ column "total", # You can specify to convert your decimal to integer
227
+ :decimal, # specifying scale will define how many decimal places to keep
228
+ :as => 'integer', # Example: :scale => 2 will convert 123.4567 to 12346 before saving
229
+ :scale => 2
230
+
231
+ More documentation can be found at {Mongify::Database::Column}
218
232
 
219
233
  == Notes
220
234
 
@@ -224,8 +238,12 @@ More testing will be done once the basic functionality is done
224
238
 
225
239
 
226
240
  == TODO
241
+ * Allow deeper embedding
242
+ * Test in Ruby 1.9
243
+ * Test in different databases
227
244
 
228
- * Update user on what is being processed
245
+ == Known Issues
246
+ * Can't do anything to an embedded table
229
247
 
230
248
  == Development
231
249
 
data/lib/mongify.rb CHANGED
@@ -3,8 +3,9 @@
3
3
  #
4
4
  require 'active_support/core_ext'
5
5
  require 'active_record'
6
- require 'progressbar'
6
+ require 'highline'
7
7
 
8
+ require 'mongify/progressbar'
8
9
  require 'mongify/ui'
9
10
  require 'mongify/status'
10
11
  require 'mongify/exceptions'
@@ -26,9 +26,12 @@ module Mongify
26
26
  begin
27
27
  cmd = @options.parse
28
28
  cmd.execute(self)
29
- rescue Exception => error
29
+ rescue MongifyError => error
30
30
  $stderr.puts "Error: #{error}"
31
31
  report_error
32
+ rescue Exception => error
33
+ report_error
34
+ raise error
32
35
  end
33
36
  return @status
34
37
  end
@@ -87,6 +87,8 @@ EOB
87
87
  # option parser, ensuring parse_options is only called once
88
88
  def parse_options
89
89
  @parsed = true && @parser.parse!(@argv) unless @parsed
90
+ rescue OptionParser::InvalidOption => er
91
+ raise Mongify::InvalidOption, er.message, er.backtrace
90
92
  end
91
93
  end
92
94
  end
@@ -41,12 +41,12 @@ module Mongify
41
41
 
42
42
  # Used to setup connection, Raises NotImplementedError because it needs to be setup in BaseConnection's children
43
43
  def setup_connection_adapter
44
- raise NotImplementedError
44
+ raise NotImplementedMongifyError
45
45
  end
46
46
 
47
47
  # Used to test connection, Raises NotImplementedError because it needs to be setup in BaseConnection's children
48
48
  def has_connection?
49
- raise NotImplementedError
49
+ raise NotImplementedMongifyError
50
50
  end
51
51
 
52
52
 
@@ -19,7 +19,7 @@ module Mongify
19
19
  # :key # Columns that are primary keys need to be marked as :key type
20
20
  # :integer # Will be converted to a integer
21
21
  # :float # Will be converted to a float
22
- # :decimal # Will be converted to a BigDecimal
22
+ # :decimal # Will be converted to a string *(you can change default behaviour read below)
23
23
  # :string # Will be converted to a string
24
24
  # :text # Will be converted to a string
25
25
  # :datetime # Will be converted to a Time format (DateTime is not currently supported in the Mongo ruby driver)
@@ -41,12 +41,46 @@ module Mongify
41
41
  #
42
42
  # column "post_id", :integer, :auto_detect => true # Will run auto detect and make this column a :references => 'posts', :on => 'post_id' for you
43
43
  # # More used when reading a sql database, NOT recommended for use during processing of translation
44
+ #
45
+ # <em>For decimal columns you can specify a few options:</em>
46
+ # column "total", # This is a default conversion setting.
47
+ # :decimal,
48
+ # :as => 'string'
44
49
  #
50
+ # column "total", # You can specify to convert your decimal to integer
51
+ # :decimal, # specifying scale will define how many decimal places to keep
52
+ # :as => 'integer', # Example: :scale => 2 will convert 123.4567 to 12346 in to mongodb
53
+ # :scale => 2
54
+ # ==== Decimal Storage
55
+ #
56
+ # Unfortunately MongoDB Ruby Drivers doesn't support BigDecimal, so to ensure all data is stored correctly (without losing information)
57
+ # I've chosen to store as String, however you can overwrite this functionality in one of two ways:
58
+ # <em>The reason you would want to do this, is to make this searchable via a query.</em>
59
+ #
60
+ # <b>1) You can specify :as => 'integer', :scale => 2</b>
61
+ # column "total", :decimal, :as => 'integer', :scale => 2
62
+ #
63
+ # #It would take a value of 123.456 and store it as an integer of value 12346
64
+ #
65
+ # <b>2) You can specify your own custom conversion by doing a {Mongify::Database::Table#before_save}
66
+ #
67
+ # Example:
68
+ # table "invoice" do
69
+ # column "name", :string
70
+ # column "total", :decimal
71
+ # before_save do |row|
72
+ # row.total = (BigDecimal.new(row.total) * 1000).round
73
+ # end
74
+ # end
75
+ #
76
+ # This would take 123.456789 in the total column and convert it to an interger of value 123457 (and in your app you can convert it back to a decimal)
77
+ #
78
+ # *REMEMBER* there is a limit on how big of an integer you can store in BSON/MongoDB (http://bsonspec.org/#/specification)
45
79
  class Column
46
80
  attr_reader :sql_name, :type, :options
47
81
 
48
82
  #List of available options for a column
49
- AVAILABLE_OPTIONS = ['references', 'ignore', 'rename_to']
83
+ AVAILABLE_OPTIONS = ['references', 'ignore', 'rename_to', 'as', 'scale']
50
84
 
51
85
  # Auto detects if a column is an :key column or is a reference column
52
86
  def self.auto_detect(column)
@@ -88,7 +122,7 @@ module Mongify
88
122
  return {} if ignored?
89
123
  case type
90
124
  when :key
91
- {"pre_mongified_id" => value}
125
+ {"pre_mongified_id" => value.to_i}
92
126
  else
93
127
  {"#{name}" => type_cast(value)}
94
128
  end
@@ -115,14 +149,20 @@ module Mongify
115
149
  def method_missing(meth, *args, &blk)
116
150
  method_name = meth.to_s.gsub("=", '')
117
151
  if AVAILABLE_OPTIONS.include?(method_name)
118
- class_eval <<-EOF
119
- def #{method_name}=(value)
120
- options['#{method_name}'] = value
121
- end
122
- def #{method_name}
123
- options['#{method_name}']
124
- end
125
- EOF
152
+ unless self.class.method_defined?(method_name.to_sym)
153
+ class_eval <<-EOF
154
+ def #{method_name}=(value)
155
+ options['#{method_name}'] = value
156
+ end
157
+ EOF
158
+ end
159
+ unless self.class.method_defined?("#{method_name}=".to_sym)
160
+ class_eval <<-EOF
161
+ def #{method_name}
162
+ options['#{method_name}']
163
+ end
164
+ EOF
165
+ end
126
166
  send(meth, *args, &blk)
127
167
  else
128
168
  super(meth, *args, &blk)
@@ -154,6 +194,34 @@ module Mongify
154
194
  !!self.ignore
155
195
  end
156
196
 
197
+ # Used when trying to figure out how to convert a decimal value
198
+ # @return [String] passed option['as'] or defaults to 'string'
199
+ def as
200
+ options['as'] ||= 'string'
201
+ end
202
+ # Sets option['as'] to either 'string' or 'integer', defults to 'string' for unknown values
203
+ # @param [String|Symbol] value, can be either 'string' or 'integer
204
+ def as=(value)
205
+ value = value.to_s.downcase
206
+ options['as'] = ['string', 'integer'].include?(value) ? value : 'string'
207
+ end
208
+ # Returns true if :as was passed as integer
209
+ def as_integer?
210
+ self.as == 'integer'
211
+ end
212
+
213
+ # Get the scale option for decimal to integer conversion
214
+ # column 'total', :decimal, :as => 'integer', :scale => 3
215
+ # @return [integer] passed option['scale'] or 0
216
+ def scale
217
+ options['scale'] ||= 0
218
+ end
219
+ # Set the scale option for decimal to integer conversion
220
+ # column 'total', :decimal, :as => 'integer', :scale => 3
221
+ # @param [Integer] number of decimal places to round off to
222
+ def scale=(value)
223
+ options['scale'] = value.to_i
224
+ end
157
225
  #######
158
226
  private
159
227
  #######
@@ -164,9 +232,15 @@ module Mongify
164
232
  case type
165
233
  when :string then value
166
234
  when :text then value
167
- when :integer then value.to_i rescue value ? 1 : 0
235
+ when :integer then value.to_i
168
236
  when :float then value.to_f
169
- when :decimal then ActiveRecord::ConnectionAdapters::Column.value_to_decimal(value)
237
+ when :decimal
238
+ value = ActiveRecord::ConnectionAdapters::Column.value_to_decimal(value)
239
+ if as_integer?
240
+ (value * (10 ** self.scale)).round.to_i
241
+ else
242
+ value.to_s
243
+ end
170
244
  when :datetime then ActiveRecord::ConnectionAdapters::Column.string_to_time(value)
171
245
  when :timestamp then ActiveRecord::ConnectionAdapters::Column.string_to_time(value)
172
246
  when :time then ActiveRecord::ConnectionAdapters::Column.string_to_dummy_time(value)
@@ -176,6 +250,7 @@ module Mongify
176
250
  else value
177
251
  end
178
252
  end
253
+
179
254
 
180
255
 
181
256
  # runs auto detect (see {Mongify::Database::Column.auto_detect})
@@ -27,6 +27,7 @@ module Mongify
27
27
  class NoSqlConnection < Mongify::Database::BaseConnection
28
28
  include Mongo
29
29
 
30
+
30
31
  #Required fields for a no sql connection
31
32
  REQUIRED_FIELDS = %w{host database}
32
33
 
@@ -114,10 +115,26 @@ module Mongify
114
115
 
115
116
  # Removes pre_mongified_id from all records in a given collection
116
117
  def remove_pre_mongified_ids(collection_name)
118
+ drop_mongified_index(collection_name)
117
119
  db[collection_name].update({}, { '$unset' => { 'pre_mongified_id' => 1} }, :multi => true)
118
120
  end
119
121
 
122
+ # Removes pre_mongified_id from collection
123
+ # @param [String] collection_name name of collection to remove the index from
124
+ # @return True if successful
125
+ # @raise MongoDBError if index isn't found
126
+ def drop_mongified_index(collection_name)
127
+ db[collection_name].drop_index('pre_mongified_id_1') if db[collection_name].index_information.keys.include?("pre_mongified_id_1")
128
+ end
129
+
130
+ # Creates a pre_mongified_id index to ensure
131
+ # speedy lookup for collections via the pre_mongified_id
132
+ def create_pre_mongified_id_index(collection_name)
133
+ db[collection_name].create_index([['pre_mongified_id', Mongo::ASCENDING]])
134
+ end
135
+
120
136
  # Asks user permission to drop the database
137
+ # @return true or false depending on user's response
121
138
  def ask_to_drop_database
122
139
  if UI.ask("Are you sure you want to drop #{database} database?")
123
140
  drop_database
@@ -1,20 +1,34 @@
1
1
  module Mongify
2
+ # Base Mongify Error
3
+ class MongifyError < RuntimeError; end
4
+
5
+ # Not Implemented Error from Mongify
6
+ class NotImplementedMongifyError < MongifyError; end
7
+
2
8
  # File Not Found Exception
3
- class FileNotFound < RuntimeError; end
9
+ class FileNotFound < MongifyError; end
4
10
  # Raise when configuration file is missing
5
11
  class ConfigurationFileNotFound < FileNotFound; end
6
12
  # Raised when Translation file is missing
7
13
  class TranslationFileNotFound < FileNotFound; end
8
14
 
9
15
  # Basic Configuration Error Exception
10
- class ConfigurationError < RuntimeError; end
16
+ class ConfigurationError < MongifyError; end
11
17
  # Raise when a sqlConnection is required but not given
12
18
  class SqlConnectionRequired < ConfigurationError; end
19
+ # Raised when a SqlConfiguration is invalid?
20
+ class SqlConnectionInvalid < ConfigurationError; end
13
21
  # Raised when a noSqlConnection is required but not given
14
22
  class NoSqlConnectionRequired < ConfigurationError; end
23
+ # Raised when a NoSqlConfiguration is invalid?
24
+ class NoSqlConnectionInvalid < ConfigurationError; end
25
+
15
26
  # Raised when a Mongify::Database::Column is expected but not given
16
27
  class DatabaseColumnExpected < ConfigurationError; end
17
-
28
+
18
29
  # Raised when application has no root folder set
19
- class RootMissing < RuntimeError; end
30
+ class RootMissing < MongifyError; end
31
+
32
+ # Raised when an invalid option is passed via CLI
33
+ class InvalidOption < MongifyError; end
20
34
  end
@@ -0,0 +1,270 @@
1
+ #
2
+ # Ruby/ProgressBar - a text progress bar library
3
+ #
4
+ # Copyright (C) 2001-2005 Satoru Takabayashi <satoru@namazu.org>
5
+ # All rights reserved.
6
+ # This is free software with ABSOLUTELY NO WARRANTY.
7
+ #
8
+ # You can redistribute it and/or modify it under the terms
9
+ # of Ruby's license.
10
+ #
11
+ # This has been modified by
12
+ # Andrew Kalek
13
+ # Anlek Consulting
14
+ # http://anlek.com
15
+
16
+ module Mongify
17
+ # Progress bar used to display results
18
+ class ProgressBar
19
+ #Progress bar version
20
+ VERSION = "0.9.1"
21
+
22
+ def initialize (title, total, out = STDERR)
23
+ @title = title
24
+ @total = total
25
+ @out = out
26
+ @terminal_width = 80
27
+ @bar_mark = "o"
28
+ @current = 0
29
+ @previous = 0
30
+ @finished_p = false
31
+ @start_time = Time.now
32
+ @previous_time = @start_time
33
+ @title_width = 35
34
+ @format = "%-#{@title_width}s %s %3d%% %s %s"
35
+ @format_arguments = [:title, :count, :percentage, :bar, :stat]
36
+ clear
37
+ show
38
+ end
39
+ attr_reader :title
40
+ attr_reader :current
41
+ attr_reader :total
42
+ attr_accessor :start_time
43
+
44
+ #######
45
+ private
46
+ #######
47
+
48
+ # Formatting for the actual bar
49
+ def fmt_bar
50
+ bar_width = do_percentage * @terminal_width / 100
51
+ sprintf("|%s%s|",
52
+ @bar_mark * bar_width,
53
+ " " * (@terminal_width - bar_width))
54
+ end
55
+
56
+ # Formatting for the percentage
57
+ def fmt_percentage
58
+ do_percentage
59
+ end
60
+
61
+ # Formatting for the stat (time left or time taken to complete)
62
+ def fmt_stat
63
+ if @finished_p then elapsed else eta end
64
+ end
65
+
66
+ # Formatting for file transfer
67
+ def fmt_stat_for_file_transfer
68
+ if @finished_p then
69
+ sprintf("%s %s %s", bytes, transfer_rate, elapsed)
70
+ else
71
+ sprintf("%s %s %s", bytes, transfer_rate, eta)
72
+ end
73
+ end
74
+
75
+ # Formatting for title
76
+ def fmt_title
77
+ @title[0,(@title_width - 1)] + ":"
78
+ end
79
+
80
+ # Formatting for count (x/y)
81
+ def fmt_count
82
+ sprintf('%15s', "(#{@current}/#{@total})")
83
+ end
84
+
85
+ # Converts bytes to kb, mb or gb
86
+ def convert_bytes (bytes)
87
+ if bytes < 1024
88
+ sprintf("%6dB", bytes)
89
+ elsif bytes < 1024 * 1000 # 1000kb
90
+ sprintf("%5.1fKB", bytes.to_f / 1024)
91
+ elsif bytes < 1024 * 1024 * 1000 # 1000mb
92
+ sprintf("%5.1fMB", bytes.to_f / 1024 / 1024)
93
+ else
94
+ sprintf("%5.1fGB", bytes.to_f / 1024 / 1024 / 1024)
95
+ end
96
+ end
97
+
98
+ # Returns the transfer rate
99
+ # works only with file transfer
100
+ def transfer_rate
101
+ bytes_per_second = @current.to_f / (Time.now - @start_time)
102
+ sprintf("%s/s", convert_bytes(bytes_per_second))
103
+ end
104
+
105
+ # Gets current byte count
106
+ def bytes
107
+ convert_bytes(@current)
108
+ end
109
+
110
+ # Gets formatting for time
111
+ def format_time (t)
112
+ t = t.to_i
113
+ sec = t % 60
114
+ min = (t / 60) % 60
115
+ hour = t / 3600
116
+ sprintf("%02d:%02d:%02d", hour, min, sec);
117
+ end
118
+
119
+ # ETA stands for Estimated Time of Arrival.
120
+ def eta
121
+ if @current == 0
122
+ "ETA: --:--:--"
123
+ else
124
+ elapsed = Time.now - @start_time
125
+ eta = elapsed * @total / @current - elapsed;
126
+ sprintf("ETA: %s", format_time(eta))
127
+ end
128
+ end
129
+
130
+ # Returns elapsed time
131
+ def elapsed
132
+ elapsed = Time.now - @start_time
133
+ sprintf("Time: %s", format_time(elapsed))
134
+ end
135
+
136
+ # Returns end of line
137
+ # @return [String] "\n" or "\r"
138
+ def eol
139
+ if @finished_p then "\n" else "\r" end
140
+ end
141
+
142
+ # Calculates percentage
143
+ # @return [Number] the percentage
144
+ def do_percentage
145
+ if @total.zero?
146
+ 100
147
+ else
148
+ @current * 100 / @total
149
+ end
150
+ end
151
+
152
+ # Gets the width of the terminal window
153
+ def get_width
154
+ UI.terminal_helper.output_cols
155
+ end
156
+
157
+ # Draws the bar
158
+ def show
159
+ arguments = @format_arguments.map {|method|
160
+ method = sprintf("fmt_%s", method)
161
+ send(method)
162
+ }
163
+ line = sprintf(@format, *arguments)
164
+
165
+ width = get_width
166
+ if line.length == width - 1
167
+ @out.print(line + eol)
168
+ @out.flush
169
+ elsif line.length >= width
170
+ @terminal_width = [@terminal_width - (line.length - width + 1), 0].max
171
+ if @terminal_width == 0 then @out.print(line + eol) else show end
172
+ else # line.length < width - 1
173
+ @terminal_width += width - line.length + 1
174
+ show
175
+ end
176
+ @previous_time = Time.now
177
+ end
178
+
179
+ # Checks if it's needed, shows if it's so
180
+ def show_if_needed
181
+ if @total.zero?
182
+ cur_percentage = 100
183
+ prev_percentage = 0
184
+ else
185
+ cur_percentage = (@current * 100 / @total).to_i
186
+ prev_percentage = (@previous * 100 / @total).to_i
187
+ end
188
+
189
+ # Use "!=" instead of ">" to support negative changes
190
+ if cur_percentage != prev_percentage ||
191
+ Time.now - @previous_time >= 1 || @finished_p
192
+ show
193
+ end
194
+ end
195
+
196
+ public
197
+ # Clear's line
198
+ def clear
199
+ @out.print "\r"
200
+ @out.print(" " * (get_width - 1))
201
+ @out.print "\r"
202
+ end
203
+
204
+ # Marks finished
205
+ def finish
206
+ @current = @total
207
+ @finished_p = true
208
+ show
209
+ end
210
+
211
+ # Returns if the bar is finished
212
+ def finished?
213
+ @finished_p
214
+ end
215
+
216
+ # Sets bar to file trasfer mode
217
+ def file_transfer_mode
218
+ @format_arguments = [:title, :percentage, :bar, :stat_for_file_transfer]
219
+ end
220
+
221
+ # Allows format to be re/defined
222
+ def format= (format)
223
+ @format = format
224
+ end
225
+
226
+ # Allows to change the arguments of items that are shown
227
+ def format_arguments= (arguments)
228
+ @format_arguments = arguments
229
+ end
230
+
231
+ # halts drawing of bar
232
+ def halt
233
+ @finished_p = true
234
+ show
235
+ end
236
+
237
+ # Incremets bar
238
+ # @return [Integer] current bar frame
239
+ def inc (step = 1)
240
+ @current += step
241
+ @current = @total if @current > @total
242
+ show_if_needed
243
+ @previous = @current
244
+ end
245
+
246
+ # Allows you to set bar frame
247
+ # @return [Integer] current bar frame
248
+ def set (count)
249
+ if count < 0 || count > @total
250
+ raise "invalid count: #{count} (total: #{@total})"
251
+ end
252
+ @current = count
253
+ show_if_needed
254
+ @previous = @current
255
+ end
256
+
257
+ # Returns string representation of this object
258
+ def inspect
259
+ "#<ProgressBar:#{@current}/#{@total}>"
260
+ end
261
+ end
262
+
263
+ # Same as progress bar but this counts the progress backwards from 100% to 0
264
+ class ReversedProgressBar < ProgressBar
265
+ # Calculates the percentage
266
+ def do_percentage
267
+ 100 - super
268
+ end
269
+ end
270
+ end