ホーム > > CakePHP 1.2.10 を PostgreSQL で使っているときに Fixture で SERIAL 型に INSERT すると SEQUENCE がインクリメントされない

CakePHP 1.2.10 を PostgreSQL で使っているときに Fixture で SERIAL 型に INSERT すると SEQUENCE がインクリメントされない

 なんでバグチケットみたいなタイトルなんだろう。まいいや。

 CakePHP でアプリを作ると,モデルへ新規レコードを保存 (AppModel::save()) するときには id (SERIAL 型とか AUTO_INCREMENT 属性とか)のデータを与えず,DB の自動生成に任せることが多いと思う。
 ところが UnitTest の fixture を書くときには,id も固定値でないと想定外の結果になったりして assertion が書けなくなってしまうので,id も与えて INSERT するようにテストデータを定義したい。

 ここで問題が発生する。

 PostgreSQL の場合,自動で挿入した id を記録しておくために SERIAL 型のレコード毎に SEQUENCE を持って保存しているんだが,SEQUENCE は SERIAL 型の DEFAULT 値に設定されている nextval() が生成した id を使っているため, fixture のようにアプリケーションが id を指定して INSERT してしまうと SEQUENCE を更新する奴が誰もいなくなってしまう,というおはなし。
 Cake on MySQL でどうなってるのかは知らん。

 というわけで,これに対処するために CakeTestFixture を継承した AppTestFixture でも作って app/tests にでも置いておく。

< ?php
class AppTestFixture extends CakeTestFixture
{
    function insert(&$db)
    {
        $result = parent::insert($db);
        if (array_key_exists('id', $this->fields)
            && $this->fields['id']['type'] == 'integer'
            && $this->fields['id']['key'] == 'primary'
        ) {
            $db->fetchAll("SELECT pg_catalog.setval(pg_get_serial_sequence('{$this->table}', 'id')"
                . ", (SELECT MAX(id) FROM {$this->table}), true);", false);
        }
        return $result;
    }
}

 あとはこれを継承して fixture を書けばおけ。

< ?php
require_once TESTS . 'app_test_fixture.php';

class HogeFixture extends AppTestFixture
{
    var $name = 'Hoge';
    var $import = array('table' => 'hoges', 'connection' => 'default');
    var $fields = array(
        0 => array(
            'id' => 1,
            'foo' => 'bar',
        ),
        1 => '以下略',
    );
}

コメント:0

コメントフォーム
入力した情報を記憶する

トラックバック:0

この記事のトラックバック URL
http://kagura-c.info/blog/2011/06/28/update_sequence_failure_on_cakephp_1-2_with_postgres/trackback/
トラックバックの送信元リスト
CakePHP 1.2.10 を PostgreSQL で使っているときに Fixture で SERIAL 型に INSERT すると SEQUENCE がインクリメントされない - Clotho の偶感録 より

ホーム > > CakePHP 1.2.10 を PostgreSQL で使っているときに Fixture で SERIAL 型に INSERT すると SEQUENCE がインクリメントされない

Twitter: clotho_moirai

ページの上部に戻る