Skip to content

Commit

Permalink
Merge pull request #106 from denyskonakhevych/LB-2095
Browse files Browse the repository at this point in the history
LB-2095: Custom change log and -lock tables with keyspace issue
  • Loading branch information
nvoxland authored May 13, 2022
2 parents 585dc8a + 8a33154 commit a260ec5
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 40 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,5 @@
package liquibase.ext.cassandra.changelog;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;

import liquibase.Scope;
import liquibase.changelog.StandardChangeLogHistoryService;
import liquibase.database.Database;
Expand All @@ -16,6 +8,14 @@
import liquibase.ext.cassandra.database.CassandraDatabase;
import liquibase.statement.core.RawSqlStatement;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;

public class CassandraChangeLogHistoryService extends StandardChangeLogHistoryService {

@Override
Expand All @@ -30,7 +30,22 @@ public boolean supports(Database database) {

@Override
public boolean hasDatabaseChangeLogTable() {
return ((CassandraDatabase)getDatabase()).hasDatabaseChangeLogLockTable();
boolean hasChangeLogTable;
try {
Statement statement = ((CassandraDatabase) getDatabase()).getStatement();
statement.executeQuery("select ID from " + getChangeLogTableName());
statement.close();
hasChangeLogTable = true;
} catch (SQLException e) {
Scope.getCurrentScope().getLog(getClass()).info("No " + getChangeLogTableName() + " available in cassandra.");
hasChangeLogTable = false;
} catch (DatabaseException e) {
e.printStackTrace();
hasChangeLogTable = false;
}

// needs to be generated up front
return hasChangeLogTable;
}


Expand All @@ -39,8 +54,7 @@ public int getNextSequenceValue() {
int next = 0;
try {
Statement statement = ((CassandraDatabase) getDatabase()).getStatement();
ResultSet rs = statement.executeQuery("SELECT ID, AUTHOR, ORDEREXECUTED FROM " +
getDatabase().getDefaultCatalogName() + ".DATABASECHANGELOG");
ResultSet rs = statement.executeQuery("SELECT ID, AUTHOR, ORDEREXECUTED FROM " + getChangeLogTableName());
while (rs.next()) {
int order = rs.getInt("ORDEREXECUTED");
next = Math.max(order, next);
Expand All @@ -55,11 +69,17 @@ public int getNextSequenceValue() {

@Override
public List<Map<String, ?>> queryDatabaseChangeLogTable(Database database) throws DatabaseException {
RawSqlStatement select = new RawSqlStatement("SELECT * FROM " + database.getDefaultCatalogName() +
".DATABASECHANGELOG");
RawSqlStatement select = new RawSqlStatement("SELECT * FROM " + getChangeLogTableName());
final List<Map<String, ?>> returnList = Scope.getCurrentScope().getSingleton(ExecutorService.class).getExecutor("jdbc", database).queryForList(select);
returnList.sort(Comparator.comparing((Map<String, ?> o) -> (Date) o.get("DATEEXECUTED")).thenComparingInt(o -> (Integer) o.get("ORDEREXECUTED")));
return returnList;
}

private String getChangeLogTableName() {
if (getDatabase().getLiquibaseCatalogName() != null) {
return getDatabase().getLiquibaseCatalogName() + "." + getDatabase().getDatabaseChangeLogTableName();
} else {
return getDatabase().getDatabaseChangeLogTableName();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -135,25 +135,6 @@ public Statement getStatement() throws DatabaseException {
return ((JdbcConnection) super.getConnection()).createStatement();
}

public boolean hasDatabaseChangeLogLockTable() {
boolean hasChangeLogLockTable;
try {
Statement statement = getStatement();
statement.executeQuery("SELECT ID from " + getDefaultCatalogName() + ".DATABASECHANGELOGLOCK");
statement.close();
hasChangeLogLockTable = true;
} catch (SQLException e) {
Scope.getCurrentScope().getLog(getClass()).info("No DATABASECHANGELOGLOCK available in cassandra.");
hasChangeLogLockTable = false;
} catch (DatabaseException e) {
e.printStackTrace();
hasChangeLogLockTable = false;
}

// needs to be generated up front
return hasChangeLogLockTable;
}

@Override
public boolean jdbcCallsCatalogsSchemas() {
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import liquibase.executor.ExecutorService;
import liquibase.ext.cassandra.database.CassandraDatabase;
import liquibase.lockservice.StandardLockService;
import liquibase.logging.LogFactory;
import liquibase.sql.Sql;
import liquibase.sqlgenerator.SqlGeneratorFactory;
import liquibase.statement.core.LockDatabaseChangeLogStatement;
Expand Down Expand Up @@ -53,7 +52,7 @@ public boolean acquireLock() throws LockException {


boolean locked = executor.queryForInt(
new RawSqlStatement("SELECT COUNT(*) FROM " + database.getDefaultCatalogName() + ".DATABASECHANGELOGLOCK where " +
new RawSqlStatement("SELECT COUNT(*) FROM " + getChangeLogLockTableName() + " where " +
"locked = TRUE ALLOW FILTERING")
) > 0;

Expand Down Expand Up @@ -140,7 +139,22 @@ public void releaseLock() throws LockException {

@Override
public boolean hasDatabaseChangeLogLockTable() {
return ((CassandraDatabase)database).hasDatabaseChangeLogLockTable();
boolean hasChangeLogLockTable;
try {
Statement statement = ((CassandraDatabase) database).getStatement();
statement.executeQuery("SELECT ID from " + getChangeLogLockTableName());
statement.close();
hasChangeLogLockTable = true;
} catch (SQLException e) {
Scope.getCurrentScope().getLog(getClass()).info("No " + getChangeLogLockTableName() + " available in cassandra.");
hasChangeLogLockTable = false;
} catch (DatabaseException e) {
e.printStackTrace();
hasChangeLogLockTable = false;
}

// needs to be generated up front
return hasChangeLogLockTable;
}

@Override
Expand All @@ -150,7 +164,7 @@ public boolean isDatabaseChangeLogLockTableInitialized(final boolean tableJustCr

try {
isDatabaseChangeLogLockTableInitialized = executor.queryForInt(
new RawSqlStatement("SELECT COUNT(*) FROM " + database.getDefaultCatalogName() + ".DATABASECHANGELOGLOCK")
new RawSqlStatement("SELECT COUNT(*) FROM " + getChangeLogLockTableName())
) > 0;
} catch (LiquibaseException e) {
if (executor.updatesDatabase()) {
Expand All @@ -164,4 +178,11 @@ public boolean isDatabaseChangeLogLockTableInitialized(final boolean tableJustCr
return isDatabaseChangeLogLockTableInitialized;
}

private String getChangeLogLockTableName() {
if(database.getLiquibaseCatalogName() != null) {
return database.getLiquibaseCatalogName() + "." + database.getDatabaseChangeLogLockTableName();
} else {
return database.getDatabaseChangeLogLockTableName();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public boolean supports(CreateDatabaseChangeLogLockTableStatement statement, Dat
public Sql[] generateSql(CreateDatabaseChangeLogLockTableStatement statement, Database database, SqlGeneratorChain sqlGeneratorChain) {

RawSqlStatement createTableStatement = new RawSqlStatement("CREATE TABLE IF NOT EXISTS " +
database.escapeTableName(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(), "databasechangeloglock") +
database.escapeTableName(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(), database.getDatabaseChangeLogLockTableName()) +
" (ID INT, LOCKED BOOLEAN, LOCKGRANTED timestamp, LOCKEDBY TEXT, PRIMARY KEY (ID))");

return SqlGeneratorFactory.getInstance().generateSql(createTableStatement, database);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public Sql[] generateSql(CreateDatabaseChangeLogTableStatement statement, Databa


RawSqlStatement createTableStatement = new RawSqlStatement("CREATE TABLE IF NOT EXISTS " +
database.escapeTableName(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(), "databasechangelog") +
database.escapeTableName(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(), database.getDatabaseChangeLogTableName()) +
"( ID TEXT, AUTHOR TEXT, FILENAME TEXT, DATEEXECUTED timestamp, ORDEREXECUTED INT, EXECTYPE TEXT, MD5SUM TEXT, DESCRIPTION TEXT, COMMENTS TEXT, TAG TEXT, LIQUIBASE TEXT, CONTEXTS TEXT, LABELS TEXT, DEPLOYMENT_ID TEXT,PRIMARY KEY (ID, AUTHOR, FILENAME))");

return SqlGeneratorFactory.getInstance().generateSql(createTableStatement, database);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public Sql[] generateSql(InitializeDatabaseChangeLogLockTableStatement statement
RawSqlStatement deleteStatement = new RawSqlStatement("TRUNCATE TABLE " + database.escapeTableName(
database.getLiquibaseCatalogName(),
database.getLiquibaseSchemaName(),
"databasechangeloglock".toUpperCase()));
database.getDatabaseChangeLogLockTableName().toUpperCase()));

return SqlGeneratorFactory.getInstance().generateSql(deleteStatement, database);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public boolean supports(LockDatabaseChangeLogStatement statement, Database datab
@Override
public Sql[] generateSql(LockDatabaseChangeLogStatement statement, Database database, SqlGeneratorChain sqlGeneratorChain) {
RawSqlStatement updateStatement = new RawSqlStatement("UPDATE " +
database.escapeTableName(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(), "databasechangeloglock") +
database.escapeTableName(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(), database.getDatabaseChangeLogLockTableName()) +
" SET LOCKED = TRUE, LOCKEDBY = '" + hostname + " (" + hostaddress + ")" + "', LOCKGRANTED = " + System.currentTimeMillis() + " WHERE ID = 1");
return SqlGeneratorFactory.getInstance().generateSql(updateStatement, database);
}
Expand Down

0 comments on commit a260ec5

Please sign in to comment.