Skip to content

Instantly share code, notes, and snippets.

@chorn
Created June 17, 2011 23:31
Show Gist options
  • Save chorn/1032587 to your computer and use it in GitHub Desktop.
Save chorn/1032587 to your computer and use it in GitHub Desktop.
#!/bin/bash
##
# Don't be a dumbass and screw this up.
# If you modify this to be more awesome and don't tell me about it you are an assface.
# - @chorn
##
DB=""
FIELD=""
VALUE=""
TODO=""
AUTH=""
NAME=""
DRYRUN=0
TAR=1
DTE=`date +'%Y%m%d'`
usage() {
echo "$0 [--name NAME THIS RUN] <--host hostname> <--user username> <--pass password> <--dryrun> <--notar> [--database db] [--field field] [--value value]"
echo
echo "Examples:"
echo "$0 --name cruft --db live --field name --value chorn"
echo
echo "$0 --name combo --db live --field name --value value1 && $0 --name combo --db live --field name --value value2"
exit 0
}
while [[ $# -gt 0 ]] ; do
curr_arg="$1" ; shift
if [[ $# -gt 0 ]] ; then next_arg="$1" ; shift ; else next_arg="" ; fi
case "$curr_arg" in
-n|--name) NAME=$next_arg ;;
-u|--user|--username) AUTH="${AUTH} -u$next_arg" ;;
-p|--pass|--password) AUTH="${AUTH} -p$next_arg" ;;
-h|--host|--hostname) AUTH="${AUTH} -h$next_arg" ;;
-d|--db|--database) DB=$next_arg ;;
-f|--field) FIELD=$next_arg ;;
--dryrun) DRYRUN=1 ;;
--notar) TAR=0 ;;
-v|--val|--value) VALUE=$next_arg ;;
*) usage ;;
esac
done
if [[ $NAME == "" || $DB == "" || $FIELD == "" || $VALUE == "" ]] ; then
usage
fi
INFO="mysql ${AUTH} information_schema -BNe"
MY="mysql ${AUTH} ${DB} -BNe"
DUMP="mysqldump --allow-keywords --add-locks --hex-blob --quick --quote-names --complete-insert=false ${AUTH} ${DB}"
DIR="${DTE}::${DB}::${NAME}/${FIELD}_${VALUE}"
mkdir -p "${DIR}"
echo "## ${FIELD} = ${VALUE}"
for table in $($INFO "SELECT TABLE_NAME FROM TABLES WHERE TABLE_SCHEMA='${DB}'") ; do
field_count=$($INFO "SELECT COUNT(*) FROM COLUMNS WHERE COLUMN_NAME='${FIELD}' AND TABLE_NAME='${table}'")
if [[ $field_count > 0 ]] ; then
record_count=$($MY "SELECT COUNT(*) FROM $table WHERE ${FIELD}='${VALUE}'")
if [[ $record_count > 0 ]] ; then
$DUMP -d $table > "${DIR}/${table}::schema.sql"
$DUMP -t $table --where="${FIELD}='${VALUE}'" > "${DIR}/${table}::data.sql"
dump_count=`grep -c '^INSERT INTO' "${DIR}/${table}::data.sql"`
if [[ $record_count != $dump_count ]] ; then
echo "**FATAL ERROR** counts don't match!"
exit 1
fi
fi
fi
done
## Now that we've successfully scanned, dumped and checked all the tables, we can delete.
for table in $($INFO "SELECT TABLE_NAME FROM TABLES WHERE TABLE_SCHEMA='${DB}'") ; do
field_count=$($INFO "SELECT COUNT(*) FROM COLUMNS WHERE COLUMN_NAME='${FIELD}' AND TABLE_NAME='${table}'")
if [[ $field_count > 0 ]] ; then
record_count=$($MY "SELECT COUNT(*) FROM $table WHERE ${FIELD}='${VALUE}'")
if [[ $record_count > 0 ]] ; then
if [[ $DRYRUN == 0 ]] ; then
$MY "DELETE FROM $table WHERE ${FIELD}='${VALUE}'"
leftover_count=$($MY "SELECT COUNT(*) FROM $table WHERE ${FIELD}='${VALUE}'")
if [[ $leftover_count > 0 ]] ; then
echo "**FATAL ERROR** delete failed."
exit 1
else
echo "Retired $record_count records for $VALUE from $table."
fi
else
echo "DRYRUN -> DELETE FROM $table WHERE ${FIELD}='${VALUE}'"
fi
fi
fi
done
if [[ $TAR == 1 ]] ; then
tar cfj "${DTE}::${DB}::${NAME}.tar.bz2" "${DIR}"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment