App-RecordStream
view release on metacpan or search on metacpan
lib/App/RecordStream/Operation/fromcsv.pm view on Meta::CPAN
package App::RecordStream::Operation::fromcsv;
our $VERSION = "4.0.25";
use strict;
use base qw(App::RecordStream::Operation);
use Text::CSV;
sub init {
my $this = shift;
my $args = shift;
my @fields;
my $header_line = undef;
my $strict = 0;
my $delim = ',';
my $escape = '"';
my $quote = '"';
my $spec = {
"keys|k|field|f=s" => sub { push @fields, split(/,/, $_[1]); },
"header" => \$header_line,
"strict" => \$strict,
"delim|d=s" => \$delim,
"escape=s" => \$escape,
"quote=s" => \$quote,
};
$this->parse_options($args, $spec);
die "Delimiter must be a single character\n\n"
unless length $delim == 1;
my $csv_args = {
binary => 1,
eol => $/,
sep_char => $delim,
escape_char => $escape,
# Text::CSV wants undef, but it's easier to pass the empty string at the shell.
quote_char => ($quote eq '' ? undef : $quote),
};
if ( !$strict ) {
$csv_args->{'allow_whitespace'} = 1;
$csv_args->{'allow_loose_quotes'} = 1;
$csv_args->{'allow_loose_escapes'} = 1;
}
$this->{'FIELDS'} = \@fields;
$this->{'HEADER_LINE'} = $header_line;
$this->{'PARSER'} = new Text::CSV($csv_args);
$this->{'EXTRA_ARGS'} = $args;
}
sub wants_input {
return 0;
}
sub stream_done {
my $this = shift;
my $files = $this->{'EXTRA_ARGS'};
if ( scalar @$files > 0 ) {
foreach my $file ( @$files ) {
$this->update_current_filename($file);
open(my $fh, '<', $file) or die "Could not open file: $!\n";
$this->get_records_from_handle($fh);
close $fh;
}
}
else {
$this->get_records_from_handle(\*STDIN);
}
}
sub get_records_from_handle {
my ($this, $handle) = @_;
my $parser = $this->{'PARSER'};
my $do_headers = $this->{'HEADER_LINE'};
my @fields = @{ $this->{'FIELDS'} };
while(my $row = $parser->getline($handle)) {
if ( $do_headers ) {
push @fields, @$row;
$do_headers = 0;
next;
}
my @values = @$row;
my $record = App::RecordStream::Record->new();
for(my $i = 0; $i < @values; ++$i) {
( run in 1.723 second using v1.01-cache-2.11-cpan-8f98c5d2c55 )