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
|
CSV: Errorhandling
Parser umgeschrieben, eof muss nach getline prüfen (bekloppt).
Errorhandling aktiviert. Dokumentation aktualisiert.