http://github.com/fujiwara/p5-Data-Model/tree/master
Data::Model を PostgreSQL でも使いたいので対応作業をやってみたら、テストまわりでいくつか困ったことが。
- テーブル名 user は PostgreSQL では予約語のため、quote しないと使えない
- quote すればいいのだけど、PostgreSQL は "", SQLite と MySQL は `` で、そこを切り替えるのが面倒そうだったので s/user/tusr/g; してしまった
- CHAR 型のカラムは、PostgreSQL では末尾に空白が埋められるので、取り出すと期待する値と異なる (MySQL では取り出すときに切り捨てられる)
- デフォルトの型を切り替えられるように Schema::Properties->default_column_type を追加
- テスト内で明示的に CHAR(100) としているのは VARCHAR(100) に変更
今のところ t/020_mock/dbi-pg-basic.t が通るところまで。
ひととおり t/020_mock/dbi-pg-*.t が成功するところまでできたので push した。
やってて気がついた PostgreSQL と MySQL, SQLite の差異。
auto increment (Pg では SERIAL 型) のカラムに明示的に NULL を入れようとすると、MySQL では auto increment された値が設定されるが、Pg では not-null constraint エラー。
CREATE TABLE foo ( id SERIAL PRIMARY KEY, bar text ); INSERT INTO foo ( bar ) VALUES ( 'BAR' ); -- OK INSERT INTO foo ( id, bar ) VALUES ( NULL, 'BAR' ); -- NG
http://github.com/fujiwara/p5-Data-Model/commit/02b5e41f37f9dacf5a3637887415f0547a4db5db
auto increment のカラムに値が指定されて INSERT された場合は last_insert_id が取れない。
nextval() が呼ばれてないから。仮にそのセッションの別の SQL で nextval() されていた場合、そっちの値を読み取ってしまう可能性があるので、まずい。
http://github.com/fujiwara/p5-Data-Model/commit/1e3e296c59c5077628843af776a722a48341fc99