charset cp932 未対応の件
訳あってちょっとConnector/NETのソースを読んでみた.最新版ver1.0.6
charsetの扱いについてはConnector/NETにおいてもConnector/Jとだいたい同じようなアーキテクチャとなっている.つまり内部にcharsetのマッピングテーブルを持っていて,マッピングできないcharsetがアプリ側から指定されるとエラーを返す.
Connector/NETにおけるこのcharsetマッピングテーブルは以下のソースファイルにて定義されている.
${ルート}/mysqlclient/CharSetMap.cs
そんでもってマッピングテーブルはこんな感じ(ソース抜粋)
private static void LoadCharsetMap() { mapping = new Hashtable(); mapping.Add("big5", "big5"); // Traditional Chinese mapping.Add("sjis", "sjis"); // Shift-JIS mapping.Add("gb2312", "gb2312"); mapping.Add("latin1", "latin1"); mapping.Add("latin2", "latin2"); mapping.Add("latin3", "latin3"); mapping.Add("latin4", "latin4"); mapping.Add("latin5", "latin5"); mapping.Add("greek", "greek"); mapping.Add("hebrew", "hebrew"); mapping.Add("utf8", "utf-8"); mapping.Add("ucs2", "UTF-16BE"); mapping.Add("cp1251", 1251); mapping.Add("tis620", 874); mapping.Add("binary", "latin1"); mapping.Add("cp1250", 1250); // relatively sure about /* mapping.Add( "default", 0 ); mapping.Add( "cp1251", 1251 ); // Russian mapping.Add( "win1251", 1251 ); mapping.Add( "gbk", 936 ); // Simplified Chinese mapping.Add( "cp866", 866 ); mapping.Add( "euc_kr", 949 ); // maybe, maybe not... mapping.Add( "win1250", 1250 ); // Central Eurpoe mapping.Add( "win1251ukr", 1251 ); mapping.Add( "latin1_de", 1252 ); // Latin1 German mapping.Add( "german1", 1252 ); // German mapping.Add( "danish", 1252 ); // Danish mapping.Add( "dos", 437 ); // Dos mapping.Add( "pclatin2", 852 ); mapping.Add( "win1250ch", 1250 ); mapping.Add( "cp1257", 1257 ); mapping.Add( "usa7", 646 ); mapping.Add( "czech", 912 ); mapping.Add( "hungarian", 912 ); mapping.Add( "croat", 912 ); */ /* ("gb2312", "EUC_CN"); ("ujis", "EUC_JP"); ("latvian", "ISO8859_13"); ("latvian1", "ISO8859_13"); ("estonia", "ISO8859_13"); ("koi8_ru", "KOI8_R"); ("tis620", "TIS620"); ("macroman", "MacRoman"); ("macce", "MacCentralEurope"); */ }
で,このテーブルに対してこんな感じでチェックしてる.
if (! mapping.Contains( CharSetName )) throw new MySqlException("Character set '" + CharSetName + "' is not supported");
Connector/NETは全てC#で実装されていて,僕はC#は一切触ったこともないのだけれども,今回ばかりは言語知識なくとも分かった.こういう話は言語知識よりも業務知識(MySQLコネクタ製品にとってcharsetの取り扱いは業務知識)のほうが約に立つってことかな.
追記:
単純に"cp932"が無いとは言ったものの,もしかすると".NET"にとってのsjisはMS932=WINDOWS-31J=cp932を意味するかもしれないとふと思ってぐぐってみたら,こんなのを発見.
http://www.atmarkit.co.jp/fdotnet/dotnettips/013enumenc/enumenc.html
ここでは、キャラクタ・セット名に加えて、その別名(Alias)も定義されている。例えば、「Shift_JIS」の別名としては、次のようなものがある。
- csShiftJIS
- csWindows31J
- ms_Kanji
- shift-jis
- x-ms-cp932
- x-sjis
サーバ側でcp932でテーブルを作っておけば".NET"的には"sjis"でもちゃんと(株)とかも上手く扱えるとか(推測).サーバ接続直後にどんな"set names"をやっているのかが気になるところ.現時点では結論でない.
追記2:
もう1つ気になったのが上記記事の以下文面.
実際には、GetEncodingメソッドのパラメータで指定可能な文字列の元となるデータは、レジストリの次のキー配下で定義されているようだ。
HKEY_CLASSES_ROOT\MIME\Database\Charset
regeditで覗いてみたらやっぱりcp932は存在しなかった.てことは(Javaにも"cp932"なる名前のコードは存在しないが)cp932をConnector/NETで指定可能だという考え自体が間違いである可能性が高い.MySQLサーバのcp932に内容的にマッピング可能な,Windows的なコード名はなにかを突き止めるのが正解への道となりそう.で,それって"sjis"じゃないの?と来て振り出しに戻り,やっぱGeneral Logで見てみないとわからんということに・・・.結論は1個前の追記と同じ.