« 山本ジャパン終わった…/男子サッカー | Main | 風邪に注意… »

2004.08.17

SQLiteメモ(CREATE TRIGGER)

PHP5に標準で含まれる組み込み型?DBMSのSQLiteですが、
いじればいじるほどちょっと面白い感じですね。
(興味をそそるという意味です。)

SQLite Introductionに書かれている内容を見ると、SQLiteDatabaseなんていうクラスがどこかで?定義されているようですが、ソースコードを見れないのであまり深く知ることができません。
サーバーにメモリをたくさん載せて、sqlite_popen(":memory:");でデータベースをオープンすると結構早くなるのでは?などと思ってみたりするのですが。

さて、本題。
XOOPSをSQLiteで動かそう作戦、お盆期間中いじり倒してそこそこ動くようにしたのですが、修正箇所を見ていくと、全てのモジュールについて修正が必要になってくるかもしれません。
それは避けたいということで、別の回避方法がないかと調査していました。
修正が必要な原因は、主に新規登録(INSERT)時、MySQLのauto_incrementのカラムに'0'を指定しているのですが、SQLiteのオートインクリメント(INTEGER PRIMARY KEY)ではエラー(0のレコードが無い場合のみ1度だけ成功するんですが、以降ユニーク制約違反になります)になってしまいます。
指定方法は、
1)オートインクリメントのカラムに値を指定しない
あるいは、
2)オートインクリメントのカラムにNULLを指定する
なんですが、
前者の方は全般的にINSERTの書き方が、カラム指定なしのVALUESの全カラム値指定になっており修正が必要。
後者の方はクエリー投げる前の文字列生成のところでsprintf()を使っているのですが、auto_incrementのカラムの場所は%dとなっており、'NULL'を指定しても結局0になってしまう状況で修正が必要です。
(Xoops'Hoge'Handler::insert()のI/Fをもっと抽象度上げてもらえれば一番いいんですけどね…)
これ、全て修正したら数十箇所になり、モジュールを追加した場合その都度修正しなければいけない可能性があるので、この修正方法は諦めました。
そこで、SQLiteはCREATE TRIGGERをサポートしているということなので、以下のようなトリガーを定義すると、
一応うまく動いているようです。

CREATE TRIGGER auto_increment AFTER INSERT ON test
FOR EACH ROW WHEN NEW.id = 0
BEGIN
DELETE FROM test WHERE id=0;
INSERT INTO test VALUES (NULL, NEW.data);
END;

この書き方も、ドキュメント見ながらやっとこさ動きました…
PostgreSQLはCで書いた関数?しか呼べないようですし、MySQLはそもそもトリガー未対応?のようですね。
さて、動いたはいいですが、このトリガーをほぼ全てのテーブルに定義しないといけないような気がします。
インストール時のsql/sqlite.sqlで定義してしまえばアプリケーション内のI/Fは変更なしでいけると読んでいるのですが…

|

« 山本ジャパン終わった…/男子サッカー | Main | 風邪に注意… »

Comments

Post a comment



(Not displayed with comment.)


Comments are moderated, and will not appear on this weblog until the author has approved them.



TrackBack


Listed below are links to weblogs that reference SQLiteメモ(CREATE TRIGGER):

« 山本ジャパン終わった…/男子サッカー | Main | 風邪に注意… »