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個前の追記と同じ.