DB2とRailsのことなど

SJISは邪悪だ。
SJISに限らず、文字コード関連は予期せぬ文字化けにあふれています。日曜プログラマーが対応できる範囲を大きく逸脱するため、ボクは文字コードを固定することを推奨しています。
Windows上でRubyのプログラミングをするときは、基本的に文字コードSJIS=>CP932を使った方が何かと気楽です。理由は単純に「不要な変換をしなくて済み、特定文字に限った予期せぬ文字化けを未然に防ぐことができるから」です。
しかし、ことはそう単純ではなく、ReXMLなどの一部のライブラリーはUTF-8を前提としていますし、RailsUTF-8以外にするだけでかなり面倒なことを必要としてくれます。そういうわけで、Railsで開発するときには「UTF-8のみで記載する」方がお手軽となるようです。(これは今回やってみて初めて知りました。)

さて、問題はここからでした。IBM DB2ではDB作成時にIBMSJIS=>CP943という特殊なコードページか、あるいはUTF-8=>CP1208のいずれかが選択可能なのですが、「DB2クライアントがDBのコードページに自動変換する」という挙動をしてくれます。

クライアントがWindowsなら、入出力される文字コードは「SJIS」となり、DBの中ではDB作成時の文字コードとして保存される、という文字化けを未然に防いでくれるはずの挙動をしてくれます。ところが、Railsなど入出力される文字コードが「UTF-8」の場合には、これがうまく機能しません。サーバーに命令を送る前段階で、「文字列の処理失敗」という痛いエラーが出てしまいます。これを修正するためには、「クライアントの文字コードUTF-8に固定する」必要があります。コマンドとしては、こんな感じ。

> set DB2CODEPAGE=1208
> ruby script\server

これで正常に動作するようになるわけですが、NetBeansを使っている場合、F6一発で起動できなくなってしまうため、ちょっと面倒くさい感じがします。
どうせ、DB2でしか使わない環境変数ですし、Railsを日本語で使うのであればUTF-8固定になるでしょう、という理由から、config/environment.rbに以下のコードを一行追加したところ、おまじない無しで動作するようになりました。

ENV["DB2CODEPAGE"] = "1208"

この設定が有効になるのは、IBM提供のアダプターibm_db(v1.1.1-mswin32)を使ったときの話。IBM DB2で生成されるODBCドライバーについては、クライアント側のコードページを変更する方法が見つかりませんでした。よって、面倒でもきちんとibm_dbをインストールする必要があります。バージョン指定無しだと、コンパイル環境を求められるため、以下のようにplatformがmswin32のgemを探すと良いでしょう。(たぶん、IBMのミス?)

> gem specification -r ibm_db --ruby --all | more
> gem install -r ibm_db -v 1.1.1

現在の最新バージョンを使いたい場合、以下のアドレスからmswin32対応のgemをダウンロードし、それをインストールします。

> gem install %USERPROFILE%\downloads\ibm_db-1.5.0-mswin32.gem

ちなみにこのアダプターですが、RDOCのREADMEを読みながら設定していると、きちんとハマります。このように書かれていますが、正しくはuser -> usernameとします。

    - To configure database connection parameters edit config.yaml
      Example:  # 接続できない例
        database: testdrv
        #user:    db2inst1  # userではダメ
        username: db2inst1  # usernameならOK
        password: password
        hostname: localhost # 省略可能
        port:     50000     # 省略可能

まあ、普通はこの記事に行き着くはずですので、あまり困ることは無いと思いますが・・・