All Downloads are FREE. Search and download functionalities are using the official Maven repository.

generator.server.springboot.dbmigration.cassandra.execute-cql.sh Maven / Gradle / Ivy

There is a newer version: 1.22.0
Show newest version
#!/usr/bin/env bash

MIGRATION_KEYSPACE_NAME=jhipstermigration

unset scripts
declare -A scripts

function log {
    echo "[$(date)]: $*"
}

function logDebug {
    ((DEBUG_LOG)) && echo "[DEBUG][$(date)]: $*"
}

function exitWithError() {
    echo "ERROR :
        $*"
    exit 1
}

# load already executed scripts in the `scripts` global variable: dictionary[scriptName->checksum]
function loadExecutedScripts {
    local rows
    # after SELECT, removes blank lines, then column names, then the query summary at the last line
    mapfile -t rows < <(cqlsh -k $MIGRATION_KEYSPACE_NAME -e "select * from schema_version" "$CASSANDRA_CONTACT_POINT" | grep "\S" | tail -n +3 | sed '$d')
    for r in "${rows[@]}"
    do
        local scriptName
        local checksum
        scriptName=$(echo "$r" |cut -d '|' -f 1 | sed s'/^[[:space:]]*//' | sed s'/[[:space:]]*$//')
        checksum=$(echo "$r" |cut -d '|' -f 2 | sed s'/^[[:space:]]*//' | sed s'/[[:space:]]*$//')
        scripts+=(["$scriptName"]="$checksum")
    done
}

function exists {
  if [ "$2" != in ]; then
    echo "Incorrect usage."
    echo "Correct usage: exists {key} in {array}"
    return 1
  fi

  eval '[ ${'"$3"'[$1]+exists} ]'
}

function checksumEquals {
    local checksum
    checksum=$(md5sum "$cqlFile" | cut -d ' ' -f 1)
    local foundChecksum=${scripts[${filename}]}

    if [[ "$checksum" == "$foundChecksum" ]]; then
        logDebug "checksum equals for $cqlFile, checksum=$checksum"
        return 0
    else
        logDebug "different checksum found for $cqlFile
        checksum=$checksum
        foundChecksum=$foundChecksum"
        return 1
    fi
}

function isExecuted {
    if exists "$filename" in scripts; then
        if checksumEquals "$cqlFile"; then
            return 0
        else
            exitWithError "$cqlFile has already been executed but has a different checksum logged in the schema_version table.
            scripts must not be changed after being executed.
            to resolve this issue you can:
            - revert the modified script to its initial state and create a new script
            OR
            - delete the script entry from the schema_version table
            "
        fi
    else
        return 1
    fi
}

function executeCqlScript {
    log "execute: $cqlFile"
    cqlsh -f "$cqlFile" "$CASSANDRA_CONTACT_POINT"

    # if execution failed
    if [ $? -ne 0 ]; then
        exitWithError "fail to apply script $filename
        stop applying database changes"
    fi
    logDebug "execution of $cqlFile succeeded"
}

function logExecutedScript {
    local duration=$1
    local checksum
    checksum=$(md5sum "$cqlFile" | cut -d ' ' -f 1)

    logDebug "save $cqlFile execution in schema_version table"
    local query="INSERT INTO schema_version (script_name, checksum, executed_by, executed_on, execution_time, status) VALUES ('$filename', '$checksum', '$USER', toTimestamp(now()), $duration, 'success');"
    cqlsh -k $MIGRATION_KEYSPACE_NAME -e "$query" "$CASSANDRA_CONTACT_POINT"
}

#usage checks
if [ -z "$1" ]; then
    echo "usage: ./execute-cql cqlFile.cql"
    exit 1
fi
if [ -z "$CASSANDRA_CONTACT_POINT" ]; then
    echo "CASSANDRA_CONTACT_POINT environment variable must be defined"
    exit 1
fi

cqlFile=$1
filename=$(basename "$1")

loadExecutedScripts
if isExecuted; then
    logDebug "skipping $cqlFile already executed"
else
    _start=$(date +"%s")
    executeCqlScript
    _end=$(date +"%s")
    duration=$((_end - _start))
    logExecutedScript "$duration"
    log "$cqlFile executed with success in $duration seconds"
fi




© 2015 - 2024 Weber Informatics LLC | Privacy Policy