Created
October 28, 2016 22:03
-
-
Save yknx4/470ec4e1378a48382fdbaf6b5896f1d0 to your computer and use it in GitHub Desktop.
Automatic database backup on branch creation with Post Checkout Git Hook
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# --- Command line | |
PREVIOUS_HEAD="$1" | |
NEW_HEAD="$2" | |
IS_BRANCH_CHECKOUT="$3" | |
# --- Constants | |
SEPARATOR="/" | |
MAIN_BACKUP="_backup" | |
MAIN_DATABASE="awesome_project_db" | |
DB_USER="postgres" | |
# --- Functions | |
database_exists () { | |
name=${1:0:63} | |
return `psql -U $DB_USER -lqtA | cut -d\| -f1 | grep -qFx "$name"` | |
} | |
kill_connections() { | |
psql -U $DB_USER -c "SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname = '$MAIN_DATABASE' AND pid <> pg_backend_pid();" > /dev/null | |
} | |
duplicate_database_to() { | |
name=${1:0:63} | |
echo "Creating $name from $MAIN_DATABASE" | |
createdb -U $DB_USER -T $MAIN_DATABASE $name | |
} | |
drop_database() { | |
name=${1:0:63} | |
echo "Deleting existing $name" | |
dropdb -U $DB_USER "$name" | |
} | |
rename_database() { | |
old_name=${1:0:63} | |
new_name=${2:0:63} | |
psql -U $DB_USER -c "SET standard_conforming_strings=on;" -q -b | |
psql -U $DB_USER -c "ALTER DATABASE \"$old_name\" RENAME TO \"$new_name\";" -q -e | |
psql -U $DB_USER -c "SET standard_conforming_strings=off;" -q -b | |
} | |
alias branch_name='git name-rev --name-only' | |
# --- Variables | |
PREVIOUS_BRANCH=`branch_name $PREVIOUS_HEAD` | |
NEW_BRANCH=`git branch | grep -e "^*" | cut -d' ' -f 2` | |
OLD_DATABASE=$MAIN_DATABASE$SEPARATOR$PREVIOUS_BRANCH | |
NEW_DATABASE=$MAIN_DATABASE$SEPARATOR$NEW_BRANCH | |
MAIN_BACKUP=$MAIN_DATABASE$MAIN_BACKUP | |
# --- Script | |
if [ $IS_BRANCH_CHECKOUT -eq 0 ]; then | |
exit 0 # Exit script if it is not a branch change | |
fi | |
echo "Switching from $PREVIOUS_BRANCH to $NEW_BRANCH" | |
echo "Killing existing connections to $MAIN_DATABASE" | |
kill_connections # We need to kill all the connections or the commands here will fail | |
if ! database_exists $MAIN_BACKUP; then | |
echo "Creating a main backup, if something goes wrong you can manually restore from this backup." | |
duplicate_database_to $MAIN_BACKUP # We should always have a master backup | |
fi | |
if [ "$PREVIOUS_BRANCH" == "$NEW_BRANCH" ]; then | |
exit 0 # We didn't change branch, so lets just exit | |
fi | |
if database_exists $OLD_DATABASE; then | |
# We need to remove old backups if they exists (they shouldn't most of the times) but | |
# sometime when we didn't had changes in the branch when we created another one, so a | |
# backup for the parent branch is created instead of one for the new branch, this is | |
# to delete that wrong backup. | |
drop_database $OLD_DATABASE | |
fi | |
if database_exists $NEW_DATABASE; then | |
# When a backup for the new branch already exists | |
# If there is already a backup for the branch we are checking to, lets just rename the active database to create a new backup | |
rename_database $MAIN_DATABASE $OLD_DATABASE | |
# and then lets rename the existing backup to the active database name | |
rename_database $NEW_DATABASE $MAIN_DATABASE | |
else | |
# If the branch we are checking to doesn't have a backup let's just copy the db to still have an active database | |
duplicate_database_to $OLD_DATABASE | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment