mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
MNT-21083: Alternative clean up script
This commit is contained in:
@@ -61,7 +61,6 @@ public class DeleteNotExistsExecutor implements StatementExecutor
|
|||||||
{
|
{
|
||||||
private static Log logger = LogFactory.getLog(DeleteNotExistsExecutor.class);
|
private static Log logger = LogFactory.getLog(DeleteNotExistsExecutor.class);
|
||||||
|
|
||||||
private static final String MSG_EXECUTING_STATEMENT = "schema.update.msg.executing_statement";
|
|
||||||
private static final String ERR_STATEMENT_FAILED = "schema.update.err.statement_failed";
|
private static final String ERR_STATEMENT_FAILED = "schema.update.err.statement_failed";
|
||||||
private static final String MSG_OPTIONAL_STATEMENT_FAILED = "schema.update.msg.optional_statement_failed";
|
private static final String MSG_OPTIONAL_STATEMENT_FAILED = "schema.update.msg.optional_statement_failed";
|
||||||
|
|
||||||
@@ -108,10 +107,10 @@ public class DeleteNotExistsExecutor implements StatementExecutor
|
|||||||
}
|
}
|
||||||
|
|
||||||
// --DELETE_NOT_EXISTS primaryTable.key,secondaryTable1.key1,... batch.size.property
|
// --DELETE_NOT_EXISTS primaryTable.key,secondaryTable1.key1,... batch.size.property
|
||||||
String[] args = sql.split("[ \\t]+");
|
String[] args = sql.split("[ \\t]+(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)");
|
||||||
if (args.length == 3 && (args[1].indexOf('.')) != -1)
|
if (args.length == 3 && (args[1].indexOf('.')) != -1)
|
||||||
{
|
{
|
||||||
String[] tableColumnArgs = args[1].split(",");
|
String[] tableColumnArgs = args[1].split(",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)");
|
||||||
if (tableColumnArgs.length >= 2)
|
if (tableColumnArgs.length >= 2)
|
||||||
{
|
{
|
||||||
// Read the batch size from the named property
|
// Read the batch size from the named property
|
||||||
@@ -137,11 +136,19 @@ public class DeleteNotExistsExecutor implements StatementExecutor
|
|||||||
// Compute upper limits
|
// Compute upper limits
|
||||||
Long[] tableUpperLimits = new Long[tableColumnArgs.length];
|
Long[] tableUpperLimits = new Long[tableColumnArgs.length];
|
||||||
Pair<String, String>[] tableColumn = new Pair[tableColumnArgs.length];
|
Pair<String, String>[] tableColumn = new Pair[tableColumnArgs.length];
|
||||||
|
String[] optionalWhereClauses = new String[tableColumnArgs.length];
|
||||||
|
String[] tableDetails;
|
||||||
for (int i = 0; i < tableColumnArgs.length; i++)
|
for (int i = 0; i < tableColumnArgs.length; i++)
|
||||||
{
|
{
|
||||||
int index = tableColumnArgs[i].indexOf('.');
|
tableDetails = tableColumnArgs[i].split("\\.");
|
||||||
String tableName = tableColumnArgs[i].substring(0, index);
|
|
||||||
String columnName = tableColumnArgs[i].substring(index + 1);
|
String tableName = tableDetails[0];
|
||||||
|
String columnName = tableDetails[1];
|
||||||
|
|
||||||
|
if (tableDetails.length == 3)
|
||||||
|
{
|
||||||
|
optionalWhereClauses[i] = removeDoubleQuotes(tableDetails[2]);
|
||||||
|
}
|
||||||
|
|
||||||
tableColumn[i] = new Pair<>(tableName, columnName);
|
tableColumn[i] = new Pair<>(tableName, columnName);
|
||||||
tableUpperLimits[i] = getBatchUpperLimit(connection, tableName, columnName, line, scriptFile);
|
tableUpperLimits[i] = getBatchUpperLimit(connection, tableName, columnName, line, scriptFile);
|
||||||
@@ -152,12 +159,12 @@ public class DeleteNotExistsExecutor implements StatementExecutor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
process(tableColumn, tableUpperLimits);
|
process(tableColumn, tableUpperLimits, optionalWhereClauses);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void process(Pair<String, String>[] tableColumn, Long[] tableUpperLimits) throws SQLException
|
private void process(Pair<String, String>[] tableColumn, Long[] tableUpperLimits, String[] optionalWhereClauses) throws SQLException
|
||||||
{
|
{
|
||||||
// The approach is to fetch ordered row ids from all referencer/secondary (e.g.
|
// The approach is to fetch ordered row ids from all referencer/secondary (e.g.
|
||||||
// alf_audit_app, alf_audit_entry, alf_prop_unique_ctx) tables and
|
// alf_audit_app, alf_audit_entry, alf_prop_unique_ctx) tables and
|
||||||
@@ -170,6 +177,7 @@ public class DeleteNotExistsExecutor implements StatementExecutor
|
|||||||
|
|
||||||
String primaryTableName = tableColumn[0].getFirst();
|
String primaryTableName = tableColumn[0].getFirst();
|
||||||
String primaryColumnName = tableColumn[0].getSecond();
|
String primaryColumnName = tableColumn[0].getSecond();
|
||||||
|
String primaryWhereClause = optionalWhereClauses[0];
|
||||||
|
|
||||||
Long primaryId = 0L;
|
Long primaryId = 0L;
|
||||||
PreparedStatement primaryPrepStmt = null;
|
PreparedStatement primaryPrepStmt = null;
|
||||||
@@ -182,7 +190,7 @@ public class DeleteNotExistsExecutor implements StatementExecutor
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
connection.setAutoCommit(false);
|
connection.setAutoCommit(false);
|
||||||
primaryPrepStmt = connection.prepareStatement(createPreparedSelectStatement(primaryTableName, primaryColumnName));
|
primaryPrepStmt = connection.prepareStatement(createPreparedSelectStatement(primaryTableName, primaryColumnName, primaryWhereClause));
|
||||||
primaryPrepStmt.setFetchSize(batchSize);
|
primaryPrepStmt.setFetchSize(batchSize);
|
||||||
primaryPrepStmt.setLong(1, primaryId);
|
primaryPrepStmt.setLong(1, primaryId);
|
||||||
primaryPrepStmt.setLong(2, tableUpperLimits[0]);
|
primaryPrepStmt.setLong(2, tableUpperLimits[0]);
|
||||||
@@ -195,7 +203,7 @@ public class DeleteNotExistsExecutor implements StatementExecutor
|
|||||||
secondaryPrepStmts = new PreparedStatement[tableColumn.length];
|
secondaryPrepStmts = new PreparedStatement[tableColumn.length];
|
||||||
for (int i = 1; i < tableColumn.length; i++)
|
for (int i = 1; i < tableColumn.length; i++)
|
||||||
{
|
{
|
||||||
PreparedStatement secStmt = connection.prepareStatement(createPreparedSelectStatement(tableColumn[i].getFirst(), tableColumn[i].getSecond()));
|
PreparedStatement secStmt = connection.prepareStatement(createPreparedSelectStatement(tableColumn[i].getFirst(), tableColumn[i].getSecond(), optionalWhereClauses[i]));
|
||||||
secStmt.setFetchSize(batchSize);
|
secStmt.setFetchSize(batchSize);
|
||||||
secStmt.setLong(1, primaryId);
|
secStmt.setLong(1, primaryId);
|
||||||
secStmt.setLong(2, tableUpperLimits[i]);
|
secStmt.setLong(2, tableUpperLimits[i]);
|
||||||
@@ -203,7 +211,7 @@ public class DeleteNotExistsExecutor implements StatementExecutor
|
|||||||
secondaryPrepStmts[i] = secStmt;
|
secondaryPrepStmts[i] = secStmt;
|
||||||
}
|
}
|
||||||
|
|
||||||
deletePrepStmt = connection.prepareStatement(createPreparedDeleteStatement(primaryTableName, primaryColumnName, deleteBatchSize));
|
deletePrepStmt = connection.prepareStatement(createPreparedDeleteStatement(primaryTableName, primaryColumnName, deleteBatchSize, primaryWhereClause));
|
||||||
|
|
||||||
// Timeout is only checked at each bach start.
|
// Timeout is only checked at each bach start.
|
||||||
// It can be further refined by being verified at each primary row processing.
|
// It can be further refined by being verified at each primary row processing.
|
||||||
@@ -341,6 +349,8 @@ public class DeleteNotExistsExecutor implements StatementExecutor
|
|||||||
deletedBatchCount = executeDeleteStatement(deletePrepStmt, deleteIds, deleteBatchSize, line, scriptFile);
|
deletedBatchCount = executeDeleteStatement(deletePrepStmt, deleteIds, deleteBatchSize, line, scriptFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deletedCount += deletedBatchCount;
|
||||||
|
|
||||||
if (logger.isTraceEnabled())
|
if (logger.isTraceEnabled())
|
||||||
{
|
{
|
||||||
String msg = ((readOnly) ? "Script would have" : "Script") + " deleted a batch of " + deletedBatchCount + " items from table " + primaryTableName + ".";
|
String msg = ((readOnly) ? "Script would have" : "Script") + " deleted a batch of " + deletedBatchCount + " items from table " + primaryTableName + ".";
|
||||||
@@ -363,9 +373,9 @@ public class DeleteNotExistsExecutor implements StatementExecutor
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
stmt = connection.createStatement();
|
stmt = connection.createStatement();
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isTraceEnabled())
|
||||||
{
|
{
|
||||||
LogUtil.debug(logger, MSG_EXECUTING_STATEMENT, sql);
|
logger.trace("Executing statement: " + sql);
|
||||||
}
|
}
|
||||||
boolean haveResults = stmt.execute(sql);
|
boolean haveResults = stmt.execute(sql);
|
||||||
if (haveResults && fetchColumnName != null)
|
if (haveResults && fetchColumnName != null)
|
||||||
@@ -428,14 +438,38 @@ public class DeleteNotExistsExecutor implements StatementExecutor
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String createPreparedSelectStatement(String tableName, String columnName)
|
private String removeDoubleQuotes(String quotedString)
|
||||||
{
|
{
|
||||||
return "SELECT " + columnName + " FROM " + tableName + " WHERE " + columnName + " > ? AND " + columnName + " <= ? ORDER BY " + columnName + " ASC";
|
if (quotedString == null || quotedString.isEmpty())
|
||||||
|
{
|
||||||
|
return quotedString;
|
||||||
|
}
|
||||||
|
|
||||||
|
return quotedString.replace("\"", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
private String createPreparedDeleteStatement(String tableName, String idColumnName, int deleteBatchSize)
|
private String createPreparedSelectStatement(String tableName, String columnName, String whereClause)
|
||||||
{
|
{
|
||||||
StringBuilder stmtBuilder = new StringBuilder("DELETE FROM " + tableName + " WHERE " + idColumnName + " IN ");
|
StringBuilder sqlBuilder = new StringBuilder("SELECT " + columnName + " FROM " + tableName + " WHERE ");
|
||||||
|
|
||||||
|
if (whereClause != null && !whereClause.isEmpty())
|
||||||
|
{
|
||||||
|
sqlBuilder.append(whereClause + " AND ");
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlBuilder.append(columnName + " > ? AND " + columnName + " <= ? ORDER BY " + columnName + " ASC");
|
||||||
|
return sqlBuilder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String createPreparedDeleteStatement(String tableName, String idColumnName, int deleteBatchSize, String whereClause)
|
||||||
|
{
|
||||||
|
StringBuilder stmtBuilder = new StringBuilder("DELETE FROM " + tableName + " WHERE ");
|
||||||
|
|
||||||
|
if (whereClause != null && !whereClause.isEmpty())
|
||||||
|
{
|
||||||
|
stmtBuilder.append(whereClause + " AND ");
|
||||||
|
}
|
||||||
|
stmtBuilder.append(idColumnName + " IN ");
|
||||||
stmtBuilder.append("(");
|
stmtBuilder.append("(");
|
||||||
|
|
||||||
for (int i = 1; i <= deleteBatchSize; i++)
|
for (int i = 1; i <= deleteBatchSize; i++)
|
||||||
@@ -471,13 +505,7 @@ public class DeleteNotExistsExecutor implements StatementExecutor
|
|||||||
stmt.setObject(j, 0);
|
stmt.setObject(j, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
|
||||||
{
|
|
||||||
LogUtil.debug(logger, MSG_EXECUTING_STATEMENT, sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
int deletedItems = stmt.executeUpdate();
|
int deletedItems = stmt.executeUpdate();
|
||||||
deletedCount += deletedItems;
|
|
||||||
return deletedItems;
|
return deletedItems;
|
||||||
}
|
}
|
||||||
catch (SQLException e)
|
catch (SQLException e)
|
||||||
|
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
--DELETE_NOT_EXISTS alf_prop_value.id,alf_audit_app.app_name_id,alf_audit_entry.audit_user_id,alf_prop_link.key_prop_id,alf_prop_link.value_prop_id,alf_prop_unique_ctx.value1_prop_id,alf_prop_unique_ctx.value2_prop_id,alf_prop_unique_ctx.value3_prop_id system.delete_not_exists.batchsize
|
--DELETE_NOT_EXISTS alf_prop_value.id,alf_audit_app.app_name_id,alf_audit_entry.audit_user_id,alf_prop_link.key_prop_id,alf_prop_link.value_prop_id,alf_prop_unique_ctx.value1_prop_id,alf_prop_unique_ctx.value2_prop_id,alf_prop_unique_ctx.value3_prop_id system.delete_not_exists.batchsize
|
||||||
|
|
||||||
--DELETE_NOT_EXISTS alf_prop_string_value.id,alf_prop_value.long_value,alf_audit_app.app_name_id,alf_audit_entry.audit_user_id,alf_prop_link.key_prop_id,alf_prop_link.value_prop_id,alf_prop_unique_ctx.value1_prop_id,alf_prop_unique_ctx.value2_prop_id,alf_prop_unique_ctx.value3_prop_id system.delete_not_exists.batchsize
|
--DELETE_NOT_EXISTS alf_prop_string_value.id,alf_prop_value.long_value."persisted_type in (3, 5, 6)",alf_audit_app.app_name_id,alf_audit_entry.audit_user_id,alf_prop_link.key_prop_id,alf_prop_link.value_prop_id,alf_prop_unique_ctx.value1_prop_id,alf_prop_unique_ctx.value2_prop_id,alf_prop_unique_ctx.value3_prop_id system.delete_not_exists.batchsize
|
||||||
|
|
||||||
--DELETE_NOT_EXISTS alf_prop_serializable_value.id,alf_prop_value.long_value,alf_audit_app.app_name_id,alf_audit_entry.audit_user_id,alf_prop_link.key_prop_id,alf_prop_link.value_prop_id,alf_prop_unique_ctx.value1_prop_id,alf_prop_unique_ctx.value2_prop_id,alf_prop_unique_ctx.value3_prop_id system.delete_not_exists.batchsize
|
--DELETE_NOT_EXISTS alf_prop_serializable_value.id,alf_prop_value.long_value.persisted_type=4,alf_audit_app.app_name_id,alf_audit_entry.audit_user_id,alf_prop_link.key_prop_id,alf_prop_link.value_prop_id,alf_prop_unique_ctx.value1_prop_id,alf_prop_unique_ctx.value2_prop_id,alf_prop_unique_ctx.value3_prop_id system.delete_not_exists.batchsize
|
||||||
|
|
||||||
--DELETE_NOT_EXISTS alf_prop_double_value.id,alf_prop_value.long_value,alf_audit_app.app_name_id,alf_audit_entry.audit_user_id,alf_prop_link.key_prop_id,alf_prop_link.value_prop_id,alf_prop_unique_ctx.value1_prop_id,alf_prop_unique_ctx.value2_prop_id,alf_prop_unique_ctx.value3_prop_id system.delete_not_exists.batchsize
|
--DELETE_NOT_EXISTS alf_prop_double_value.id,alf_prop_value.long_value.persisted_type=2,alf_audit_app.app_name_id,alf_audit_entry.audit_user_id,alf_prop_link.key_prop_id,alf_prop_link.value_prop_id,alf_prop_unique_ctx.value1_prop_id,alf_prop_unique_ctx.value2_prop_id,alf_prop_unique_ctx.value3_prop_id system.delete_not_exists.batchsize
|
||||||
|
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
--DELETE_NOT_EXISTS alf_prop_value.id,alf_audit_app.app_name_id,alf_audit_entry.audit_user_id,alf_prop_link.key_prop_id,alf_prop_link.value_prop_id,alf_prop_unique_ctx.value1_prop_id,alf_prop_unique_ctx.value2_prop_id,alf_prop_unique_ctx.value3_prop_id system.delete_not_exists.batchsize
|
--DELETE_NOT_EXISTS alf_prop_value.id,alf_audit_app.app_name_id,alf_audit_entry.audit_user_id,alf_prop_link.key_prop_id,alf_prop_link.value_prop_id,alf_prop_unique_ctx.value1_prop_id,alf_prop_unique_ctx.value2_prop_id,alf_prop_unique_ctx.value3_prop_id system.delete_not_exists.batchsize
|
||||||
|
|
||||||
--DELETE_NOT_EXISTS alf_prop_string_value.id,alf_prop_value.long_value,alf_audit_app.app_name_id,alf_audit_entry.audit_user_id,alf_prop_link.key_prop_id,alf_prop_link.value_prop_id,alf_prop_unique_ctx.value1_prop_id,alf_prop_unique_ctx.value2_prop_id,alf_prop_unique_ctx.value3_prop_id system.delete_not_exists.batchsize
|
--DELETE_NOT_EXISTS alf_prop_string_value.id,alf_prop_value.long_value."persisted_type in (3, 5, 6)",alf_audit_app.app_name_id,alf_audit_entry.audit_user_id,alf_prop_link.key_prop_id,alf_prop_link.value_prop_id,alf_prop_unique_ctx.value1_prop_id,alf_prop_unique_ctx.value2_prop_id,alf_prop_unique_ctx.value3_prop_id system.delete_not_exists.batchsize
|
||||||
|
|
||||||
--DELETE_NOT_EXISTS alf_prop_serializable_value.id,alf_prop_value.long_value,alf_audit_app.app_name_id,alf_audit_entry.audit_user_id,alf_prop_link.key_prop_id,alf_prop_link.value_prop_id,alf_prop_unique_ctx.value1_prop_id,alf_prop_unique_ctx.value2_prop_id,alf_prop_unique_ctx.value3_prop_id system.delete_not_exists.batchsize
|
--DELETE_NOT_EXISTS alf_prop_serializable_value.id,alf_prop_value.long_value.persisted_type=4,alf_audit_app.app_name_id,alf_audit_entry.audit_user_id,alf_prop_link.key_prop_id,alf_prop_link.value_prop_id,alf_prop_unique_ctx.value1_prop_id,alf_prop_unique_ctx.value2_prop_id,alf_prop_unique_ctx.value3_prop_id system.delete_not_exists.batchsize
|
||||||
|
|
||||||
--DELETE_NOT_EXISTS alf_prop_double_value.id,alf_prop_value.long_value,alf_audit_app.app_name_id,alf_audit_entry.audit_user_id,alf_prop_link.key_prop_id,alf_prop_link.value_prop_id,alf_prop_unique_ctx.value1_prop_id,alf_prop_unique_ctx.value2_prop_id,alf_prop_unique_ctx.value3_prop_id system.delete_not_exists.batchsize
|
--DELETE_NOT_EXISTS alf_prop_double_value.id,alf_prop_value.long_value.persisted_type=2,alf_audit_app.app_name_id,alf_audit_entry.audit_user_id,alf_prop_link.key_prop_id,alf_prop_link.value_prop_id,alf_prop_unique_ctx.value1_prop_id,alf_prop_unique_ctx.value2_prop_id,alf_prop_unique_ctx.value3_prop_id system.delete_not_exists.batchsize
|
||||||
|
Reference in New Issue
Block a user