Chat (Lingr.com)
Informaiton
Daily
Column
- MySQL日本語の旅(5/1)
- アクセス向上秘伝(5/9)
- 一風変ったHaskellλ門(6/13)
- SICP Answer Book (5/31) 問題3.26追加
Zope Solution
Extra
アーカイブ
OSS案内所
Site Info
関連リンク
mysql.cc の変更
ということで、以下のように変更してみた。
2231 {
2232 const char* charsn = get_charset_name(field->charsetnr);
2233 CHARSET_INFO *charset_info= get_charset_by_name(charsn, MYF(MY_WME));
2234
2235 uint currlength= (uint) lengths[off];
2236 uint numcells= charset_info->cset->numcells(charset_info,
2237 str, str + currlength);
2238 tee_fprintf(PAGER, num_flag[off] ? "%*s |" : " %-*s|",
2239 maxlength + currlength - numcells, str);
2240 }
追加したのは、2232, 2233の2行である。
2232行で、キャラクタセット名称を文字列として得て、
2233行で、932行を真似て、局所的な charset_info を作ってみた。
コンパイル
プログラムを変更したら、make だ。configureは必要ない。
最初の時には、makeに大変時間がかかったが、今度はすぐに終わる。
shell$ make
インストール
インストールする前に、MySQLサーバが動いていたら止めておく。
shell$ /usr/local/mysql/bin/mysqladmin -u root shutdown
動いていなくても、このコマンドを実行して構わない。 実行中に、止めずにインストールしちゃったりすると、厄介なことになるので、 無駄にshutdownを行なっても全然構わないし、推奨すべきことである。
shell# make install shell# cd /usr/local/mysql shell# bin/mysql_install_db --user=mysql shell# chown -R root . shell# chown -R mysql var shell# chgrp -R mysql . shell# bin/mysqld_safe --user=mysql &
実行、確認
shell$ mysql -u root Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 1 to server version: 5.0.10-beta-debug-log Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> SET NAMES eucjpms; Query OK, 0 rows affected (0.00 sec) mysql> SELECT 'サカマチ'; +----------+ | サカマチ | +----------+ | サカマチ | +----------+ 1 row in set (0.06 sec) mysql>
予想した通りに動いているようだ。
念のため、gdbで修正した後のプログラムの動きを確認しておこう。
shell$ gdb /usr/local/mysql/bin/mysql メッセージ省略 (gdb) b mysql.cc:2232 Breakpoint 1 at 0x8054fa7: file mysql.cc, line 2232. (gdb) r -u root Starting program: /usr/local/mysql/bin/mysql -u root Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 4 to server version: 5.0.10-beta-debug-log Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> SET NAMES eucjpms; Query OK, 0 rows affected (0.00 sec) mysql> SELECT 'サカマチ'; +----------+ | サカマチ | +----------+ Breakpoint 1, print_table_data (result=0x809cce0) at mysql.cc:2232 2232 const char* charsn = get_charset_name(field->charsetnr); (gdb)
挿入した部分の先頭までやってきた。
(gdb) n
2233 CHARSET_INFO *charset_info= get_charset_by_name(charsn, MYF(MY_WME));
(gdb) p field->charsetnr
$2 = 97
(gdb) p charsn
$3 = 0x8092d98 "eucjpms_japanese_ci"
(gdb) n
2235 uint currlength= (uint) lengths[off];
(gdb) p *charset_info
$4 = {number = 97, primary_number = 0, binary_number = 0, state = 801, csname = 0x8092d90 "eucjpms",
name = 0x8092d98 "eucjpms_japanese_ci", comment = 0x8092d70 "UJIS for Windows Japanese", tailoring = 0x0,
ctype = 0x400ea220 "", to_lower = 0x400ea340 "", to_upper = 0x400ea440 "", sort_order = 0x400ea540 "",
contractions = 0x0, sort_order_big = 0x0, tab_to_uni = 0x0, tab_from_uni = 0x0, caseinfo = 0x4012b960,
state_map = 0x80898c0 .....以下省略 ,
ident_map = 0x80899c0 "", strxfrm_multiply = 1, caseup_multiply = 1 '\001', casedn_multiply = 1 '\001',
mbminlen = 1, mbmaxlen = 3, min_sort_char = 0, max_sort_char = 255, cset = 0x401051a0, coll = 0x40105160}
(gdb)
勝手に局所的に用意した charset_info の値は、何だかうまく行っているみたいだ。 このお陰で、ちゃんと表示されたのではないかと思う。
ここで、一旦gdbは抜けておこう。
(gdb) q The program is running. Exit anyway? (y or n) y shell $
もうちょっと複雑なのを表示してみよう。
テーブルの縦線が揃わないで行なったのと同じことをここでやってみよう。
一気に、テーブルを作ってレコードを入れるところまでやってしまおう。
shell$ mysql -u root
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 6 to server version: 5.0.10-beta-debug-log
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql> USE test;
Database changed
mysql> SET NAMES eucjpms;
Query OK, 0 rows affected (0.01 sec)
mysql> CREATE TABLE `town` (
-> `post` char(7),
-> `name` varchar(40),
-> `yomi` varchar(40)
-> ) ENGINE=InnoDB DEFAULT CHARSET=eucjpms;
Query OK, 0 rows affected (0.09 sec)
mysql> SHOW COLUMNS FROM town;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| post | char(7) | YES | | NULL | |
| name | varchar(40) | YES | | NULL | |
| yomi | varchar(40) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.07 sec)
mysql> INSERT INTO town VALUES
-> ('1620824','揚場町','アゲバチョウ'),
-> ('1620848','市谷鷹匠町','イチガヤタカジョウマチ'),
-> ('1620802','改代町','カイタイチョウ'),
-> ('1600002','坂町','サカマチ');
Query OK, 4 rows affected (0.05 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql>
さて、データは入った。SELECTすると、どのように表示されるであろうか。
mysql> SELECT * FROM town; +---------+------------+----------------------------+ | post | name | yomi | +---------+------------+----------------------------+ | 1620824 | 揚場町 | アゲバチョウ | | 1620848 | 市谷鷹匠町 | イチガヤタカジョウマチ | | 1620802 | 改代町 | カイタイチョウ | | 1600002 | 坂町 | サカマチ | +---------+------------+----------------------------+ 4 rows in set (0.00 sec) mysql>
ちゃんと揃っている。
続いて、SET NAMES utf8 をやってみよう。 その前に、gnome-terminalのCharacter Coding は UTF-8にしておく。
mysql> SET NAMES utf8; Query OK, 0 rows affected (0.00 sec) mysql> SELECT * FROM town; +---------+-----------------+-----------------------------------------+ | post | name | yomi | +---------+-----------------+-----------------------------------------+ | 1620824 | 揚場町 | アゲバチョウ | | 1620848 | 市谷鷹匠町 | イチガヤタカジョウマチ | | 1620802 | 改代町 | カイタイチョウ | | 1600002 | 坂町 | サカマチ | +---------+-----------------+-----------------------------------------+ 4 rows in set (0.00 sec) mysql>
いずれもうまく行くようだ。
これで、デフォルトキャラクタセットでの指定が無くても問題がなくなったようだ。 もちろん、途中でキャラクタセットを変更してもちゃんと反映されている。
フィードバック:
There is no comment.