Revision 8fba112b
Von Sven Schöling vor mehr als 13 Jahren hinzugefügt
SL/Helper/Csv.pm | ||
---|---|---|
8 | 8 |
use Text::CSV; |
9 | 9 |
use Params::Validate qw(:all); |
10 | 10 |
use Rose::Object::MakeMethods::Generic scalar => [ qw( |
11 |
file encoding sep_char quote_char header header_acc class numberformat
|
|
12 |
dateformat _io _csv _objects _parsed _data
|
|
11 |
file encoding sep_char quote_char escape_char header header_acc class
|
|
12 |
numberformat dateformat _io _csv _objects _parsed _data _errors
|
|
13 | 13 |
) ]; |
14 | 14 |
|
15 | 15 |
|
... | ... | |
20 | 20 |
my %params = validate(@_, { |
21 | 21 |
sep_char => { default => ';' }, |
22 | 22 |
quote_char => { default => '"' }, |
23 |
escape_char => { default => '"' }, |
|
23 | 24 |
header => { type => ARRAYREF, optional => 1 }, |
24 | 25 |
header_acc => { type => HASHREF, optional => 1 }, |
25 | 26 |
file => 1, |
... | ... | |
35 | 36 |
$self->_io(IO::File->new); |
36 | 37 |
$self->_csv(Text::CSV->new({ |
37 | 38 |
binary => 1, |
38 |
sep_char => $self->sep_char, |
|
39 |
quote_char => $self->quote_char, |
|
39 |
sep_char => $self->sep_char, |
|
40 |
quote_char => $self->quote_char, |
|
41 |
escape_char => $self->escape_char, |
|
40 | 42 |
|
41 | 43 |
})); |
44 |
$self->_errors([]); |
|
42 | 45 |
|
43 | 46 |
return $self; |
44 | 47 |
} |
... | ... | |
67 | 70 |
return wantarray ? @{ $self->_objects } : $self->_objects; |
68 | 71 |
} |
69 | 72 |
|
73 |
sub errors { |
|
74 |
@{ $_[0]->_errors } |
|
75 |
} |
|
76 |
|
|
70 | 77 |
# private stuff |
71 | 78 |
|
72 | 79 |
sub _open_file { |
... | ... | |
91 | 98 |
|
92 | 99 |
sub _parse_data { |
93 | 100 |
my ($self, %params) = @_; |
94 |
my @data;
|
|
101 |
my (@data, @errors);
|
|
95 | 102 |
|
96 | 103 |
$self->_csv->column_names(@{ $self->header }); |
97 | 104 |
|
98 |
push @data, $self->_csv->getline_hr($self->_io) |
|
99 |
while !$self->_csv->eof; |
|
105 |
while (1) { |
|
106 |
my $row = $self->_csv->getline($self->_io); |
|
107 |
last if $self->_csv->eof; |
|
108 |
|
|
109 |
if ($row) { |
|
110 |
my %hr; |
|
111 |
@hr{@{ $self->header }} = @$row; |
|
112 |
push @data, \%hr; |
|
113 |
} else { |
|
114 |
push @errors, [ |
|
115 |
$self->_csv->error_input, |
|
116 |
$self->_csv->error_diag, |
|
117 |
$self->_io->input_line_number, |
|
118 |
]; |
|
119 |
} |
|
120 |
} |
|
100 | 121 |
|
101 | 122 |
$self->_data(\@data); |
123 |
$self->_errors(\@errors); |
|
124 |
|
|
125 |
return if @errors; |
|
126 |
return \@data; |
|
102 | 127 |
} |
103 | 128 |
|
104 | 129 |
sub _encode_layer { |
... | ... | |
134 | 159 |
|
135 | 160 |
__END__ |
136 | 161 |
|
162 |
=encoding utf-8 |
|
163 |
|
|
137 | 164 |
=head1 NAME |
138 | 165 |
|
139 | 166 |
SL::Helper::Csv - take care of csv file uploads |
... | ... | |
153 | 180 |
) |
154 | 181 |
|
155 | 182 |
my $status = $csv->parse; |
156 |
my @hrefs = $csv->get_data;
|
|
183 |
my $hrefs = $csv->get_data;
|
|
157 | 184 |
my @objects = $scv->get_objects; |
158 | 185 |
|
159 | 186 |
=head1 DESCRIPTION |
... | ... | |
182 | 209 |
|
183 | 210 |
Parse the data into objects and return those. |
184 | 211 |
|
212 |
This method will return list or arrayref depending on context. |
|
213 |
|
|
185 | 214 |
=item C<get_data> |
186 | 215 |
|
187 | 216 |
Returns an arrayref of the raw lines as hashrefs. |
188 | 217 |
|
218 |
=item C<errors> |
|
219 |
|
|
220 |
Return all errors that came up druing parsing. See error handling for detailed |
|
221 |
information. |
|
222 |
|
|
223 |
=back |
|
224 |
|
|
225 |
=head1 PARAMS |
|
226 |
|
|
227 |
=over 4 |
|
228 |
|
|
189 | 229 |
=item C<file> |
190 | 230 |
|
191 | 231 |
The file which contents are to be read. Can be a name of a physical file or a |
... | ... | |
200 | 240 |
|
201 | 241 |
=item C<quote_char> |
202 | 242 |
|
243 |
=item C<escape_char> |
|
244 |
|
|
203 | 245 |
Same as in L<Text::CSV> |
204 | 246 |
|
205 | 247 |
=item C<header> \@FIELDS |
... | ... | |
223 | 265 |
|
224 | 266 |
=back |
225 | 267 |
|
226 |
=head1 BUGS |
|
268 |
=head1 ERROR HANDLING |
|
269 |
|
|
270 |
After parsing a file all errors will be accumulated into C<errors>. |
|
271 |
|
|
272 |
Each entry is an arrayref with the following structure: |
|
273 |
|
|
274 |
[ |
|
275 |
offending raw input, |
|
276 |
Text::CSV error code if present, |
|
277 |
Text::CSV error diagnostics if present, |
|
278 |
position in line, |
|
279 |
estimated line in file, |
|
280 |
] |
|
281 |
|
|
282 |
Note that the last entry can be off, but will give an estimate. |
|
283 |
|
|
284 |
=head1 CAVEATS |
|
285 |
|
|
286 |
=over 4 |
|
287 |
|
|
288 |
=item * |
|
289 |
|
|
290 |
sep_char, quote_char, and escape_char are passed to Text::CSV on creation. |
|
291 |
Changing them later has no effect currently. |
|
292 |
|
|
293 |
=item * |
|
294 |
|
|
295 |
Encoding errors are not dealt with properly. |
|
296 |
|
|
297 |
=item * |
|
298 |
|
|
299 |
Errors are not gathered. |
|
300 |
|
|
301 |
=back |
|
227 | 302 |
|
228 | 303 |
=head1 AUTHOR |
229 | 304 |
|
305 |
Sven Schöling E<lt>s.schoeling@linet-services.deE<gt> |
|
306 |
|
|
230 | 307 |
=cut |
Auch abrufbar als: Unified diff
CSV: Errorhandling
Parser umgeschrieben, eof muss nach getline prüfen (bekloppt).
Errorhandling aktiviert. Dokumentation aktualisiert.