pcsv 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,4 @@
1
+ pcsv
2
+ ===
3
+
4
+ A command line utility for working with data in Excel.
data/lib/pcsv.rb ADDED
@@ -0,0 +1,75 @@
1
+ require 'csv'
2
+ require 'pcsv/version'
3
+
4
+ class PCSV
5
+ ##############################################################################
6
+ #
7
+ # Static Methods
8
+ #
9
+ ##############################################################################
10
+
11
+ # Opens a CSV file and runs the block on each cell in parallel. Returns a
12
+ # copy of the CSV file.
13
+ def self.each(path, options={})
14
+ return process(:each, path, options, &Proc.new)
15
+ end
16
+
17
+ # Opens a CSV file and maps the results of a block on each cell in parallel.
18
+ # Returns a copy of the CSV file.
19
+ def self.map(path, options={})
20
+ return process(:map, path, options, &Proc.new)
21
+ end
22
+
23
+ # Performs a given action on each cell of a CSV file.
24
+ def self.process(action, path, options={})
25
+ thread_count = options.delete(:thread_count) || 10
26
+
27
+ # Open CSV & build a worker queue.
28
+ csv = CSV.read(path, options)
29
+ queue = []
30
+ csv.each_with_index do |row, row_index|
31
+ row.fields.each_with_index do |field, col_index|
32
+ queue << {
33
+ row_index:row_index,
34
+ col_index:col_index,
35
+ row:row,
36
+ value:field
37
+ }
38
+ end
39
+ end
40
+
41
+ # Launch threads and iterate over queue until it's done.
42
+ mutex = Mutex.new()
43
+ threads = []
44
+ thread_count.times do |thread_index|
45
+ threads << Thread.new() do
46
+ loop do
47
+ # Grab an item from the front of the queue.
48
+ item = nil
49
+ mutex.synchronize do
50
+ item = queue.shift()
51
+ end
52
+ break if item.nil?
53
+
54
+ # Invoke the block with the row info.
55
+ begin
56
+ result = yield item, mutex
57
+
58
+ if action == :map
59
+ mutex.synchronize {
60
+ item[:row][item[:col_index]] = result
61
+ }
62
+ end
63
+
64
+ rescue StandardError => e
65
+ warn("[ERROR] #{e.message} [R#{item[:row_index]},C#{item[:col_index]}]")
66
+ end
67
+ end
68
+ end
69
+ end
70
+
71
+ threads.each { |t| t.join }
72
+
73
+ return csv
74
+ end
75
+ end
@@ -0,0 +1,3 @@
1
+ class PCSV
2
+ VERSION = "0.1.0"
3
+ end
data/test/pcsv_test.rb ADDED
@@ -0,0 +1,45 @@
1
+ require 'test_helper'
2
+
3
+ class TestPCSV < MiniTest::Unit::TestCase
4
+ ######################################
5
+ # Each
6
+ ######################################
7
+
8
+ def test_each
9
+ obj = {}
10
+ csv = PCSV.each('fixtures/simple.csv', :headers => true) do |item, mutex|
11
+ mutex.synchronize {
12
+ obj[item[:value].to_i] = true
13
+ }
14
+ end
15
+
16
+ exp = []
17
+ (0...50).each {|i| exp << i}
18
+ assert_equal exp, obj.keys.sort
19
+ end
20
+
21
+
22
+ ######################################
23
+ # Map
24
+ ######################################
25
+
26
+ def test_map
27
+ csv = PCSV.map('fixtures/simple.csv', :headers => true) do |item, mutex|
28
+ item[:value].to_i + 100
29
+ end
30
+
31
+ assert_equal IO.read('fixtures/simple.map.csv'), csv.to_csv
32
+ end
33
+
34
+ def test_map_error
35
+ csv = PCSV.map('fixtures/simple.csv', :headers => true) do |item, mutex|
36
+ if item[:value] == '30'
37
+ raise 'OH NO!'
38
+ else
39
+ item[:value].to_i + 100
40
+ end
41
+ end
42
+
43
+ assert_equal IO.read('fixtures/simple.map_error.csv'), csv.to_csv
44
+ end
45
+ end
@@ -0,0 +1,18 @@
1
+ require 'bundler/setup'
2
+ require 'minitest/autorun'
3
+ require 'mocha'
4
+ require 'unindentable'
5
+ require 'pcsv'
6
+
7
+ class MiniTest::Unit::TestCase
8
+ def assert_worksheet exp, worksheet, msg = nil
9
+ act = []
10
+ worksheet.each do |row|
11
+ act << row.map {|cell| cell.to_s.strip }
12
+ end
13
+ exp = exp.map {|row| row.map {|cell| '%-10s' % cell.to_s}.join('').rstrip}.join("\n")
14
+ act = act.map {|row| row.map {|cell| '%-10s' % cell.to_s}.join('').rstrip}.join("\n")
15
+ assert_equal(exp, act, msg)
16
+ end
17
+ end
18
+
metadata ADDED
@@ -0,0 +1,116 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pcsv
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Ben Johnson
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-01-24 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.9.2.2
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 0.9.2.2
30
+ - !ruby/object:Gem::Dependency
31
+ name: minitest
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 3.5.0
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 3.5.0
46
+ - !ruby/object:Gem::Dependency
47
+ name: mocha
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 0.12.5
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 0.12.5
62
+ - !ruby/object:Gem::Dependency
63
+ name: unindentable
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: 0.1.0
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 0.1.0
78
+ description:
79
+ email:
80
+ - benbjohnson@yahoo.com
81
+ executables: []
82
+ extensions: []
83
+ extra_rdoc_files: []
84
+ files:
85
+ - lib/pcsv/version.rb
86
+ - lib/pcsv.rb
87
+ - README.md
88
+ - test/pcsv_test.rb
89
+ - test/test_helper.rb
90
+ homepage: http://github.com/benbjohnson/pcsv
91
+ licenses: []
92
+ post_install_message:
93
+ rdoc_options: []
94
+ require_paths:
95
+ - lib
96
+ required_ruby_version: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ none: false
104
+ requirements:
105
+ - - ! '>='
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ requirements: []
109
+ rubyforge_project:
110
+ rubygems_version: 1.8.24
111
+ signing_key:
112
+ specification_version: 3
113
+ summary: A simple, parallel processing framework for CSV files.
114
+ test_files:
115
+ - test/pcsv_test.rb
116
+ - test/test_helper.rb