SL::Helper::Csv: neues flag "strict_profile". Wenn gesetzt werden nur Daten aus dem...
authorSven Schöling <s.schoeling@linet-services.de>
Wed, 2 Mar 2011 13:19:07 +0000 (14:19 +0100)
committerMoritz Bunkus <m.bunkus@linet-services.de>
Thu, 16 Jun 2011 06:44:08 +0000 (08:44 +0200)
SL/Helper/Csv.pm
SL/Helper/Csv/Dispatcher.pm
t/helper/csv.t

index 945758f..1b8a4b7 100644 (file)
@@ -9,8 +9,8 @@ use Params::Validate qw(:all);
 use Text::CSV;
 use Rose::Object::MakeMethods::Generic scalar => [ qw(
   file encoding sep_char quote_char escape_char header profile class
 use Text::CSV;
 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;
 ) ];
 
 use SL::Helper::Csv::Dispatcher;
@@ -32,6 +32,7 @@ sub new {
     numberformat           => 0,
     dateformat             => 0,
     ignore_unknown_columns => 0,
     numberformat           => 0,
     dateformat             => 0,
     ignore_unknown_columns => 0,
+    strict_profile         => 0,
   });
   my $self = bless {}, $class;
 
   });
   my $self = bless {}, $class;
 
@@ -342,6 +343,11 @@ and the return value used instead of the line itself.
 If set, the import will ignore unkown header columns. Useful for lazy imports,
 but deactivated by default.
 
 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
 =back
 
 =head1 ERROR HANDLING
index cbcae0d..6375daf 100644 (file)
@@ -71,7 +71,15 @@ sub parse_profile {
 
   for my $col (@$header) {
     next unless $col;
 
   for my $col (@$header) {
     next unless $col;
-    push @specs, $self->make_spec($col, $profile->{$col} || $col);
+    if ($self->_csv->strict_profile) {
+      if (exists $profile->{$col}) {
+        push @specs, $self->make_spec($col, $profile->{$col});
+      } else {
+        $self->unknown_column($col, undef);
+      }
+    } else {
+      push @specs, $self->make_spec($col, $profile->{$col} || $col);
+    }
   }
 
   $self->_specs(\@specs);
   }
 
   $self->_specs(\@specs);
index cc00994..e54dcb6 100644 (file)
@@ -1,4 +1,4 @@
-use Test::More tests => 31;
+use Test::More tests => 36;
 use SL::Dispatcher;
 use Data::Dumper;
 use utf8;
 use SL::Dispatcher;
 use Data::Dumper;
 use utf8;
@@ -225,4 +225,44 @@ is $csv->parse, undef, 'wrong profile gets rejected';
 is_deeply $csv->errors, [ 'buchungsgruppen.1.description', undef, "Profile path error. Indexed relationship is not OneToMany around here: 'buchungsgruppen.1'", undef ,0 ], 'error indicates wrong header';
 isa_ok( ($csv->errors)[0], 'SL::Helper::Csv::Error', 'Errors get objectified');
 
 is_deeply $csv->errors, [ 'buchungsgruppen.1.description', undef, "Profile path error. Indexed relationship is not OneToMany around here: 'buchungsgruppen.1'", undef ,0 ], 'error indicates wrong header';
 isa_ok( ($csv->errors)[0], 'SL::Helper::Csv::Error', 'Errors get objectified');
 
+####
+
+$csv = SL::Helper::Csv->new(
+  file   => \<<EOL,
+description;partnumber;sellprice;lastcost;wiener;
+Kaffee;;0.12;1,221.52;ja wiener
+Beer;1123245;0.12;1.5234;nein kein wieder
+EOL
+  numberformat => '1,000.00',
+  ignore_unknown_columns => 1,
+  strict_profile => 1,
+  class  => 'SL::DB::Part',
+  profile => {
+    lastcost => 'lastcost_as_number',
+  }
+);
+$csv->parse;
+is $csv->get_objects->[0]->lastcost, '1221.52', 'strict_profile with ignore';
+is $csv->get_objects->[0]->sellprice, undef,  'strict profile with ignore 2';
+
+####
+
+$csv = SL::Helper::Csv->new(
+  file   => \<<EOL,
+description;partnumber;sellprice;lastcost;wiener;
+Kaffee;;0.12;1,221.52;ja wiener
+Beer;1123245;0.12;1.5234;nein kein wieder
+EOL
+  numberformat => '1,000.00',
+  strict_profile => 1,
+  class  => 'SL::DB::Part',
+  profile => {
+    lastcost => 'lastcost_as_number',
+  }
+);
+$csv->parse;
+
+is_deeply( ($csv->errors)[0], [ 'description', undef, 'header field \'description\' is not recognized', undef, 0 ], 'strict_profile without ignore_columns throws error');
+
+
 # vim: ft=perl
 # vim: ft=perl