一度に複数のテーブルを更新するモジュール(1)
本記事では、html フォームから送られてきたデータを元に一度に複数のテーブルを更新するモジュールについて解説します。
対象は,Cubson でいちおうモジュールを作れる方です。
はじめに
Cubson ではテーブル単位にコードを自動生成しますので、そのままのコードでは一度にひとつのテーブルしか更新しません。
しかしソーシャルブックマークのようなモジュールの場合、HTML フォームから送られてきたデータを、ブックマーク本体用のテーブルとタグ用のテーブルといった具合に複数のテーブルに保存する必要があります。*1
そこで本記事では、HTML フォームからの POST データを元に複数のテーブルを更新する Cubson ベースのモジュールについて解説していきます。
方針
基本方針
データベースへの追加・更新の主役になっているのは ActionForm なので、これを、必要なテーブルの分だけ作ってやれば良さそう。
主キーの取得
新規追加の場合は、フォームからデータが送られてきた段階では主となるテーブルのキーの値が決まっていません。テーブルの主キーには、mysql の autoincrement 属性が設定されている前提で、テーブルにレコードが追加されたときに初めて主キーの値が決まります。そのため、主となるテーブルのキーの値を、そのほかのテーブルの項目としてセットする必要があるなら(普通あると思いますが)、主となるテーブルにレコードが追加されたあとでこのキーの値を取得し、そのほかのテーブルの該当する項目にセットします。
たとえばブックマークモジュール(テーブルbm(主キー:bm_id)、テーブルtag(主キー:tag_id))の場合、
- bm_idが未設定の状態で html フォームから POST データが送られてくる。
- POSTデータがテーブル bm に新規レコードとして追加される。そのとき、bm_id に連番が設定される。
- 設定された連番を取得し、テーブル tag の中の項目 bm_id にその値をセットする。
- テーブル tag にレコードが追加される。
という処理になります。
更新失敗時の扱い
一つ目のテーブルの更新は成功したけど二つ目以降のテーブルの更新に失敗した場合、ロールバックしなければいけません。
これには幾つか問題があって、
- XOOPS の基本設計はロールバックしないようになっているみたいで、Core では全くやっていません(複数のテーブルを一度に更新する、というのがない)。なのであまり好ましくないのかもしれない。
- MySQL のバージョンや設定によってはトランザクションをサポートしている InnoDB が使えない可能性がある。実際、テストで使っている XSAS, Xaio は InnoDB が使えない(Xaio についてはここを参照)。
- あまり経験がないぞ(ロールバックに限らないけど)。簡単なテストでロールバックが機能するのは確認しましたが、抜け落ちているケースとかありそうな気もします。
具体的なコードについては次回以降で解説します。
*1:もちろん、テーブルの持たせ方によっては必要ないのですが、参考にした Scuttle の場合、ブックマーク URL やコメントを保存するブックマークテーブルと、タグを分解して保存するタグテーブルとに分けたテーブル設計になっていますし、妥当なところだろうと思います。