From 7e17aaa89464e27c0596bb6fd06f17096b0c9c16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=A7=E8=83=83=E7=8E=8B?= <253498229@qq.com> Date: Wed, 11 Dec 2019 17:48:52 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0procedure?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/dictionaries/wangbin.xml | 4 +- .../cn/codeforfun/migrate/core/Migrate.java | 25 ++++ .../migrate/core/diff/DiffResult.java | 17 +++ .../core/entity/structure/Database.java | 2 + .../core/entity/structure/Procedure.java | 113 ++++++++++++++++++ .../main/resources/sql/detail/procedure.sql | 20 ++++ 6 files changed, 179 insertions(+), 2 deletions(-) create mode 100644 mysql-migrate/src/main/java/cn/codeforfun/migrate/core/entity/structure/Procedure.java create mode 100644 mysql-migrate/src/main/resources/sql/detail/procedure.sql diff --git a/.idea/dictionaries/wangbin.xml b/.idea/dictionaries/wangbin.xml index f635da8..d43e56e 100644 --- a/.idea/dictionaries/wangbin.xml +++ b/.idea/dictionaries/wangbin.xml @@ -4,13 +4,13 @@ InnoDB SQL aliyun + codeforfun + gitee ossrh pactera sonatype updatable wangbin - codeforfun - gitee \ No newline at end of file diff --git a/mysql-migrate/src/main/java/cn/codeforfun/migrate/core/Migrate.java b/mysql-migrate/src/main/java/cn/codeforfun/migrate/core/Migrate.java index a87648f..60242c7 100644 --- a/mysql-migrate/src/main/java/cn/codeforfun/migrate/core/Migrate.java +++ b/mysql-migrate/src/main/java/cn/codeforfun/migrate/core/Migrate.java @@ -86,6 +86,7 @@ private void compare() { compareTable(fromTableList, toTableList, fromTableNameList, toTableNameList); compareView(); compareFunction(); + compareProcedure(); compareTrigger(); } @@ -113,6 +114,30 @@ private void compareTrigger() { this.diff.getUpdate().addAll(updateTriggerList); } + /** + * 对比procedure + */ + private void compareProcedure() { + // Procedure + List fromProcedureList = this.diff.getFrom().getProcedures(); + List toProcedureList = this.diff.getTo().getProcedures(); + List fromProcedureNameList = fromProcedureList.stream().map(Procedure::getName).collect(Collectors.toList()); + List toProcedureNameList = toProcedureList.stream().map(Procedure::getName).collect(Collectors.toList()); + // 删除Procedure + List deleteProcedureList = toProcedureList.stream().filter(s -> !fromProcedureNameList.contains(s.getName())).collect(Collectors.toList()); + this.diff.getDelete().addAll(deleteProcedureList); + // 新建Procedure + List createProcedureList = fromProcedureList.stream().filter(s -> !toProcedureNameList.contains(s.getName())).collect(Collectors.toList()); + this.diff.getCreate().addAll(createProcedureList); + // 更新Procedure + List updateProcedureList = toProcedureList.stream().map(s -> fromProcedureList.stream().filter(j -> + s.getName().equals(j.getName()) + && s.getSchema().equals(j.getSchema()) + && !s.equals(j)).collect(Collectors.toList()) + ).flatMap(List::stream).collect(Collectors.toList()); + this.diff.getUpdate().addAll(updateProcedureList); + } + /** * 对比function */ diff --git a/mysql-migrate/src/main/java/cn/codeforfun/migrate/core/diff/DiffResult.java b/mysql-migrate/src/main/java/cn/codeforfun/migrate/core/diff/DiffResult.java index 57bf4be..6899b99 100644 --- a/mysql-migrate/src/main/java/cn/codeforfun/migrate/core/diff/DiffResult.java +++ b/mysql-migrate/src/main/java/cn/codeforfun/migrate/core/diff/DiffResult.java @@ -89,6 +89,11 @@ public void resolveDeleteSql() { Function delete = (Function) difference; String deleteSql = delete.getDeleteSql(); this.sqlList.add(deleteSql); + } else if (difference instanceof Procedure) { + // 删除Procedure + Procedure delete = (Procedure) difference; + String deleteSql = delete.getDeleteSql(); + this.sqlList.add(deleteSql); } else if (difference instanceof Trigger) { // 删除trigger Trigger delete = (Trigger) difference; @@ -125,6 +130,11 @@ public void resolveCreateSql() { Function create = (Function) difference; String createSql = create.getCreateSql(); this.sqlList.add(createSql); + } else if (difference instanceof Procedure) { + // 创建Procedure + Procedure create = (Procedure) difference; + String createSql = create.getCreateSql(); + this.sqlList.add(createSql); } else if (difference instanceof Trigger) { // 创建Trigger Trigger create = (Trigger) difference; @@ -160,6 +170,13 @@ public void resolveUpdateSql() { this.sqlList.add(deleteSql); String createSql = update.getCreateSql(); this.sqlList.add(createSql); + } else if (difference instanceof Procedure) { + // 更新Procedure + Procedure update = (Procedure) difference; + String deleteSql = update.getDeleteSql(); + this.sqlList.add(deleteSql); + String createSql = update.getCreateSql(); + this.sqlList.add(createSql); } else if (difference instanceof Trigger) { // 更新Trigger Trigger update = (Trigger) difference; diff --git a/mysql-migrate/src/main/java/cn/codeforfun/migrate/core/entity/structure/Database.java b/mysql-migrate/src/main/java/cn/codeforfun/migrate/core/entity/structure/Database.java index 01191c8..e49cef6 100644 --- a/mysql-migrate/src/main/java/cn/codeforfun/migrate/core/entity/structure/Database.java +++ b/mysql-migrate/src/main/java/cn/codeforfun/migrate/core/entity/structure/Database.java @@ -36,6 +36,7 @@ public class Database { private List tables; private List views; private List functions; + private List procedures; private List triggers; public static final String SQL = FileUtil.getStringByClasspath("sql/detail/database.sql"); @@ -64,6 +65,7 @@ private Database configure() throws SQLException { bean.setTables(Table.configure(this.connection, this.info.getName())); bean.setViews(View.configure(this.connection, this.info.getName())); bean.setFunctions(Function.configure(this.connection, this.info.getName())); + bean.setProcedures(Procedure.configure(this.connection, this.info.getName())); bean.setTriggers(Trigger.configure(this.connection, this.info.getName())); bean.setInfo(this.info); bean.setConnection(this.connection); diff --git a/mysql-migrate/src/main/java/cn/codeforfun/migrate/core/entity/structure/Procedure.java b/mysql-migrate/src/main/java/cn/codeforfun/migrate/core/entity/structure/Procedure.java new file mode 100644 index 0000000..1182383 --- /dev/null +++ b/mysql-migrate/src/main/java/cn/codeforfun/migrate/core/entity/structure/Procedure.java @@ -0,0 +1,113 @@ +package cn.codeforfun.migrate.core.entity.structure; + +import cn.codeforfun.migrate.core.diff.Difference; +import cn.codeforfun.migrate.core.utils.DbUtil; +import cn.codeforfun.migrate.core.utils.FileUtil; +import lombok.Getter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; + +import java.io.Serializable; +import java.sql.Connection; +import java.sql.SQLException; +import java.util.*; +import java.util.stream.Collectors; + +/** + * Procedure结构定义 + * + * @author wangbin + */ +@Getter +@Setter +@Slf4j +public class Procedure implements Serializable, Difference { + private static final long serialVersionUID = -7316847891519066690L; + + private String securityType; + private String definer; + private String schema; + private String name; + private String source; + + private List routines = new ArrayList<>(); + + public static List configure(Connection connection, String databaseName) throws SQLException { + List beanList = DbUtil.getBeanList(connection, + FileUtil.getStringByClasspath("sql/detail/procedure.sql"), + Routine.class, databaseName); + Map procedures = new HashMap<>(0); + for (Routine routine : beanList) { + Procedure procedure = procedures.get(routine.getName()); + if (procedure == null) { + procedure = new Procedure(); + } + procedure.getRoutines().add(routine); + procedure.setDefiner(routine.getDefiner()); + procedure.setSecurityType(routine.getSecurityType()); + procedure.setSchema(routine.getSchema()); + procedure.setName(routine.getName()); + procedure.setSource(routine.getSource()); + procedures.put(routine.getName(), procedure); + } + return new ArrayList<>(procedures.values()); + } + + @Override + public String getCreateSql() { + StringBuilder sb = new StringBuilder(); + String[] split = this.definer.split("@"); + sb.append("CREATE DEFINER = `").append(split[0]).append("`@`").append(split[1]).append("`"); + sb.append(" PROCEDURE `").append(this.name).append("`"); + sb.append("("); + List inputTypeList = this.getRoutines().stream().filter(s -> "IN".equals(s.getParamMode())).collect(Collectors.toList()); + List resultTypeList = this.getRoutines().stream().filter(s -> "OUT".equals(s.getParamMode())).collect(Collectors.toList()); + for (Routine inList : inputTypeList) { + sb.append("IN ").append(inList.getParamName()).append(" ").append(inList.getResultType()).append(","); + } + for (Routine outList : resultTypeList) { + sb.append("OUT ").append(outList.getParamName()).append(" ").append(outList.getResultType()).append(","); + } + sb = new StringBuilder(sb.substring(0, sb.length() - 1)); + sb.append(")\n"); + sb.append(this.source).append(";"); + return sb.toString(); + } + + @Override + public String getUpdateSql() { + return null; + } + + @Override + public String getDeleteSql() { + return "DROP PROCEDURE `" + this.name + "`;"; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof Procedure)) { + return false; + } + Procedure procedure = (Procedure) o; + return Objects.equals(getSecurityType(), procedure.getSecurityType()) && + Objects.equals(getDefiner(), procedure.getDefiner()) && + Objects.equals(getSchema(), procedure.getSchema()) && + Objects.equals(getName(), procedure.getName()) && + Objects.equals(getSource(), procedure.getSource()) && + Objects.equals(getRoutines(), procedure.getRoutines()); + } + + @Override + public int hashCode() { + return Objects.hash(getSecurityType(), + getDefiner(), + getSchema(), + getName(), + getSource(), + getRoutines()); + } +} diff --git a/mysql-migrate/src/main/resources/sql/detail/procedure.sql b/mysql-migrate/src/main/resources/sql/detail/procedure.sql new file mode 100644 index 0000000..bde1e1b --- /dev/null +++ b/mysql-migrate/src/main/resources/sql/detail/procedure.sql @@ -0,0 +1,20 @@ +SELECT r.SECURITY_TYPE, + r.DEFINER, + r.ROUTINE_SCHEMA, + r.SPECIFIC_NAME, + r.ROUTINE_DEFINITION, + p.PARAMETER_MODE, + p.PARAMETER_NAME, + p.DATA_TYPE, + p.CHARACTER_MAXIMUM_LENGTH, + p.NUMERIC_PRECISION, + p.NUMERIC_SCALE, + p.DATETIME_PRECISION, + p.DTD_IDENTIFIER, + p.CHARACTER_SET_NAME, + p.COLLATION_NAME +FROM information_schema.ROUTINES r + LEFT JOIN information_schema.PARAMETERS p + ON r.ROUTINE_SCHEMA = p.SPECIFIC_SCHEMA AND r.SPECIFIC_NAME = p.SPECIFIC_NAME +WHERE r.ROUTINE_SCHEMA = ? + AND r.ROUTINE_TYPE = 'PROCEDURE' \ No newline at end of file