goodsheet 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +43 -4
- data/lib/goodsheet/read_result.rb +24 -5
- data/lib/goodsheet/row.rb +24 -14
- data/lib/goodsheet/spreadsheet.rb +1 -1
- data/lib/goodsheet/validation_error.rb +1 -1
- data/lib/goodsheet/validation_errors.rb +14 -0
- data/lib/goodsheet/version.rb +1 -1
- data/test/fixtures/ss_01.xls +0 -0
- data/test/test_row.rb +7 -2
- data/test/test_spreadsheet_01.rb +22 -0
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 857c86e4b9ce1ab63a12d69a98a89194374731c8
|
4
|
+
data.tar.gz: 6bc6c520ab684b0933288c25db1d389c1aa221de
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7e93e30871d1548a6f71fd969f1cde562ab99564045f29a79108ebfc191e73f53a23b830769d9c29a286028ba6c6d27c88cb3485f7846f86ddb3b61c709ce867
|
7
|
+
data.tar.gz: 8cbded3dfb2890d91799a872d7d3b0489aec4bfaa55abe549a89321c331f30c83ed7c11a8db6b5422958d2318c08db1dcee92aacb0a476538f0443d519cece94
|
data/README.md
CHANGED
@@ -39,6 +39,7 @@ res.values # => {:a => [1.0, 1.0, 1.4], :b => [0.0, 3.7, 10.9]}
|
|
39
39
|
By default:
|
40
40
|
* the first sheet is selected
|
41
41
|
* one line (the first) is skipped (i'm expeting that is the header line)
|
42
|
+
* the content is returned as an hash of columns
|
42
43
|
|
43
44
|
Pass your validation rules into the block passed to the read method, together with the column_names method that define the position (or index) and the name of the columns you want to read.
|
44
45
|
|
@@ -81,7 +82,7 @@ end
|
|
81
82
|
|
82
83
|
Get the content of header row:
|
83
84
|
```ruby
|
84
|
-
ss.
|
85
|
+
ss.get_header # => ["year", "month", "day"]
|
85
86
|
```
|
86
87
|
|
87
88
|
Get the number of rows:
|
@@ -94,16 +95,17 @@ ss.rows_wo_skipped # => except the skipped ones, aliased by `rows` method
|
|
94
95
|
|
95
96
|
Use the `validate` and `read` methods to perform validation and reading. Note that the reading function include a validation call.
|
96
97
|
Pass the previously seen `options` hash and a block to `validate`/`read` method.
|
97
|
-
Inside the block you define columns names and indexes you want to validate/read using the `column_names` method. You can use one of these
|
98
|
+
Inside the block you define columns names and indexes you want to validate/read using the `column_names` method. You can use one of these 4 forms:
|
98
99
|
- `column_names :a => 0, :b => 1, :c => 3`
|
99
100
|
- `column_names 0 => :a, 1 => :b, 3 => :c`
|
100
101
|
- `column_names [:a, :b, nil, :c]`
|
102
|
+
- `column_names :a, :b, nil, :c`
|
101
103
|
|
102
104
|
Aside from define the columns settings, into block you define the validation rules.
|
103
105
|
Refer to the [official guide](http://guides.rubyonrails.org/active_record_validations.html) and [ROR Api](http://api.rubyonrails.org/classes/ActiveModel/Validations/ClassMethods.html)
|
104
106
|
|
105
107
|
|
106
|
-
|
108
|
+
Here another example:
|
107
109
|
```ruby
|
108
110
|
ss = Goodsheet::Spreadsheet.new("my_data.xlsx")
|
109
111
|
ss.sheet(1, :max_errors => 50, :force_nil => 0.0)
|
@@ -121,12 +123,49 @@ res = ss.read do
|
|
121
123
|
end
|
122
124
|
end
|
123
125
|
end
|
126
|
+
|
127
|
+
res.valid?
|
128
|
+
```
|
129
|
+
|
130
|
+
If validation fails you get `false` on `res.valid?` call, and you retrieve an array with errors by calling `errors` method on result object:
|
131
|
+
If validation fails you can retrieve the errors array by calling `errors` method on result object:
|
132
|
+
|
133
|
+
```ruby
|
134
|
+
res.valid? # => false
|
135
|
+
res.invalid? # => true
|
136
|
+
res.errors # => a ValidationErrors object
|
137
|
+
res.errors.size # => 1
|
138
|
+
res.errors[0].to_s # => "Row 5 is invalid for the following reason(s): Year is not a number, Month is not a number"
|
139
|
+
```
|
140
|
+
|
141
|
+
If the validation ends successfully without errors, the result values are available using one of these three forms:
|
142
|
+
- hash of columns (default)
|
143
|
+
- array of rows, where the rows are array
|
144
|
+
- array of rows, where the rows are hashes
|
145
|
+
|
146
|
+
|
147
|
+
```
|
148
|
+
+------+-------+
|
149
|
+
| year | month |
|
150
|
+
+------+-------+
|
151
|
+
| 2012 | 1 |
|
152
|
+
+------+-------+
|
153
|
+
| 2012 | 2 |
|
154
|
+
+------+-------+
|
155
|
+
| 2012 | 3 |
|
156
|
+
+------+-------+
|
124
157
|
```
|
125
158
|
|
159
|
+
```ruby
|
160
|
+
res.values # => { :year => [2012, 2012, 2012], :month => [1, 2, 3]}
|
161
|
+
res.values(:columns) # same as the previous
|
162
|
+
res.values(:rows_array) # => [[2012, 1], [2012, 2], [2012, 3]]
|
163
|
+
res.values(:rows_hash) # => [{:year => 2012, :month => 1}, {:year => 2012, :month => 2}, {:year => 2012, :month => 3}]
|
164
|
+
```
|
126
165
|
|
127
166
|
|
128
167
|
|
129
|
-
|
168
|
+
Note:
|
130
169
|
* integer numbers are converted to float numbers. Also don't pretend to obtain an integer in validation. This undesired behaviour depend on Roo gem
|
131
170
|
* if you import data from a CSV spreadsheet keep in mind that numbers are readed as strings
|
132
171
|
|
@@ -1,11 +1,11 @@
|
|
1
1
|
module Goodsheet
|
2
2
|
|
3
3
|
class ReadResult
|
4
|
-
attr_reader :
|
4
|
+
attr_reader :vv, :errors
|
5
5
|
|
6
6
|
def initialize(errors=ValidationErrors.new)
|
7
7
|
@errors = errors
|
8
|
-
@
|
8
|
+
@vv = {}
|
9
9
|
end
|
10
10
|
|
11
11
|
def valid?
|
@@ -18,11 +18,30 @@ module Goodsheet
|
|
18
18
|
|
19
19
|
def add(attribute, row, force_nil=nil)
|
20
20
|
attribute = attribute.to_sym
|
21
|
-
(@
|
21
|
+
(@vv[attribute] ||= []) << (row.send(attribute) || force_nil)
|
22
22
|
end
|
23
23
|
|
24
|
-
def
|
25
|
-
@
|
24
|
+
def values(format=:columns)
|
25
|
+
values_size = @vv.values.first.size
|
26
|
+
|
27
|
+
case format
|
28
|
+
when :columns
|
29
|
+
@vv
|
30
|
+
|
31
|
+
when :rows_array
|
32
|
+
Array.new(values_size) do |i1|
|
33
|
+
Array.new(@vv.size) do |i2|
|
34
|
+
@vv[@vv.keys[i2]][i1]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
when :rows_hash
|
39
|
+
Array.new(values_size) do |i1|
|
40
|
+
hh = {}
|
41
|
+
@vv.keys.each{|k| hh[k] = @vv[k][i1] }
|
42
|
+
hh
|
43
|
+
end
|
44
|
+
end
|
26
45
|
end
|
27
46
|
end
|
28
47
|
end
|
data/lib/goodsheet/row.rb
CHANGED
@@ -30,37 +30,47 @@ module Goodsheet
|
|
30
30
|
end
|
31
31
|
|
32
32
|
# Define the position (or index) and the name of columns.
|
33
|
-
#
|
34
|
-
# using an hash index
|
35
|
-
# or name
|
33
|
+
# You have four ways to define them:
|
34
|
+
# using an hash index-to-name (like { 0 => :year, 2 => :day })
|
35
|
+
# or its reversed version name-to-index (like { :year => 0, :day => 2 }), using an array
|
36
36
|
# with the names at desired positions (like [:year, nil, :day]), put a nil
|
37
|
-
# at the position
|
37
|
+
# at the position, or simply put the list of names.
|
38
38
|
# The positions are 0-based.
|
39
|
-
def self.column_names(
|
39
|
+
def self.column_names(*attr)
|
40
|
+
# def self.column_names(param)
|
40
41
|
@keys = {}
|
41
|
-
if
|
42
|
-
|
43
|
-
|
42
|
+
raise ArgumentError, 'You have to pass at least one attribute' if attr.empty?
|
43
|
+
if attr[0].is_a? Array
|
44
|
+
attr[0].each_with_index do |name, idx|
|
45
|
+
if name
|
46
|
+
self.keys[idx] = name
|
47
|
+
attr_accessor name
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
elsif attr[0].is_a? Hash
|
52
|
+
if attr[0].first[0].is_a? Integer
|
53
|
+
attr[0].each do |idx, name|
|
44
54
|
self.keys[idx] = name
|
45
55
|
attr_accessor name
|
46
56
|
end
|
47
57
|
else
|
48
|
-
|
58
|
+
attr[0].each do |name, idx|
|
49
59
|
self.keys[idx] = name
|
50
60
|
attr_accessor name
|
51
61
|
end
|
52
62
|
end
|
53
|
-
|
54
|
-
|
63
|
+
|
64
|
+
else
|
65
|
+
attr.each_with_index do |name, idx|
|
55
66
|
if name
|
67
|
+
name = name.to_s.gsub(" ", "_").to_sym unless name.is_a? Symbol
|
56
68
|
self.keys[idx] = name
|
57
69
|
attr_accessor name
|
58
70
|
end
|
59
71
|
end
|
60
|
-
|
61
|
-
else
|
62
|
-
raise "parameter non valid"
|
63
72
|
end
|
73
|
+
|
64
74
|
end
|
65
75
|
|
66
76
|
|
data/lib/goodsheet/version.rb
CHANGED
data/test/fixtures/ss_01.xls
CHANGED
Binary file
|
data/test/test_row.rb
CHANGED
@@ -4,17 +4,22 @@ require 'goodsheet'
|
|
4
4
|
class TestRow < Test::Unit::TestCase
|
5
5
|
|
6
6
|
def test_column_names
|
7
|
-
assert_raise
|
7
|
+
assert_raise ArgumentError do
|
8
|
+
Goodsheet::Row.column_names
|
9
|
+
end
|
10
|
+
assert_raise NameError do
|
8
11
|
Goodsheet::Row.column_names(6)
|
9
12
|
end
|
10
13
|
|
14
|
+
Goodsheet::Row.column_names(:a, nil, :b, :c)
|
15
|
+
assert_equal(Goodsheet::Row.keys, {0 => :a, 2 => :b, 3 => :c})
|
16
|
+
|
11
17
|
Goodsheet::Row.column_names([:a, nil, :b, :c])
|
12
18
|
assert_equal(Goodsheet::Row.keys, {0 => :a, 2 => :b, 3 => :c})
|
13
19
|
|
14
20
|
Goodsheet::Row.column_names(:a => 0, :b => 2, :c => 3)
|
15
21
|
assert_equal(Goodsheet::Row.keys, {0 => :a, 2 => :b, 3 => :c})
|
16
22
|
|
17
|
-
|
18
23
|
Goodsheet::Row.column_names(0 => :a, 2 => :b, 3 => :c)
|
19
24
|
assert_equal(Goodsheet::Row.keys, {0 => :a, 2 => :b, 3 => :c})
|
20
25
|
end
|
data/test/test_spreadsheet_01.rb
CHANGED
@@ -168,4 +168,26 @@ class TestSpreadsheet_01 < Test::Unit::TestCase
|
|
168
168
|
|
169
169
|
end
|
170
170
|
|
171
|
+
def test_result_formats
|
172
|
+
result = @ss.read do
|
173
|
+
column_names :a, :b, :c, :d
|
174
|
+
end
|
175
|
+
y = {
|
176
|
+
:a=>[2012.0, 2012.0, 2012.0, 2013.0],
|
177
|
+
:b=>["F", "F", "G", "F"],
|
178
|
+
:c=>[3.1, 2.5, 0.0, 0.78],
|
179
|
+
:d=>[4.1, 3.5, 1.0, 1.78]
|
180
|
+
}
|
181
|
+
values_size = y.values.first.size
|
182
|
+
|
183
|
+
assert_equal(y, result.values)
|
184
|
+
assert_equal(y, result.values(:columns))
|
185
|
+
|
186
|
+
y = [[2012.0, "F", 3.1, 4.1], [2012.0, "F", 2.5, 3.5], [2012.0, "G", 0.0, 1.0], [2013.0, "F", 0.78, 1.78]]
|
187
|
+
assert_equal(y, result.values(:rows_array))
|
188
|
+
|
189
|
+
y = [{:a=>2012.0, :b=>"F", :c=>3.1, :d=>4.1}, {:a=>2012.0, :b=>"F", :c=>2.5, :d=>3.5}, {:a=>2012.0, :b=>"G", :c=>0.0, :d=>1.0}, {:a=>2013.0, :b=>"F", :c=>0.78, :d=>1.78}]
|
190
|
+
assert_equal(y, result.values(:rows_hash))
|
191
|
+
end
|
192
|
+
|
171
193
|
end
|