use Carp;
use IO::File;
use Params::Validate qw(:all);
-use Text::CSV;
+use Text::CSV_XS;
use Rose::Object::MakeMethods::Generic scalar => [ qw(
file encoding sep_char quote_char escape_char header profile class
- numberformat dateformat ignore_unknown_columns _io _csv _objects _parsed
- _data _errors
+ numberformat dateformat ignore_unknown_columns strict_profile _io _csv
+ _objects _parsed _data _errors
) ];
use SL::Helper::Csv::Dispatcher;
numberformat => 0,
dateformat => 0,
ignore_unknown_columns => 0,
+ strict_profile => 0,
});
my $self = bless {}, $class;
$self->$_($params{$_}) for keys %params;
$self->_io(IO::File->new);
- $self->_csv(Text::CSV->new({
+ $self->_csv(Text::CSV_XS->new({
binary => 1,
sep_char => $self->sep_char,
quote_char => $self->quote_char,
sub _check_header {
my ($self, %params) = @_;
- return $self->header if $self->header;
+ my $header = $self->header;
- my $header = $self->_csv->getline($self->_io);
+ if (! $header) {
+ $header = $self->_csv->getline($self->_io);
- $self->_push_error([
- $self->_csv->error_input,
- $self->_csv->error_diag,
- 0,
- ]) unless $header;
+ $self->_push_error([
+ $self->_csv->error_input,
+ $self->_csv->error_diag,
+ 0,
+ ]) unless $header;
+ }
- $self->header($header);
+ return unless $header;
+ return $self->header([ map { lc } @$header ]);
}
sub _parse_data {
while (1) {
my $row = $self->_csv->getline($self->_io);
- last if $self->_csv->eof;
if ($row) {
my %hr;
@hr{@{ $self->header }} = @$row;
push @data, \%hr;
} else {
+ last if $self->_csv->eof;
push @errors, [
$self->_csv->error_input,
$self->_csv->error_diag,
$self->_io->input_line_number,
];
}
+ last if $self->_csv->eof;
}
$self->_data(\@data);
If set, the import will ignore unkown header columns. Useful for lazy imports,
but deactivated by default.
+=item C<strict_profile>
+
+If set, all columns to be parsed must be specified in C<profile>. Every header
+field not listed there will be treated like an unknown column.
+
=back
=head1 ERROR HANDLING