本番MySQLと開発MySQLのテーブル+カラムが一致しているか確認する(Perl,MySQL)
2013年5月2日
デプロイ時に、テーブルとかカラムを追加したり変更したりした時のtest用に。
use strict;
use warnings;
use Test::More;
BEGIN{ use_ok('DBI') }
BEGIN{ use_ok('Test::Fixture::DBI') }
BEGIN{ use_ok('Test::mysqld') }
my $db = 'myapp';
# 本番のDB
sub dbh {
return DBI->connect( 'dbi:mysql:'. $db .':localhost','db_user','db_password', +{ 'AutoCommit' => 0, 'RaiseError' => 1 } );
}
# testのDB
sub test_dbh {
my $mysqld = shift;
return DBI->connect( $mysqld->dsn( dbname => 'test' ), 'root','', +{ AutoCommit => 0, RaiseError => 1, });
}
# testDBの作成
sub setup_test {
my $mysqld = Test::mysqld->new( +{ my_cnf => +{ "skip-networking" => undef } });
my $test_dbh = test_dbh( $mysqld );
my $schema = construct_database(
dbh => $test_dbh,
database => 'schema.yaml', # testDBで作成したschema(下記参照)
);
return $mysqld;
}
# 本番DB
my $dbh = dbh();
# testDB
my $mysqld = setup_test();
my $test_dbh = test_dbh($mysqld);
# testDBのテーブル一覧
my $test_tables = $test_dbh->prepare('SHOW TABLES');
$test_tables->execute;
for my $table ( @{ $test_tables->fetchall_arrayref(+{}) } ) {
# 本番DBの該当テーブルのカラム
my $column = $dbh->prepare('DESC '. $table->{'Tables_in_' . $db } );
$column->execute;
my $release = $column->fetchall_arrayref(+{});
# testDBの該当テーブルのカラム
my $test_column = $test_dbh->prepare('DESC '. $table->{'Tables_in_' . $db } );
$test_column->execute;
my $test = $test_column->fetchall_arrayref(+{});
my $i = 0;
for my $r ( @{ $release } ) {
ok( $r->{'Field'} eq $test->[$i]->{'Field'} , $table->{'Tables_in_' . $db } . ' Field');
if ( $r->{'Default'} ) {
if ( $test->[$i]->{'Default'} ) {
# 同じか確認
ok( $r->{'Default'} eq $test->[$i]->{'Default'} , $table->{'Tables_in_' . $db } . ' Default(1)');
}
else {
# testのDefaultが無い -> err
ok( 0 , $table->{'Tables_in_' . $db } . ' Default(2)' );
}
}
else {
if ( $test->[$i]->{'Default'} ) {
# testのDefaultがある -> err
ok( 0 , $table->{'Tables_in_' . $db } . ' Default(3)' );
}
}
ok( $r->{'Type'} eq $test->[$i]->{'Type'} , $table->{'Tables_in_' . $db } . ' Type');
ok( $r->{'Null'} eq $test->[$i]->{'Null'} , $table->{'Tables_in_' . $db } . ' Null');
ok( $r->{'Key'} eq $test->[$i]->{'Key'} , $table->{'Tables_in_' . $db } . ' Key');
ok( $r->{'Extra'} eq $test->[$i]->{'Extra'} , $table->{'Tables_in_' . $db } . ' Extra');
$i++;
}
}
# 本番DB切断
$dbh->disconnect;
# testDB切断
$test_dbh->disconnect;
done_testing();
schema.yamlの生成(Test::Fixture::DBI)
Test::Fixture::DBIをインストールすると、make_database_yaml.plコマンドが使えるようになるので、下記のコマンドでschema.yamlを生成します。
make_database_yaml.pl -d "dbi:mysql:myapp:localhost" -u root -o schema.yaml
ま、手動でデプロイしない限りは本番と開発で違うとかないと思いますが・・。