Text-CSV_XS

 view release on metacpan or  search on metacpan

CSV_XS.pm  view on Meta::CPAN

	    $cboi = undef;
	    }
	if ($cbai) {
	    my $cb = $cbai;
	    $cbai = sub { $cb->(@_); $_[0]->say ($fho, $_[1]); 0 };
	    }
	else {
	    $cbai = sub {            $_[0]->say ($fho, $_[1]); 0 };
	    }

	# Put all callbacks back in place for streaming behavior
	$attr{'callbacks'}{'after_parse'} = $cbai; $cbai = undef;
	$attr{'callbacks'}{'before_out'}  = $cbbo; $cbbo = undef;
	$attr{'callbacks'}{'on_in'}       = $cboi; $cboi = undef;
	$attr{'callbacks'}{'on_error'}    = $cboe; $cboe = undef;
	$out  = undef;
	$sink = 1;
	}

    if ($out) {
	if (ref $out and ("ARRAY" eq ref $out or "HASH" eq ref $out)) {

CSV_XS.pm  view on Meta::CPAN

 my %hash;
 csv (in => $_, out => \%hash, key => "id") for sort glob "foo-[0-9]*.csv";

 my @list; # List of arrays
 csv (in => $_, out => \@list)              for sort glob "foo-[0-9]*.csv";

 my @list; # List of hashes
 csv (in => $_, out => \@list, bom => 1)    for sort glob "foo-[0-9]*.csv";

=head4 Streaming
X<streaming>

If B<both> C<in> and C<out> are files, file handles or globs,  streaming is
enforced by injecting an C<after_parse> callback  that immediately uses the
L<C<say ()>|/say> method of the same instance to output the result and then
rejects the record.

If a C<after_parse> was already passed as attribute,  that will be included
in the injected call. If C<on_in> was passed and C<after_parse> was not, it
will be used instead. If both were passed, C<on_in> is ignored.

The EOL of the first record of the C<in> source is consistently used as EOL
for all records in the C<out> destination.

CSV_XS.pm  view on Meta::CPAN

 my $csv = Text::CSV_XS->new ({ binary => 1, eol => "\r\n" });
 my $sth = $dbh->prepare ($sql); $sth->execute;
 $csv->print ($fh, $sth->{NAME_lc});
 while (my $row = $sth->fetch) {
     $csv->print ($fh, $row);
     }

 # using the csv function, all in memory
 csv (out => "foo.csv", in => $dbh->selectall_arrayref ($sql));

 # using the csv function, streaming with callbacks
 my $sth = $dbh->prepare ($sql); $sth->execute;
 csv (out => "foo.csv", in => sub { $sth->fetch            });
 csv (out => "foo.csv", in => sub { $sth->fetchrow_hashref });

Note that this does not discriminate between "empty" values and NULL-values
from the database,  as both will be the same empty field in CSV.  To enable
distinction between the two, use L<C<quote_empty>|/quote_empty>.

 csv (out => "foo.csv", in => sub { $sth->fetch }, quote_empty => 1);

ChangeLog  view on Meta::CPAN

    * CR/NL/CRNL inside quoted fields not affected by strict_eol
    * Fix incorrect error 2014 (issue 62)

1.59	- 2025-01-05, H.Merijn Brand
    * Fixed EOL test for Windows with crnl layer
    * It is 2025

1.58	- 2024-12-30, H.Merijn Brand
    * Add strict_eol (warnings default in csv ())
    * Add XS line number in errors
    * Add streaming support - not set in stone

1.57	- 2024-11-12, H.Merijn Brand
    * Keep runtime error from csv ()
    * add csv (on_error)

1.56	- 2024-08-09, H.Merijn Brand
    * Yet another strict/comment_str conflict (issue 57)
    * Strict affected by column_names

1.55	- 2024-06-18, H.Merijn Brand

ChangeLog  view on Meta::CPAN

    * [csv2xls/csv2xlsx] do not generate xls/xlsx on empty CSV (issue 18)
    * New: support $csv->formula (sub { ... })
    * Support stacked encodings

1.39	- 2019-03-15, H.Merijn Brand
    * It's 2019
    * Fix tests to skip on Encode failing (PR#17 charsbar + klapperl)
    * Tested on Z/OS (s390x - Hercules) :)
    * Test with new Module::CPANTS::Analyse
    * Add options -w/-b/-Z to csvdiff
    * Fix strict on streaming EOF
    * Now also tested with cperl

1.38	- 2018-12-30, H.Merijn Brand
    * Name the duplicate headers on error 1013
    * Add missing attributes to default list (doc only, David H. Gutteridge)
    * Add support for combined keys
    * Look at $NO_COLOR for csvdiff
    * Add support for key-value pair

1.37	- 2018-09-27, H.Merijn Brand

t/92_stream.t  view on Meta::CPAN

	    callbacks => {
	      after_parse  => sub {
		warn ++$I, "\n";
		$co->print ($fho, $_[1]);
		},
	      },
	    );
	}
    close $tfno;
    chomp @W;
    is ("@W", "1 1 2 2 3 3", "Old-fashioned streaming");
    }

# Basic straight-forward streaming, no filters/modifiers
unlink $tfno if -e $tfno;
csv (in => $tfni, out => $tfno, quote_space => 0);
ok (-s $tfno, "FILE -> FILE");
is_deeply (csv (in => $tfno), $aoa, "Data is equal");

unlink $tfno if -e $tfno;
open my $fho, ">", $tfno;
csv (in => $tfni, out => $fho,  quote_space => 0);
close   $fho;
ok (-s $tfno, "FILE -> FH");

t/92_stream.t  view on Meta::CPAN

csv (
    in          => $tfni,
    out         => $tfno,
    quote_space => 0,
    after_parse => sub { $_[1][1] .= "X" },
    );
ok (-s $tfno, "With after_parse");
my @new = map { my @x = @$_; $x[1] .= "X"; \@x } @$aoa;
is_deeply (csv (in => $tfno), \@new, "Data is equal");

# Prove streaming behavior
my $io = "";
unlink $tfno if -e $tfno;
csv (
    in        => $tfni,
    out       => $tfno,
    on_in     => sub { $io .= "I" },
    callbacks => { before_print => sub { $io .= "O" }},
    );
ok (-s $tfno, "FILE -> FILE");
is_deeply (csv (in => $tfno), $aoa, "Data is equal");



( run in 0.245 second using v1.01-cache-2.11-cpan-4d50c553e7e )