Sequel + Ruby/MySQL

最初に結論。Sequel で Ruby/MySQL を使いたい場合は、オプションで :compress => false をつければOK。

以下、経緯。
Ruby 1.9.2 で Sequel を使ってみたら DB から取得した文字列のエンコーディングが全部 ASCII-8BIT だったので、ソースを読んでみたところ、MySQL/Ruby(libmysqlclient を使ってる方) の問題らしいことが分かり、代わりに Ruby/MySQL(pure Ruby 実装の方)を使おうとしたらこれが全く動かなくてハマってしまった。
さらに調べてみたところ、以下のことが分かった。

  • Sequel の MySQL アダプターはデフォルトで圧縮プロトコル (Mysql::CLIENT_COMPRESS オプションを使おうとする。
  • Ruby/MySQL は圧縮プロトコルには対応していない。
  • にも関わらず、接続時オプションで渡された CLIENT_COMPRESS をそのまま MySQL サーバに渡してしまうので、MySQL サーバは圧縮プロトコルで通信をしようとする。
  • クエリー実行時にエラーが起きる。

圧縮プロトコルに対応していないのは仕方がないとしても、接続時に CLIENT_COMPRESS が指定されてた場合は例外を投げるようにすればハマりも最小限に出来そうなので、Issue Tracker に報告してみた。
http://github.com/tmtm/ruby-mysql/issues/#issue/9
まあ、エンドユーザーとしては、最初に書いたように Sequel でオプションを付ければ大丈夫。

TokyuRuby会議01へ行ってきた

TokyuRuby会議01へ行ってきました。
真っ昼間から酒と食べ物をつまみつつ Ruby に関係したりしなかったりする内容を語る、たいへん楽しいイベントでした。プログラムの前半も終わっていないのに「会場が酒臭い」とか「カオス」とか言われてしまうような勉強会は初めてです。Tokyu.rb のイベントは初参加なのですが、普段からこんな感じなんでしょうか。
以下、LT の内容メモ(と感想)です。

続きを読む

Git で過去の commit の Author を書き換える

git-log を見ていたらメールアドレスを間違えていたのに気づいたので、何とか書き換えられないかと試行錯誤してみた。
その結果、git-format-patch でパッチ作って sed とかで書き換えた後、git-am で取り込み直せば Author を書き換えられることが分かった。なお、最初の commit については、git-show の出力をメール形式に書き換えて(FromSubject あたり)使えば何とかなる。
……というような記事を書こうとしたら、以下のような記事を見付けた。

Pro Git - Pro Git 6.4 Git Tools Rewriting Historyによると、git-filter-branchを使うと良いらしい。ということで、次のようなコマンドを実行してみた。*3また、名前だけでなくemailも古かったので、ついでに変更した。

$ git filter-branch --commit-filter '
    GIT_AUTHOR_NAME="idesaku"
    GIT_AUTHOR_EMAIL="(メールアドレス)"
    GIT_COMMITTER_NAME="idesaku"
    GIT_COMMITTER_EMAIL="(メールアドレス)"
    git commit-tree "$@"
' HEAD
GitのCommit中のAuthor名およびCommitter名を変える - idesaku blog

git-filter-branch なんてのがあったのか……。
http://progit.org は一度きちんと読まないといけないなあ。

DataMapper + MySQL でカラムごとに COLLATE を指定する

DataMapper + MySQL ではデフォルトの COLLATE として utf8_general_ci が使われるため、文字列の比較の際は大文字・小文字やアクセント符号が無視されてしまう。大文字・小文字を区別したい場合は utf8_general_ci の代わりに utf8_bin を指定しなければいけないが、DataMapper の仕組みの中ではこれを指定することはできないようだ。
そこで、カラム単位の COLLATE を指定するためのプラグイン(というかモンキーパッチ?)を書いてみた。コードは gist に置いた。*1

使い方はこんな感じ。

class Model
  include DataMapper::Resource
  property :text, String, :collate => 'utf8_bin'
end

他の DBMS の collation support の様子が分からないので、upstream に送る予定は無し。
他にも、BIGINT 型をサポートする Bigint クラスを作ってみたりしたけど(gist:159375)、この場合は Integer を拡張して size オプションを元に SMALLINT/INT/BIGINT を使い分けられるようにする方が真っ当な方法のような気がするなあ。

*1:gist の embed をはてなで使う方法が無いのが残念。idea:21170 というのがあるけど注目度は低いようだ。 直に <script> で埋め込めた…。

Debian Ruby 1.9 会議に参加してきた

Debian Ruby 1.9 会議という集まりに参加してきた。(参考: http://arika.org/diary/2009/06/04/DebianRuby19Kaigi)
DebianRuby、ともに仕事でもプライベート環境でも頼っている都合上、今後のパッケージングがどうなるかとか、RubyGemsDebian Package の共存(あるいは連携)がどうなりそうなのかに興味があったので、参加してみた次第。
以下、会議中のメモのまとめ。事実誤認があったらごめんなさい。

  • lenny に ruby1.9 が入ってしまったのは事故
    • 入れるつもりは無かったが、依存関係の都合で抜けなくなった。 (やまだあきらさん)
    • 仕様が確定する前のバージョンなので使って欲しくない。(yugui さん)
  • sid に 1.9.1 が入らない理由
    • $LOAD_PATH に /usr/lib/ruby/1.9.1 のような teeny を含んだパスが入るようになり、今後 1.9.2、1.9.3 と増えていくと、バージョンが上がるたびに全ライブラリのリビルドが必要になってしまう。ユーザ側の移行作業もたいへん。そこら辺を何とかする方法を考える必要があった。
    • ところで 1.9.1 使ってます?
      • experimental のをビルドしてる、ruby1.9 を使ってた、使ってない、etc.
  • Ruby の compatibility level
    • 1.9 系には compatibility level というバージョン概念がある。(yugui さん)
    • 1.9.2 は 1.9.1 と ABI 互換なので、リリース時は soname や /usr/lib/ruby/X.X.X の部分のバージョン番号は 1.9.1 のままになる。(未実装かも?)
  • Ruby 本体の互換性
    • Ruby の teeny 違いは Python の minor version 違いくらいに相当 (yugui さん)
    • 非互換性に関する注意が deb package のドキュメントにも欲しい。(NEWS.Debian?)
    • 1.9.2 では Time と Socket がわりと変わる。
  • lucas さんによる新しい Debian Ruby Policy の提案。(debian-ruby ML のこの辺りのスレッド)
    • ruby-support というパッケージを作り、python-support のようなことをやりたい。
      • Ruby の実装/バージョンごとにディレクトリを作って symlink を貼りまくる。
    • ruby-support パッケージに依存し過ぎでは?
    • バージョン依存性などの問題にぶつかった時、ユーザ側で何かするのが難しそう。
    • Dmitry Borodaenko さんの意見「Pure Ruby ライブラリはバージョン番号なしの /usr/lib/ruby/vendor_ruby に入れるのが現実的」、というのに個人的に賛同。
    • ruby-support がポリシー先行で実装が追いついてない? 実際に動かしてみないとよく分からない。(やまだあきらさん)
    • sid に 1.9.1 を入れるのは、ruby-support を待たない方針で。(daigo さん)
  • gem から自動で deb を作る方法があると嬉しい
    • 過去に作ったけどあまり反響がない。(やまだあきらさん、daigo さん)
    • ユーザが gem から deb をビルドすることを支援するツールが欲しい。
      • dh-make-perl みたいなの。
      • ユーザが実行すると gem をダウンロードして展開して debian ディレクトリを作成してくれて、後は debian/control を各自でいじって debuild しろ、みたいな。
  • rubygems パッケージが gcc や ruby1.8-dev に Depends?
    • ruby1.8-dev に依存したところで、gem のバイナリビルドはたぶん失敗する。その他の依存ライブラリ(libXXX-dev)を解決する方法が無いので。
    • Depends にしても嬉しくない。Recommends もやり過ぎ。やっぱり Suggests で。
  • gem install で作られた実行ファイルを /usr/local/bin に入れるのはどう?
    • ファイル名の衝突を解決できない。(1.8 系と 1.9 系とか)
    • tarball から入れたものとぶつかりそう。
    • /var/lib/gems/X.X/bin から /usr/local/bin へ symlink を貼るようなスクリプトを例示しておいて「気になるならそれを使え」というのはどうか。
  • JRubyRubyGems ってどうなってるの?
    • JRuby で独自にやってる。
      • Debianjruby パッケージでどうなってるかは未確認。
    • Debianrubygems パッケージは MRI/CRuby のみが対象。
  • 1.8 系のパフォーマンスの話
    • configure で --enable-pthread すると遅くなるらしい。
    • 1.9 系には関係ない話。1.8 系に手間をかけても仕方ないので、現状維持で。
    • Ruby Enterprise Edition とかどう?
      • 1.8.6 をベースに GC や memory allocator をいじってあり、Rails では速くなるようだけど、平均的には遅くなる。(yugui さん)

最後に、有志による keysign 交換が行なわれて解散。

ruby-protobuf の fork を GitHub に作った

Google Protocol Buffers の Ruby 実装として ruby-protobuf (Google Code) というライブラリがあるが、それの fork を GitHub に作成してみた。

オリジナル版からの変更点は以下の Wiki にまとめている。

今日時点までの変更点は以下のとおり。

  • 機能改善
    • rprotoc コマンドの挙動
    • C 言語風のコメント
      • /* コメント */
    • エンコードを高速化
    • メッセージのネストの改善
    • Ruby 1.9 サポートの改善
      • Wiki には明示してないが、1.8.7 と 1.9 開発版で動作確認をしている
  • バグ修正
    • enum 型のデフォルト値を指定できるようにした
    • エンコード時に未初期化の optional field においてデフォルト値が出力されないようにした
    • 各型の最大値・最小値の値を修正
    • 固定長型や負の整数のエンコード・デコードに関する修正
    • repeated field に関する修正

GitHub の機能を使って gem を作成しているので、以下の手順でインストールできる。

 $ gem source -a http://gems.github.com
 $ sudo gem install macks-ruby_protobuf

今のところ、機能もインタフェースもオリジナル版と大差ないので、そちらで困っていない方はわざわざ使う必要は無いと思う。
fork した理由は、バグ修正は始めのうちは本家の Issue Tracker に報告していたものの、だんだん面倒になってきたりとか、バグ修正以外の(個人的な趣味に属する)変更がしたくなってきたとか、メンテナンスの速度と私が欲する開発速度とが合わなかったとか、そういった理由。
Upstream への merge は、目的にはしていないが、特に否定もしない、というスタンス。*1
1ヵ月くらい前にリポジトリを作成したんだけど、私のツリーからさらに fork を作る方がいたり、メッセージを送ってくださる方がいたり、GitHubSNS 的な側面がなかなか面白い。

*1:GitHub の pull request みたいなものを送れれば楽なんだけど……。