updated PostgreSQL homebrew script

With the release of PostgreSQL 10, I’ve updated my pg script. You might recall from previous posts that this script is for Homebrew users that have tapped Peter’s brew recipes. It allows for installing and switching between multiple version of PostgreSQL seemlessly. While I was in there adding v10 support, I tweaked and tuned the code a bit and tidyied up the output significantly. I’m pretty pleased with the new version actually.

As always, it’s been added as a gist:

#!/bin/zsh

wanted_ver=$1
no_restart=

# is the version requested installed?
brew ls --version postgresql@${wanted_ver} &>/dev/null
if [[ $? -eq 0 ]] ; then
  # yes, carry on
  :
else
  # nope, so install it
  echo "Installing PostgreSQL ${wanted_ver}... "
  brew install petere/postgresql/postgresql@${wanted_ver}
fi

# is postgresql is running?
for i in /usr/local/var/postgres/*
do
  check_ver=$(basename ${i})
  is_running=$(ps -few|egrep -- "[p]ostgres.*-D.*${check_ver}")

  if [[ -z ${is_running} ]] ; then
    # nope, carry on
    :
  else
    # it is. is it the requested version?
    if [[ "${wanted_ver}" = "${check_ver}" ]] ; then
      # yup, carry on
      no_restart=t
    else
      # nope, so kill it
      echo -n "Stopping PostgreSQL ${check_ver}... "
      /usr/local/opt/postgresql@${check_ver}/bin/pg_ctl \
          -D /usr/local/var/postgres/${check_ver} \
          stop -w -mf | grep 'stopped'
    fi
  fi
done

# what version is active?
if [[ -e /usr/local/bin/psql ]] ; then
    active_ver=$(/usr/bin/stat -f %Y /usr/local/bin/psql | cut -d\/ -f3 | cut -d\- -f2 | cut -d\@ -f2)
else
    active_ver=0
fi

# is the active version the requested version?
if [[ "${active_ver}" = "${wanted_ver}" ]] ; then
  # yup, carry on
  :
else
  # nope, so deactivate it
  echo -n "Deactivating PostgreSQL ${active_ver}... "
  brew unlink --force --overwrite postgresql@${active_ver} | cut -d\  -f3-
  # and activate the correct version
  echo -n "Activating PostgreSQL ${wanted_ver}... "
  brew link --force --overwrite postgresql@${wanted_ver} | grep 'created' | cut -d\  -f3-
fi

# point to the correct data dir and port
PGDATA=/usr/local/var/postgres/${wanted_ver}
PGPORT="54$(echo ${wanted_ver} | tr -d .)"

# should we be starting a cluster?
if [[ "${no_restart}" = "t" ]] ; then
  # nope, carry on
  :
else
  # yup. has the cluster been initialized?
  if [[ ! -d ${PGDATA} ]] ; then
    # nope, so let's do that
    echo "Initializing PostgreSQL ${wanted_ver} cluster... "
    initdb -k ${PGDATA} || initdb ${PGDATA}
    echo "port = ${PGPORT}" >> ${PGDATA}/postgresql.conf
    echo "log_destination = 'stderr'" >> ${PGDATA}/postgresql.conf
    echo "logging_collector = on" >> ${PGDATA}/postgresql.conf
    echo "log_filename = 'postgresql-%a.log'" >> ${PGDATA}/postgresql.conf
    echo "log_truncate_on_rotation = on" >> ${PGDATA}/postgresql.conf
    echo "log_rotation_age = 1d" >> ${PGDATA}/postgresql.conf
    echo "log_rotation_size = 0" >> ${PGDATA}/postgresql.conf
    echo "log_timezone = 'US/Michigan'" >> ${PGDATA}/postgresql.conf
    echo "log_line_prefix = '%t [%p]: [%l-1] user=%u,db=%d,app=%a,client=%h '" >> ${PGDATA}/postgresql.conf
  else
    # yup, carry on
    :
  fi
  # start the cluster
  echo -n "Starting PostgreSQL ${wanted_ver}... "
  pg_ctl -D ${PGDATA} start  > /tmp/pg.start 2>&1
  grep 'server start' /tmp/pg.start
  if [[ -x /usr/local/bin/pg_isready ]] ; then
      ret=1
      while [[ ${ret} -eq 1 ]]
      do
        # wait for the cluster to be available before exiting
        pg_isready -q
        ret=$?
      done
    fi
fi

echo "export PGDATA=${PGDATA}"
echo "export PGPORT=${PGPORT}"

Enjoy.