From 13d03971365471b00c405527abbd64eb4a27d4b1 Mon Sep 17 00:00:00 2001 From: hgaurav Date: Tue, 15 Jun 2021 11:03:34 +0100 Subject: [PATCH 1/2] Fix: Liquibase TAG command execution failure issue with Cassandra plugin. --- .../TagDatabaseGeneratorCassandra.java | 97 +++++++++++++++++++ .../liquibase.sqlgenerator.SqlGenerator | 3 +- 2 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 src/main/java/liquibase/ext/cassandra/sqlgenerator/TagDatabaseGeneratorCassandra.java diff --git a/src/main/java/liquibase/ext/cassandra/sqlgenerator/TagDatabaseGeneratorCassandra.java b/src/main/java/liquibase/ext/cassandra/sqlgenerator/TagDatabaseGeneratorCassandra.java new file mode 100644 index 00000000..a2f65ab2 --- /dev/null +++ b/src/main/java/liquibase/ext/cassandra/sqlgenerator/TagDatabaseGeneratorCassandra.java @@ -0,0 +1,97 @@ +package liquibase.ext.cassandra.sqlgenerator; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.sql.Timestamp; +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.OffsetDateTime; +import java.util.Calendar; +import java.util.TimeZone; + +import liquibase.Scope; +import liquibase.database.Database; +import liquibase.database.ObjectQuotingStrategy; +import liquibase.datatype.DataTypeFactory; +import liquibase.ext.cassandra.database.CassandraDatabase; +import liquibase.sql.Sql; +import liquibase.sql.UnparsedSql; +import liquibase.sqlgenerator.SqlGeneratorChain; +import liquibase.sqlgenerator.core.TagDatabaseGenerator; +import liquibase.statement.core.TagDatabaseStatement; +import liquibase.structure.core.Column; + +public class TagDatabaseGeneratorCassandra extends TagDatabaseGenerator { + + @Override + public int getPriority() { + return PRIORITY_DATABASE; + } + + @Override + public boolean supports(TagDatabaseStatement statement, Database database) { + return database instanceof CassandraDatabase; + } + + @Override + public Sql[] generateSql(TagDatabaseStatement statement, Database database, SqlGeneratorChain sqlGeneratorChain) { + ObjectQuotingStrategy currentStrategy = database.getObjectQuotingStrategy(); + database.setObjectQuotingStrategy(ObjectQuotingStrategy.LEGACY); + + try { + String tagEscaped = DataTypeFactory.getInstance().fromObject(statement.getTag(), database).objectToSql(statement.getTag(), database); + //Added condition to check database type = cassandra to execute below code + if (database instanceof CassandraDatabase) { + + Statement statement1 = ((CassandraDatabase) database).getStatement(); + //Query to get last executed changeset date + String query1 = "SELECT TOUNIXTIMESTAMP(MAX(DATEEXECUTED)) as DATEEXECUTED FROM " + + database.escapeTableName(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(), "databasechangelog"); + ResultSet rs1 = statement1.executeQuery(query1); + String date = ""; + while (rs1.next()) { + date = rs1.getString("DATEEXECUTED"); + } + rs1.close(); + //Query to get composite key details of last executed change set + String query2 = "select id,author, filename from " + + database.escapeTableName(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(), "databasechangelog") + + " where dateexecuted = '"+date+"' ALLOW FILTERING"; + ResultSet rs2 = statement1.executeQuery(query2); + String id = "", author = "", filename = ""; + while (rs2.next()) { + id = rs2.getString("id"); + author = rs2.getString("author"); + filename = rs2.getString("filename"); + } + rs2.close(); + statement1.close(); + //Query to update tag + String updateQuery = "UPDATE " + + database.escapeTableName(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(), "databasechangelog") + + " SET TAG = "+tagEscaped + + " WHERE id = '"+ id +"' and author = '"+ author +"' and filename = '"+ filename+ "'"; + + return new Sql[]{ + new UnparsedSql(updateQuery) + }; + + } else { + return super.generateSql(statement, database, sqlGeneratorChain); + } + + } catch (SQLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return super.generateSql(statement, database, sqlGeneratorChain); + } catch (ClassNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return super.generateSql(statement, database, sqlGeneratorChain); + } finally { + database.setObjectQuotingStrategy(currentStrategy); + } + } +} diff --git a/src/main/resources/META-INF/services/liquibase.sqlgenerator.SqlGenerator b/src/main/resources/META-INF/services/liquibase.sqlgenerator.SqlGenerator index efb4b189..3e8eb5f3 100644 --- a/src/main/resources/META-INF/services/liquibase.sqlgenerator.SqlGenerator +++ b/src/main/resources/META-INF/services/liquibase.sqlgenerator.SqlGenerator @@ -7,4 +7,5 @@ liquibase.ext.cassandra.sqlgenerator.DeleteGeneratorCassandra liquibase.ext.cassandra.sqlgenerator.InitializeDatabaseChangeLogLockTableGeneratorCassandra liquibase.ext.cassandra.sqlgenerator.CreateTableGeneratorCassandra liquibase.ext.cassandra.sqlgenerator.DropColumnGeneratorCassandra -liquibase.ext.cassandra.sqlgenerator.RenameColumnGeneratorCassandra \ No newline at end of file +liquibase.ext.cassandra.sqlgenerator.RenameColumnGeneratorCassandra +liquibase.ext.cassandra.sqlgenerator.TagDatabaseGeneratorCassandra \ No newline at end of file From 5184f8dd58588a4c88724250f12190cc0e788415 Mon Sep 17 00:00:00 2001 From: Himanshu Gaurav Date: Mon, 16 Aug 2021 17:55:14 +0100 Subject: [PATCH 2/2] Fix: Removed if condition to check Cassandra database. It is already taken care by support+priority function. --- .../TagDatabaseGeneratorCassandra.java | 69 +++++++++---------- 1 file changed, 33 insertions(+), 36 deletions(-) diff --git a/src/main/java/liquibase/ext/cassandra/sqlgenerator/TagDatabaseGeneratorCassandra.java b/src/main/java/liquibase/ext/cassandra/sqlgenerator/TagDatabaseGeneratorCassandra.java index a2f65ab2..e3bfdd38 100644 --- a/src/main/java/liquibase/ext/cassandra/sqlgenerator/TagDatabaseGeneratorCassandra.java +++ b/src/main/java/liquibase/ext/cassandra/sqlgenerator/TagDatabaseGeneratorCassandra.java @@ -42,45 +42,42 @@ public Sql[] generateSql(TagDatabaseStatement statement, Database database, SqlG try { String tagEscaped = DataTypeFactory.getInstance().fromObject(statement.getTag(), database).objectToSql(statement.getTag(), database); - //Added condition to check database type = cassandra to execute below code - if (database instanceof CassandraDatabase) { + - Statement statement1 = ((CassandraDatabase) database).getStatement(); - //Query to get last executed changeset date - String query1 = "SELECT TOUNIXTIMESTAMP(MAX(DATEEXECUTED)) as DATEEXECUTED FROM " + - database.escapeTableName(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(), "databasechangelog"); - ResultSet rs1 = statement1.executeQuery(query1); - String date = ""; - while (rs1.next()) { - date = rs1.getString("DATEEXECUTED"); - } - rs1.close(); - //Query to get composite key details of last executed change set - String query2 = "select id,author, filename from " + - database.escapeTableName(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(), "databasechangelog") - + " where dateexecuted = '"+date+"' ALLOW FILTERING"; - ResultSet rs2 = statement1.executeQuery(query2); - String id = "", author = "", filename = ""; - while (rs2.next()) { - id = rs2.getString("id"); - author = rs2.getString("author"); - filename = rs2.getString("filename"); - } - rs2.close(); - statement1.close(); - //Query to update tag - String updateQuery = "UPDATE " - + database.escapeTableName(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(), "databasechangelog") - + " SET TAG = "+tagEscaped - + " WHERE id = '"+ id +"' and author = '"+ author +"' and filename = '"+ filename+ "'"; + Statement statement1 = ((CassandraDatabase) database).getStatement(); + //Query to get last executed changeset date + String query1 = "SELECT TOUNIXTIMESTAMP(MAX(DATEEXECUTED)) as DATEEXECUTED FROM " + + database.escapeTableName(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(), "databasechangelog"); + ResultSet rs1 = statement1.executeQuery(query1); + String date = ""; + while (rs1.next()) { + date = rs1.getString("DATEEXECUTED"); + } + rs1.close(); + //Query to get composite key details of last executed change set + String query2 = "select id,author, filename from " + + database.escapeTableName(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(), "databasechangelog") + + " where dateexecuted = '"+date+"' ALLOW FILTERING"; + ResultSet rs2 = statement1.executeQuery(query2); + String id = "", author = "", filename = ""; + while (rs2.next()) { + id = rs2.getString("id"); + author = rs2.getString("author"); + filename = rs2.getString("filename"); + } + rs2.close(); + statement1.close(); + //Query to update tag + String updateQuery = "UPDATE " + + database.escapeTableName(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(), "databasechangelog") + + " SET TAG = "+tagEscaped + + " WHERE id = '"+ id +"' and author = '"+ author +"' and filename = '"+ filename+ "'"; - return new Sql[]{ - new UnparsedSql(updateQuery) - }; + return new Sql[]{ + new UnparsedSql(updateQuery) + }; - } else { - return super.generateSql(statement, database, sqlGeneratorChain); - } + } catch (SQLException e) { // TODO Auto-generated catch block