Permalink
Browse files

Added document per second to progress bar

  • Loading branch information...
1 parent 109b20c commit c0b42793323dbe0f9bffa8cfb9fc56481c43503c @delitescere committed Jun 26, 2010
Showing with 96 additions and 57 deletions.
  1. +7 −47 lib/example_squeal.rb
  2. +15 −5 lib/squealer/progress_bar.rb
  3. +6 −0 spec/data_objects.rb
  4. 0 spec/mongo.rb
  5. +68 −5 spec/squealer/progress_bar_spec.rb
View
@@ -1,50 +1,17 @@
require 'squealer'
# connect to the source mongodb database
-import('localhost', 27017, 'development')
-
+import 'localhost', 27017, 'development'
# connect to the target mysql database
-export('mysql', 'localhost', 'root', '', 'reporting_export')
-
-# Here we extract, transform and load all documents in a collection...
+export 'mysql', 'localhost', 'root', '', 'reporting_export'
-#
-# You don't want to use a find() on the MongoDB collection...
-# import.source("users") { |users| users.find_one() }.each do |user|
-#
-# Also accepts optional conditions...
-# import.source("users", "{disabled: 'false'}").each do |user|
-#
-# Defaults to find all...
import.source('users').each do |user|
-
- # TODO: Allow specification of import row_id (export still uses "id" column as primary key):
- # import_row_id { user['_id'] }
- # import_row_id :_id
- # import_row_id :name, :dob # Digest::SHA1.hexdigest(concatenated keys)[0,24]
-
- # Insert or Update on table 'user' where 'id' is the column name of the primary key.
- #
- # The primary key value is taken from the '_id' field of the source document,
- # referenced using a variable with the same name as the table name passed to target().
- #
- # The block parameter |user| above, matches the target() parameter :user below...
target(:user) do
- #
- # assign() takes a column name and a block to set the value.
- #
- # You can use an valid arbitrary expression...
assign(:name) { "#{user.last_name.upcase}, #{user.first_name}" }
- #
- # You can use a simple access on the source document...
assign(:dob) { user.date_of_birth }
- #
- # You can use an empty block to infer the value from a field of the same
- # name on the source document...
assign(:gender) #or# assign(:gender) { user.gender }
- #
# You can normalize the export...
# home_address and work_address are a formatted string like: "661 W Lake St, Suite 3NE, Chicago IL, 60611, USA"
addresses = []
@@ -59,28 +26,23 @@
end
end
- #
# You can denormalize the export...
# user.home_address = { street: '661 W Lake St', city: 'Chicago', state: 'IL' }
assign(:home_address) { flatten_address(user.home_address) } # flatten_address is some custom method of yours
assign(:work_address) { flatten_address(user.work_address) }
user.activities.each do |activity|
target(:activity) do
- #
- # You can use an empty block to infer the value from the '_id' field
- # of a parent document where the name of the parent collection matches
- # a variable that is in scope...
assign(:user_id) #or# assign(:user_id) { user._id }
- assign(:name) #or# assign(:name) { activity.name }
- assign(:due_date) #or# assign(:due_date) { activity.due_date }
+ assign(:name)
+ assign(:due_date)
end
activity.tasks.each do |task|
target(:task) do
- assign(:user_id) #or# assign(:user_id) { user._id }
- assign(:activity_id) #or# assign(:activity_id) { activity._id }
- assign(:due_date) #or# assign(:due_date) { task.due_date }
+ assign(:user_id)
+ assign(:activity_id)
+ assign(:due_date)
end
end #activity.tasks
end #user.activities
@@ -91,8 +53,6 @@
import.source('organizations', {'disabled_date' => {'exists' => true}}).each do |organization|
import.source('users', {'organization_id' => organization.id}) do |user|
target(:user) do
- #
- # Source boolean values are converted to integer (0 or 1)...
assign(:disabled) { true }
end
end
@@ -17,17 +17,16 @@ def initialize(total)
@progress_bar_width = 50
@count_width = total.to_s.size
-
end
def start
- @start_time = Time.new
+ @start_time = clock
@emitter = start_emitter if total > 0
self
end
def finish
- @end_time = Time.new
+ @end_time = clock
@emitter.wakeup.join if @emitter
@@progress_bar = nil
end
@@ -46,8 +45,8 @@ def start_emitter
end
def emit
- format = "\r[%-#{progress_bar_width}s] %#{count_width}i/%i (%i%%)"
- console.print format % [progress_markers, ticks, total, percentage]
+ format = "\r[%-#{progress_bar_width}s] %#{count_width}i/%i (%i%%) [%i/s]"
+ console.print format % [progress_markers, ticks, total, percentage, tps]
emit_final if done?
end
@@ -59,6 +58,10 @@ def emit_final
console.puts "Duration: #{duration}"
end
+ def clock
+ Time.now
+ end
+
def done?
ticks >= total || end_time
end
@@ -75,6 +78,13 @@ def ticks
@ticks
end
+ def tps
+ elapsed_secs = (clock - start_time) / 60
+ (ticks / elapsed_secs).ceil
+ rescue
+ 0
+ end
+
def total
@total
end
View
@@ -0,0 +1,6 @@
+module DataObjects
+ class Connection
+ end
+ class Command
+ end
+end
View
No changes.
@@ -1,10 +1,12 @@
require 'spec_helper'
describe Squealer::ProgressBar do
+ let(:clock) { Time.new }
let(:total) { 200 }
let(:progress_bar) do
testable_progress_bar = Class.new(Squealer::ProgressBar) do
attr_reader :emitter
+ attr_accessor :clock
public :total, :ticks, :percentage, :progress_markers, :emit,
:duration, :start_time, :end_time, :progress_bar_width
@@ -17,7 +19,9 @@ def start_emitter; end
public :real_start_emitter
end
- testable_progress_bar.new(total).start
+ bar = testable_progress_bar.new(total)
+ bar.clock = clock
+ bar.start
end
let(:console) { progress_bar.console }
let(:progress_bar_width) { progress_bar.progress_bar_width }
@@ -69,7 +73,66 @@ def start_emitter; end
it "prints a progress bar to the console" do
progress_bar.emit
- console.string.should == "\r[#{' ' * progress_bar_width}] #{0}/#{total} (0%)"
+ console.string.should == "\r[#{' ' * progress_bar_width}] #{0}/#{total} (0%) [0/s]"
+ end
+
+ context "0 ticks per second" do
+ it "shows 0 documents per second" do
+ progress_bar.clock = progress_bar.clock + 60
+ progress_bar.emit
+ console.string.should =~ %r{ \[0/s\]$}
+
+ progress_bar.clock = progress_bar.clock + 60
+ progress_bar.emit
+ console.string.should =~ %r{ \[0/s\]$}
+ end
+ end
+
+ context "1 ticks per second" do
+ it "shows 1 document per second" do
+ progress_bar.clock = progress_bar.clock + 60
+ progress_bar.tick
+ progress_bar.emit
+ console.string.should =~ %r{ \[1/s\]$}
+
+ progress_bar.clock = progress_bar.clock + 60
+ progress_bar.tick
+ progress_bar.emit
+ console.string.should =~ %r{ \[1/s\]$}
+ end
+ end
+
+ context "2 ticks per second" do
+ it "shows 2 documents per second" do
+ progress_bar.clock = progress_bar.clock + 60
+ progress_bar.tick
+ progress_bar.tick
+ progress_bar.emit
+ console.string.should =~ %r{ \[2/s\]$}
+
+ progress_bar.clock = progress_bar.clock + 60
+ progress_bar.tick
+ progress_bar.tick
+ progress_bar.emit
+ console.string.should =~ %r{ \[2/s\]$}
+ end
+ end
+
+ context "averaging 2 ticks per second" do
+ it "shows 2 documents per second" do
+ progress_bar.clock = progress_bar.clock + 60
+ progress_bar.tick
+ progress_bar.emit
+
+ progress_bar.clock = progress_bar.clock + 60
+ progress_bar.tick
+ progress_bar.emit
+
+ progress_bar.clock = progress_bar.clock + 60
+ 4.times { progress_bar.tick }
+ progress_bar.emit
+ console.string.should =~ %r{ \[2/s\]$}
+ end
end
end
@@ -101,8 +164,8 @@ def start_emitter; end
it "prints a progress bar to the console" do
progress_bar.emit
- percentag = (ticks.to_f * 100 / total).floor
- console.string.should == "\r[=#{' ' * (progress_bar_width - 1)}] #{ticks}/#{total} (#{percentag}%)"
+ percentage = (ticks.to_f * 100 / total).floor
+ console.string.should == "\r[=#{' ' * (progress_bar_width - 1)}] #{ticks}/#{total} (#{percentage}%) [0/s]"
end
end
@@ -147,7 +210,7 @@ def start_emitter; end
it "prints a progress bar to the console" do
progress_bar.finish
progress_bar.emit
- console.string.split("\n").first.should == "\r[#{'=' * progress_bar_width}] #{ticks}/#{total} (100%)"
+ console.string.split("\n").first.should == "\r[#{'=' * progress_bar_width}] #{ticks}/#{total} (100%) [0/s]"
end
end

0 comments on commit c0b4279

Please sign in to comment.