Revision a54fc392
Von Sven Schöling vor etwa 12 Jahren hinzugefügt
SL/Helper/Csv.pm | ||
---|---|---|
10 | 10 |
use Rose::Object::MakeMethods::Generic scalar => [ qw( |
11 | 11 |
file encoding sep_char quote_char escape_char header profile class |
12 | 12 |
numberformat dateformat ignore_unknown_columns strict_profile _io _csv |
13 |
_objects _parsed _data _errors |
|
13 |
_objects _parsed _data _errors all_cvar_configs case_insensitive_header
|
|
14 | 14 |
) ]; |
15 | 15 |
|
16 | 16 |
use SL::Helper::Csv::Dispatcher; |
... | ... | |
33 | 33 |
dateformat => 0, |
34 | 34 |
ignore_unknown_columns => 0, |
35 | 35 |
strict_profile => 0, |
36 |
case_insensitive_header => 0, |
|
36 | 37 |
}); |
37 | 38 |
my $self = bless {}, $class; |
38 | 39 |
|
... | ... | |
120 | 121 |
} |
121 | 122 |
|
122 | 123 |
return unless $header; |
123 |
return $self->header([ map { lc } @$header ]); |
|
124 |
|
|
125 |
# Special case: human stupidity |
|
126 |
# people insist that case sensitivity doesn't exist and try to enter all |
|
127 |
# sorts of stuff. at this point we've got a profile (with keys that represent |
|
128 |
# valid methods), and a header full of strings. if two of them match, the user |
|
129 |
# mopst likely meant that field, so rewrite the header |
|
130 |
if ($self->case_insensitive_header) { |
|
131 |
die 'case_insensitive_header is only possible with profile' unless $self->profile; |
|
132 |
my @names = ( |
|
133 |
keys %{ $self->profile || {} }, |
|
134 |
); |
|
135 |
for my $name (@names) { |
|
136 |
for my $i (0..$#$header) { |
|
137 |
$header->[$i] = $name if lc $header->[$i] eq lc $name; |
|
138 |
} |
|
139 |
} |
|
140 |
} |
|
141 |
|
|
142 |
return $self->header($header); |
|
124 | 143 |
} |
125 | 144 |
|
126 | 145 |
sub _parse_data { |
... | ... | |
345 | 364 |
will have to do that for yourself. Since you provided the profile, it is |
346 | 365 |
assumed you know what to do in this case. |
347 | 366 |
|
367 |
If no profile is given, any header field found will be taken as is. |
|
368 |
|
|
369 |
If the path in a profile entry is empty, the field will be subjected to |
|
370 |
C<strict_profile> and C<case_insensitive_header> checking, will be parsed into |
|
371 |
C<get_data>, but will not be attempted to be dispatched into objects. |
|
372 |
|
|
348 | 373 |
=item C<class> |
349 | 374 |
|
350 | 375 |
If present, the line will be handed to the new sub of this class, |
... | ... | |
355 | 380 |
If set, the import will ignore unkown header columns. Useful for lazy imports, |
356 | 381 |
but deactivated by default. |
357 | 382 |
|
383 |
=item C<case_insensitive_header> |
|
384 |
|
|
385 |
If set, header columns will be matched against profile entries case |
|
386 |
insensitive, and on match the profile name will be taken. |
|
387 |
|
|
388 |
Only works if a profile is given, will die otherwise. |
|
389 |
|
|
390 |
If both C<case_insensitive_header> and C<strict_profile> is set, matched header |
|
391 |
columns will be accepted. |
|
392 |
|
|
358 | 393 |
=item C<strict_profile> |
359 | 394 |
|
360 | 395 |
If set, all columns to be parsed must be specified in C<profile>. Every header |
361 | 396 |
field not listed there will be treated like an unknown column. |
362 | 397 |
|
398 |
If both C<case_insensitive_header> and C<strict_profile> is set, matched header |
|
399 |
columns will be accepted. |
|
400 |
|
|
363 | 401 |
=back |
364 | 402 |
|
365 | 403 |
=head1 ERROR HANDLING |
SL/Helper/Csv/Dispatcher.pm | ||
---|---|---|
78 | 78 |
$self->unknown_column($col, undef); |
79 | 79 |
} |
80 | 80 |
} else { |
81 |
push @specs, $self->make_spec($col, $profile->{$col} || $col); |
|
81 |
if (exists $profile->{$col}) { |
|
82 |
push @specs, $self->make_spec($col, $profile->{$col}); |
|
83 |
} else { |
|
84 |
push @specs, $self->make_spec($col, $col); |
|
85 |
} |
|
82 | 86 |
} |
83 | 87 |
} |
84 | 88 |
|
... | ... | |
91 | 95 |
my ($self, $col, $path) = @_; |
92 | 96 |
|
93 | 97 |
my $spec = { key => $col, steps => [] }; |
98 |
|
|
99 |
return unless $path; |
|
100 |
|
|
94 | 101 |
my $cur_class = $self->_csv->class; |
95 | 102 |
|
96 | 103 |
return unless $cur_class; |
t/helper/csv.t | ||
---|---|---|
1 |
use Test::More tests => 41;
|
|
1 |
use Test::More tests => 47;
|
|
2 | 2 |
|
3 | 3 |
use lib 't'; |
4 |
use utf8; |
|
4 | 5 |
|
5 | 6 |
use Data::Dumper; |
6 |
use utf8;
|
|
7 |
use Support::TestSetup;
|
|
7 | 8 |
|
8 |
use_ok 'Support::TestSetup'; |
|
9 | 9 |
use_ok 'SL::Helper::Csv'; |
10 | 10 |
|
11 | 11 |
Support::TestSetup::login(); |
... | ... | |
278 | 278 |
$csv = SL::Helper::Csv->new( |
279 | 279 |
file => \"Description\nKaffee", |
280 | 280 |
class => 'SL::DB::Part', |
281 |
case_insensitive_header => 1, |
|
282 |
profile => { description => 'description' }, |
|
281 | 283 |
); |
282 | 284 |
$csv->parse; |
283 | 285 |
is_deeply $csv->get_data, [ { description => 'Kaffee' } ], 'case insensitive header from csv works'; |
... | ... | |
285 | 287 |
##### |
286 | 288 |
|
287 | 289 |
$csv = SL::Helper::Csv->new( |
288 |
file => \"Kaffee", |
|
289 |
header => [ 'Description' ], |
|
290 |
class => 'SL::DB::Part', |
|
290 |
file => \"Kaffee", |
|
291 |
header => [ 'Description' ], |
|
292 |
class => 'SL::DB::Part', |
|
293 |
case_insensitive_header => 1, |
|
294 |
profile => { description => 'description' }, |
|
291 | 295 |
); |
292 | 296 |
$csv->parse; |
293 | 297 |
is_deeply $csv->get_data, [ { description => 'Kaffee' } ], 'case insensitive header as param works'; |
... | ... | |
302 | 306 |
$csv->parse; |
303 | 307 |
is_deeply $csv->get_data, [ { description => 'Kaffee' } ], 'utf8 BOM works (bug 1872)'; |
304 | 308 |
|
309 |
##### |
|
310 |
|
|
311 |
$csv = SL::Helper::Csv->new( |
|
312 |
file => \"Kaffee", |
|
313 |
header => [ 'Description' ], |
|
314 |
class => 'SL::DB::Part', |
|
315 |
); |
|
316 |
$csv->parse; |
|
317 |
is_deeply $csv->get_data, undef, 'case insensitive header without flag ignores'; |
|
318 |
|
|
319 |
##### |
|
320 |
|
|
321 |
$csv = SL::Helper::Csv->new( |
|
322 |
file => \"Kaffee", |
|
323 |
header => [ 'foo' ], |
|
324 |
class => 'SL::DB::Part', |
|
325 |
profile => { foo => '' }, |
|
326 |
); |
|
327 |
$csv->parse; |
|
328 |
|
|
329 |
is_deeply $csv->get_data, [ { foo => 'Kaffee' } ], 'empty path still gets parsed into data'; |
|
330 |
ok $csv->get_objects->[0], 'empty path gets ignored in object creation'; |
|
331 |
|
|
332 |
##### |
|
333 |
|
|
334 |
$csv = SL::Helper::Csv->new( |
|
335 |
file => \"Kaffee", |
|
336 |
header => [ 'foo' ], |
|
337 |
class => 'SL::DB::Part', |
|
338 |
strict_profile => 1, |
|
339 |
profile => { foo => '' }, |
|
340 |
); |
|
341 |
$csv->parse; |
|
342 |
|
|
343 |
is_deeply $csv->get_data, [ { foo => 'Kaffee' } ], 'empty path still gets parsed into data (strict profile)'; |
|
344 |
ok $csv->get_objects->[0], 'empty path gets ignored in object creation (strict profile)'; |
|
345 |
|
|
346 |
$csv = SL::Helper::Csv->new( |
|
347 |
file => \"Phil", |
|
348 |
header => [ 'CVAR_grOUnDHog' ], |
|
349 |
class => 'SL::DB::Part', |
|
350 |
strict_profile => 1, |
|
351 |
case_insensitive_header => 1, |
|
352 |
profile => { cvar_Groundhog => '' }, |
|
353 |
); |
|
354 |
$csv->parse; |
|
355 |
|
|
356 |
is_deeply $csv->get_data, [ { cvar_Groundhog => 'Phil' } ], 'using empty path to get cvars working'; |
|
357 |
ok $csv->get_objects->[0], '...and not destorying the objects'; |
|
358 |
|
|
305 | 359 |
# vim: ft=perl |
Auch abrufbar als: Unified diff
Helper::Csv: Support für leere profile.path Angaben und case_insensitive_header