# Dump Development DB Sul Production Server
#
# Autore: Matteo Alessani
# 
# Quest'opera è stata rilasciata sotto la licenza Creative Commons Attribuzione-Condividi
# allo stesso modo 2.5 Italia. Per leggere una copia della licenza visita il sito web
# http://creativecommons.org/licenses/publicdomain/ o spedisci una lettera a 
# Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
#
# Docs: http://www.extendi.it/ruby-on-rails/index.php/2006/10/23/capistrano-dump-del-development-database-to-production-database
# 
# USATELO A VOSTRO RISCHIO! QUESTO SCRIPT CREA E MODIFICA FILE, CREA DATABASE E
# SPOSTA FILE TRA SERVER ATTRAVERSO INTERNET. SOLO PER UTENTI AVANZATI!
#
# DESCRIZIONE
#
# Questa e' una ricetta personalizzata per Capistrano. Effettua una replica del development
# database sul server di deploy, in modo da avere oltre che la struttura replicata anche
# i dati contenuti nel database.
#
# Per una descrizione completa, vedere http://www.extendi.it/ruby-on-rails/index.php/2006/10/23/capistrano-dump-del-development-database-to-production-database
#
# Utilizzare scrivendo da shell:
#
# $ cap -a dump_db_to_database_server
#
# Una volta lanciato il comando sarà richiesta prima la password di connessione al server
# contenente il development database, poi la password per il server specificato nella variabile
# :site_url e infine la password per il server su cui verrà creato il production database.
# Queste ultime due possono risultare uguali.
#
# =============================================================================
# VARIABILI OBBLIGATORIE
# =============================================================================
# :application Impostare il nome dell'applicazione per cui effettuare il deploy
# :repository  Impostare l'indirizzo del repositorio in cui si trova l'applicazione

set :application, "your_app_name"
set :repository, "svn://svn.your_domain.com/#{application}/trunk"

# =============================================================================
# RUOLI
# =============================================================================
# Impostare l'indirizzo corrispondente ai vari server che utilizza l'applicazione
# in produzione. Supponiamo che Database, Applicazione e Web Server siano tutti
# sullo stesso computer, corrispondente a www.your_domain.com

role :web, "www.your_domain.com"
role :app, "www.your_domain.com"
role :db,  "www.your_domain.com", :primary => true
# Server su cui si ha il database in development (ad esempio all'interno della
# rete interna): development.your_domain.com. Viene utilizzata l'opzione
# :no_release => true per escluderlo dal deploy dell'applicazione
role :db,  "developemnt.your_domain.com", :primary => false, :no_release => true

set :deploy_to, "/home/rails/#{application}" # defaults to "/u/apps/#{application}"
set :user, "root"            # defaults to the currently logged in user
set :site_url, "www.your_domain.com" # Indica il server su cui è presente il production database


# =============================================================================
# DUMP DEVELOPMENT DB SUL PRODUCTION SERVER
# =============================================================================
desc "Dumb development DB sul production server"
task :dump_db_to_database_server, :roles => :db, :only => { :primary => false } do
  on_rollback { delete "/tmp/#{application}.sql" 
                delete "/tmp/script_#{application}"}
  require 'yaml'
  db = YAML.load(File.read(File.dirname(__FILE__) + "/database.yml"))
  # Dump del development database
  run "mysqldump -u #{db['development']['username']} -p --create-options --skip-comments --add-drop-table --default-character-set=UTF8 --database #{db['development']['database']} > /tmp/#{application}.sql" do |ch, stream, out|
    ch.send_data "#{db['development']['password']}\n" if out =~ /^Enter password:/
  end
  # Crea uno script che sostituisce il nome del database da creare in modo da settarlo come il
  # production database specificato nel file database.yml
  buffer = render(:template => <<PARSEFILE)
#!/usr/bin/ruby
@new_file = ''
File.open("/tmp/#{application}.sql", "r+") do |file|
  file.each_line {|l| @new_file = @new_file + l.sub("#{db['development']['database']}","#{db['production']['database']}")}
end
nuovo_file=File.new("/tmp/#{application}.sql", "w+")
nuovo_file << @new_file
nuovo_file.flush
nuovo_file.close
PARSEFILE
  
  put buffer, "/tmp/script_#{application}", :mode => 0755
  # Eseguo lo script creato precedentemente
  run "/tmp/script_#{application}"
  # Copio il file contenente il database all'interno del server su cui si creerà il poduction database
  run "scp /tmp/#{application}.sql #{user}@#{site_url}:/tmp/#{application}.sql " do |ch, stream, out|
    ch.send_data "yes\n" if out =~ /(yes\/no)/
    ch.send_data "#{root_db_server_password}\n" if out =~ /password:/
  end
  
  # Elimino i file temporanei oramai non più necessari
  delete "/tmp/#{application}.sql"
  delete "/tmp/script_#{application}"
end

desc "Copia il development file sul production server e crea il database"
task :after_dump_db_to_database_server, :roles => :db, :only => { :primary => true } do
  on_rollback { delete "/tmp/#{application}.sql" }
  require 'yaml'
  db = YAML.load(File.read(File.dirname(__FILE__) + "/database.yml"))
  # Effettuo la creazione del Database
  run "mysql -u #{db['production']['username']} -p < /tmp/#{application}.sql" do |ch, stream, out|
    ch.send_data "#{db['production']['password']}\n" if out =~ /^Enter password:/
  end
  # Elimino il file non più necessario perché oramai completate le operazioni
  delete "/tmp/#{application}.sql"
end

#Serve per chiedere una password e memorizzarla nella variabile root_db_server_password
set :root_db_server_password, Proc.new {Capistrano::CLI.password_prompt("Inserisci la password per il DB server Password: ")}
