diff options
Diffstat (limited to 'activerecord/lib/active_record/tasks/postgresql_database_tasks.rb')
-rw-r--r-- | activerecord/lib/active_record/tasks/postgresql_database_tasks.rb | 43 |
1 files changed, 37 insertions, 6 deletions
diff --git a/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb b/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb index a3a9430c03..647e066137 100644 --- a/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb +++ b/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb @@ -1,8 +1,13 @@ +# frozen_string_literal: true + +require "tempfile" + module ActiveRecord module Tasks # :nodoc: class PostgreSQLDatabaseTasks # :nodoc: DEFAULT_ENCODING = ENV["CHARSET"] || "utf8" ON_ERROR_STOP_1 = "ON_ERROR_STOP=1".freeze + SQL_COMMENT_BEGIN = "--".freeze delegate :connection, :establish_connection, :clear_active_connections!, to: ActiveRecord::Base @@ -17,7 +22,7 @@ module ActiveRecord configuration.merge("encoding" => encoding) establish_connection configuration rescue ActiveRecord::StatementInvalid => error - if /database .* already exists/ === error.message + if error.cause.is_a?(PG::DuplicateDatabase) raise DatabaseAlreadyExists else raise @@ -43,7 +48,7 @@ module ActiveRecord create true end - def structure_dump(filename) + def structure_dump(filename, extra_flags) set_psql_env search_path = \ @@ -57,20 +62,30 @@ module ActiveRecord end args = ["-s", "-x", "-O", "-f", filename] + args.concat(Array(extra_flags)) if extra_flags unless search_path.blank? args += search_path.split(",").map do |part| "--schema=#{part.strip}" end end + + ignore_tables = ActiveRecord::SchemaDumper.ignore_tables + if ignore_tables.any? + args += ignore_tables.flat_map { |table| ["-T", table] } + end + args << configuration["database"] run_cmd("pg_dump", args, "dumping") + remove_sql_header_comments(filename) File.open(filename, "a") { |f| f << "SET search_path TO #{connection.schema_search_path};\n\n" } end - def structure_load(filename) + def structure_load(filename, extra_flags) set_psql_env - args = [ "-v", ON_ERROR_STOP_1, "-q", "-f", filename, configuration["database"] ] - run_cmd("psql", args, "loading" ) + args = ["-v", ON_ERROR_STOP_1, "-q", "-f", filename] + args.concat(Array(extra_flags)) if extra_flags + args << configuration["database"] + run_cmd("psql", args, "loading") end private @@ -102,11 +117,27 @@ module ActiveRecord end def run_cmd_error(cmd, args, action) - msg = "failed to execute:\n" + msg = "failed to execute:\n".dup msg << "#{cmd} #{args.join(' ')}\n\n" msg << "Please check the output above for any errors and make sure that `#{cmd}` is installed in your PATH and has proper permissions.\n\n" msg end + + def remove_sql_header_comments(filename) + removing_comments = true + tempfile = Tempfile.open("uncommented_structure.sql") + begin + File.foreach(filename) do |line| + unless removing_comments && (line.start_with?(SQL_COMMENT_BEGIN) || line.blank?) + tempfile << line + removing_comments = false + end + end + ensure + tempfile.close + end + FileUtils.cp(tempfile.path, filename) + end end end end |