Skip to content
This repository has been archived by the owner on Jul 2, 2022. It is now read-only.

Commit

Permalink
Merge pull request #147 from liquibase/DAT-9306
Browse files Browse the repository at this point in the history
[+] InsertOrUpdateGeneratorSnowflake
  • Loading branch information
KushnirykOleh authored Feb 11, 2022
2 parents 0ad6770 + 1b538a7 commit feb8d6f
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package liquibase.ext.snowflake.sqlgenerator;

import liquibase.database.Database;
import liquibase.datatype.DataTypeFactory;
import liquibase.ext.snowflake.database.SnowflakeDatabase;
import liquibase.sqlgenerator.SqlGeneratorChain;
import liquibase.sqlgenerator.core.InsertOrUpdateGenerator;
import liquibase.statement.core.InsertOrUpdateStatement;

import java.util.Date;

public class InsertOrUpdateGeneratorSnowflake extends InsertOrUpdateGenerator {
@Override
public boolean supports(InsertOrUpdateStatement statement, Database database) {
return database instanceof SnowflakeDatabase;
}

@Override
protected String getInsertStatement(InsertOrUpdateStatement insertOrUpdateStatement, Database database, SqlGeneratorChain sqlGeneratorChain) {
StringBuilder columns = new StringBuilder();
StringBuilder values = new StringBuilder();

for (String columnKey : insertOrUpdateStatement.getColumnValues().keySet()) {
columns.append(",");
columns.append(columnKey);
values.append(",");
values.append(convertToString(insertOrUpdateStatement.getColumnValue(columnKey), database));
}
columns.deleteCharAt(0);
values.deleteCharAt(0);
return "INSERT (" + columns + ") VALUES (" + values + ")";
}

@Override
protected String getUpdateStatement(InsertOrUpdateStatement insertOrUpdateStatement, Database database, String whereClause, SqlGeneratorChain sqlGeneratorChain) {
//We don't need 'whereClause' param here, for Snowflake it's only needed in getRecordCheck() method
StringBuilder sql = new StringBuilder("UPDATE SET ");

for (String columnKey : insertOrUpdateStatement.getColumnValues().keySet()) {
if (insertOrUpdateStatement.getAllowColumnUpdate(columnKey)) {
sql.append(columnKey).append(" = ");
sql.append(convertToString(insertOrUpdateStatement.getColumnValue(columnKey), database));
sql.append(",");
}
}
int lastComma = sql.lastIndexOf(",");
if (lastComma > -1) {
sql.deleteCharAt(lastComma);
}

return sql.toString();
}

@Override
protected String getRecordCheck(InsertOrUpdateStatement insertOrUpdateStatement, Database database, String whereClause) {
return "MERGE INTO " + insertOrUpdateStatement.getTableName() + " USING (VALUES (1)) ON " + whereClause + " WHEN NOT MATCHED THEN ";
}

@Override
protected String getElse(Database database) {
return " WHEN MATCHED THEN ";
}

// Copied from liquibase.sqlgenerator.core.InsertOrUpdateGeneratorHsql
private String convertToString(Object newValue, Database database) {
String sqlString;
if ((newValue == null) || "".equals(newValue.toString()) || "NULL".equalsIgnoreCase(newValue.toString())) {
sqlString = "NULL";
} else if ((newValue instanceof String) && !looksLikeFunctionCall(((String) newValue), database)) {
sqlString = "'" + database.escapeStringForDatabase(newValue.toString()) + "'";
} else if (newValue instanceof Date) {
sqlString = database.getDateLiteral(((Date) newValue));
} else if (newValue instanceof Boolean) {
if (((Boolean) newValue)) {
sqlString = DataTypeFactory.getInstance().getTrueBooleanValue(database);
} else {
sqlString = DataTypeFactory.getInstance().getFalseBooleanValue(database);
}
} else {
sqlString = newValue.toString();
}
return sqlString;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ liquibase.ext.snowflake.sqlgenerator.SnowflakeRenameTableGenerator
liquibase.ext.snowflake.sqlgenerator.SnowflakeRenameViewGenerator
liquibase.ext.snowflake.sqlgenerator.SnowflakeDropDefaultValueGenerator
liquibase.ext.snowflake.sqlgenerator.SnowflakeSetTableRemarksGenerator
liquibase.ext.snowflake.sqlgenerator.SnowflakeSetColumnRemarksGenerator
liquibase.ext.snowflake.sqlgenerator.SnowflakeSetColumnRemarksGenerator
liquibase.ext.snowflake.sqlgenerator.InsertOrUpdateGeneratorSnowflake
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
MERGE INTO authors USING (VALUES (1)) ON id = '1' WHEN NOT MATCHED THEN INSERT (id,first_name,last_name,email,birthdate,added) VALUES ('1','Adam','Gods','test1@example.com','1000-02-27','2000-02-04T02:32:00') WHEN MATCHED THEN UPDATE SET id = '1',first_name = 'Adam',last_name = 'Gods',email = 'test1@example.com',birthdate = '1000-02-27',added = '2000-02-04T02:32:00'
MERGE INTO authors USING (VALUES (1)) ON id = '7' WHEN NOT MATCHED THEN INSERT (id,first_name,last_name,email,birthdate,added) VALUES ('7','Noah','Lamekhs','test2@example.com','2000-02-27','1994-12-10T01:00:00') WHEN MATCHED THEN UPDATE SET id = '7',first_name = 'Noah',last_name = 'Lamekhs',email = 'test2@example.com',birthdate = '2000-02-27',added = '1994-12-10T01:00:00'
MERGE INTO authors USING (VALUES (1)) ON id = '8' WHEN NOT MATCHED THEN INSERT (id,first_name,last_name,email,birthdate,added) VALUES ('8','Muhammad','Ibn Abdullah','test3@example.com','3000-02-27','2000-12-10T01:00:00') WHEN MATCHED THEN UPDATE SET id = '8',first_name = 'Muhammad',last_name = 'Ibn Abdullah',email = 'test3@example.com',birthdate = '3000-02-27',added = '2000-12-10T01:00:00'

0 comments on commit feb8d6f

Please sign in to comment.