167 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
		
		
			
		
	
	
			167 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
|   | # typed: false | ||
|  | # frozen_string_literal: true | ||
|  | 
 | ||
|  | require "cli/parser" | ||
|  | require "formula" | ||
|  | 
 | ||
|  | module Homebrew | ||
|  |   module_function | ||
|  | 
 | ||
|  |   sig { returns(CLI::Parser) } | ||
|  |   def postgresql_upgrade_database_args | ||
|  |     Homebrew::CLI::Parser.new do | ||
|  |       description <<~EOS | ||
|  |         Upgrades the database for the `postgresql` formula. | ||
|  |       EOS | ||
|  | 
 | ||
|  |       named_args :none | ||
|  |     end | ||
|  |   end | ||
|  | 
 | ||
|  |   sig { void } | ||
|  |   def postgresql_upgrade_database | ||
|  |     postgresql_upgrade_database_args.parse | ||
|  | 
 | ||
|  |     name = "postgresql" | ||
|  |     pg = Formula[name] | ||
|  |     bin = pg.bin | ||
|  |     var = pg.var | ||
|  |     version = pg.version | ||
|  |     pg_version_file = var/"postgres/PG_VERSION" | ||
|  | 
 | ||
|  |     pg_version_installed = version.to_s[/^\d+/] | ||
|  |     pg_version_data = pg_version_file.read.chomp | ||
|  |     if pg_version_installed == pg_version_data | ||
|  |       odie <<~EOS | ||
|  |         #{name} data already upgraded! | ||
|  |       EOS | ||
|  |     end | ||
|  | 
 | ||
|  |     datadir = var/"postgres" | ||
|  |     old_datadir = var/"postgres.old" | ||
|  |     if old_datadir.exist? | ||
|  |       odie <<~EOS | ||
|  |         #{old_datadir} already exists! | ||
|  |         Remove it if you want to upgrade data automatically. | ||
|  |       EOS | ||
|  |     end | ||
|  | 
 | ||
|  |     old_pg_name = "#{name}@#{pg_version_data}" | ||
|  |     old_pg_glob = "#{HOMEBREW_CELLAR}/#{old_pg_name}/#{pg_version_data}.*/bin" | ||
|  |     old_bin = Pathname.glob(old_pg_glob).first | ||
|  |     old_bin ||= begin | ||
|  |       Formula[old_pg_name] | ||
|  |       ohai "brew install #{old_pg_name}" | ||
|  |       system "brew", "install", old_pg_name | ||
|  |       Pathname.glob(old_pg_glob).first | ||
|  |     rescue FormulaUnavailableError | ||
|  |       nil | ||
|  |     end | ||
|  | 
 | ||
|  |     odie "No #{name} #{pg_version_data}.* version installed!" unless old_bin | ||
|  | 
 | ||
|  |     server_stopped = false | ||
|  |     moved_data = false | ||
|  |     initdb_run = false | ||
|  |     upgraded = false | ||
|  | 
 | ||
|  |     begin | ||
|  |       # Following instructions from: | ||
|  |       # https://www.postgresql.org/docs/10/static/pgupgrade.html | ||
|  |       ohai "Upgrading #{name} data from #{pg_version_data} to #{pg_version_installed}..." | ||
|  |       services_json_output = Utils.popen_read("brew", "services", "info", "--all", "--json") | ||
|  |       services_json = JSON.parse(services_json_output) | ||
|  |       loaded_service_names = services_json.select { |sj| sj[:loaded] }.map { |sj| sj[:name] } | ||
|  |       if loaded_service_names.include?(name) | ||
|  |         system "brew", "services", "stop", name | ||
|  |         service_stopped = true | ||
|  |       elsif quiet_system "#{bin}/pg_ctl", "-D", datadir, "status" | ||
|  |         system "#{bin}/pg_ctl", "-D", datadir, "stop" | ||
|  |         server_stopped = true | ||
|  |       end | ||
|  | 
 | ||
|  |       # Shut down old server if it is up via brew services | ||
|  |       system "brew", "services", "stop", old_pg_name if loaded_service_names.include?(old_pg_name) | ||
|  | 
 | ||
