― Web Technology and Life ―

【Amon2のオレオレTips】Test::mysqldを使ってTengのSchemaクラスをラクラク生成

2013-01-06
schema.sqlみたいなファイルにmysqlのテーブル定義を管理しているとして、その修正をした時にできるだけ楽にMyDB::SchemaみたいなTengのSchemaクラスを生成するというときのオレオレTipsです。

TengのSchemaクラスの生成について

このTipsはAmon2とは直接関係ないですが、Teng使う場合はきっとついてくる問題だと思ったのですし、Amon2とTengを一緒に使う人はたくさんいるでしょうと思ったりしたので、オレオレTipsとして入れ込みました。

で早速本題ですが、PerlのO/RマッパーのTengを使う場合は、Schemaクラスというのを用意しなくてはいけないんですが、その作り方としては主に3つあります。

自分でDSLをゴニョゴニョ書くのはしんどいけど、Loaderを使うとTengのオブジェクト生成に時間がかかりそうなので、ある程度しっかりしたところでは、真ん中のTeng::Schema::Dumperを使うのが無難な感じです。

ただ、Teng::Schema::Dumperは以下のように使うわけですが、

use DBI;
use Teng::Schema::Dumper;

my $dbh = DBI->connect(@dsn) or die;
print Teng::Schema::Dumper->dump(
    dbh       => $dbh,
    namespace => 'Mock::DB',
);

予め@dsnで渡している情報にホントにmysqlにテーブルが入ってないといけないんですが、Amon2の場合は、sql/mysql.sqlとかって感じにテーブルの定義をファイルに書いて管理する構成になっているので、一旦mysql.sqlに書き足した定義をTengのSchemaクラスに反映させるには、

  1. mysql.sqlに新しいテーブル加えたり、既存のテーブルの定義を変更したりする
  2. 開発用のmysqlに最新のテーブル定義を反映/最新のテーブル定義専用のdbを生成
  3. 先ほど反映/生成させたdb情報をもとに、Teng::Schema::DumperでSchemaクラスを生成

という流れになって、手でゴニョゴニョするとなんだか一手間めんどいと思っているんですが、みなさまはどうでしょうか?

で、長くなりましたが、2,3つを一気に行いたいなというのが今回のテーマです。

ラクラク生成コード

というわけで、早速そのコードはこんな感じなっております。

#!/usr/bin/env perl
use strict;
use warnings;
use utf8;
use Test::mysqld;
use DBI;
use Teng::Schema::Dumper;
use Path::Class qw/file/;

my $teng_schema_class = $ARGV[0] or die "you must input teng_schema_class";

my $mysql_schema_path = $ARGV[1] or die "you must input mysql schema path";

my $mysqld = Test::mysqld->new(
    my_cnf => {
        'skip-networking' => '', # no TCP socket
    }
) or die $Test::mysqld::errstr;

my $dbh = DBI->connect(
    $mysqld->dsn.';mysql_multi_statements=1',
) or die "can't create dbh";

$dbh->do('create database test_db');
my $sql = "use test_db;\n";
$sql   .= "set names utf8;\n";
$sql   .= file($mysql_schema_path)->slurp(iomode => '<:encoding(UTF-8)');
$dbh->do($sql);

my $schema = Teng::Schema::Dumper->dump(
    dbh       => $dbh,
    namespace => $teng_schema_class,
#    inflate   => $inflate_conf, #inlateを入れたい時はここにほげほげ
);

## なんか入れ込みたい時は、ここで強引に置換
#$schema =~ s!Teng\:\:Schema\:\:Declare\;!Teng\:\:Schema\:\:Declare\;\nuse Time::Piece\;!;

print $schema;

inflateとかしない場合は、これでたいていオッケーだと思いますし、inflateとかしたい場合でも、コメントアウトしたところをゴニョゴニョすればいいと思います。

perl ./script/helper/schema_dumper.pl MyApp::DB::Shema ./sql/mysql.sql > ./lib/MyApp/DB/Schema.pm

こんな感じで、プロジェクトの開発に必要なヘルパースクリプトとして管理して、こんな感じで変更があった時は、既存のクラスを上書きしちゃいます。

終わりに

そもそもですが、Dumperとか使っていないで、Loaderとか使っている人も多いんでしょうか?というか、Tengじゃなくて、○○という人もたくさんいそうですが。。。

今回のオレオレは、Test::mysqldとか使ってなんか強引ですが、、、とりあえず、Tengを使っている皆さまはどうされているでしょうか?何かツッコミあればどしどしお願いしますー。

ふう、ちょっと息切れモードですが、あと、3つほどですが、締切目標を来週中くらいに伸ばして残りのオレオレTipsも気軽にメモっておきますよー。

Perl update_at : 2013-01-07T00:22:36
hirobanex.netの更新情報の取得
 RSSリーダーで購読する   
blog comments powered by Disqus