package liquibase.sqlgenerator.core;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import liquibase.database.Database;
import liquibase.database.core.MySQLDatabase;
import liquibase.database.typeconversion.TypeConverterFactory;
import liquibase.sqlgenerator.SqlGeneratorChain;
import liquibase.statement.core.InsertOrUpdateStatement;
/**
*
* @author Carles
*/
public class InsertOrUpdateGeneratorMySQL extends InsertOrUpdateGenerator {
@Override
public boolean supports(InsertOrUpdateStatement statement, Database database) {
return database instanceof MySQLDatabase;
}
@Override
protected String getInsertStatement(InsertOrUpdateStatement insertOrUpdateStatement, Database database, SqlGeneratorChain sqlGeneratorChain) {
StringBuffer sql = new StringBuffer(super.getInsertStatement(insertOrUpdateStatement, database, sqlGeneratorChain));
sql.deleteCharAt(sql.lastIndexOf(";"));
StringBuffer updateClause = new StringBuffer("ON DUPLICATE KEY UPDATE ");
String[] pkFields=insertOrUpdateStatement.getPrimaryKey().split(",");
HashSet<String> hashPkFields = new HashSet<String>(Arrays.asList(pkFields));
boolean hasFields = false;
for(String columnKey:insertOrUpdateStatement.getColumnValues().keySet())
{
if (!hashPkFields.contains(columnKey)) {
hasFields = true;
updateClause.append(columnKey).append(" = ");
updateClause.append(convertToString(insertOrUpdateStatement.getColumnValue(columnKey),database));
updateClause.append(",");
}
}
if(hasFields) {
// append the updateClause onto the end of the insert statement
updateClause.deleteCharAt(updateClause.lastIndexOf(","));
sql.append(updateClause);
} else {
// insert IGNORE keyword into insert statement
sql.insert(sql.indexOf("INSERT ")+"INSERT ".length(), "IGNORE ");
}
return sql.toString();
}
@Override
protected String getUpdateStatement(InsertOrUpdateStatement insertOrUpdateStatement, Database database, String whereClause, SqlGeneratorChain sqlGeneratorChain) {
return "";
}
@Override
protected String getRecordCheck(InsertOrUpdateStatement insertOrUpdateStatement, Database database, String whereClause) {
return "";
}
@Override
protected String getElse(Database database) {
return "";
}
private String convertToString(Object newValue, Database database) {
String sqlString;
if (newValue == null || newValue.toString().equals("") || newValue.toString().equalsIgnoreCase("NULL")) {
sqlString = "NULL";
} else if (newValue instanceof String && database.shouldQuoteValue(((String) newValue))) {
sqlString = "'" + database.escapeStringForDatabase(newValue.toString()) + "'";
} else if (newValue instanceof Date) {
sqlString = database.getDateLiteral(((Date) newValue));
} else if (newValue instanceof Boolean) {
if (((Boolean) newValue)) {
sqlString = TypeConverterFactory.getInstance().findTypeConverter(database).getBooleanType().getTrueBooleanValue();
} else {
sqlString = TypeConverterFactory.getInstance().findTypeConverter(database).getBooleanType().getFalseBooleanValue();
}
} else {
sqlString = newValue.toString();
}
return sqlString;
}
}