| 
									
										
										
										
											2023-04-01 18:56:42 -07:00
										 |  |  | # typed: true | 
					
						
							| 
									
										
										
										
											2023-03-14 12:32:11 -04:00
										 |  |  | # 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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-01 18:56:42 -07:00
										 |  |  |     server_stopped = T.let(false, T::Boolean) | 
					
						
							|  |  |  |     moved_data = T.let(false, T::Boolean) | 
					
						
							|  |  |  |     initdb_run = T.let(false, T::Boolean) | 
					
						
							|  |  |  |     upgraded = T.let(false, T::Boolean) | 
					
						
							| 
									
										
										
										
											2023-03-14 12:32:11 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-01 18:56:42 -07:00
										 |  |  |       initdb_args = T.let([], T::Array[String]) | 
					
						
							| 
									
										
										
										
											2023-03-14 12:32:11 -04:00
										 |  |  |       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 |