symfony 1.4 メモ（schemaの書き方）

1. [symfony 1.4 メモ（アクション）](https://qiita.com/shotets/items/dd56c98d397a42fa4f50)
2. [symfony 1.4 メモ（context）](https://qiita.com/shotets/items/ffa0baa3f930d8992dcb)
3. [symfony 1.4 メモ（モデル）](https://qiita.com/shotets/items/535204c3e7ad1decdab4)
4. **symfony 1.4 メモ（schemaの書き方）**
5. [symfony 1.4 メモ（Doctrine）](https://qiita.com/shotets/items/e7638a72fa90c687ab81)
6. [symfony 1.4 メモ（フォーム）](https://qiita.com/shotets/items/8343167452d42d67b93e)
7. [symfony 1.4 メモ（コマンド）](https://qiita.com/shotets/items/82d1f9f8d00f25e65197)
8. [symfony 1.4 メモ（ユーティリティ）](https://qiita.com/shotets/items/ca32b99e43badfe53f98)

## テーブル定義

<dl>
<dt>abstract</dt>
<dd>生成クラスをabstractするかどうか。デフォルトはfalse。クラスはabstractのときはデータベースにエクスポートされない。</dd>
<dt>className</dt>
<dd>生成するクラスの名前</dd>
<dt>tableName</dt>
<dd>使用するDBMSのテーブルの名前</dd>
<dt>connection</dt>
<dd>モデルにバインドするDoctrine_Connectionインスタンスの名前</dd>
<dt>columns</dt>
<dd>カラムの定義</dd>
<dt>relations</dt>
<dd>リレーションの定義</dd>
<dt>indexes</dt>
<dd>インデックスの定義</dd>
<dt>attributes</dt>
<dd>属性の定義</dd>
<dt>actAs</dt>
<dd>ActAsの定義</dd>
<dt>options</dt>
<dd>オプションの定義</dd>
<dt>inheritance</dt>
<dd>継承の定義用の配列</dd>
<dt>listeners</dt>
<dd>アタッチするリスナーを定義する配列</dd>
<dt>checks</dt>
<dd>DBMSにエクスポートするのと同様にアプリケーションレベルで実行するチェック</dd>
</dl>

## ビヘイビア

モデルに指定した機能拡張を追加できる。

```yaml
  actAs:
    # 緯度と経度をモデルに追加してレコード間のマイル/キロメータを計算する機能を提供する。
    Geographical:
 
    # モデルに国際化機能を追加する。
    I18n:
      fields: [name, genre, level1, level2, level3, level4, level5]
 
    # モデルをtraversableツリーに変換する。
    NestedSet:
 
    # モデルのデータすべてのインデックスを作成して検索可能にする。
    Searchable:
 
    # slugフィールドをモデルに追加し設定に基づいてスラグを自動的に作成する。
    Sluggable:
      fields: [username]
      name: slug       # defaults to 'slug'
      type: string     # defaults to 'clob'
      length: 255      # defaults to null. clob doesn't require a length
 
    # 実際にはレコードを削除しない。代わりにdeletedフラグを設定してクエリのselectからすべてのdeleteされたレコードをフィルタリングします。
    # deleted: { type: boolean, notnull: true, default: false }
    SoftDelete:
 
    # created_atとupdated_atカラムをモデルに追加しレコードのinsertとupdateをするときにDoctrineにそれらを設定させる。
    Timestampable: ~
 
    # モデルをauditログに切り替えすべての変更を記録する。以前のバージョンに簡単に差し戻しする機能を提供する。
    Versionable:
```

## モデルの継承

似たような、あるいはまったく同じ動作をするモデルの場合、モデルを継承させることができる。

```yaml
  inheritance:
    extends: 親のモデル名
    type: concrete  # 子クラスは親のカラムをすべて持ち、さらに個別のテーブルを持つ（子クラスのテーブルが生成されるが、モデルClassは継承される）
    type: simple    # 子クラスは親と同じテーブルとカラムを持つ（同一のテーブルを共有する）
    type: column_aggregation  # すべてのカラムは親の中で定義しなければならずそれぞれの子クラスはtypeカラムで決定される（同一のテーブルを共有し、typeフィールドによってクラスを切り替える）
```

## リレーション

```yaml
  relations:
    ModelName:
        class         リレーション用に使うクラスの名前。
        alias         リレーションを識別するために使うエイリアス。
        type          リレーションの型。値はoneもしくはmanyのどちらかでデフォルトはone。
        refClass      多対多のリレーション用に使われる中間の参照クラス。
        local         リレーションで使われるローカルフィールドの名前。
        foreign       リレーションで使われる外部フィールドの名前。
        foreignAlias  リレーションの反対端のエイリアス。autoCompleteがtrueに設定されるときのみ許可されます。（リレーション先で使われるパラメータ名、メソッド名）
        foreignType   リレーションの反対端の型。autoCompleteがtrueに設定されるときのみ許可されます。
        autoComplete  リレーションを反対側に追加して双方向にするかどうか。デフォルトはtrue。
        cascade       アプリケーションレベルのカスケーディングオプション。
        onDelete      データベースレベルのカスケーディング削除の値。
        onUpdate      データベースレベルのカスケーディング更新の値。
        equal         リレーションが入れ子の多対多に等しいかどうか。
```

```yaml:記述例
  # 一対一
  relations:
    User:              # 関連するテーブル名を入れると自動的に設定される
      foreignType: one
 
  # 一対多
  # 子側に設定する
Phonenumber:
  relations:
    User:              # 関連するテーブル
      foreignAlias: Phonenumbers   # 親側が子を取得する際のメソッド名
 
  # 多対多
BlogPost:
  columns:
    user_id: integer
    title: string(255)
    body: clob
  relations:
    User:
      local: user_id
      foreign: id
      type: one
      foreignType: one
      foreignAlias: BlogPosts
    Tags:
      class: Tag
      foreignAlias: BlogPosts
      refClass: BlogPostTag
      local: blog_post_id
      foreign: tag_id
 
Tag:
  columns:
    name: string(255)
 
BlogPostTag:
  columns:
    blog_post_id:
      type: integer
      primary: true
    tag_id:
      type: integer
      primary: true
  relations:
    BlogPost:
      local: blog_post_id
      foreign: id
      foreignAlias: BlogPostTags
    Tag:
      local: tag_id
      foreign: id
      foreignAlias: BlogPostTags
 
  # カスケード
  relations:
    User:
      foreignAlias: Phonenumbers
      onDelete: CASCADE
```

## オプション

```yaml:記述例
  options:
    symfony:
      form: false      # フォームクラスを生成しない
      filter: false    # フィルタフォームクラスを生成しない
    comment: 'コメント'
```

## Indexes

```yaml:記述例
  indexes:
    name_index:
      fields:
        first_name:
          sorting: ASC
          length: 10
          primary: true
        last_name: []
      type: unique
```

## 省略

```yaml:記述例
#id というフィールド名で設定を省略すると、自動採番のプライマリーキーとして設定される。
id:  ~

#_id で終わるフィールド名で設定を省略すると、外部キーとして設定される。
xxx_id:  ~

#created_at というフィールド名で設定を省略すると、新規追加時に時刻が登録されるtimestamp型として設定される。
created_at:  ~

#updated_at というフィールド名で設定を省略すると、更新時に時刻が登録されるtimestamp型として設定される。
updated_at:  ~
```

## カラム

<dl>
<dt>name</dt>          <dd>カラムの名前</dd>
<dt>fixed</dt>         <dd>カラムが修正されるかどうか。（固定長かどうか）</dd>
<dt>primary</dt>       <dd>カラムが主キーの一部であるかどうか</dd>
<dt>autoincrement</dt> <dd>autoincrementカラムであるかどうか</dd>
<dt>type</dt>          <dd>Doctrineのカラムのデータ型</dd>
<dt>length</dt>        <dd>カラムの長さ</dd>
<dt>default</dt>       <dd>カラムのデフォルト値</dd>
<dt>scale</dt>         <dd>カラムのスケール。decimal型に使用される</dd>
<dt>values</dt>        <dd>enum型用の値のリスト</dd>
<dt>comment</dt>       <dd>カラム用のコメント</dd>
<dt>sequence</dt>      <dd>カラム用のシーケンスの定義</dd>
<dt>zerofill</dt>      <dd>カラムの空の文字列をゼロで満たすかどうか</dd>
<dt>extra</dt>         <dd>カラム定義に保存する追加情報の配列</dd>
<dt>unsigned</dt>      <dd>整数</dd>
</dl>

```yaml:記述例
User:
  columns:
    id:
      type: integer(4)
      primary: true
      autoincrement: true
    username: string(255)
    password: string(255)
    latitude: float
    longitude: float
    hourly_rate:
      type: decimal
      scale: 2
    groups_array: array
    session_object: object
    description: clob
    profile_image_binary_data: blob
    created_at: timestamp
    time_last_available: time
    date_last_available: date
    roles:
      type: enum
      values: [administrator, moderator, normal]
      default: normal
    html_header: gzip
```

## データ型

|schema|MySQL|
|:-----|:----|
|integer|integer|
|float|double|
|decimal|decimal|
|string|varchar &frasl; text|
|array|text|
|object|text|
|blob|longblob|
|clob|longtext|
|timestamp|datetime|
|time|time|
|date|date|
|enum|varchar &frasl; enum|
|gzip|text|

stringはstring(255)以上ならvarcharではなくtextになります。

clob (Character Large OBject)データ型は、通常はファイルに保存されるデータのように、
テキストフィールドで保存するには大きすぎる未定義の長さのデータを保存することを意味します。

blobフィールドがデータのすべての型を保存するのが想定されているのに対して
clobフィールドは印字可能なASCII文字で構成されるデータのみを保存することを想定しています。

内在するDBMSが”全文検索”として知られる機能をサポートしない限りclobフィールドは
クエリ検索句(WHERE)のパラメータとして使われることが想定されています。

gzipデータ型は存続するときに自動的に圧縮取得されたときに解凍される以外は文字列と同じです。
ビットマップ画像など、大きな圧縮率でデータを保存するときにこのデータ型は役に立ちます。