Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision f9f7b56e

Von Sven Schöling vor etwa 14 Jahren hinzugefügt

  • ID f9f7b56eb62b165317bdf2253171ff09da7ae2ed
  • Vorgänger 8fba112b
  • Nachfolger 62add698

SL/Helper/Csv.pm: header_acc umbenannt in dispatch, Doku, check_header

Unterschiede anzeigen:

SL/Helper/Csv.pm
use Text::CSV;
use Params::Validate qw(:all);
use Rose::Object::MakeMethods::Generic scalar => [ qw(
file encoding sep_char quote_char escape_char header header_acc class
file encoding sep_char quote_char escape_char header dispatch class
numberformat dateformat _io _csv _objects _parsed _data _errors
) ];
......
quote_char => { default => '"' },
escape_char => { default => '"' },
header => { type => ARRAYREF, optional => 1 },
header_acc => { type => HASHREF, optional => 1 },
dispatch => { type => HASHREF, optional => 1 },
file => 1,
encoding => 0,
class => 0,
......
@{ $_[0]->_errors }
}
sub check_header {
$_[0]->_check_header;
}
# private stuff
sub _open_file {
......
$self->header($header);
}
sub _check_header_for_class {
my ($self, %params) = @_;
my @errors;
return unless $self->class;
return $self->header;
for my $method (@{ $self->header }) {
next if $self->class->can($self->_real_method($method));
push @errors, [
$method,
undef,
"header field $method is not recognized",
undef,
0,
];
}
$self->_push_error(@errors);
return ! @errors;
}
sub _parse_data {
my ($self, %params) = @_;
my (@data, @errors);
......
}
$self->_data(\@data);
$self->_errors(\@errors);
$self->_push_error(@errors);
return if @errors;
return \@data;
return ! @errors;
}
sub _encode_layer {
......
for my $line (@{ $self->_data }) {
push @objs, $self->class->new(
map {
($self->header_acc && $self->header_acc->{$_}) || $_ => $line->{$_}
$self->_real_method($_) => $line->{$_}
} grep { $_ } keys %$line
);
}
......
$self->_objects(\@objs);
}
sub _real_method {
my ($self, $arg) = @_;
($self->dispatch && $self->dispatch->{$arg}) || $arg;
}
sub _guess_encoding {
# won't fix
'utf-8';
}
sub _push_error {
my ($self, @errors) = @_;
my @new_errors = ($self->errors, @errors);
$self->_errors(\@new_errors);
}
1;
......
sep_char => ',', # default ';'
quote_char => ''', # default '"'
header => [qw(id text sellprice word)] # see later
header_acc => { sellprice => 'sellprice_as_number' }
dispatch => { sellprice => 'sellprice_as_number' }
class => 'SL::DB::CsvLine', # if present, map lines to this
)
......
most cases you will want those line to be parsed into hashes or even objects,
so this model just skips ahead and gives you objects.
Encoding autodetection is not easy, and should not be trusted. Try to avoid it if possible.
Encoding autodetection is not easy, and should not be trusted. Try to avoid it
if possible.
=head1 METHODS
......
=item C<encoding>
Encoding of the CSV file. Note that this module does not do any encoding guessing.
Know what your data ist. Defaults to utf-8.
Encoding of the CSV file. Note that this module does not do any encoding
guessing. Know what your data ist. Defaults to utf-8.
=item C<sep_char>
......
=item C<header> \@FIELDS
can be an array of columns, in this case the first line is not used as a
Can be an array of columns, in this case the first line is not used as a
header. Empty header fields will be ignored in objects.
=item C<header_acc> \%ACCESSORS
=item C<dispatch> \%ACCESSORS
May be used to map header fields to custom accessors. Example:
......
[
offending raw input,
Text::CSV error code if present,
Text::CSV error diagnostics if present,
Text::CSV error code if T:C error, 0 else,
error diagnostics,
position in line,
estimated line in file,
]
......
Encoding errors are not dealt with properly.
=item *
Errors are not gathered.
=back
=head1 TODO
Dispatch to child objects, like this:
$csv = SL::Helper::Csv->new(
file => ...
class => SL::DB::Part,
dispatch => [
makemodel => {
make_1 => make,
model_1 => model,
},
makemodel => {
make_2 => make,
model_2 => model,
},
]
);
=head1 AUTHOR
Sven Schöling E<lt>s.schoeling@linet-services.deE<gt>
t/helper/csv.t
$csv = SL::Helper::Csv->new(
file => \"Kaffee;0.12;12,2;1,5234\n",
header => [ 'description', 'sellprice', 'lastcost_as_number', 'listprice' ],
header_acc => { listprice => 'listprice_as_number' },
dispatch => { listprice => 'listprice_as_number' },
class => 'SL::DB::Part',
);
$csv->parse;
is $csv->get_objects->[0]->sellprice, 0.12, 'numeric attr works';
is $csv->get_objects->[0]->lastcost, 12.2, 'attr helper works';
is $csv->get_objects->[0]->listprice, 1.5234, 'header_acc works';
is $csv->get_objects->[0]->listprice, 1.5234, 'dispatch works';
#####
......
EOL
sep_char => ',',
quote_char => "'",
header_acc => { listprice => 'listprice_as_number' },
dispatch => { listprice => 'listprice_as_number' },
class => 'SL::DB::Part',
);
$csv->parse;

Auch abrufbar als: Unified diff