以前、RakeタスクからFluetnMigratorを実行しましたが、Albacore v2.xではfluentmigrator
メソッドがなく、Wikiに書かれている内容では実行できませんでした。
そんな中、Albacore v2.xのGitHubを眺めていたところ、albacore/fluent_migrator.rbとそれに対応するspecのalbacore/fluent_migrator_spec.rbを見つけました。
Gitのログを見ていると、それらはv2.0.0のリリース後の2014/9/3に更新されていることが分かりました。
ということは、Wikiなどには記載されていないものの、もしかしたらAlbacore v2.xでもFluentMigratorを実行できるのではと考え、試してみました。
環境
- Windows7 x64
- .NET Framework 4.5
- NuGet
- FluentMigrator 1.3.1.0
- FluentMigrator.Tools 1.3.1.0
- System.Data.SQLite.Core 1.0.94.0
- Ruby 2.1.5
- gem
- Rake 10.4.2
- Albacore 2.3.8
Albacore v2.x のコードを読んでみる
ここでは現バージョンである、Albacore 2.3.8のコードを読んでみます。
Albacore::Tools::FluentMigrator::Cmdクラス
initializeメソッド
17行目にあるinitialize
メソッドにて、FluentMigratorのコマンドやパラメータを生成しています。
21行目で、FluentMigrator用の設定を行っています。initializeメソッドの引数になかった内容については、ここでデフォルト値を設定しています。
71行目で、mono_command
メソッドを実行して、Monoでも動作するようにしています。
executeメソッド
74行目にありますが、ここでFluentMigratorを実行しているようです。
Albacore::Tools::FluentMigrator::MigrateCmdFactoryクラス
Albacore::Tools::FluentMigrator::Cmdクラスを直接生成しても良さそうでしたが、ファクトリメソッドを持つクラス(MigrateCmdFactory)が176行目にあったため、こちらも見てみます。
ファクトリメソッドなので、initializeではなく、MigrateCmdFactory.create
というクラスメソッドを使ってインスタンスを生成します。
以上より、MigrateCmdFactory.createでインスタンスを生成した後、executeメソッドを使えば実行できそうに見えたので、試してみることにします。
事前準備
上記のgemやNuGetのパッケージをインストールします。
FluentMigratorについては、以前と同様、以下の2ファイルをリンクとして追加し、ビルド時に出力ディレクトリへとコピーするようにします。
- FluentMigrator.Runner.dll
- Migrate.exe
Rakefileの作成
今回は、FluentMigratorのRakeタスクの書き方に似たような感じで作成してみます。
MigrateCmdFactory.create の引数を確認
FluentMigratorの実行に関するものは、MigrateCmdFactory.createの引数として渡せます。主な引数は以下の通りです。
メソッドの引数名 | 対応するオプションなど | 値 |
---|---|---|
exe | FluentMigratorの実行ファイル | path/to/Migrate.exe |
dll | --target | FluentMigraotorのマイグレーションファイルが含まれるexeやdll |
db | --db | sqlite やpostgres など |
conn | --conn | FluentMigratorで使う、接続文字列 |
direction | --task | migrate やrollback など |
extras | 他のオプション | 単一は"--steps=2" 、複数は配列で["--steps=2", "--output=true"] |
interactive | 該当なし | false で対話画面なし |
参考: Command Line Runner Options · schambers/fluentmigrator Wiki · GitHub
注意しなければいけないのはinteractive
です。FluentMigratorには存在しないオプションですが、デフォルトがtrue
となっているため、何も指定しないと対話式になってしまいます。
invoke_taskの修正
FluentMigratorのWikiでは、
Rake.application.invoke_task("db:migrator[\"migrate\"]")
となっていますが、このままコピペをして実行すると、
-conn "Data Source=D:\db\albacore.db" --timeout=200 --task "migrate"
のようにtaskがダブルクオーテーションで囲まれて指定されるため、マイグレーション自体が実行されなくなります。
そのため、
Rake.application.invoke_task("db:migrator[migrate]")
のようにダブルクオーテーションを外すと、実行結果が以下となり、問題なく実行されます。
-conn "Data Source=D:\db\albacore.db" --timeout=200 --task migrate
reenable
とinvoke_task
はそのまま
reenable
とinvoke_task
にも手を付けようかと考えましたが、以下を読んで今回はそのままにしておきます。
- ruby - How to run Rake tasks from within Rake tasks? - Stack Overflow
- ruby - Why is Rake not able to invoke multiple tasks consecutively? - Stack Overflow
- ruby - How do I pass command line arguments to a rake task? - Stack Overflow
存在しないfluentmigrator
メソッドを修正
fluentmigrator
をtask
に直します。
以上で完了です。
実行
FluentMigratorが実行できました。
d:\GitHub\Albacore-FluentMigrator-sample>bundle exec rake db:migrate --trace DL is deprecated, please use Fiddle ** Invoke db:migrate (first_time) ** Invoke db:migrate:up (first_time) ** Execute db:migrate:up ** Invoke db:migrator (first_time) ** Execute db:migrator packages\FluentMigrator.Tools.1.3.1.0\tools\x86\40\Migrate.exe -a Albacore-FluentMigrator-sample\bin\Debug\Albacore-FluentMigrator-sample.exe -db sqlite -conn "Data Source=D:\db\albacore.db" --timeout=200 --task migrate --steps=2 ------------------------------------------------------------------------------- =============================== FluentMigrator ================================ ------------------------------------------------------------------------------- Source Code: http://github.com/schambers/fluentmigrator Ask For Help: http://groups.google.com/group/fluentmigrator-google-group ------------------------------------------------------------------------------- [+] Using Database sqlite and Connection String "Data Source=D:\db\albacore.db" ------------------------------------------------------------------------------- VersionMigration migrating ------------------------------------------------------------------------------- [+] CreateTable VersionInfo [+] VersionMigration migrated ------------------------------------------------------------------------------- VersionUniqueMigration migrating ------------------------------------------------------------------------------- [+] CreateIndex VersionInfo (Version) [+] AlterTable VersionInfo [+] CreateColumn VersionInfo AppliedOn DateTime [+] VersionUniqueMigration migrated ------------------------------------------------------------------------------- VersionDescriptionMigration migrating ------------------------------------------------------------------------------- [+] AlterTable VersionInfo [+] CreateColumn VersionInfo Description String [+] VersionDescriptionMigration migrated ------------------------------------------------------------------------------- 1: Mig_01_CreateTable migrating ------------------------------------------------------------------------------- [+] CreateTable user_table [+] 1: Mig_01_CreateTable migrated ------------------------------------------------------------------------------- 2: Mig_02_InsertData migrating ------------------------------------------------------------------------------- [+] -> 1 Insert operations completed in 00:00:00.0050003 taking an average of 00:00:00.0050003 [+] 2: Mig_02_InsertData migrated [+] Task completed. ** Execute db:migrate
アンドキュメントな内容ですが、自分でいろいろと実装するのが手間なので、コードが残っている限りは使えそうです。
ソースコード
GitHubに上げておきました。
thinkAmi-sandbox/Albacore-FluentMigrator-sample