sycsvpro 0.1.3 → 0.1.4
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.
- data/Gemfile.lock +1 -1
- data/README.md +21 -0
- data/bin/sycsvpro +45 -0
- data/lib/sycsvpro/header.rb +47 -3
- data/lib/sycsvpro/table.rb +174 -0
- data/lib/sycsvpro/version.rb +1 -1
- data/lib/sycsvpro.rb +1 -0
- data/spec/sycsvpro/header_spec.rb +79 -0
- data/spec/sycsvpro/table_spec.rb +65 -0
- metadata +5 -2
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -16,6 +16,7 @@ Processing of csv files. *sycsvpro* offers following functions
|
|
16
16
|
* create or edit a Ruby script
|
17
17
|
* list scripts available optionally with methods (since version 0.0.7)
|
18
18
|
* execute a Ruby script file that operates a csv file
|
19
|
+
* create a table from a source file with dynamically create columns (since version 0.1.4)
|
19
20
|
|
20
21
|
To get help type
|
21
22
|
|
@@ -308,6 +309,26 @@ command: `sycsvpro execute script.rb method infile param1 param2`
|
|
308
309
|
* Add `clean_up` to *Dsl* that takes files to be deleted after the script has
|
309
310
|
run: `clean_up(%w{file1 file2})`
|
310
311
|
|
312
|
+
Version 0.1.4
|
313
|
+
-------------
|
314
|
+
* A new Table class is available with following features
|
315
|
+
* Create dynamic headline columns based on source table data
|
316
|
+
* Associate values to multi keys
|
317
|
+
* Create values based on arithmetic operations of source table data
|
318
|
+
Example
|
319
|
+
`sycsvpro -f in.csv -o out.csv table -h "c4,c5,c0=~/\\.(\\d{4})/" \
|
320
|
+
-k "c4,c5" \
|
321
|
+
-c "c0=~/\\.(\\d{4})/:+n1"`
|
322
|
+
h:: the header is created from the source table header of column 4 and 5.
|
323
|
+
Another header column is created dynamicall based on the year part of a
|
324
|
+
date in column 0
|
325
|
+
k:: the key is based on source table of column 4 and 5
|
326
|
+
c:: the column operation is in the form HeaderName:Operation. In this case the
|
327
|
+
HeaderName is dynamically determined based on column 0 and added the value
|
328
|
+
of column 1 to this column that is associated to the key
|
329
|
+
|
330
|
+
c4, n4, d4 are string, number and date values respectively
|
331
|
+
|
311
332
|
Installation
|
312
333
|
============
|
313
334
|
[](http://badge.fury.io/rb/sycsvpro)
|
data/bin/sycsvpro
CHANGED
@@ -303,6 +303,51 @@ command :aggregate do |c|
|
|
303
303
|
|
304
304
|
end
|
305
305
|
|
306
|
+
desc 'Creates a table from a source file'
|
307
|
+
|
308
|
+
command :table do |c|
|
309
|
+
|
310
|
+
c.desc 'Rows to consider'
|
311
|
+
c.arg_name '1,2,10-30,45-EOF,REGEXP'
|
312
|
+
c.flag [:r, :row], :must_match => row_regex
|
313
|
+
|
314
|
+
c.desc 'Header can be defined by Words (Year), references to source header (c1) and dynamically created header values (c1+c2,c0=~/\\.(\\d{4})/)'
|
315
|
+
c.arg_name "COL_A,c6,c2+c4,c0=~/\\.(\\d{4})/"
|
316
|
+
c.flag [:h, :header]
|
317
|
+
|
318
|
+
c.desc 'Key to that the other columns are associated to. A key can be created dynamically'
|
319
|
+
c.arg_name "c0=~/\\.(\\d{4})/,c6"
|
320
|
+
c.flag [:k, :key]
|
321
|
+
|
322
|
+
c.desc 'Columns to be associated to the key. Columns are identified by the column name. The operation to create the column value is separated by a colon (:) from the column name'
|
323
|
+
c.arg_name "c0=~/\\.(\\d{4})/:+n1,Value:+n2"
|
324
|
+
c.flag [:c, :col]
|
325
|
+
|
326
|
+
c.desc 'Format of date values'
|
327
|
+
c.arg_name '%d.%m.%Y|%m/%d/%Y|...'
|
328
|
+
c.flag [:df]
|
329
|
+
|
330
|
+
c.desc 'Format of number values'
|
331
|
+
c.arg_name 'DE|EN'
|
332
|
+
c.default_value 'EN'
|
333
|
+
c.flag [:nf]
|
334
|
+
|
335
|
+
c.action do |global_options,options,args|
|
336
|
+
print "Table..."
|
337
|
+
table = Sycsvpro::Table.new(infile: global_options[:f],
|
338
|
+
outfile: global_options[:o],
|
339
|
+
df: options[:df],
|
340
|
+
nf: options[:nf],
|
341
|
+
rows: options[:r],
|
342
|
+
header: options[:h],
|
343
|
+
key: options[:k],
|
344
|
+
cols: options[:c])
|
345
|
+
table.execute
|
346
|
+
puts "done"
|
347
|
+
end
|
348
|
+
|
349
|
+
end
|
350
|
+
|
306
351
|
desc 'Sort rows based on column values'
|
307
352
|
command :sort do |c|
|
308
353
|
c.desc 'Rows to consider'
|
data/lib/sycsvpro/header.rb
CHANGED
@@ -21,12 +21,56 @@ module Sycsvpro
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
+
def method_missing(id, *args, &block)
|
25
|
+
return @row_cols[$1.to_i] if id =~ /^c(\d+)$/
|
26
|
+
super
|
27
|
+
end
|
28
|
+
|
24
29
|
# Returns the header
|
25
|
-
def process(line)
|
30
|
+
def process(line, values = true)
|
26
31
|
return "" if @header_cols.empty?
|
27
|
-
|
28
|
-
@
|
32
|
+
header_patterns = {}
|
33
|
+
@row_cols = unstring(line).split(';')
|
34
|
+
if @header_cols[0] == '*'
|
35
|
+
@header_cols[0] = @row_cols
|
36
|
+
else
|
37
|
+
@header_cols.each_with_index do |h,i|
|
38
|
+
if h =~ /^c\d+(?:[=~]{,2}).*$/
|
39
|
+
if col = eval(h)
|
40
|
+
last_eval = $1
|
41
|
+
unless @header_cols.index(last_eval) || @header_cols.index(col)
|
42
|
+
if values
|
43
|
+
@header_cols[i] = (h =~ /^c\d+=~/) ? last_eval : col
|
44
|
+
header_patterns[i+1] = h if h =~ /^c\d+[=~+-]{1,2}/
|
45
|
+
else
|
46
|
+
@header_cols[i] = col if h =~ /^c\d+$/
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
else
|
51
|
+
@header_cols[i] = h
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
header_patterns.each { |i,h| @header_cols.insert(i,h) }
|
56
|
+
to_s
|
57
|
+
end
|
58
|
+
|
59
|
+
# Returns @header_cols without pattern
|
60
|
+
def clear_header_cols
|
61
|
+
@header_cols.flatten.select { |col| col !~ /^c\d+[=~+]{1,2}/ }
|
29
62
|
end
|
63
|
+
|
64
|
+
# Returns the index of the column
|
65
|
+
def column_of(value)
|
66
|
+
clear_header_cols.index(value)
|
67
|
+
end
|
68
|
+
|
69
|
+
# Returns the header
|
70
|
+
def to_s
|
71
|
+
clear_header_cols.join(';')
|
72
|
+
end
|
73
|
+
|
30
74
|
end
|
31
75
|
|
32
76
|
end
|
@@ -0,0 +1,174 @@
|
|
1
|
+
require_relative 'row_filter'
|
2
|
+
require_relative 'header'
|
3
|
+
require_relative 'dsl'
|
4
|
+
require 'date'
|
5
|
+
|
6
|
+
module Sycsvpro
|
7
|
+
|
8
|
+
class Table
|
9
|
+
|
10
|
+
include Dsl
|
11
|
+
|
12
|
+
# infile contains the data that is operated on
|
13
|
+
attr_reader :infile
|
14
|
+
# outfile is the file where the result is written to
|
15
|
+
attr_reader :outfile
|
16
|
+
# filter that is used for rows
|
17
|
+
attr_reader :row_filter
|
18
|
+
# date format for date operations
|
19
|
+
attr_reader :date_format
|
20
|
+
# header of the outfile
|
21
|
+
attr_reader :header
|
22
|
+
# rows of the created table
|
23
|
+
attr_reader :rows
|
24
|
+
|
25
|
+
# Creates a new Table. Options expects :infile, :outfile, :rows and
|
26
|
+
# :columns. Optionally a header can be provided. The header can be
|
27
|
+
# supplemented with additional column names that are generated due to a
|
28
|
+
# arithmetic operation that creates new columns
|
29
|
+
# :call-seq:
|
30
|
+
# Sycsvpro::Table.new(infile: "in.csv",
|
31
|
+
# outfile: "out.csv",
|
32
|
+
# df: "%d.%m.%Y",
|
33
|
+
# rows: "1,2,BEGINn3>20END",
|
34
|
+
# header: "Year,c6,c1",
|
35
|
+
# key: "c0=~/\\.(\\d{4})/,c6",
|
36
|
+
# cols: "Value:+n1,c2+c3:+n1",
|
37
|
+
# nf: "DE").execute
|
38
|
+
def initialize(options = {})
|
39
|
+
@infile = options[:infile]
|
40
|
+
@outfile = options[:outfile]
|
41
|
+
@date_format = options[:df] || "%Y-%m-%d"
|
42
|
+
@row_filter = RowFilter.new(options[:rows], df: options[:df])
|
43
|
+
@header = Header.new(options[:header])
|
44
|
+
@keys = options[:key].split(',')
|
45
|
+
@cols = options[:cols].split(',')
|
46
|
+
@number_format = options[:nf] || 'EN'
|
47
|
+
@rows = {}
|
48
|
+
end
|
49
|
+
|
50
|
+
# Retrieves the values from a row as the result of a arithmetic operation
|
51
|
+
# with #eval
|
52
|
+
def method_missing(id, *args, &block)
|
53
|
+
return @columns[$1.to_i] if id =~ /c(\d+)/
|
54
|
+
return to_number(@columns[$1.to_i]) if id =~ /n(\d+)/
|
55
|
+
return to_date(@columns[$1.to_i]) if id =~ /d(\d+)/
|
56
|
+
super
|
57
|
+
end
|
58
|
+
|
59
|
+
# Executes the table and writes the result to the _outfile_
|
60
|
+
def execute
|
61
|
+
create_table_data
|
62
|
+
write_to_file
|
63
|
+
end
|
64
|
+
|
65
|
+
# Create the table
|
66
|
+
def create_table_data
|
67
|
+
processed_header = false
|
68
|
+
|
69
|
+
File.open(infile).each_with_index do |line, index|
|
70
|
+
line = line.chomp
|
71
|
+
|
72
|
+
next if line.empty?
|
73
|
+
|
74
|
+
line = unstring(line).chomp
|
75
|
+
|
76
|
+
header.process line, processed_header
|
77
|
+
|
78
|
+
unless processed_header
|
79
|
+
processed_header = true
|
80
|
+
next
|
81
|
+
end
|
82
|
+
|
83
|
+
next if row_filter.process(line, row: index).nil?
|
84
|
+
|
85
|
+
@columns = line.split(';')
|
86
|
+
|
87
|
+
create_row(create_key, line)
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
# Write table to _outfile_
|
93
|
+
def write_to_file
|
94
|
+
File.open(outfile, 'w') do |out|
|
95
|
+
out.puts header.to_s
|
96
|
+
rows.each do |key, row|
|
97
|
+
line = [] << row[:key]
|
98
|
+
header.clear_header_cols.each_with_index do |col, index|
|
99
|
+
next if index < row[:key].size
|
100
|
+
line << row[:cols][col]
|
101
|
+
end
|
102
|
+
out.puts line.flatten.join(';')
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# Creates a key from the provided key pattern
|
108
|
+
def create_key
|
109
|
+
key = []
|
110
|
+
@keys.each { |k| key << evaluate(k, "") }
|
111
|
+
key
|
112
|
+
end
|
113
|
+
|
114
|
+
# Creates a table row based on the column pattern
|
115
|
+
# Examples of column patterns
|
116
|
+
# * Value:+n1 Adds content of column 1 to Value column
|
117
|
+
# * Value:+n1,c2+c3:+n1 Creates a dynamic column and adds column 1 value
|
118
|
+
# * c0=~/\\.(\\d{4})/:+n1 Creates dynamic column from regex and adds
|
119
|
+
# column 1 value
|
120
|
+
def create_row(key, line)
|
121
|
+
row = rows[key] || rows[key] = { key: key, cols: Hash.new(0) }
|
122
|
+
@cols.each do |col|
|
123
|
+
column, formula = col.split(':')
|
124
|
+
column = evaluate(column) if column =~ /^c\d+[=~+]/
|
125
|
+
row[:cols][column] = eval("#{row[:cols][column]}#{formula}")
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
private
|
130
|
+
|
131
|
+
# Casts a string to an integer or float depending whether the value has a
|
132
|
+
# decimal point
|
133
|
+
def to_number(value)
|
134
|
+
value = convert_to_en(value)
|
135
|
+
return value.to_i unless value =~ /\./
|
136
|
+
return value.to_f if value =~ /\./
|
137
|
+
end
|
138
|
+
|
139
|
+
# Casts a string to a date
|
140
|
+
def to_date(value)
|
141
|
+
if value.nil? or value.strip.empty?
|
142
|
+
nil
|
143
|
+
else
|
144
|
+
Date.strptime(value, date_format)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
# Localize the number to EN
|
149
|
+
def convert_to_en(value)
|
150
|
+
if @number_format == 'DE'
|
151
|
+
value.gsub('.', '_').gsub(',', '.')
|
152
|
+
else
|
153
|
+
value
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
# Evaluate a formula
|
158
|
+
# Example invokation
|
159
|
+
# evaluate("n1+n2", 0)
|
160
|
+
# evaluate("c1+c2", "failed")
|
161
|
+
# evaluate("c0=~/\\.(\\d{4})/", "0")
|
162
|
+
def evaluate(formula, fail_result = 0)
|
163
|
+
if value = eval(formula)
|
164
|
+
last_match = $1
|
165
|
+
(formula =~ /^c\d+=~/) ? last_match : value
|
166
|
+
else
|
167
|
+
fail_result
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
end
|
172
|
+
|
173
|
+
end
|
174
|
+
|
data/lib/sycsvpro/version.rb
CHANGED
data/lib/sycsvpro.rb
CHANGED
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'sycsvpro/header'
|
2
|
+
|
3
|
+
module Sycsvpro
|
4
|
+
|
5
|
+
describe Header do
|
6
|
+
|
7
|
+
it "should create a header from '*,A,B'" do
|
8
|
+
header = Header.new("*,A,B")
|
9
|
+
|
10
|
+
header.process("a;b;c").should eq 'a;b;c;A;B'
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should create a header form 'A,c6,c1'" do
|
14
|
+
header = Header.new("A,c6,c1")
|
15
|
+
|
16
|
+
header.process("a0;a1;a2;a3;a4;a5;a6").should eq "A;a6;a1"
|
17
|
+
header.process("x0;x1;x2;x3;x4;x5;x6").should eq "A;a6;a1"
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should not create columns on arithmetic operation" do
|
21
|
+
header = Header.new("A,c1,c2+c3")
|
22
|
+
|
23
|
+
header.process("h0;h1;h2;h3;h4;h5", false).should eq "A;h1"
|
24
|
+
header.process("a0;a1;a2;a3;a4;a5").should eq "A;h1;a2a3"
|
25
|
+
header.process("b0;b1;b2;b3;b4;b5").should eq "A;h1;a2a3;b2b3"
|
26
|
+
header.process("c0;a1;a2;c3;a4;a5").should eq "A;h1;a2a3;b2b3;a2c3"
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should create a header from 'A,c1,c2+c3'" do
|
31
|
+
header = Header.new("A,c1,c2+c3")
|
32
|
+
|
33
|
+
header.process("a0;a1;a2;a3;a4;a5").should eq "A;a1;a2a3"
|
34
|
+
header.process("b0;b1;b2;b3;b4;b5").should eq "A;a1;a2a3;b2b3"
|
35
|
+
header.process("c0;a1;a2;c3;a4;a5").should eq "A;a1;a2a3;b2b3;a2c3"
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should create a header form 'A,c1,c2+'-'+c3'" do
|
39
|
+
header = Header.new("A,c1,c2+'-'+c3")
|
40
|
+
|
41
|
+
header.process("a0;a1;a2;a3;a4;a5").should eq "A;a1;a2-a3"
|
42
|
+
header.process("b0;b1;b2;b3;b4;b5").should eq "A;a1;a2-a3;b2-b3"
|
43
|
+
header.process("c0;a1;a2;a3;c4;c5").should eq "A;a1;a2-a3;b2-b3"
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should create a header from 'c4,A,c0=~/\.(\d{4})/,c1,B'" do
|
47
|
+
header = Header.new("c4,A,c0=~/\\.(\\d{4})/,c1,B")
|
48
|
+
|
49
|
+
header.process("a0;a1;a2;a3;a4;a5").should eq "a4;A;a1;B"
|
50
|
+
header.process("1.1.2012;b1;b2;b3;b4;b5").should eq "a4;A;2012;a1;B"
|
51
|
+
header.process("3.4.2013;c1;c2;c3;c4;c5").should eq "a4;A;2012;2013;a1;B"
|
52
|
+
header.process("5.5.2012;d1;d2;d3;d4;d5").should eq "a4;A;2012;2013;a1;B"
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should return the header" do
|
56
|
+
header = Header.new("c4,A,c0=~/\\.(\\d{4})/,c1,B")
|
57
|
+
|
58
|
+
header.process("a0;a1;a2;a3;a4;a5").should eq "a4;A;a1;B"
|
59
|
+
header.process("1.1.2012;b1;b2;b3;b4;b5").should eq "a4;A;2012;a1;B"
|
60
|
+
header.process("3.4.2013;c1;c2;c3;c4;c5").should eq "a4;A;2012;2013;a1;B"
|
61
|
+
header.process("5.5.2012;d1;d2;d3;d4;d5").should eq "a4;A;2012;2013;a1;B"
|
62
|
+
|
63
|
+
header.to_s.should eq "a4;A;2012;2013;a1;B"
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should return the index of the coloum" do
|
67
|
+
header = Header.new("c4,A,c0=~/\\.(\\d{4})/,c1,B")
|
68
|
+
|
69
|
+
header.process("a0;a1;a2;a3;a4;a5").should eq "a4;A;a1;B"
|
70
|
+
header.column_of("a1").should eq 2
|
71
|
+
header.process("1.1.2012;b1;b2;b3;b4;b5").should eq "a4;A;2012;a1;B"
|
72
|
+
header.column_of("a1").should eq 3
|
73
|
+
header.process("3.4.2013;c1;c2;c3;c4;c5").should eq "a4;A;2012;2013;a1;B"
|
74
|
+
header.column_of("B").should eq 5
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'sycsvpro/table'
|
2
|
+
|
3
|
+
module Sycsvpro
|
4
|
+
|
5
|
+
describe Table do
|
6
|
+
before do
|
7
|
+
@in_file = File.join(File.dirname(__FILE__), "files/table.csv")
|
8
|
+
@out_file = File.join(File.dirname(__FILE__), "files/out.csv")
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should create headings from String and column values" do
|
12
|
+
Sycsvpro::Table.new(infile: @in_file,
|
13
|
+
outfile: @out_file,
|
14
|
+
header: "Year,c6,c1",
|
15
|
+
key: "c0=~/\\.(\\d{4})/,c6",
|
16
|
+
cols: "Value:+n1").execute
|
17
|
+
|
18
|
+
result = [ "Year;Country;Value",
|
19
|
+
"2013;AT;53.7",
|
20
|
+
"2014;DE;21.0",
|
21
|
+
"2014;AT;20.5" ]
|
22
|
+
|
23
|
+
File.open(@out_file).each_with_index do |line, index|
|
24
|
+
line.chomp.should eq result[index]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should create headings from operation" do
|
29
|
+
Sycsvpro::Table.new(infile: @in_file,
|
30
|
+
outfile: @out_file,
|
31
|
+
header: "Year,c6,c1,c2+c3",
|
32
|
+
key: "c0=~/\\.(\\d{4})/,c6",
|
33
|
+
cols: "Value:+n1,c2+c3:+n1").execute
|
34
|
+
|
35
|
+
result = [ "Year;Country;Value;A1;B2;B4",
|
36
|
+
"2013;AT;53.7;20.5;0;33.2",
|
37
|
+
"2014;DE;21.0;0;21.0;0",
|
38
|
+
"2014;AT;20.5;20.5;0;0" ]
|
39
|
+
|
40
|
+
File.open(@out_file).each_with_index do |line, index|
|
41
|
+
line.chomp.should eq result[index]
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should create key from operation" do
|
47
|
+
Sycsvpro::Table.new(infile: @in_file,
|
48
|
+
outfile: @out_file,
|
49
|
+
header: "c4,c5,c0=~/\\.(\\d{4})/",
|
50
|
+
key: "c4,c5",
|
51
|
+
cols: "c0=~/\\.(\\d{4})/:+n1").execute
|
52
|
+
|
53
|
+
result = [ "Customer Name;Customer-ID;2013;2014",
|
54
|
+
"Hank;133;20.5;20.5",
|
55
|
+
"Hans;234;0;21.0",
|
56
|
+
"Jack;432;33.2;0" ]
|
57
|
+
|
58
|
+
File.open(@out_file).each_with_index do |line, index|
|
59
|
+
line.chomp.should eq result[index]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sycsvpro
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-06-
|
12
|
+
date: 2014-06-23 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -148,6 +148,7 @@ files:
|
|
148
148
|
- lib/sycsvpro/script_creator.rb
|
149
149
|
- lib/sycsvpro/script_list.rb
|
150
150
|
- lib/sycsvpro/sorter.rb
|
151
|
+
- lib/sycsvpro/table.rb
|
151
152
|
- lib/sycsvpro/version.rb
|
152
153
|
- spec/sycsvpro/aggregator_spec.rb
|
153
154
|
- spec/sycsvpro/allocator_spec.rb
|
@@ -161,12 +162,14 @@ files:
|
|
161
162
|
- spec/sycsvpro/files/profile.rb
|
162
163
|
- spec/sycsvpro/files/script.rb
|
163
164
|
- spec/sycsvpro/files/unsert.ins
|
165
|
+
- spec/sycsvpro/header_spec.rb
|
164
166
|
- spec/sycsvpro/inserter_spec.rb
|
165
167
|
- spec/sycsvpro/mapper_spec.rb
|
166
168
|
- spec/sycsvpro/profiler_spec.rb
|
167
169
|
- spec/sycsvpro/row_filter_spec.rb
|
168
170
|
- spec/sycsvpro/script_list_spec.rb
|
169
171
|
- spec/sycsvpro/sorter_spec.rb
|
172
|
+
- spec/sycsvpro/table_spec.rb
|
170
173
|
- sycsvpro.gemspec
|
171
174
|
- sycsvpro.rdoc
|
172
175
|
homepage: https://github.com/sugaryourcoffee/syc-svpro
|