【PHP】CodeIgniter でマイグレーション【CodeIgniter】

CodeIgniterでのマイグレーションの設定をタイムスタンプにて行いましたので、備忘録として残しておきます。

## CodeIgniterバージョン

CodeIgniter 3.0.0

## 1. マイグレーション使用設定

まず、マイグレーションを使用するための設定をします。

```php:application/config/migration.php

// マイグレーションを使用する設定
// デフォルトでFALSEなので、TRUEに変更
$config['migration_enabled'] = TRUE;

// マイグレーションファイルを配置するディレクトリのパス
// デフォルトで APPPATH.'migrations/' だが、任意に変更可能
$config['migration_path'] = APPPATH.'migrations/';

// マイグレーションのバージョン管理方法
// デフォルトで 'timestamp'、連番での管理の場合は 'sequential'
$config['migration_type'] = 'timestamp';

```

## 2. migrationsディレクトリの作成

「1. マイグレーション使用設定」にて設定した`$config['migration_path']`の通りに migrationsフォルダを作成します。
(フォルダ作成後に設定ファイルにパスを書くほうが順序としては分かりやすいかもしれないですね。)

今回はデフォルトで

```php

$config['migration_path'] = APPPATH.'migrations/';

```

なので、
`application/migrations`
のようにディレクトリを作成しました。


## 3. コントローラクラスの作成

以下のようにコントローラディレクトリにコントローラクラスを作成しました。

```php:application/controllers/Migrate.php

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Migrate extends CI_Controller {

    function __construct()
    {   
        parent::__construct();
        if(! $this->input->is_cli_request()) {
            show_404();
            exit;
        }   
        $this->load->library('migration');
    }   

    function current()
    {   
        if ($this->migration->current()) {
            log_message('error', 'Migration Success.');
        } else {
            log_message('error', $this->migration->error_string());
        }   
    }   

    function rollback($version)
    {   
        if ($this->migration->version($version)) {
            log_message('error', 'Migration Success.');
        } else {
            log_message('error', $this->migration->error_string());
        }   
    }   

    function latest()
    {   
        if ($this->migration->latest()) {
            log_message('error', 'Migration Success.');
        } else {
            log_message('error', $this->migration->error_string());
        }   
    }

}

```

## 4. マイグレーションファイルの作成

### 作成場所

`$config['migration_path']`で設定したディレクトリ内（今回は<code>application/migrations</code>ディレクトリの中）</dd>

### ファイル名

`{YYYYMMDDHHIISS}_{一意の名前}.php`
例：`20150914082232_add_mycolumn_to_mytable.php`

今回、`$config['migration_type']`でタイムスタンプを選択したので、
ファイル名の始めに「YYYYMMDDHHIISS」フォーマットのタイムスタンプをつけます。
次に、アンダースコアで区切って`{一意の名前}`の部分を追加してファイル名とします。
`{一意の名前}`の部分はマイグレーションファイル内に記述するクラス名として使用するため、他のマイグレーションファイルの名前（タイムスタンプを除いた部分）と被らないようにします。

今回私が携わったプロジェクトでは、`{一意の名前}`の部分は以下のRailsの命名規則を参考にしました。
http://kzy52.com/entry/2014/11/28/210004


### ファイル内容

```php:application/migrations/20150914082232_add_mycolumn_to_mytable.php

<?php
class Migration_Add_mycolumn_to_mytable extends CI_Migration {

    public function __construct()
    {   
        parent::__construct();
    }

    // アップデート処理
    public function up()
    {   
        $fields = array(
            'mycolumn' => array (
                'type' => 'VARCHAR',
                'constraint' => '100'
            )   
        );  
        $this->dbforge->add_column('mytable', $fields);
    }   

    // ロールバック処理
    public function down()
    {   
        $this->dbforge->drop_column('mytable', 'mycolumn');
    }

}

```

クラス名として`Migration_{ファイル名の一意の名前部分}`を使用します。
`{ファイル名の一意の名前部分}`はリファレンスでは先頭を大文字にしていますが、小文字のままでも動きました。

dbforgeの使い方は以下を参照ください。
http://codeigniter.jp/user_guide/3/database/forge.html

upとdownで整合性が取れていればいいので、dbforgeの利用だけでなく、
テーブル作成直後に`$this->db->insert()`でマスターデータの挿入をしたり、
`$this->db->simple_query();`で直接SQLを書いてリレーションを張ったりもできるかと思います。

また、一つのファイルの中で複数のテーブル作成やカラムの追加などを実行することもできますが、
今回のプロジェクトでは、
細かく管理するために１つのマイグレーションファイルで実行する操作は１つとしました。


## 5. マイグレーションの実行

マイグレーションの実行は
プロジェクトのルートディレクトリにて、コマンドラインから以下を実行します。

```

php index.php migrate latest

```

`latest`であれば`$config['migration_path']`内の最新のマイグレーションファイルまで実行されます。

以下のように`current`を指定すると`application/config/migration.php`の`$config['migration_version']`にて指定した
バージョンまでマイグレーションされます。

```

php index.php migrate current

```

## 終わりに

以上となりますが、マイグレーションファイルをタイムスタンプをつけて自分で作成しないといけないのが面倒なので、その辺りが自動化できれば、、
と思っていたら下のような記事を見つけました。
http://blog.a-way-out.net/blog/2015/05/07/codeigniter-cli/
まだきちんと読んでいないので、読んでみて参考にさせていただければと思います。


## 参考
http://www.codeigniter.com/user_guide/libraries/migration.html
http://qiita.com/shikataka/items/d3fd15f650f85a8ce118