cake schema でコメントを取得/設定する(MySQL 限定)
2 月からのプロジェクトは CakePHP でアジャイルっぽく進めるという話になっています。後で仕様が変わるのは確実なので、テーブル定義なんかは migration 風に管理したいところです。(※migration というのは Rails なんかで使われている仕組みで、テーブルへのカラム追加等を ALTER TABLE で実行するので、データを消失することなくスキーマ情報を変更できる仕組みです。)
CakePHP では、
にあるように、cake schema upgrade で migration に近いことができますが、どうもテーブルやカラムのコメントを認識してくれないようで。これでは不便なので、コメントを取得/設定できるように dbo_mysql.php を変更してみました。
下調べ
カラムのコメント
あたりにあるように、SHOW FULL COLUMNS FROM <テーブル名> で取得できますよと。
mysql> describe `users`; +-------+---------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+---------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | name | text | NO | | NULL | | | email | text | NO | | NULL | | +-------+---------+------+-----+---------+----------------+ mysql> show columns from `users`; +-------+---------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+---------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | name | text | NO | | NULL | | | email | text | NO | | NULL | | +-------+---------+------+-----+---------+----------------+ mysql> show full columns from `users`; +-------+---------+-----------------+------+-----+---------+----------------+---------------------------------+----------------+ | Field | Type | Collation | Null | Key | Default | Extra | Privileges | Comment | +-------+---------+-----------------+------+-----+---------+----------------+---------------------------------+----------------+ | id | int(11) | NULL | NO | PRI | NULL | auto_increment | select,insert,update,references | ユーザID | | name | text | utf8_general_ci | NO | | NULL | | select,insert,update,references | 氏名 | | email | text | utf8_general_ci | NO | | NULL | | select,insert,update,references | メールアドレス | +-------+---------+-----------------+------+-----+---------+----------------+---------------------------------+----------------+
別の取得方法もあるみたいで
mysql> select * from information_schema.columns where table_name='users'\G *************************** 1. row *************************** TABLE_CATALOG: NULL TABLE_SCHEMA: exam TABLE_NAME: users COLUMN_NAME: id ORDINAL_POSITION: 1 COLUMN_DEFAULT: NULL IS_NULLABLE: NO DATA_TYPE: int CHARACTER_MAXIMUM_LENGTH: NULL CHARACTER_OCTET_LENGTH: NULL NUMERIC_PRECISION: 10 NUMERIC_SCALE: 0 CHARACTER_SET_NAME: NULL COLLATION_NAME: NULL COLUMN_TYPE: int(11) COLUMN_KEY: PRI EXTRA: auto_increment PRIVILEGES: select,insert,update,references COLUMN_COMMENT: ユーザID (snip)
という拾い方もできるようですが、元の処理が DESCRIBE を使っているので、SHOW FULL COLUMNS FROM <テーブル名> の方を使うことにします。
テーブルのコメント
SHOW TABLE STATUS で取得できるそうで。
mysql> show table status\G *************************** 1. row *************************** Name: users Engine: InnoDB Version: 10 Row_format: Compact Rows: 0 Avg_row_length: 0 Data_length: 16384 Max_data_length: 0 Index_length: 0 Data_free: 11534336 Auto_increment: 1 Create_time: 2010-02-01 13:45:47 Update_time: NULL Check_time: NULL Collation: utf8_general_ci Checksum: NULL Create_options: Comment: ユーザ
元々 SHOW TABLE STATUS が使われているようなので、Comment 列を取得する処理を追加するだけでよさそうですね。
完成品
とりあえず github に上げました。
今回使う DB が MySQL なので、対応は MySQL のみ(検証環境は 5.1.33)です。また、CakePHP 1.3 のブランチで変更しています。
動作検証
>cake schema generate -f
とすると、
var $users = array( 'id' => array('type' => 'integer', 'null' => false, 'default' => NULL, 'comment' => 'ユーザID', 'key' => 'primary'), 'name' => array('type' => 'text', 'null' => false, 'default' => NULL, 'comment' => '氏名'), 'email' => array('type' => 'text', 'null' => false, 'default' => NULL, 'comment' => 'メールアドレス'), 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1)), 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB', 'comment' => 'ユーザ') );
こんな感じで comment のデータが含まれた形で schema.php に出力されます。そして、
>cake schema create -dry
とすると、
Dry run for users : CREATE TABLE `users` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ユーザID', `name` text NOT NULL COMMENT '氏名', `email` text NOT NULL COMMENT 'メールアドレス', PRIMARY KEY (`id`)) DEFAULT CHARSET=utf8, COLLATE=utf8_general_ci, ENGINE=InnoDB, COMMENT='ユーザ';
こんな感じでコメントつきの CREATE TABLE 文が生成されます。最低限の使い方なら問題ないんじゃないかと。
問題点
この変更を加えると、cake/tests/cases/libs/model/cake_schema.test.php のテストに失敗してしまいます。今回コメントの情報を返すように変更しましたが、これがテストの想定と異なるためです。普段であればテストの想定値を変更してしまえばいいんですが、MySQL 以外の DBO で対応していないので、そうするわけにもいかなくて困っています。ベストなのはすべての dbo_xxxxx.php で comment を返すように変更することですが、そこまでの体力はありませんし。
・・・と悩んでいたところに、ちょうど Twitter で
@hiromi2424 | 誰かmysqlのコメントを論理名とするscaffold view書いてないかな、書いてないなら書くんだけど #cakephp | link | |
@miau_jp | @hiromi2424 cake schema でコメントの取得&設定ができるように dbo_mysql.php に手を入れたものなら手元に・・・。これを使えば比較的簡単にview の scaffolding にも利用できる気もします。 | link | |
@hiromi2424 | @miau_jp show full colmuns なのでscemaの領域ですか・・・!素晴らしいです。 単純に$db->query()でゴリ押そうと思ってました。 | link | |
@miau_jp | @hiromi2424 実は「ちょこちょこ変更してたら動いちゃった」という程度のものなんですけどね・・・。unit test をどう書くか思案してたんですけど、そこは無視して github にでもあげちゃいます。おそらく明日中くらいに。 | link | |
@cakephper | @miau_jp @hiromi2424 それかなり便利そう! そのアイディアは良いですね! | link | |
@hiromi2424 | @miau_jp 助かります! testは面倒なところがありますが、本家にマージするとしてチケット投げて任せてしまうという手もあります(ぇー | link | |
@miau_jp | . @hiromi2424 @cakephper 期待されすぎないように断っておくと、1.3 ベースで対応してます。1.2 にもすんなりマージできればいいんですけど。test はとりあえず忘れます・・・。 | link |
改善すべき点があればご意見ください。(すぐに対応できるとも限らないので、github で直接編集していただく形のほうがいいですけど・・・。)