package com.sap.cloud.lm.sl.cf.core.liquibase;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import com.sap.cloud.lm.sl.cf.core.message.Messages;
import com.sap.cloud.lm.sl.cf.persistence.changes.liquibase.AbstractChange;
import com.sap.cloud.lm.sl.cf.persistence.util.JdbcUtil;

import liquibase.database.jvm.JdbcConnection;

public class DropConfigurationRegistryUniqueConstraintPostgresqlChange extends AbstractChange {

    private static final String POSTGRESQL_SEARCH_QUERY = "SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_NAME='configuration_registry' and CONSTRAINT_TYPE='UNIQUE'";
    private static final String DROP_QUERY = "ALTER TABLE configuration_registry DROP CONSTRAINT ?";
    private static final String CONSTRAINT_NAME_COLUMN = "CONSTRAINT_NAME";

    @Override
    public String getConfirmationMessage() {
        return Messages.DROPPED_UNNAMED_UNIQUE_CONSTRAINT_FOR_CONFIGURATION_REGISTRY;
    }

    @Override
    protected void executeInTransaction(JdbcConnection jdbcConnection) throws Exception {
        String constraintName = retrieveConstraintName(jdbcConnection);
        dropConstraint(jdbcConnection, constraintName);
    }

    private String retrieveConstraintName(JdbcConnection jdbcConnection) throws Exception {
        PreparedStatement preparedStatement = null;
        ResultSet result = null;

        try {
            String searchQuery = getSearchQuery(jdbcConnection);
            preparedStatement = jdbcConnection.prepareStatement(searchQuery);
            result = preparedStatement.executeQuery();
            result.next();
            String constraintName = result.getString(CONSTRAINT_NAME_COLUMN);
            logger.info(String.format("Executed statement '%s' returned constraint name: %s", searchQuery, constraintName));
            return constraintName;
        } finally {
            JdbcUtil.closeQuietly(result);
            JdbcUtil.closeQuietly(preparedStatement);
        }
    }

    protected String getSearchQuery(JdbcConnection jdbcConnection) throws SQLException {
        return POSTGRESQL_SEARCH_QUERY;
    }

    private void dropConstraint(JdbcConnection jdbcConnection, String constraintName) throws Exception {
        PreparedStatement statement = null;

        try {
            statement = jdbcConnection.prepareStatement(DROP_QUERY);
            statement.setString(1, constraintName);
            statement.execute();
            logger.info(String.format("Executed statement '%s' with parameters %s.", DROP_QUERY, constraintName));
        } finally {
            JdbcUtil.closeQuietly(statement);
        }
    }

}

@@ -790,9 +790,10 @@
 INT 
-?
+%25s
 %22;%0A 
@@ -2293,32 +2293,24 @@
 n %7B%0A        
-Prepared
 Statement st
@@ -2371,38 +2371,37 @@
  jdbcConnection.
-prepar
+creat
 eStatement(DROP_
@@ -2395,26 +2395,16 @@
 atement(
-DROP_QUERY
 );%0A     
@@ -2414,29 +2414,51 @@
     
-statement.setString(1
+String dropQuery = String.format(DROP_QUERY
 , co
@@ -2502,16 +2502,25 @@
 execute(
+dropQuery
 );%0A     
@@ -2580,57 +2580,21 @@
 '%25s'
- with parameters %25s.%22, DROP_QUERY, constraintName
+.%22, dropQuery
 ));%0A

Revert "Using preparedStatement instead of string formatting for building sql query."