Hatena::ブログ(Diary)

cooldaemonの備忘録 RSSフィード

2008-01-26

テスト用 DB の準備を行うモジュールを作った

Catalyst 本を参考に、やっつけで書いてみた。

Catalyst 本との違いは fixture に対応している点。

使い方(Test::WWW::Mechanize::Catalyst と連携等)や解説は、近いうちに書く。後で Helper にする。

package MyApp::Test::Database;

use strict;
use warnings;

use Directory::Scratch;
use MyApp::Schema;
use FindBin qw($Bin $Script);
use YAML::Syck;

use base 'Exporter';
our @EXPORT = qw(schema);

my $schema;
my $config;

BEGIN {
    my $tmp = Directory::Scratch->new;
    my $db  = $tmp->touch('database');
    my $dns = "DBI:SQLite:$db";

    $schema = MyApp::Schema->connect($dsn);
    $schema->deploy;

    $config = "$Bin/../conf/myapp_local.yml";
    DumpFile($config, {'Model::DBIC' => {connect_info => [$dsn]}});

    _load_fixture();

    sub _load_fixture {
        my $fixture_file = "$Bin/fixture/$Script";
        $fixture_file =~ s/\.t$/.yml/;
        return if ! -f $fixture_file;

        my $fixture_for = LoadFile($fixture_file);
        while (my ($model, $fixtures) = each %$fixture_for) {
            for (@$fixtures) {
                $schema->resultset($model)->create($_);
            }
        }
    }
}

END {
    unlink $config;
}

sub schema {
    $schema;
}

1;

便利な CPAN Modules があった

Jonathan Rockway 氏作 の DBICx::TestDatabase が良さ気。

SQLite を利用してテスト用の一時データベースを作ってくれる。

source を覗いたら $schema->deploy を実行していた。

私が書いた Module と異なり myapp_local.yml を生成してくれないので、直接 Controller を叩くテストには使えない。

これに tokuhirom 氏作の Test::Fixture::DBIC::Schema を組み合わせて、テスト用の Module を書いてみよう。(後でこのエントリに追記する)

2007-05-04

inflate_column

ブログが続かないわけ | DBIC で+select と+as : ああ、今頃気づくなんて...

でも、どうにも不便だと思ってDBIx::Class::ResultsetのPODを読んでいると、+select と+as なるものがあるじゃないですか。これだと、まさに先ほど直感的に書いたような方法で書けるのです。

$c->model('DBIC::TranDiary')->search(
    $query_ref,
    {
        '+select' => [
            { date_format => 'me.create_date,\'%Y/%m/%d\'' },
        ],
        '+as' => [
            qw/create_date/
        ]
    }
);

これって常識なんだろな。だってPODに書いてあるんだもん。

ちょっとへこみました。

+select と +as なんて、あるんだなー便利だなーと思いつつ、それは、inflate_column を使った方が良いんじゃないかと思いました。

上記の例であれば、xxxxx::Model::DBIC::TranDiary に下記を追加。

__PACKAGE__->inflate_column(
  'create_date',
  {
    inflate => sub { DateTime::Format::xxx->parse_datetime(shift);  },
    deflate => sub { DateTime::Format::xxx->format_datetime(shift); },
  }
);

DateTime::Format::xxx の、xxx の箇所は、Pg、MySQLOracleDB2 等が CPAN にあるので、環境にあわせて選択。

search メソッドだけでなく、create メソッドでも使えるので、こちらの方が便利かと。

参考URI

Perl/DBIC - Nekokak’s core dump

2006-12-26

Migration

rails の「rake db:migrate」と似たような事を、Catalyst でもできないか?と思い、いろいろ調べてみた。

http://search.cpan.org/~bricas/DBIx-Class-0.07003/lib/DBIx/Class/Manual/Cookbook.pod#Easy_migration_from_class-based_to_schema-based_setup

http://search.cpan.org/~bricas/DBIx-Class-0.07003/lib/DBIx/Class/Manual/Cookbook.pod#Schema_versioning

SQL::Translator を使うのか・・・なるほど。

今は時間がないので、後で使い方をまとめよう。