package liquibase.sqlgenerator.core;
import liquibase.database.Database;
import liquibase.database.core.PostgresDatabase;
import liquibase.exception.DatabaseException;
import liquibase.exception.LiquibaseException;
import liquibase.sql.Sql;
import liquibase.sql.UnparsedSql;
import liquibase.sqlgenerator.SqlGeneratorChain;
import liquibase.statement.core.InsertOrUpdateStatement;
public class InsertOrUpdateGeneratorPostgres extends InsertOrUpdateGenerator {
@Override
public boolean supports(InsertOrUpdateStatement statement, Database database) {
if (database instanceof PostgresDatabase) {
try {
return database.getDatabaseMajorVersion() >= 9;
} catch (DatabaseException e) {
return true;
}
}
return false;
}
@Override
public Sql[] generateSql(InsertOrUpdateStatement insertOrUpdateStatement,
Database database, SqlGeneratorChain sqlGeneratorChain) {
StringBuilder generatedSql = new StringBuilder();
generatedSql.append("DO\n");
generatedSql.append("$$\n");
generatedSql.append("BEGIN\n");
try {
generatedSql.append(getUpdateStatement(insertOrUpdateStatement,
database, getWhereClause(insertOrUpdateStatement, database),
sqlGeneratorChain));
} catch (LiquibaseException e) {
// do a select statement instead
/*
generatedSql.append("select * from " + database.escapeTableName(insertOrUpdateStatement.getCatalogName(), insertOrUpdateStatement.getSchemaName(), insertOrUpdateStatement.getTableName()) + " WHERE " +
getWhereClause(insertOrUpdateStatement, database) + "\n");
*/
// The above code results in an invalid pl/pgsql statement as the select is not being stored.
// The perform keyword can be used here as an alternative as it does not return a value.
// Additionally the statement is not being terminated correctly, it is missing a semi-colon.
generatedSql.append("perform * from "
+ database.escapeTableName(insertOrUpdateStatement.getCatalogName(), insertOrUpdateStatement.getSchemaName(),
insertOrUpdateStatement.getTableName()) + " WHERE " + getWhereClause(insertOrUpdateStatement, database) + ";\n");
}
generatedSql.append("IF not found THEN\n");
generatedSql.append(getInsertStatement(insertOrUpdateStatement,
database, sqlGeneratorChain));
generatedSql.append("END IF;\n");
generatedSql.append("END;\n");
generatedSql.append("$$\n");
generatedSql.append("LANGUAGE plpgsql;\n");
return new Sql[] { new UnparsedSql(generatedSql.toString(), getAffectedTable(insertOrUpdateStatement)) };
}
@Override
protected String getElse(Database arg0) {
throw new UnsupportedOperationException();
}
@Override
protected String getRecordCheck(InsertOrUpdateStatement arg0,
Database arg1, String arg2) {
throw new UnsupportedOperationException();
}
}