Como migrar suas Stored Procedures no ambiente de teste

11 de Junho de 2007

Normalmente, evito utilizar Stored Procedures e Functions até onde posso, mas no Spesa, não foi possível, devido uma quantidade de consultas "avançadas" que são feitas. Se não as utilizasse, a repetição de código seria absurdamente grande e, por conseguinte, seria impossível de se fazer eventuais modificações. Como estou refatorando o código do Spesa e escrevendo testes para cada item do sistema, caí em um problema um pouco incômodo na hora da migração.

Não sei se você sabe, mas toda vez que você quer sincronizar o seu banco de testes com o de desenvolvimento, basta executar o comando rake db:test:prepare. O grande problema deste comando é que ele não leva em consideração os arquivos de migração, mas sim o arquivo schema.rb, que não adiciona queries executadas através do método execute. Para corrigir isto, basta executar o comando rake db:migrate RAILS_ENV="test".

Update: depois de fazer alguns testes, vi que as stored procedures continuavam a serem excluídas. O único jeito foi estender o ActiveRecord para ele fazer o dump das funções e salvá-las no arquivo schema.rb. Basta adicionar o código abaixo no arquivo environment.rb.

module ActiveRecord
  class SchemaDumper
    def dump(stream)
      header(stream)
      tables(stream)
      functions(stream)
      trailer(stream)
      stream
    end
 
    private
      def functions(stream)
        result = @connection.execute <<QUERY
        SELECT
          ROUTINE_NAME AS name
        FROM 
          INFORMATION_SCHEMA.ROUTINES 
        WHERE 
          ROUTINE_TYPE='FUNCTION' AND 
          ROUTINE_SCHEMA='#{@connection.current_database}'
QUERY
        result.each do |row|
          stream = function(row[0], stream)
        end
      end
 
      def function(name, stream)
        result = @connection.execute "SHOW CREATE FUNCTION #{name}"
        fields = result.fetch_hash
        func = fields['Create Function'].gsub(/CREATE DEFINER.*? FUNCTION/, "CREATE FUNCTION")
 
        stream.puts <<FUNCTION
execute <<QUERY
  #{func}
QUERY
 
FUNCTION
        stream
      end
  end
end
Posts relacionados
Otimizando o Autotest
Formatando datas no Ruby on Rails
Suprimindo avisos no Ruby
Intype
Test-driven Development no Rails - Começando seu projeto com o pé direito

Comentários #

#1 Walter Cruz disse:
11 Jun 07, 03:44PM

Bacana Nando. Dica anotada!

#2 Fernando Machado disse:
07 Nov 07, 05:14PM

Olá Nando!
Você tem algum exemplo de como chamar stored procedures no Rails? Estou tentando Model.find+by_sql("CALL procidure") e não estou conseguindo. Grato! Fernando.

#3 Nando Vieira disse:
07 Nov 07, 06:47PM

Fernando, utilize o método "execute"; provavelmente funciona, embora não tenha testado. Dá uma olhada neste post para saber como utilizar o ActiveRecord para executar SQL: http://simplesideias.com.br/executando-sql-no-rails/

Deixe um comentário




Este blog usa o Gravatar.


Não é aceito código HTML: adicione-o no pastie.org ou paste.milk-it.net e poste apenas o link.

Se este é seu primeiro comentário, ele terá que ser aprovado antes de ser exibido.