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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8b1634cd26b21129c05cf1c5655e46ff3b81307135ce8dd686022cd8a4ff5adc
4
- data.tar.gz: 53312f6841e32ddcae0e97cd9aab4513a47580c35a3ec39964f8933fdbbcff10
3
+ metadata.gz: 98303ab9b2df05bc501c1c66b66a62be5ade9d79ab38a5b8bda8eb52d91b26cc
4
+ data.tar.gz: 8adfd2144220de2cc4f23136ee4eb7314a3c16eeac68be87e1dc19b1ac7dc350
5
5
  SHA512:
6
- metadata.gz: 5733c0ff8b730e957c46fc73b1080690dd79fb481b30f9591f4256507abc3ea46139d9758605c4c4e143e23781468b9adbd623812ceb105bb610a61943ffbc57
7
- data.tar.gz: 4ce9256c44ed50fc289fbe2b0ce970b2798310d50b4f69dffe9fa57098b0acab0539049bd5c945b43768ea7cb3d97b2421e54bf4c069df7751bd3704b68db9ec
6
+ metadata.gz: a2a2b2067a9ca06920b171230a122eba479c1f91af3919e2965eaec6d073fff34d544221a92cffaa1b9546078960aee0c9b9031e7b652368e975cff9b196214c
7
+ data.tar.gz: '0786cfb3e75771ccb68bfa0e2cba42994c7c04a5c8be14432ae6467425536e7dfd4a4ef33403ae5bd129eafd871a07077610c000a78762052e0b055192c0cc16'
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = 'csv-utils'
5
- s.version = '0.2.3'
5
+ s.version = '0.3.0'
6
6
  s.licenses = ['MIT']
7
7
  s.summary = 'CSV Utils'
8
8
  s.description = 'Tools for debugging malformed CSV files'
@@ -7,4 +7,6 @@ module CSVUtils
7
7
  autoload :CSVReport, 'csv_utils/csv_report'
8
8
  autoload :CSVRow, 'csv_utils/csv_row'
9
9
  autoload :CSVSort, 'csv_utils/csv_sort'
10
+ autoload :CSVTransformer, 'csv_utils/csv_transformer'
11
+ autoload :CSVWrapper, 'csv_utils/csv_wrapper'
10
12
  end
@@ -1,20 +1,15 @@
1
1
  # Utility class for appending data to a csv file.
2
2
  class CSVUtils::CSVExtender
3
- attr_reader :csv_file,
4
- :new_csv_file,
5
- :csv_options
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 = src.shift)
10
+ while (row = @src_csv.shift)
16
11
  additional_columns = yield row, current_headers
17
- dest << (row + additional_columns)
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
- dest << (row + additional_rows[idx])
25
+ @dest_csv << (row + additional_rows[idx])
31
26
  end
32
27
 
33
28
  batch = []
34
29
  end
35
30
 
36
- while (row = src.shift)
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
- src.close
64
- dest.close
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 = src.shift
73
- dest << (current_headers + additional_headers)
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.2.3
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-08 00:00:00.000000000 Z
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: