March 20, 2013

FuelPHPの物理削除と論理削除の実行結果メモ

FuelPHP1.5.3にて、以下の組み合わせに対して、それぞれ親Modelからdeleteメソッドを実行してみました。その結果をメモしておきます。尚、実行環境はMAMP(Mac)のPHP5.4.4、ドライバはPDOです。

(1) 親: 物理削除モデル / 子: 物理削除モデル
(2) 親: 論理削除モデル / 子: 論理削除モデル
(3) 親: 物理削除モデル / 子: 論理削除モデル
(4) 親: 論理削除モデル / 子: 物理削除モデル

初期化用SQLは以下です。各組み合わせの実行前に、このSQLで初期化しました。
-- -----------------------------------------------------
-- Table `parents`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `parents` ;

CREATE  TABLE IF NOT EXISTS `parents` (
  `id` INT NOT NULL AUTO_INCREMENT ,
  `name` VARCHAR(255) NOT NULL ,
  `created_at` INT NOT NULL ,
  `updated_at` INT NOT NULL ,
  `deleted_at` INT ,
  PRIMARY KEY (`id`) )
ENGINE = InnoDB;

INSERT INTO `parents` (`id`, `name`, `created_at`, `updated_at`) VALUES
(1, 'parent1', 1363709961, 1363709961),
(2, 'parent2', 1363709961, 1363709961);

-- -----------------------------------------------------
-- Table `children`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `children` ;

CREATE  TABLE IF NOT EXISTS `children` (
  `id` INT NOT NULL AUTO_INCREMENT ,
  `parent_id` INT NOT NULL ,
  `name` VARCHAR(255) NOT NULL ,
  `created_at` INT NOT NULL ,
  `updated_at` INT NOT NULL ,
  `deleted_at` INT ,
  PRIMARY KEY (`id`) ,
  INDEX `fk_children_parents_idx` (`parent_id` ASC) )
ENGINE = InnoDB;

INSERT INTO `children` (`id`, `parent_id`, `name`, `created_at`, `updated_at`) VALUES
(1, 1, 'child1', 1363709961, 1363709961),
(2, 1, 'child2', 1363709961, 1363709961),
(3, 2, 'child3', 1363709961, 1363709961);
初期化用SQLに対する検索結果は以下です。
mysql> select * from parents;
+----+---------+------------+------------+------------+
| id | name    | created_at | updated_at | deleted_at |
+----+---------+------------+------------+------------+
|  1 | parent1 | 1363709961 | 1363709961 |       NULL |
|  2 | parent2 | 1363709961 | 1363709961 |       NULL |
+----+---------+------------+------------+------------+
2 rows in set (0.00 sec)

mysql> select * from children;
+----+-----------+--------+------------+------------+------------+
| id | parent_id | name   | created_at | updated_at | deleted_at |
+----+-----------+--------+------------+------------+------------+
|  1 |         1 | child1 | 1363709961 | 1363709961 |       NULL |
|  2 |         1 | child2 | 1363709961 | 1363709961 |       NULL |
|  3 |         2 | child3 | 1363709961 | 1363709961 |       NULL |
+----+-----------+--------+------------+------------+------------+
3 rows in set (0.00 sec)

使用したModelは、それぞれ以下です。
尚、物理削除モデルと論理削除モデルとで異なるのは、継承するクラスとprotected static $_soft_deleteの有無のみです。

親: 物理削除モデル
<?php

class Model_Parent extends \Orm\Model
{
    protected static $_properties = array(
        'id',
        'name',
        'deleted_at',
        'created_at',
        'updated_at',
    );

    protected static $_observers = array(
        'Orm\Observer_CreatedAt' => array(
            'events' => array('before_insert'),
            'mysql_timestamp' => false,
        ),
        'Orm\Observer_UpdatedAt' => array(
            'events' => array('before_save'),
            'mysql_timestamp' => false,
        ),
    );

    protected static $_has_many = array(
        'comments' => array(
            'key_from' => 'id',
            'model_to' => 'Model_Child',
            'key_to' => 'parent_id',
            'cascade_save' => true,
            'cascade_delete' => true,
        )
    );
}
子: 物理削除モデル
<?php

class Model_Child extends \Orm\Model
{
    protected static $_properties = array(
        'id',
        'parent_id',
        'name',
        'deleted_at',
        'created_at',
        'updated_at',
    );

    protected static $_observers = array(
        'Orm\Observer_CreatedAt' => array(
            'events' => array('before_insert'),
            'mysql_timestamp' => false,
        ),
        'Orm\Observer_UpdatedAt' => array(
            'events' => array('before_save'),
            'mysql_timestamp' => false,
        ),
    );

    protected static $_belongs_to = array(
        'post' => array(
            'key_from' => 'parent_id',
            'model_to' => 'Model_Parent',
            'key_to' => 'id',
            'cascade_save' => false,
            'cascade_delete' => false,
        )
    );
}
親: 論理削除モデル
<?php

