Railsアプリの開発環境下でMySQLのストアドファンクションを作成し、
rakeでロードできるようにしています。
おおよそ次の手順で実現しました。
ストアドファンクションを書く。
{Rails.root}/script/db/sql 配下に、拡張子sqlのファイルとして、 ストアドファンクションを作成。
rakeタスクを書く。
{Rails.root}/lib/task 配下に、db_functions.rakeを作成。
タスクは、
- db:functions
- db:functions:load
1つ目は、ロードするファンクションの一覧を表示するタスク。
2つ目は、実際にファンクションをロードするタスク。
内容は以下の通り。
namespace :db do namespace :functions do desc "List .sql files." task :list => :environment do path = Rails.root + "script/db/sql/*.sql" Dir.glob(path) do |sql| puts File.basename(sql) end end desc "Load stored functions to the database." task :load => :environment do begin cmd = build_load_cmd(ActiveRecord::Base.configurations) path = Rails.root + "script/db/sql/*.sql" Dir.glob(path) do |file| exec(cmd + " < " + file) end rescue => e puts e.message raise e end end end end def build_load_cmd(db_config) env = ENV['RAILS_ENV'] env = 'development' if env.nil? conf = db_config[env] cmd = "mysql" cmd << " -h " + conf["host"] if conf["host"] cmd << " -u " + conf["username"] if conf["username"] cmd << " -p" + conf["password"] if conf["password"] cmd << " " + conf["database"] cmd end
これで、rake db:functions:load とすると、ファンクションが生成されます。
もちろん、sqlファイル内で、drop functionしてからcreate functionしています。
デプロイにCapistranoを使う場合、deploy:migrateタスクのafterフックにdb:functions:loadを追加すれば、 DBに変更がある場合に、ファンクションの更新も漏れ無く実行されます。
0 件のコメント:
コメントを投稿