|  |       # get 'lc_collate' from old DB" | ||
|  |       unless quiet_system "#{old_bin}/pg_ctl", "-w", "-D", datadir, "status" | ||
|  |         system "#{old_bin}/pg_ctl", "-w", "-D", datadir, "start" | ||
|  |       end | ||
|  | 
 | ||
|  |       initdb_args = [] | ||
|  |       locale_settings = %w[
 | ||
|  |         lc_collate | ||
|  |         lc_ctype | ||
|  |         lc_messages | ||
|  |         lc_monetary | ||
|  |         lc_numeric | ||
|  |         lc_time | ||
|  |         server_encoding | ||
|  |       ] | ||
|  |       locale_settings.each do |setting| | ||
|  |         sql = "SELECT setting FROM pg_settings WHERE name LIKE '#{setting}';" | ||
|  |         value = Utils.popen_read("#{old_bin}/psql", "postgres", "-qtAX", "-U", ENV.fetch("USER"), "-c", sql).strip | ||
|  | 
 | ||
|  |         next if value.empty? | ||
|  | 
 | ||
|  |         initdb_args += if setting == "server_encoding" | ||
|  |           ["-E #{value}"] | ||
|  |         else | ||
|  |           ["--#{setting.tr("_", "-")}=#{value}"] | ||
|  |         end | ||
|  |       end | ||
|  | 
 | ||
|  |       if quiet_system "#{old_bin}/pg_ctl", "-w", "-D", datadir, "status" | ||
|  |         system "#{old_bin}/pg_ctl", "-w", "-D", datadir, "stop" | ||
|  |       end | ||
|  | 
 | ||
|  |       ohai "Moving #{name} data from #{datadir} to #{old_datadir}..." | ||
|  |       FileUtils.mv datadir, old_datadir | ||
|  |       moved_data = true | ||
|  | 
 | ||
|  |       (var/"postgres").mkpath | ||
|  |       ohai "Creating database..." | ||
|  |       safe_system "#{bin}/initdb", *initdb_args, "#{var}/postgres" | ||
|  |       initdb_run = true | ||
|  | 
 | ||
|  |       ohai "Migrating and upgrading data..." | ||
|  |       (var/"log").cd do | ||
|  |         safe_system "#{bin}/pg_upgrade", | ||
|  |                     "-r", | ||
|  |                     "-b", old_bin, | ||
|  |                     "-B", bin, | ||
|  |                     "-d", old_datadir, | ||
|  |                     "-D", datadir, | ||
|  |                     "-j", Hardware::CPU.cores.to_s | ||
|  |       end | ||
|  |       upgraded = true | ||
|  | 
 | ||
|  |       ohai "Upgraded #{name} data from #{pg_version_data} to #{pg_version_installed}!" | ||
|  |       ohai "Your #{name} #{pg_version_data} data remains at #{old_datadir}" | ||
|  |     ensure | ||
|  |       if upgraded | ||
|  |         if server_stopped | ||
|  |           safe_system "#{bin}/pg_ctl", "-D", datadir, "start" | ||
|  |         elsif service_stopped | ||
|  |           safe_system "brew", "services", "start", name | ||
|  |         end | ||
|  |       else | ||
|  |         onoe "Upgrading #{name} data from #{pg_version_data} to #{pg_version_installed} failed!" | ||
|  |         if initdb_run | ||
|  |           ohai "Removing empty #{name} initdb database..." | ||
|  |           FileUtils.rm_r datadir | ||
|  |         end | ||
|  |         if moved_data | ||
|  |           ohai "Moving #{name} data back from #{old_datadir} to #{datadir}..." | ||
|  |           FileUtils.mv old_datadir, datadir | ||
|  |         end | ||
|  |         if server_stopped | ||
|  |           system "#{bin}/pg_ctl", "-D", datadir, "start" | ||
|  |         elsif service_stopped | ||
|  |           system "brew", "services", "start", name | ||
|  |         end | ||
|  |       end | ||
|  |     end | ||
|  |   end | ||
|  | end |