DBD :: CSV:如何使用两个f_ext-options“.csv”和“.csv / r”生成不同的行为?

时间:2010-05-10 14:18:04

标签: perl csv dbi

这是来自DBD :: File-documentation:

  

f_ext

     

此属性用于设置打开(CSV)文件的文件扩展名。有几种可能性。

    DBI:CSV:f_dir=data;f_ext=.csv  
  

在这种情况下,如果table.csv和table都存在于datadir中,则DBD :: File将仅打开table.csv。该表仍将命名为表。如果您的datadir具有带扩展名的文件,并且您没有传递此属性,那么您的表名为table.csv,这可能不是您想要的。扩展始终不区分大小写。表名不是。

    DBI:CSV:f_dir=data;f_ext=.csv/r
  

在这种情况下,扩展名是必需的,并且忽略所有不匹配的文件名。

我不可能使用两个选项“.csv / r”和“.csv”生成不同的行为。有人能告诉我一个例子,我可以看到“.csv / r”和“.csv”之间的区别吗?

3 个答案:

答案 0 :(得分:1)

我似乎无法做任何不同的事情。相关的代码部分是

sub file2table
{
    my ($data, $dir, $file, $file_is_tab, $quoted) = @_;

    $file eq "." || $file eq ".."       and return;

    my ($ext, $req) = ("", 0);
    if ($data->{f_ext}) {
        ($ext, my $opt) = split m/\//, $data->{f_ext};
        if ($ext && $opt) {
            $opt =~ m/r/i and $req = 1;
            }
        }

    (my $tbl = $file) =~ s/$ext$//i;
    $file_is_tab and $file = "$tbl$ext";

    # Fully Qualified File Name
    my $fqfn;
    unless ($quoted) { # table names are case insensitive in SQL
        opendir my $dh, $dir or croak "Can't open '$dir': $!";
        my @f = grep { lc $_ eq lc $file } readdir $dh;
        @f == 1 and $file = $f[0];
        closedir $dh or croak "Can't close '$dir': $!";
        }
    $fqfn = File::Spec->catfile ($dir, $file);

    $file = $fqfn;
    if ($ext) {
        if ($req) {
            # File extension required
            $file =~ s/$ext$//i                 or  return;
            }
        else {
            # File extension optional, skip if file with extension exists
            grep m/$ext$/i, glob "$fqfn.*"      and return;
            $file =~ s/$ext$//i;
            }
        }

    $data->{f_map}{$tbl} = $fqfn;
    return $tbl;
    } # file2table

答案 1 :(得分:1)

这是否证明了差异?:

sandbox % echo "a,b,c" > foo
sandbox % echo "a,b,c" > foo.csv
sandbox % echo "a,b,c" > bar
sandbox % echo "a,b,c" > baz.csv
sandbox % perl -MDBI -wle'print for DBI->connect("dbi:CSV:f_ext=.csv")->tables'
"merijn".baz
"merijn".bar
"merijn".foo
sandbox % perl -MDBI -wle'print for DBI->connect("dbi:CSV:f_ext=.csv/r")->tables'
"merijn".baz
"merijn".foo
sandbox %

f_ext=.csv仅使.csv成为首选项,但也不是要求:在第一种情况下,仍然使用没有.csv扩展名的文件“bar”,但是“foo.csv”是选择超过“foo”。使用f_ext=.csv/r"时,“bar”将被忽略,因为它没有“.csv”扩展名。

答案 2 :(得分:0)

现在在DBD :: File的0.39版本中,这部分看起来像这样:

sub file2table
{
    my ($self, $meta, $file, $file_is_table, $respect_case) = @_;

    $file eq "." || $file eq ".."   and return; # XXX would break a possible DBD::Dir

    my ($ext, $req) = ("", 0);
    if ($meta->{f_ext}) {
    ($ext, my $opt) = split m/\//, $meta->{f_ext};
    if ($ext && $opt) {
        $opt =~ m/r/i and $req = 1;
        }
    }

    # (my $tbl = $file) =~ s/$ext$//i;
    my ($tbl, $dir, $user_spec_file);
    if ($file_is_table and defined $meta->{f_file}) {
    $tbl = $file;
    ($file, $dir, undef) = File::Basename::fileparse ($meta->{f_file});
    $user_spec_file = 1;
    }
    else {
    ($tbl, $dir, undef) = File::Basename::fileparse ($file, $ext);
    $user_spec_file = 0;
    }

    -d File::Spec->catdir ($meta->{f_dir}, $dir) or
    croak (File::Spec->catdir ($meta->{f_dir}, $dir) . ": $!");

    !$respect_case and $meta->{sql_identifier_case} == 1 and # XXX SQL_IC_UPPER
        $tbl = uc $tbl;
    !$respect_case and $meta->{sql_identifier_case} == 2 and # XXX SQL_IC_LOWER
        $tbl = lc $tbl;
    my $searchdir = File::Spec->file_name_is_absolute ($dir)
    ? $dir
    : Cwd::abs_path (File::Spec->catdir ($meta->{f_dir}, $dir));
    $searchdir eq $meta->{f_dir} and
    $dir = "";

    unless ($user_spec_file) {
    $file_is_table and $file = "$tbl$ext";

    # Fully Qualified File Name
    my $cmpsub;
    if ($respect_case) {
        $cmpsub = sub {
        my ($fn, undef, $sfx) = File::Basename::fileparse ($_, qr/\.[^.]*/);
        $fn eq $tbl and
            return (lc $sfx eq lc $ext or !$req && !$sfx);
        return 0;
        }
        }
    else {
        $cmpsub = sub {
        my ($fn, undef, $sfx) = File::Basename::fileparse ($_, qr/\.[^.]*/);
        lc $fn eq lc $tbl and
            return (lc $sfx eq lc $ext or !$req && !$sfx);
        return 0;
        }
        }

    opendir my $dh, $searchdir or croak "Can't open '$searchdir': $!";
    my @f = sort { length $b <=> length $a } grep { &$cmpsub ($_) } readdir $dh;
    @f > 0 && @f <= 2 and $file = $f[0];
    !$respect_case && $meta->{sql_identifier_case} == 4 and # XXX SQL_IC_MIXED
        ($tbl = $file) =~ s/$ext$//i;
    closedir $dh or croak "Can't close '$searchdir': $!";

    #(my $tdir = $dir) =~ s{^\./}{};    # XXX We do not want all tables to start with ./
    #$tdir and $tbl = File::Spec->catfile ($tdir, $tbl);
    $dir and $tbl = File::Spec->catfile ($dir, $tbl);

    my $tmpfn = $file;
    if ($ext) {
        if ($req) {
        # File extension required
    $tmpfn =~ s/$ext$//i            or  return;
        }
#       else {
#       # File extension optional, skip if file with extension exists
#       grep m/$ext$/i, glob "$fqfn.*"  and return;
#       $tmpfn =~ s/$ext$//i;
#       }
        }
    }

    my $fqfn = File::Spec->catfile ($searchdir, $file);
    my $fqbn = File::Spec->catfile ($searchdir, $tbl);

    $meta->{f_fqfn} = $fqfn;
    $meta->{f_fqbn} = $fqbn;
    !defined $meta->{f_lockfile} && $meta->{f_lockfile} and
    $meta->{f_fqln} = $meta->{f_fqbn} . $meta->{f_lockfile};

    $meta->{table_name} = $tbl;

    return $tbl;
    } # file2table

据我所知,这两个f_ext选项正在按预期工作。