0

我在生产中使用 MySQL 数据库,并在运行测试时使用 SQLite 数据库。我的应用程序的一部分用于收集一年的每月统计数据。我已经成功地做到了这一点,但是它的代价是无法自动化测试,因为我在查询数据时使用了 MySQL 特定的函数:

my $criteria = {
    status => ['Complete'],
    'YEAR(completed_on)' => DateTime->now()->year(),
};

my $attributes = {
    select => [ { count => 'title' }, 'completed_on' ],
    as => [qw/num_completed datetime/],
    group_by => [qw/MONTH(completed_on)/],
};

注意我正在使用YEARMONTHMySQL 函数。

我知道一种方法可以替换 where 子句来消除 MySQLYEAR函数的使用,如下所示:

my $dtf = $schema->storage->datetime_parser;
my $begin_date = DateTime->from_day_of_year( year => DateTime->now()->year(), day_of_year => 1 ); #inception o_O
my $end_date = DateTime->from_day_of_year( year => DateTime->now()->year(), day_of_year => 36[56] );

my $criteria = {
    status => ['Complete'],
    completed_on =>
    -between => [
        $dtf->format_datetime($begin_date),
        $dtf->format_datetime($end_date),
    ]
};

使用推荐的方式使用 DBIC 查询日期字段

但是我对如何处理该group_by子句以及如何使这个字段日期值按月数据库不可知的分组感到困惑。想知道是否有人有任何想法?

谢谢!

4

1 回答 1

1

有时,如果您尝试做一些特殊的事情,您将不得不在 DBIx::Class 中编写特定于引擎的代码。你可以$schema->storage->sqlt_type用来制作不同的SQL。

请注意,您还可以使用substr(completed_on,1,4)在 SQLite 中获取年份。

这将解决您的问题:

my $type = $schema->storage->sqlt_type;

my $criteria;
my $attributes;

if ($type eq 'MySQL') {
    $criteria = {
        status => ['Complete'],
        'YEAR(completed_on)' => DateTime->now()->year(),
    };

    $attributes = {
        select => [ { count => 'title' }, 'completed_on' ],
        as => [qw/num_completed datetime/],
        group_by => [qw/MONTH(completed_on)/],
    };
}
elsif ($type eq 'SQLite') {
    my $dtf = $schema->storage->datetime_parser;
    my $begin_date = DateTime->from_day_of_year( year => DateTime->now()->year(), day_of_year => 1 ); #inception o_O
    my $end_date = DateTime->from_day_of_year( year => DateTime->now()->year() + 1, day_of_year => 1 )->add( seconds => -1 );

    $criteria = {
        status => ['Complete'],
        completed_on => {
            -between => [
                $dtf->format_datetime($begin_date),
                $dtf->format_datetime($end_date),
            ]
        }
    };

    $attributes = {
        select => [ { count => 'title' }, 'completed_on' ],
        as => [qw/num_completed datetime/],
        group_by => ['substr(completed_on,6,2)'],
    };
}
于 2016-03-01T09:43:24.993 回答