DBIx::Class経由で取得する文字列にUTF-8 flagを付けたい[Catalyst]

以前からブログに書こうかどうか迷っていたものです。


DBIx::Class::UTF8Columnsでできるんですが、カラムを指定するのが面倒。
MySchemaはDBIx::Class::Schema::Loaderで自動生成してることもあって、あんまりMySchema/*をいじりたくない。
というわけで、inflate/deflate(DBIx::Class::InflateColumn)でやってます。


もっと簡単な方法あるんじゃないかなあ、と思って改めてCPANを探してみたのですがしっくりくるものが見当たらず。
とりあえず晒しておきます。

package MyApp::Model::MyModel;

use base qw(Catalyst::Model::DBIC::Schema);

my $inflate_utf8 = sub {
    my $value = shift;
    if ( !utf8::is_utf8($value) ) {
        utf8::decode($value);
    }
    return $value;
};

my $deflate_utf8 = sub {
    my $value = shift;
    if ( utf8::is_utf8($value) ) {
        utf8::encode($value);
    }
    return $value;
};

sub new {
    my $class = shift;

    my $self = $class->next::method(@_);
    foreach my $schema ( keys %{ $self->schema->class_mappings } ) {
        foreach my $column ( $schema->columns ) {
            my $data_type = $schema->column_info($column)->{data_type};
            if ($data_type eq 'TEXT'
                || $data_type eq 'CHAR'
                || $data_type eq 'VARCHAR' )
            {
                $schema->inflate_column( $column,
                    { inflate => $inflate_utf8, deflate => $deflate_utf8 } );
            }
        }
    }
    return $self;
}

ちなみに上記ソースには書いてないですが、data_typeがDATETIME/TIMESTAMP等のときはDateTime::Format::*してます。↓ここで書いてたやつです。

「data_typeがTIMESTAMPだったらinflate_column仕掛ける」ってのをやっていたのに、できなくなってしまったではないか。
あれー?こんなクラスあったっけ…。
DBIx::Class::InflateColumn::DateTime - Auto-create DateTime objects from date and datetime columns. - metacpan.org
DBIx-Class-0.07000(1年以上前)からあるらしい…全然知らなかった!恥ずかし過ぎる(><)

data_typeを見る方法は、名前で識別(「_onで終わってたら」とか)するより確実かなーと思って割と気に入ってます。