Skip to content

Commit

Permalink
Fixed several issues
Browse files Browse the repository at this point in the history
  • Loading branch information
PeachThinking committed Jan 30, 2024
1 parent 3e74835 commit b18a41e
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,11 @@ public ListResponse<TableComparing> skipTableComparing(@PathVariable Long id,
@RequestMapping(value = "/structureComparison/{id}", method = RequestMethod.GET)
public SuccessResponse<DBStructureComparisonResp> listStructureComparisonResult(@PathVariable Long id,
@RequestParam(required = false) OperationType operationType,
@RequestParam(required = false, name = "dbObjectName") String dbObjectName,
@PageableDefault(size = Integer.MAX_VALUE, sort = {"id"}, direction = Direction.DESC) Pageable pageable) {
return Responses
.success(structureComparisonService.getDBStructureComparisonResult(id, operationType, pageable));
.success(structureComparisonService.getDBStructureComparisonResult(id, operationType, dbObjectName,
pageable));
}

@RequestMapping(value = "/structureComparison/{id}/{structureComparisonId}", method = RequestMethod.GET)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import org.springframework.data.jpa.domain.Specification;

import com.oceanbase.odc.common.util.StringUtils;
import com.oceanbase.odc.service.structurecompare.model.ComparisonResult;

import lombok.NonNull;
Expand All @@ -29,6 +30,7 @@
public class StructureComparisonEntitySpecs {
private static final String STRUCTURE_COMPARISON_TASK_ID = "comparisonTaskId";
private static final String COMPARING_RESULT = "comparingResult";
private static final String DB_OBJECT_NAME = "databaseObjectName";

public static Specification<StructureComparisonEntity> comparisonTaskIdEquals(@NonNull Long comparisonTaskId) {
return (root, query, builder) -> builder.equal(root.get(STRUCTURE_COMPARISON_TASK_ID), comparisonTaskId);
Expand All @@ -38,4 +40,10 @@ public static Specification<StructureComparisonEntity> comparisonResultEquals(
@NonNull ComparisonResult comparisonResult) {
return (root, query, builder) -> builder.equal(root.get(COMPARING_RESULT), comparisonResult);
}

public static Specification<StructureComparisonEntity> dbObjectNameLike(
@NonNull String dbObjectName) {
return (root, query, builder) -> builder.like(root.get(DB_OBJECT_NAME),
"%" + StringUtils.escapeLike(dbObjectName) + "%");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -161,21 +161,23 @@ private ConnectionConfig getConnectionConfigByDatabaseEntity(DatabaseEntity data
}

public DBStructureComparisonResp getDBStructureComparisonResult(@NonNull Long id, OperationType operationType,
String dbObjectName,
@NotNull Pageable pageable) {
StructureComparisonTaskEntity taskEntity = structureComparisonTaskRepository.findById(id).orElseThrow(
() -> new NotFoundException(ResourceType.ODC_STRUCTURE_COMPARISON_TASK, "id", id));
checkPermission(taskEntity);

Specification<StructureComparisonEntity> specification;
Page<StructureComparisonEntity> entities;
if (operationType == null) {
specification = Specification.where(StructureComparisonEntitySpecs.comparisonTaskIdEquals(id));
entities = structureComparisonRepository.findAll(specification, pageable);
} else {
specification = Specification.where(StructureComparisonEntitySpecs.comparisonTaskIdEquals(id))
Specification<StructureComparisonEntity> specification =
Specification.where(StructureComparisonEntitySpecs.comparisonTaskIdEquals(id));
if (operationType != null) {
specification = specification
.and(StructureComparisonEntitySpecs.comparisonResultEquals(operationType.getComparisonResult()));
entities = structureComparisonRepository.findAll(specification, pageable);
}
if (dbObjectName != null) {
specification = specification.and(StructureComparisonEntitySpecs.dbObjectNameLike(dbObjectName));
}
entities = structureComparisonRepository.findAll(specification, pageable);

DBStructureComparisonResp resp = new DBStructureComparisonResp();
resp.setId(id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
import com.oceanbase.tools.dbbrowser.util.OracleSqlBuilder;
import com.oceanbase.tools.dbbrowser.util.SqlBuilder;

import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;

/**
Expand Down Expand Up @@ -75,8 +76,6 @@ public DBTableStructureComparator(DBTableEditor tgtTableEditor, DialectType tgtD
@Override
public List<DBObjectComparisonResult> compare(List<DBTable> srcTables, List<DBTable> tgtTables) {
List<DBObjectComparisonResult> returnVal = new LinkedList<>();
preHandleDBTable(srcTables);
preHandleDBTable(tgtTables);
if (srcTables.isEmpty() && tgtTables.isEmpty()) {
this.totalTableCount = 0;
return returnVal;
Expand Down Expand Up @@ -131,19 +130,17 @@ public List<DBObjectComparisonResult> compare(List<DBTable> srcTables, List<DBTa
return returnVal;
}

private void preHandleDBTable(List<DBTable> tables) {
private void filterNotNullCheckConstraint(@NonNull DBTable table) {
if (tgtDialectType != DialectType.OB_ORACLE) {
return;
}
// Filter out not null check constraints which will be compared in column comparison
tables.forEach(table -> {
List<DBTableConstraint> filteredConstraints = table.getConstraints().stream()
.filter(constraint -> !(constraint.getType() == DBConstraintType.CHECK &&
constraint.getCheckClause() != null &&
constraint.getCheckClause().endsWith("IS NOT NULL")))
.collect(Collectors.toList());
table.setConstraints(filteredConstraints);
});
List<DBTableConstraint> filteredConstraints = table.getConstraints().stream()
.filter(constraint -> !(constraint.getType() == DBConstraintType.CHECK &&
constraint.getCheckClause() != null &&
constraint.getCheckClause().endsWith("IS NOT NULL")))
.collect(Collectors.toList());
table.setConstraints(filteredConstraints);
}

private List<DBObjectComparisonResult> buildOnlyInSourceResult(List<String> toCreate,
Expand Down Expand Up @@ -171,6 +168,7 @@ private List<DBObjectComparisonResult> buildOnlyInSourceResult(List<String> toCr
private DBTable copySrcSourceTable(DBTable srcTable) {
DBTable copiedSrcTable = new DBTable();
if (tgtDialectType == DialectType.OB_ORACLE) {
filterNotNullCheckConstraint(srcTable);
List<DBTableConstraint> pk = srcTable.getConstraints().stream().filter(
cons -> cons.getType() == DBConstraintType.PRIMARY_KEY).collect(
Collectors.toList());
Expand Down Expand Up @@ -262,6 +260,8 @@ public DBObjectComparisonResult compare(DBTable sourceTable, DBTable targetTable
Collections.singletonMap(sourceTable.getName(), sourceTable), this.srcSchemaName,
this.tgtSchemaName).get(0);
}
filterNotNullCheckConstraint(sourceTable);
filterNotNullCheckConstraint(targetTable);

DBObjectComparisonResult result = new DBObjectComparisonResult(DBObjectType.TABLE, sourceTable.getName(),
this.srcSchemaName, this.tgtSchemaName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@
package com.oceanbase.odc.service.structurecompare.model;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;

import com.oceanbase.odc.core.shared.constant.DialectType;
Expand All @@ -30,8 +30,7 @@
import com.oceanbase.odc.metadb.structurecompare.StructureComparisonEntity;
import com.oceanbase.odc.service.common.util.SqlUtils;
import com.oceanbase.tools.dbbrowser.model.DBObjectType;
import com.oceanbase.tools.sqlparser.statement.Statement;
import com.oceanbase.tools.sqlparser.statement.alter.table.AlterTable;
import com.oceanbase.tools.dbbrowser.parser.constant.SqlType;

import lombok.Data;
import lombok.NonNull;
Expand Down Expand Up @@ -87,59 +86,59 @@ public StructureComparisonEntity toEntity(@NonNull Long structureComparisonTaskI
continue;
}
// DDL operations involving deletion of database objects are placed in comments
DBObjectType objectType = subResult.getDbObjectType();
if (subResult.getComparisonResult() == ComparisonResult.ONLY_IN_TARGET) {
totalSubScript.append("/*\n")
.append(subResult.getChangeScript())
.append("*/\n")
.append("\n");
} else if (subResult.getDbObjectType() == DBObjectType.PARTITION) {
.append("*/\n\n");
} else if (objectType == DBObjectType.PARTITION || objectType == DBObjectType.CONSTRAINT
|| objectType == DBObjectType.INDEX) {
List<String> sqls = SqlUtils.split(dialectType, subResult.getChangeScript(), ";");
for (String sql : sqls) {
String sqlWithoutComment =
SqlUtils.removeComments(new SqlCommentProcessor(dialectType, false, false), sql);
String comments = sql.replace(sqlWithoutComment, "");
if (isDropPartitionStatement(parseSingleSql(dialectType, sqlWithoutComment))) {
if (SqlType.DROP.equals(parseSingleSqlType(dialectType, sqlWithoutComment))) {
totalSubScript.append(comments)
.append("/*\n")
.append(sqlWithoutComment)
.append(";\n")
.append("*/\n")
.append("\n");
.append(appendDelimiterIfNotExists(sqlWithoutComment))
.append("*/\n\n");
} else {
totalSubScript.append(subResult.getChangeScript())
.append("\n");
if (StringUtils.isNotEmpty(sqlWithoutComment)) {
totalSubScript.append(appendDelimiterIfNotExists(sqlWithoutComment));
}
if (StringUtils.isNotEmpty(comments)) {
totalSubScript.append(comments).append("\n");
}
}
}
} else {
totalSubScript.append(subResult.getChangeScript())
.append("\n");
totalSubScript.append(subResult.getChangeScript()).append("\n");
}
}
}
entity.setChangeSqlScript(totalSubScript + "\n" + changeScript);
return entity;
}

private Statement parseSingleSql(DialectType dialectType, String sql) {
private SqlType parseSingleSqlType(DialectType dialectType, String sql) {
if (Objects.isNull(sql) || sql.isEmpty()) {
return null;
}
try {
AbstractSyntaxTreeFactory factory = AbstractSyntaxTreeFactories.getAstFactory(dialectType, 0);
Validate.notNull(factory, "AbstractSyntaxTreeFactory can not be null");
return factory.buildAst(sql).getStatement();
return factory.buildAst(sql).getParseResult().getSqlType();
} catch (Exception e) {
return null;
}
}

private boolean isDropPartitionStatement(Statement stmt) {
if (stmt instanceof AlterTable) {
return ((AlterTable) stmt).getAlterTableActions().stream().filter(Objects::nonNull)
.anyMatch(action -> !getSafeList(action.getDropPartitionNames()).isEmpty()
|| !getSafeList(action.getDropSubPartitionNames()).isEmpty());
private String appendDelimiterIfNotExists(String sql) {
String s = sql.trim();
if (StringUtils.isBlank(s) || s.endsWith(";")) {
return sql + "\n";
}
return false;
}

private <T> List<T> getSafeList(List<T> list) {
return list == null ? Collections.emptyList() : list;
return sql + ";\n";
}
}

0 comments on commit b18a41e

Please sign in to comment.