augustash / capistrano-ash

August Ash recipes for Capistrano
http://augustash.com
MIT License
73 stars 12 forks source link

add a method to run mysql statements in a consistent manner #36

Open grafikchaos opened 11 years ago

grafikchaos commented 11 years ago

Just an idea, but maybe something like this would help DRY up some of the manual MySQL commands we use for updating database configuration settings. I'd like to be able to do something more along the lines of run where I can pass in the statement (e.g., mysql.execute "UPDATE ...") directly instead of having to overwrite the sql_statement parameter within each task.


For comparison, here's the old/current way this is being handled

run "mysql -u #{wp_db_user} --password=#{wp_db_pass} -e 'UPDATE #{wp_db_name}.#{wp_db_prefix}options SET option_value = \"#{wp_base_url}\" WHERE option_name = \"siteurl\" OR option_name = \"home\"'"

DRY(?) method of running mysql statements

# example task that would override any previously set :sql_statement value 
# and utilize the `mysql.execute` task
namespace :wordpress do
  desc "Set WordPress Base URL in database"
  task :updatedb, :roles => :db, :except => { :no_release => true } do
    wp_blogs.each do |blog|
      wp_blog_directory   = blog[:directory]
      wp_db_prefix        = blog[:db_prefix]
      wp_base_url_prefix  = blog[:base_url]["#{stage}".to_sym]
      wp_base_url         = "#{wp_base_url_prefix}/#{wp_blog_directory}"

      set :sql_statement, "UPDATE #{wp_db_name}.#{wp_db_prefix}options SET option_value = \"#{wp_base_url}\" WHERE option_name = \"siteurl\" OR option_name = \"home\""

      # executes the above :sql_statement
      mysql.execute
    end
  end
end

# --------------------------------------------
# MySQL commands
# --------------------------------------------
namespace :mysql do
  desc <<-DESC
    [internal] Runs mysql commands in a more reliable pattern.

    This would essentially be similar to our backup:db task but with some additional \ 
    assumptions that you need to define the :sql_statement parameter within your task \ 
    to override any previously defined value and that you use the same values for \ 
    username and password as your :dbuser and :dbpass
  DESC
  task :execute, :roles => :db do
    full_sql_statement = "mysql -u #{dbuser} -p -e '#{sql_statement}'"
    run "#{full_sql_statement}" do |ch, stream, out|
      ch.send_data "#{dbpass}\n" if out =~ /^Enter password:/
    end
  end
end