一度に複数のテーブルを更新するモジュール(1)

本記事では、html フォームから送られてきたデータを元に一度に複数のテーブルを更新するモジュールについて解説します。

対象は,Cubson でいちおうモジュールを作れる方です。

はじめに

Cubson ではテーブル単位にコードを自動生成しますので、そのままのコードでは一度にひとつのテーブルしか更新しません。

しかしソーシャルブックマークのようなモジュールの場合、HTML フォームから送られてきたデータを、ブックマーク本体用のテーブルとタグ用のテーブルといった具合に複数のテーブルに保存する必要があります。*1

そこで本記事では、HTML フォームからの POST データを元に複数のテーブルを更新する Cubson ベースのモジュールについて解説していきます。

方針

基本方針

データベースへの追加・更新の主役になっているのは ActionForm なので、これを、必要なテーブルの分だけ作ってやれば良さそう。

主キーの取得

新規追加の場合は、フォームからデータが送られてきた段階では主となるテーブルのキーの値が決まっていません。テーブルの主キーには、mysql の autoincrement 属性が設定されている前提で、テーブルにレコードが追加されたときに初めて主キーの値が決まります。そのため、主となるテーブルのキーの値を、そのほかのテーブルの項目としてセットする必要があるなら(普通あると思いますが)、主となるテーブルにレコードが追加されたあとでこのキーの値を取得し、そのほかのテーブルの該当する項目にセットします。

たとえばブックマークモジュール(テーブルbm(主キー:bm_id)、テーブルtag(主キー:tag_id))の場合、

  1. bm_idが未設定の状態で html フォームから POST データが送られてくる。
  2. POSTデータがテーブル bm に新規レコードとして追加される。そのとき、bm_id に連番が設定される。
  3. 設定された連番を取得し、テーブル tag の中の項目 bm_id にその値をセットする。
  4. テーブル tag にレコードが追加される。

という処理になります。

更新失敗時の扱い

一つ目のテーブルの更新は成功したけど二つ目以降のテーブルの更新に失敗した場合、ロールバックしなければいけません。

これには幾つか問題があって、

  1. XOOPS の基本設計はロールバックしないようになっているみたいで、Core では全くやっていません(複数のテーブルを一度に更新する、というのがない)。なのであまり好ましくないのかもしれない。
  2. MySQL のバージョンや設定によってはトランザクションをサポートしている InnoDB が使えない可能性がある。実際、テストで使っている XSAS, XaioInnoDB が使えない(Xaio についてはここを参照)。
  3. あまり経験がないぞ(ロールバックに限らないけど)。簡単なテストでロールバックが機能するのは確認しましたが、抜け落ちているケースとかありそうな気もします。

具体的なコードについては次回以降で解説します。

*1:もちろん、テーブルの持たせ方によっては必要ないのですが、参考にした Scuttle の場合、ブックマーク URL やコメントを保存するブックマークテーブルと、タグを分解して保存するタグテーブルとに分けたテーブル設計になっていますし、妥当なところだろうと思います。