マイグレーション処理の流れ

d:id:nattou_curry_2:20081108:1226139684では、マイグレーション時のインデックスDDL作成について少し調べました。
今回はもう少し範囲を広げて、ソースの内容からマイグレーション処理の流れを調べてみました。対象のクラスはnet.java.ao.schema.SchemaGeneratorです。(ちなみに、このクラスはAcitveObjectsの公開APIではありません。)
以下、SchemaGeneratorの主要な関数毎に、処理の流れを記載しました。なお、依存関係に関する処理は言葉で書くと複雑なので、詳細は省略しました。依存関係については、余力があれば後で図解します。

エンティティインタフェースのマイグレーションを行う。

public static void migrate()

  1. エンティティインタフェースからSQL文を生成する。
  2. すべてのSQL文について繰り返す。
    1. SQL文を実行する。

エンティティインタフェースからSQL文を生成する。

private static String[] generateImpl()

  1. エンティティインタフェースを解析してDDLを作成する。
  2. スキーマを読み取り、DDLを作成する。(詳細は別クラスのため未解読)
  3. DDLの差分をとり、並べ替えを行い、DDLアクションを作成する。(詳細は別クラスのため未解読)
  4. すべてのDDLアクションについて繰り返す。
    1. DDLアクションからSQL文を作成する。

エンティティインタフェースを解析してDDLを作成する。

static DDLTable[] parseDDL()

  1. すべてのエンティティインタフェースについて繰り返す。
    1. エンティティインタフェースを解析して依存関係を取得する。
  2. 依存関係に含まれるすべてのエンティティインタフェースについて繰り返す。(詳細は省略)
    1. エンティティインタフェースがポリモフィックアノテーションを持たないことを確認する。
      1. エンティティインタフェースを解析してテーブルDDLを作成する。

エンティティインタフェースを解析して依存関係を取得する。

private static void parseDependencies()

  1. すべてのエンティティインタフェースについて繰り返す。
    1. エンティティインタフェースのすべてのメソッドについて繰り返す。
      1. 以下をすべて満たすことを確認する。
        • メソッドから属性名を取得できること。
        • メソッドから属性型を取得できること。
        • メソッドから取得した属性型がエンティティであること。
          1. エンティティインタフェースから、メソッドから取得した属性型への、依存関係を作成する。(詳細は省略)

エンティティインタフェースを解析してテーブルDDLを作成する。

private static DDLTable parseInterface()

  1. エンティティインタフェースからテーブルDDLを作成する。
  2. エンティティインタフェースを解析してフィールドDDLを作成し、テーブルDDLに追加する。
  3. エンティティインタフェースを解析して外部キーDDLを作成し、テーブルDDLに追加する。
  4. エンティティインタフェースを解析してインデックスDDLを作成し、テーブルDDLに追加する。

エンティティインタフェースを解析してフィールドDDLを作成する。

private static DDLField[] parseFields()

  1. エンティティインタフェースのすべてのメソッドについて繰り返す。
    1. メソッドが以下のアノテーションを一切持たないことを確認する。
    2. 以下をすべて満たすことを確認する。
      • メソッドから属性名を取得できる。
      • メソッドから属性型を取得できる。
        1. 未処理の属性型であることを確認する。
          1. 処理済みである:次の繰り返しに進む。
        2. メソッド用のフィールドを作成する。
        3. メソッドがPrimaryKeyアノテーションを持つことを確認する。
          1. メソッド用のフィールドを主キーにする。
        4. メソッドがNotNullアノテーションを持つことを確認する。
          1. メソッド用のフィールドを非nullにする。
        5. メソッドがUniqueアノテーションを持つことを確認する。
          1. メソッド用のフィールドをユニークにする。
        6. メソッドがAutoIncrementアノテーションを持つことを確認する。
          1. メソッド用のフィールドをオートインクリメントにする。
        7. メソッドがAutoIncrementアノテーションを持たない: メソッドがDefaultアノテーションを持つことを確認する。
          1. メソッド用のフィールドのデフォルト値として、AutoIncrementアノテーションの値を設定する。
        8. メソッドがOnUpdateアノテーションを持つことを確認する。
          1. メソッド用のフィールドの更新イベントを受け取るフィールドとして、OnUpdateアノテーションの値を設定する。
        9. 以下をすべて満たすことを確認する。
          • 属性型がエンティティであること。
          • 属性型がPolymorphicアノテーションを持つこと。
            1. メソッド用のフィールドからデフォルト値を削除する。
            2. メソッド用のフィールドから更新イベントを受け取るフィールドを削除する。
            3. メソッドからポリモフィック型フラグの属性名を取得する。
            4. ポリモフィック型フラグ用のフィールドを作成する。
            5. メソッドがNotNullアノテーションを持つことを確認する。
              1. ポリモフィック型フラグ用のフィールドを非nullにする。

エンティティインタフェースを解析して外部キーDDLを作成する。

private static DDLForeignKey[] parseForeignKeys()

  1. エンティティインタフェースのすべてのメソッドについて繰り返す。
    1. 以下をすべて満たすことを確認する。
      • メソッドから属性型を取得できる。
      • メソッドから属性名を取得できる。
      • メソッドの属性型がエンティティである。
      • メソッドの属性型がPolymorphicアノテーションを持たない。
        1. 外部キーを作成する。

エンティティインタフェースを解析してインデックスDDLを作成する。

private static DDLIndex[] parseIndexes()

  1. エンティティインタフェースのすべてのメソッドについて繰り返す。
    1. メソッドがアクセッサかミューテータのいずれかであることを確認する。
      1. 以下のいずれかに当てはまることを確認する。
        • メソッドがIndexedアノテーションを持つ。
        • メソッドから属性型が取得でき、その属性型がエンティティである。
          1. メソッドからインデックスを作成する。
  2. エンティティインタフェースのすべての上位インタフェースについて繰り返す。
    1. 上位インタフェースがエンティティであることを確認する。
      1. 上位エンティティインタフェースを解析してインデックスDDLを作成する。