csv-utils 0.2.3 → 0.3.0
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.
- checksums.yaml +4 -4
- data/csv-utils.gemspec +1 -1
- data/lib/csv-utils.rb +2 -0
- data/lib/csv_utils/csv_extender.rb +13 -26
- data/lib/csv_utils/csv_transformer.rb +119 -0
- data/lib/csv_utils/csv_wrapper.rb +47 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 98303ab9b2df05bc501c1c66b66a62be5ade9d79ab38a5b8bda8eb52d91b26cc
|
4
|
+
data.tar.gz: 8adfd2144220de2cc4f23136ee4eb7314a3c16eeac68be87e1dc19b1ac7dc350
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a2a2b2067a9ca06920b171230a122eba479c1f91af3919e2965eaec6d073fff34d544221a92cffaa1b9546078960aee0c9b9031e7b652368e975cff9b196214c
|
7
|
+
data.tar.gz: '0786cfb3e75771ccb68bfa0e2cba42994c7c04a5c8be14432ae6467425536e7dfd4a4ef33403ae5bd129eafd871a07077610c000a78762052e0b055192c0cc16'
|
data/csv-utils.gemspec
CHANGED
data/lib/csv-utils.rb
CHANGED
@@ -1,20 +1,15 @@
|
|
1
1
|
# Utility class for appending data to a csv file.
|
2
2
|
class CSVUtils::CSVExtender
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
def initialize(csv_file, new_csv_file, csv_options = {})
|
8
|
-
@csv_file = csv_file
|
9
|
-
@new_csv_file = new_csv_file
|
10
|
-
@csv_options = csv_options
|
3
|
+
def initialize(src_csv, dest_csv, csv_options = {})
|
4
|
+
@src_csv = CSVUtils::CSVWrapper.new(src_csv, 'rb', csv_options)
|
5
|
+
@dest_csv = CSVUtils::CSVWrapper.new(dest_csv, 'wb', csv_options)
|
11
6
|
end
|
12
7
|
|
13
8
|
def append(additional_headers)
|
14
9
|
process(additional_headers) do |current_headers|
|
15
|
-
while (row =
|
10
|
+
while (row = @src_csv.shift)
|
16
11
|
additional_columns = yield row, current_headers
|
17
|
-
|
12
|
+
@dest_csv << (row + additional_columns)
|
18
13
|
end
|
19
14
|
end
|
20
15
|
end
|
@@ -27,13 +22,13 @@ class CSVUtils::CSVExtender
|
|
27
22
|
additional_rows = yield batch, current_headers
|
28
23
|
|
29
24
|
batch.each_with_index do |row, idx|
|
30
|
-
|
25
|
+
@dest_csv << (row + additional_rows[idx])
|
31
26
|
end
|
32
27
|
|
33
28
|
batch = []
|
34
29
|
end
|
35
30
|
|
36
|
-
while (row =
|
31
|
+
while (row = @src_csv.shift)
|
37
32
|
batch << row
|
38
33
|
|
39
34
|
process_batch_proc.call if batch.size >= batch_size
|
@@ -43,6 +38,8 @@ class CSVUtils::CSVExtender
|
|
43
38
|
end
|
44
39
|
end
|
45
40
|
|
41
|
+
private
|
42
|
+
|
46
43
|
def process(additional_headers)
|
47
44
|
current_headers = append_headers(additional_headers)
|
48
45
|
|
@@ -51,26 +48,16 @@ class CSVUtils::CSVExtender
|
|
51
48
|
close
|
52
49
|
end
|
53
50
|
|
54
|
-
def src
|
55
|
-
@src ||= CSV.open(csv_file, 'rb', csv_options)
|
56
|
-
end
|
57
|
-
|
58
|
-
def dest
|
59
|
-
@dest ||= CSV.open(new_csv_file, 'wb', csv_options)
|
60
|
-
end
|
61
|
-
|
62
51
|
def close
|
63
|
-
|
64
|
-
|
52
|
+
@src_csv.close
|
53
|
+
@dest_csv.close
|
65
54
|
end
|
66
55
|
|
67
|
-
private
|
68
|
-
|
69
56
|
def append_headers(additional_headers)
|
70
57
|
return nil unless additional_headers
|
71
58
|
|
72
|
-
current_headers =
|
73
|
-
|
59
|
+
current_headers = @src_csv.shift
|
60
|
+
@dest_csv << (current_headers + additional_headers)
|
74
61
|
current_headers
|
75
62
|
end
|
76
63
|
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
# Transforms a CSV given a series of steps
|
2
|
+
class CSVUtils::CSVTransformer
|
3
|
+
attr_reader :headers
|
4
|
+
|
5
|
+
def initialize(src_csv, dest_csv, csv_options = {})
|
6
|
+
@src_csv = CSVUtils::CSVWrapper.new(src_csv, 'rb', csv_options)
|
7
|
+
@dest_csv = CSVUtils::CSVWrapper.new(dest_csv, 'wb', csv_options)
|
8
|
+
end
|
9
|
+
|
10
|
+
def read_headers
|
11
|
+
@headers = @src_csv.shift
|
12
|
+
self
|
13
|
+
end
|
14
|
+
|
15
|
+
def additional_data(&block)
|
16
|
+
steps << [:additional_data, @headers, block]
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
def select(&block)
|
21
|
+
steps << [:select, @headers, block]
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def reject(&block)
|
26
|
+
steps << [:reject, @headers, block]
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
30
|
+
def map(new_headers, &block)
|
31
|
+
steps << [:map, @headers, block]
|
32
|
+
@headers = new_headers
|
33
|
+
self
|
34
|
+
end
|
35
|
+
|
36
|
+
def append(additional_headers, &block)
|
37
|
+
steps << [:append, @headers, block]
|
38
|
+
|
39
|
+
if additional_headers
|
40
|
+
@headers += additional_headers
|
41
|
+
else
|
42
|
+
@headers = nil
|
43
|
+
end
|
44
|
+
|
45
|
+
self
|
46
|
+
end
|
47
|
+
|
48
|
+
def each(&block)
|
49
|
+
steps << [:each, @headers, block]
|
50
|
+
self
|
51
|
+
end
|
52
|
+
|
53
|
+
def set_headers(headers)
|
54
|
+
@headers = headers
|
55
|
+
self
|
56
|
+
end
|
57
|
+
|
58
|
+
def process(batch_size = 10_000, &block)
|
59
|
+
batch = []
|
60
|
+
|
61
|
+
@dest_csv << @headers if @headers
|
62
|
+
|
63
|
+
steps_proc = Proc.new do
|
64
|
+
steps.each do |step_type, current_headers, proc|
|
65
|
+
batch = process_step(step_type, current_headers, batch, &proc)
|
66
|
+
end
|
67
|
+
|
68
|
+
batch.each { |row| @dest_csv << row }
|
69
|
+
|
70
|
+
batch = []
|
71
|
+
end
|
72
|
+
|
73
|
+
while (row = @src_csv.shift)
|
74
|
+
batch << row
|
75
|
+
steps_proc.call if batch.size >= batch_size
|
76
|
+
end
|
77
|
+
|
78
|
+
steps_proc.call if batch.size > 0
|
79
|
+
|
80
|
+
@src_csv.close
|
81
|
+
@dest_csv.close
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def steps
|
87
|
+
@steps ||= []
|
88
|
+
end
|
89
|
+
|
90
|
+
|
91
|
+
def process_step(step_type, current_headers, batch, &block)
|
92
|
+
case step_type
|
93
|
+
when :select
|
94
|
+
batch.select! do |row|
|
95
|
+
block.call row, current_headers, @additional_data
|
96
|
+
end
|
97
|
+
when :reject
|
98
|
+
batch.reject! do |row|
|
99
|
+
block.call row, current_headers, @additional_data
|
100
|
+
end
|
101
|
+
when :map
|
102
|
+
batch.map! do |row|
|
103
|
+
block.call row, current_headers, @additional_data
|
104
|
+
end
|
105
|
+
when :append
|
106
|
+
batch.map! do |row|
|
107
|
+
row + block.call(row, current_headers, @additional_data)
|
108
|
+
end
|
109
|
+
when :additional_data
|
110
|
+
@additional_data = block.call(batch, current_headers)
|
111
|
+
when :each
|
112
|
+
batch.each do |row|
|
113
|
+
block.call(row, current_headers, @additional_data)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
batch
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# Wraps a CSV object, if wrapper opens the csv file it will close it
|
2
|
+
class CSVUtils::CSVWrapper
|
3
|
+
attr_reader :csv
|
4
|
+
|
5
|
+
def initialize(csv, mode, csv_options)
|
6
|
+
open(csv, mode, csv_options)
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.open(file, mode, csv_options = {})
|
10
|
+
csv = new(file, mode, csv_options)
|
11
|
+
|
12
|
+
if block_given?
|
13
|
+
yield csv
|
14
|
+
csv.close
|
15
|
+
else
|
16
|
+
csv
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def open(csv, mode, csv_options)
|
21
|
+
if csv.is_a?(String)
|
22
|
+
@close_when_done = true
|
23
|
+
@csv = CSV.open(csv, mode, csv_options)
|
24
|
+
else
|
25
|
+
@close_when_done = false
|
26
|
+
@csv = csv
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def <<(row)
|
31
|
+
csv << row
|
32
|
+
end
|
33
|
+
|
34
|
+
def shift
|
35
|
+
csv.shift
|
36
|
+
end
|
37
|
+
|
38
|
+
def close
|
39
|
+
csv.close if close_when_done?
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def close_when_done?
|
45
|
+
@close_when_done
|
46
|
+
end
|
47
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: csv-utils
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Doug Youch
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-07-
|
11
|
+
date: 2020-07-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: inheritance-helper
|
@@ -50,6 +50,8 @@ files:
|
|
50
50
|
- lib/csv_utils/csv_report.rb
|
51
51
|
- lib/csv_utils/csv_row.rb
|
52
52
|
- lib/csv_utils/csv_sort.rb
|
53
|
+
- lib/csv_utils/csv_transformer.rb
|
54
|
+
- lib/csv_utils/csv_wrapper.rb
|
53
55
|
- script/console
|
54
56
|
homepage: https://github.com/dougyouch/csv-utils
|
55
57
|
licenses:
|