CSVから配列を作るサブロジックと、配列からハッシュを作るサブロジック。
最終的にハッシュからDBにinsertするものを作りたかったけど、そこはDBIx::Classにお任せすることにした。
一応インサート文を組み立てるサブロジックも作ったけど、使うのはちょっとどうかと思う作り。手元のソースからはあとで消そう。
そうなるとモジュール名も変えなきゃ。
Csv2Db.pm
#!/usr/bin/perl -Ilib
package Csv2Db;
use strict;
use warnings;
use IO::File;
use Text::CSV_XS;
sub csv2array {
shift;
my $file = shift;
my $csv_reader = new Text::CSV_XS( { binary => 1 } );
my @_line = ();
my @csv_lines = ();
while (<$file>) {
#CSV_XSを利用し、カラムを分解する
$csv_reader->parse($_)
|| die "error: " . $csv_reader->error_input() . "\n";
@_line = $csv_reader->fields();
push( @csv_lines, [@_line] );
}
return @csv_lines;
}
sub array2hash {
shift;
my ( $schema, $csvlist ) = @_;
_check_hash_refference($schema);
_check_array_refference($csvlist);
my %hash = ();
foreach my $key ( keys %$schema ) {
$hash{$key} = @$csvlist[ $schema->{$key} ];
}
return %hash;
}
sub createInsertSql {
shift;
my ( $table, $valueHash ) = @_;
_check_hash_refference($valueHash);
my $fields = '';
my $sql = "INSERT $table SET ";
foreach my $key ( sort keys %$valueHash ) {
$fields = $fields . "$key='$valueHash->{$key}', ";
}
$fields = substr( $fields, 0, -2 );
$sql = $sql . $fields . ";";
return $sql;
}
sub _check_hash_refference {
my $hash = shift;
die 'Undefined Hash..' unless defined $hash;
die 'Not a HASH refernce..' unless ref $hash eq 'HASH';
die 'Empty Hash..' unless keys(%$hash) > 0;
}
sub _check_array_refference {
my $array = shift;
die 'Undefined Array..' unless defined $array;
die 'Not a ARRAY refernce..' unless ref $array eq 'ARRAY';
die 'Empty Array..' unless $#$array > -1;
}
1;
ここからテストコード。
01_csv2db_csv2array.t
use strict;
use warnings;
use Test::More;
use File::Temp qw( tempfile );
use Csv2Db::Csv2Db;
plan( tests => 2 );
#test1
{
my ( $tmp, $filename ) = tempfile();
print {$tmp} "0,k,hiro,m\n1,k,mai,f";
close($tmp);
my @result_arr
= ( [ ( '0', 'k', 'hiro', 'm' ) ], [ ( '1', 'k', 'mai', 'f' ) ] );
open( $tmp, "<", $filename );
my @res = Csv2Db->csv2array($tmp);
ok( eq_array( \@res, \@result_arr ), 'normal pattern' );
close($tmp);
}
#test2
{
my ( $tmp, $filename ) = tempfile();
close($tmp);
open( $tmp, "<", $filename );
my @res = Csv2Db->csv2array($tmp);
ok( eq_array( \@res, [ () ] ), 'empty file' );
close($tmp);
}
02_csv2db_array2hash.t
use strict;
use warnings;
use Test::More;
use Csv2Db::Csv2Db;
plan( tests => 7 );
#normal
{
my %schema = ( 'id' => 0, 'fname' => 2 );
my @arr = ( '000', 'k', 'name' );
my %result = ( 'id' => '000', 'fname' => 'name' );
my %test = Csv2Db->array2hash( \%schema, \@arr );
ok( eq_hash( \%test, \%result ), 'normal case' );
}
#undef hash
{
my @arr = ( '000', 'k', 'name' );
my %result = ( 'id' => '000', 'fname' => 'name' );
eval { my %test = Csv2Db->array2hash( undef, \@arr ); };
like( $@, qr/Undefined/, 'undef schema' );
}
#empty hash
{
my %schema = ();
my @arr = ( '000', 'k', 'name' );
my %result = ( 'id' => '000', 'fname' => 'name' );
eval{my %test = Csv2Db->array2hash( \%schema, \@arr )};
like( $@, qr/Empty/, 'empty schema' );
}
#not hash
{
my @schema = ();
my @arr = ( '000', 'k', 'name' );
my %result = ( 'id' => '000', 'fname' => 'name' );
eval{my %test = Csv2Db->array2hash( \@schema, \@arr )};
like( $@, qr/HASH/, 'not a hash' );
}
#undef arr
{
my %schema = ( 'id' => 0, 'fname' => 2 );
my %result = ( 'id' => '000', 'fname' => 'name' );
eval { my %test = Csv2Db->array2hash( \%schema, undef ); };
like( $@, qr/Undefined/, 'undef array' );
}
#empty arr
{
my %schema = ( 'id' => 0, 'fname' => 2 );
my @arr = ();
my %result = ( 'id' => '000', 'fname' => 'name' );
eval{my %test = Csv2Db->array2hash( \%schema, \@arr )};
like( $@, qr/Empty/, 'empty array' );
}
#not hash
{
my %schema = ( 'id' => 0, 'fname' => 2 );
my $arr = 'not a array';
my %result = ( 'id' => '000', 'fname' => 'name' );
eval{my %test = Csv2Db->array2hash( \%schema, \$arr )};
like( $@, qr/ARRAY/, 'not a array' );
}
03_csv2db_createInsert.t
use strict;
use warnings;
use Test::More;
use Csv2Db::Csv2Db;
plan( tests => 1 );
#createInsertSql
my $table1 = 'main_table';
my %values1 = ( 'id' => "000", 'fname' => "hiro" );
my $sql1 = Csv2Db->createInsertSql( $table1, \%values1 );
is( $sql1, "INSERT main_table SET fname='hiro', id='000';" );
PODを一切書いていないので、書かなきゃですね。
とりあえず目標期間内にここまで作れたのでOKとしよう。
0 件のコメント:
コメントを投稿