class Model_Parent extends \Orm\Model_Soft
{
    protected static $_soft_delete = array(
        'mysql_timestamp' => false,
    );

    protected static $_properties = array(
        'id',
        'name',
        'deleted_at',
        'created_at',
        'updated_at',
    );

    protected static $_observers = array(
        'Orm\Observer_CreatedAt' => array(
            'events' => array('before_insert'),
            'mysql_timestamp' => false,
        ),
        'Orm\Observer_UpdatedAt' => array(
            'events' => array('before_save'),
            'mysql_timestamp' => false,
        ),
    );

    protected static $_has_many = array(
        'comments' => array(
            'key_from' => 'id',
            'model_to' => 'Model_Child',
            'key_to' => 'parent_id',
            'cascade_save' => true,
            'cascade_delete' => true,
        )
    );
}
子: 論理削除モデル
<?php

class Model_Child extends \Orm\Model_Soft
{
    protected static $_soft_delete = array(
        'mysql_timestamp' => false,
    );

    protected static $_properties = array(
        'id',
        'parent_id',
        'name',
        'deleted_at',
        'created_at',
        'updated_at',
    );

    protected static $_observers = array(
        'Orm\Observer_CreatedAt' => array(
            'events' => array('before_insert'),
            'mysql_timestamp' => false,
        ),
        'Orm\Observer_UpdatedAt' => array(
            'events' => array('before_save'),
            'mysql_timestamp' => false,
        ),
    );

    protected static $_belongs_to = array(
        'post' => array(
            'key_from' => 'parent_id',
            'model_to' => 'Model_Parent',
            'key_to' => 'id',
            'cascade_save' => false,
            'cascade_delete' => false,
        )
    );
}

実行に使用したタスクは以下です。
<?php

namespace Fuel\Tasks;

class Delete
{
    public static function run()
    {
        $parent = \Model_Parent::find(1);
        $parent->delete();
    }
}

上記タスク実行後の検索結果は、それぞれ以下です。

(1) 親: 物理削除モデル / 子: 物理削除モデル
mysql> select * from parents;
+----+---------+------------+------------+------------+
| id | name    | created_at | updated_at | deleted_at |
+----+---------+------------+------------+------------+
|  2 | parent2 | 1363709961 | 1363709961 |       NULL |
+----+---------+------------+------------+------------+
1 row in set (0.00 sec)

mysql> select * from children;
+----+-----------+--------+------------+------------+------------+
| id | parent_id | name   | created_at | updated_at | deleted_at |
+----+-----------+--------+------------+------------+------------+
|  3 |         2 | child3 | 1363709961 | 1363709961 |       NULL |
+----+-----------+--------+------------+------------+------------+
1 row in set (0.00 sec)
(2) 親: 論理削除モデル / 子: 論理削除モデル
mysql> select * from parents;
+----+---------+------------+------------+------------+
| id | name    | created_at | updated_at | deleted_at |
+----+---------+------------+------------+------------+
|  1 | parent1 | 1363709961 | 1363712747 | 1363712747 |
|  2 | parent2 | 1363709961 | 1363709961 |       NULL |
+----+---------+------------+------------+------------+
2 rows in set (0.00 sec)

mysql> select * from children;
+----+-----------+--------+------------+------------+------------+
| id | parent_id | name   | created_at | updated_at | deleted_at |
+----+-----------+--------+------------+------------+------------+
|  1 |         1 | child1 | 1363709961 | 1363712747 | 1363712747 |
|  2 |         1 | child2 | 1363709961 | 1363712747 | 1363712747 |
|  3 |         2 | child3 | 1363709961 | 1363709961 |       NULL |
+----+-----------+--------+------------+------------+------------+
3 rows in set (0.00 sec)
(3) 親: 物理削除モデル / 子: 論理削除モデル
mysql> select * from parents;
+----+---------+------------+------------+------------+
| id | name    | created_at | updated_at | deleted_at |
+----+---------+------------+------------+------------+
|  2 | parent2 | 1363709961 | 1363709961 |       NULL |
+----+---------+------------+------------+------------+
1 row in set (0.00 sec)

mysql> select * from children;
+----+-----------+--------+------------+------------+------------+
| id | parent_id | name   | created_at | updated_at | deleted_at |
+----+-----------+--------+------------+------------+------------+
|  1 |         0 | child1 | 1363709961 | 1363712797 | 1363712797 |
|  2 |         0 | child2 | 1363709961 | 1363712797 | 1363712797 |
|  3 |         2 | child3 | 1363709961 | 1363709961 |       NULL |
+----+-----------+--------+------------+------------+------------+
3 rows in set (0.00 sec)
(4) 親: 論理削除モデル / 子: 物理削除モデル
* この組み合わせのみ、エラーが出ました。
Error - Both sides of the relation must be subclasses of Model_Soft if cascade delete is true in PKGPATH/orm/classes/model/soft.php on line 177

No comments:

Post a Comment