cp932対応パッチを作ってみた
本日13個目のエントリ.間違いなく過去最高記録.もう疲れた・・・.
diff出力
D:\share\connector-net-svn\connector-net\branches\1.0\mysqlclient>diff CharSetMap.cs CharSetMap.cs.patch 85a86 > mapping.Add("cp932", "sjis"); // cp932
ソース改変場所抜粋 CharSetMap.cs
private static void LoadCharsetMap() { mapping = new Hashtable(); mapping.Add("big5", "big5"); // Traditional Chinese mapping.Add("sjis", "sjis"); // Shift-JIS mapping.Add("cp932", "sjis"); // cp932 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);
テストコード
using System; using MySql.Data.MySqlClient; namespace CNTNS { class ConnectorNETTest { public static void Main() { Console.WriteLine("Hello World!"); string myConnectionString = "server=127.0.0.1;uid=root;" + "pwd=;database=test;charset=cp932"; MySqlConnection conn = new MySqlConnection(); conn.ConnectionString = myConnectionString; conn.Open(); MySqlDataReader reader = null; MySqlCommand cmd = null; cmd = new MySqlCommand("DROP TABLE IF EXISTS t1", conn); reader = cmd.ExecuteReader(); reader.Close(); cmd = new MySqlCommand("CREATE TABLE t1 (c1 INT, c2 CHAR(1)) DEFAULT CHARSET=cp932", conn); reader = cmd.ExecuteReader(); reader.Close(); cmd = new MySqlCommand("INSERT INTO t1 VALUES (1, '㈱')", conn); reader = cmd.ExecuteReader(); reader.Close(); cmd = new MySqlCommand("SELECT * FROM t1", conn); reader = cmd.ExecuteReader(); while (reader.Read()) { Console.WriteLine(reader.GetString(0) + "=" + reader.GetString(1)); } reader.Close(); conn.Close(); Console.WriteLine("Hello MySQL!"); } } }
テストコード実行結果
D:\share\workspace\current\CSharp>ConnectorNETTest.exe Hello World! 1=㈱ Hello MySQL!
mapping.Add("A", "B")だけどConnector/NETではAがC#アプリから指定される名前兼サーバ側から返るパケットに含まれる名前ということらしい.Bが.NETフレームワーク的な名前(Windowsのレジストリにあるやつ/以前のエントリ参照)ということらしい.
だからサーバ側のcp932テーブルをConnector/NET側が扱えるようにするためにはmapping.Add("cp932","B")って感じの定義が必要.
このBだけど,Windows上には"cp932"という名前の文字コードは存在しない,そしてその代わりに"sjis"が内容的に該当するものなのでmapping.Add("cp932", "sjis")が正解であると思う.
この辺りはConnector/Jとは違うところ.Connector/Jの場合はAがJava的な名前.BがMySQL的な名前.
ちなみにmapping.Add("cp932", "cp932")の場合は".NETフレームワーク"からエラーが返る(理由は前述の通り).
テストではサーバ上にcp932テーブルを作ってcp932で接続した状態でNEC特殊文字をINSERT/SELECTしている.
".NETフレームワーク"を通過する間だけ"sjis"の振りをしている感じ.
Connector/NET開発者のReggie Burnett氏に後で送っておこう.