【问题标题】:DBD::CSV: How can I generate different behavior with the two f_ext-options ".csv" and ".csv/r"?DBD::CSV:如何使用两个 f_ext 选项“.csv”和“.csv/r”生成不同的行为?
【发布时间】:2011-02-17 16:47:03
【问题描述】:

这来自 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”之间的区别吗?

【问题讨论】:

    标签: perl csv dbi


    【解决方案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
    

    【讨论】:

    • 如果“my @f = grep { lc $_ eq lc $file } readdir $dh;”-grep 找不到文件,是否应该有“返回”?
    【解决方案2】:

    这是否表明了区别?:

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

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

    【讨论】:

      【解决方案3】:

      现在在 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-options 都按预期工作。

      【讨论】:

        猜你喜欢
        • 2011-02-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-21
        相关资源
        最近更新 更多