2

我正在开发一个DBIx::Class用于访问 MySQL 数据库的 Catalyst 应用程序。该应用程序对文件执行数据质量检查。这些文件被加载到一个表中FileContent

 FILE_ID LINE_NUMBER FOO BAR BAZ
 -----------------------------------
 1       1           A   99  Blah
 1       2           B   11  Blargh
 1       3           A   4   Sproing
 1       4           B   7   Sproing
 1       5           B   10  Doink

然后我有另一个表 ,Format它定义了每一列的验证操作:

 COL_ORDER COL_NAME VALIDATION
 1         FOO      regex:/^[AB]$/
 2         BAR      unique_number
 3         BAZ      regex:/\S/

我想要做的是FileContent逐行遍历给定文件,将所有规则Format应用于每一行:

my @lines  = $c->model('DB::FileContent')->search({file_id => 1});
my @format = $c->model('DB::Format')->search();

foreach my $line (@lines)
{
    foreach my $column (@format)
    {
        #Get the field matching this column from $line.
        #e.g. for first $column get $line->foo()  
    }
}

但是,我不确定如何最好地从与格式中的当前列匹配的行中有效地获取列。访问列的正常方式是通过方法,例如$line->foo. foo但是当是变量时我该怎么办?

我不认为我想这样做:

eval "$line->${$column->col_name}";

我知道 get_column,但这对于从一行中获取单个值是否有效?

$line->get_column($column->col_name)

根据另一个表中的值检索列的最有效方法是什么?我可以使用列名或列位置。在此先感谢您的帮助。

4

1 回答 1

2

尝试首先将所有验证规则放入 hashref(或哈希)中,并且 - 最重要的是 - 确保 FileContent 项通过DBIx::Class::ResultClass::HashRefInflator膨胀到 hashrefs 中。这使得在您循环浏览项目时访问项目中的字段更加方便。

像这样:

#------------------------------------------------------------------------------------------
# get all formats into a hashref
#------------------------------------------------------------------------------------------

my $format = $c->model('DB::Format')->search({}, { order_by => ['COL_ORDER'] } );
my @col_names = $format->get_column('COL_NAME')->all;
# @col_names now contains qw/FOO BAR BAZ/

my $formats;
@{$formats}{@col_names} = $format->get_column('VALIDATION')->all;

#------------------------------------------------------------------------------------------
# create an iterator over DB::FileContent, and make items inflate to hashrefs 
#------------------------------------------------------------------------------------------

my $file_content  = $c->model('DB::FileContent')->search({file_id => 1});
$file_content->result_class('DBIx::Class::ResultClass::HashRefInflator');
# this ensures that every item inflates into a hashref


# this way you can iterate over items, and don't have to put them all into an array 
while (my $hashref = $file_content->next) {
    # put relevant field values into an array
    my @values = @{$hashref}{@col_names};
}
于 2013-03-18T19:09:16.830 回答