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