Cucumber and RSpec testing with zeus: Postgres is being accessed by other users

旧城冷巷雨未停 提交于 2019-12-04 20:21:59
Pascal Lindelauf

Inspired by this answer, we created the following database.rake file. Where the original answer worked only for PostgreSQL 9.1, this one is modified to work for PostgreSQL 9.2 as well. The mechanism is not the prettiest: when the 9.1 command fails, it simply executes the 9.2 command. But the most important thing: it works!

#{Rails.root}/lib/tasks/databases.rake
# monkey patch ActiveRecord to avoid There are n other session(s) using the database.
def drop_database(config)
  case config['adapter']
  when /mysql/
    ActiveRecord::Base.establish_connection(config)
    ActiveRecord::Base.connection.drop_database config['database']
  when /sqlite/
    require 'pathname'
    path = Pathname.new(config['database'])
    file = path.absolute? ? path.to_s : File.join(Rails.root, path)

    FileUtils.rm(file)
  when /postgresql/
    begin
      ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public'))
      ActiveRecord::Base.connection.select_all("select * from pg_stat_activity order by procpid;").each do |x|
        if config['database'] == x['datname'] && x['current_query'] =~ /<IDLE>/
          ActiveRecord::Base.connection.execute("select pg_terminate_backend(#{x['procpid']})")
        end
      end
      ActiveRecord::Base.connection.drop_database config['database']
    rescue # in PG 9.2 column procpid was renamed pid and the query status is checked not using 'current_query' but using 'state'
      ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public'))
      ActiveRecord::Base.connection.select_all("select * from pg_stat_activity order by pid;").each do |x|
        if config['database'] == x['datname'] && x['state'] =~ /idle/
          ActiveRecord::Base.connection.execute("select pg_terminate_backend(#{x['pid']})")
        end
      end
      ActiveRecord::Base.connection.drop_database config['database']
    end
  end
end
namespace :db do

  desc 'Clear the database'
  task :clear_db => :environment do |t,args|
    ActiveRecord::Base.establish_connection
    ActiveRecord::Base.connection.tables.each do |table|
      next if table == 'schema_migrations'
      ActiveRecord::Base.connection.execute("TRUNCATE #{table}")
    end
  end

  desc 'Delete all tables (but not the database)'
  task :drop_schema => :environment do |t,args|
    ActiveRecord::Base.establish_connection
    ActiveRecord::Base.connection.execute("DROP SCHEMA public CASCADE")
    ActiveRecord::Base.connection.execute("CREATE SCHEMA public")
    ActiveRecord::Base.connection.execute("GRANT ALL ON SCHEMA public TO postgres")
    ActiveRecord::Base.connection.execute("GRANT ALL ON SCHEMA public TO public")
    ActiveRecord::Base.connection.execute("COMMENT ON SCHEMA public IS 'standard public schema'")
  end

  desc 'Recreate the database and seed'
  task :redo_db => :environment do |t,args|
    # Executes the dependencies, but only once
    Rake::Task["db:drop_schema"].invoke
    Rake::Task["db:migrate"].invoke
    Rake::Task["db:migrate:status"].invoke
    Rake::Task["db:structure:dump"].invoke
    Rake::Task["db:seed"].invoke
  end

end
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!