S2Dao.NETでバイナリをログ出力できるようにしてみた

うちの会社、最近Seasar2S2Container.NET)をフレームワークに使って開発することがだいぶ増えてきています。 ご多分に漏れず僕が今やってるプロジェクトもそうです。 そのシステムでS2Dao.NET(以下.NETを省略しますが.NET版の話です)が出力するSQLログをとっておいて 障害復旧に使うという仕組みを入れています。 ただこのシステム、バイナリ(jpgとxls)をInsertする場面があります。 バイナリのデータはEntity上ではByte配列で保持しています。 その部分がSQLログの上では'System.Byte'と表示されてしまいます。 バイナリをどうやって障害復旧するか考えていました。 使っているDBMSはAccessで、調べてみたところAccessは0x....の16進数方式で SQL文を書いてやればバイナリのInsertができるようです。 そこで、SQLログに16進を出力してやろうと考え S2Daoのソースを見て改良を加えてみました。 S2Daoのソースを読んでみた分かったのは ・S2DaoはDBMSに送ったSQLを忠実に出力しているわけではない ・↑ADO.NETのParameters.Addで変数をバインドしてSQLをDBMSに発行しているためSQLが取得できない? ・ログに出力するSQLはSeasar.Extension.ADO.Impl.BasicCommandFactoryのGetCompleteSqlメソッドで生成している ・さらにその中で、?で表されている変数をバインドするためにReplaceSqlメソッドを呼んでいる ・さらにさらに、バインドする変数をGetBindVariableTextにかけてログ用のテキストにしている さてその、GetBindVariableTextの中身を見ると >> >|cs| if (bindVariable is INullable) { INullable nullable = bindVariable as INullable; if (nullable.IsNull) { return GetBindVariableText(null); } else { PropertyInfo pi = bindVariable.GetType().GetProperty("Value"); return GetBindVariableText(pi.GetValue(bindVariable, null)); } } #if NHIBERNATE_NULLABLES else if (bindVariable is INullableType) { INullableType nullable = bindVariable as INullableType; if (!nullable.HasValue) { return GetBindVariableText(null); } else { PropertyInfo pi = bindVariable.GetType().GetProperty("Value"); return GetBindVariableText(pi.GetValue(bindVariable, null)); } } #endif else if (bindVariable is string) { return "'" + bindVariable + "'"; } else if (bindVariable == null) { return "null"; } 〜中略〜 else { return "'" + bindVariable + "'"; } ||< << という風になっています。 つまりバイナリを格納しているByteはどこのifにも引っかからずに最後のelseで'System.Byte'として出力されていたわけです。 #ByteをToStringしたら内容はでずにSystem.Byteとなりますからね。 そんなわけで >> >|cs| else if (bindVariable is byte) { return "0x" + BitConverter.ToString((byte)bindVariable).Replace("-", string.Empty); } ||< << を加えて、SQLログに0x...形式の16進バイナリ文字列がでるようにしましたとさ。 ちなみに、VisualStudioのデバッグウィンドへの出力って結構時間がかかるので 大きなバイナリをInsertするとログ表示に結構時間がかかります。