增加数据库函数和存储过程的增删改查支持,优化数据源管理
This commit is contained in:
@@ -1,11 +1,14 @@
|
||||
package com.zyplayer.doc.db.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.zyplayer.doc.core.annotation.AuthMan;
|
||||
import com.zyplayer.doc.core.json.ResponseJson;
|
||||
import com.zyplayer.doc.data.config.security.DocUserDetails;
|
||||
import com.zyplayer.doc.data.config.security.DocUserUtil;
|
||||
import com.zyplayer.doc.data.repository.manage.entity.DbDatasource;
|
||||
import com.zyplayer.doc.data.repository.manage.entity.UserInfo;
|
||||
import com.zyplayer.doc.data.repository.support.consts.DocAuthConst;
|
||||
import com.zyplayer.doc.data.service.manage.DbDatasourceService;
|
||||
import com.zyplayer.doc.db.framework.configuration.DatasourceUtil;
|
||||
@@ -20,6 +23,7 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 数据源控制器
|
||||
@@ -38,14 +42,27 @@ public class DbDatasourceController {
|
||||
DbDatasourceService dbDatasourceService;
|
||||
|
||||
@PostMapping(value = "/list")
|
||||
public ResponseJson list() {
|
||||
public ResponseJson list(Integer pageNum, Integer pageSize, String name, String groupName) {
|
||||
QueryWrapper<DbDatasource> wrapper = new QueryWrapper<>();
|
||||
wrapper.eq("yn", 1);
|
||||
List<DbDatasource> datasourceList = dbDatasourceService.list(wrapper);
|
||||
for (DbDatasource dbDatasource : datasourceList) {
|
||||
wrapper.eq(StringUtils.isNotBlank(groupName), "group_name", groupName);
|
||||
wrapper.like(StringUtils.isNotBlank(name), "name", "%" + name + "%");
|
||||
IPage<DbDatasource> page = new Page<>(pageNum, pageSize, pageNum == 1);
|
||||
dbDatasourceService.page(page, wrapper);
|
||||
for (DbDatasource dbDatasource : page.getRecords()) {
|
||||
dbDatasource.setSourcePassword("***");
|
||||
}
|
||||
return DocDbResponseJson.ok(datasourceList);
|
||||
return DocDbResponseJson.ok(page);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/groups")
|
||||
public ResponseJson groups() {
|
||||
QueryWrapper<DbDatasource> wrapper = new QueryWrapper<>();
|
||||
wrapper.eq("yn", 1);
|
||||
wrapper.select("group_name");
|
||||
List<DbDatasource> datasourceList = dbDatasourceService.list(wrapper);
|
||||
Set<String> groupNameSet = datasourceList.stream().map(DbDatasource::getGroupName).filter(StringUtils::isNotBlank).collect(Collectors.toSet());
|
||||
return DocDbResponseJson.ok(groupNameSet);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/test")
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
package com.zyplayer.doc.db.controller;
|
||||
|
||||
import com.zyplayer.doc.core.annotation.AuthMan;
|
||||
import com.zyplayer.doc.core.json.ResponseJson;
|
||||
import com.zyplayer.doc.data.config.security.DocUserUtil;
|
||||
import com.zyplayer.doc.data.repository.support.consts.DocAuthConst;
|
||||
import com.zyplayer.doc.db.controller.param.ProcedureListParam;
|
||||
import com.zyplayer.doc.db.framework.db.dto.ProcedureDto;
|
||||
import com.zyplayer.doc.db.framework.db.mapper.base.ExecuteResult;
|
||||
import com.zyplayer.doc.db.framework.json.DocDbResponseJson;
|
||||
import com.zyplayer.doc.db.service.DbBaseFactory;
|
||||
import com.zyplayer.doc.db.service.DbBaseService;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 存储过程管理控制器
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2021年4月24日
|
||||
*/
|
||||
@AuthMan
|
||||
@RestController
|
||||
@RequestMapping("/zyplayer-doc-db/procedure")
|
||||
public class DbProcedureController {
|
||||
private static Logger logger = LoggerFactory.getLogger(DbProcedureController.class);
|
||||
|
||||
@Resource
|
||||
DbBaseFactory dbBaseFactory;
|
||||
|
||||
/**
|
||||
* 存储过程列表
|
||||
*
|
||||
* @param procedureParam 参数
|
||||
* @return 列表
|
||||
*/
|
||||
@PostMapping(value = "/list")
|
||||
public ResponseJson list(ProcedureListParam procedureParam) {
|
||||
boolean manageAuth = DocUserUtil.haveAuth(DocAuthConst.DB_DATASOURCE_MANAGE);
|
||||
if (!manageAuth) {
|
||||
return DocDbResponseJson.warn("没有该数据源的管理权限");
|
||||
}
|
||||
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(procedureParam.getSourceId());
|
||||
procedureParam.setOffset((procedureParam.getPageNum() - 1) * procedureParam.getPageSize());
|
||||
List<ProcedureDto> procedureDtoList = dbBaseService.getProcedureList(procedureParam);
|
||||
DocDbResponseJson responseJson = DocDbResponseJson.ok(procedureDtoList);
|
||||
if (procedureParam.getPageNum() == 1) {
|
||||
responseJson.setTotal(dbBaseService.getProcedureCount(procedureParam));
|
||||
}
|
||||
return responseJson;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取函数详情
|
||||
*
|
||||
* @param sourceId 数据源ID
|
||||
* @param dbName 数据库名
|
||||
* @param typeName 类型名
|
||||
* @param procName 函数名
|
||||
* @return 详情
|
||||
*/
|
||||
@PostMapping(value = "/detail")
|
||||
public ResponseJson detail(Long sourceId, String dbName, String typeName, String procName) {
|
||||
boolean manageAuth = DocUserUtil.haveAuth(DocAuthConst.DB_DATASOURCE_MANAGE);
|
||||
if (!manageAuth) {
|
||||
return DocDbResponseJson.warn("没有该数据源的管理权限");
|
||||
}
|
||||
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(sourceId);
|
||||
ProcedureDto procedureDto = dbBaseService.getProcedureDetail(sourceId, dbName, typeName, procName);
|
||||
return DocDbResponseJson.ok(procedureDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除函数
|
||||
*
|
||||
* @param sourceId 数据源ID
|
||||
* @param dbName 数据库名
|
||||
* @param typeName 类型名
|
||||
* @param procName 函数名
|
||||
* @return 结果
|
||||
*/
|
||||
@PostMapping(value = "/delete")
|
||||
public ResponseJson delete(Long sourceId, String dbName, String typeName, String procName) {
|
||||
boolean manageAuth = DocUserUtil.haveAuth(DocAuthConst.DB_DATASOURCE_MANAGE);
|
||||
if (!manageAuth) {
|
||||
return DocDbResponseJson.warn("没有该数据源的管理权限");
|
||||
}
|
||||
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(sourceId);
|
||||
dbBaseService.deleteProcedure(sourceId, dbName, typeName, procName);
|
||||
return DocDbResponseJson.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存函数
|
||||
*
|
||||
* @param sourceId 数据源ID
|
||||
* @param dbName 数据库名
|
||||
* @param typeName 类型名
|
||||
* @param procName 函数名
|
||||
* @param procSql 存储过程创建SQL
|
||||
* @return 结果
|
||||
*/
|
||||
@PostMapping(value = "/save")
|
||||
public ResponseJson save(Long sourceId, String dbName, String typeName, String procName, String procSql) {
|
||||
boolean manageAuth = DocUserUtil.haveAuth(DocAuthConst.DB_DATASOURCE_MANAGE);
|
||||
if (!manageAuth) {
|
||||
return DocDbResponseJson.warn("没有该数据源的管理权限");
|
||||
}
|
||||
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(sourceId);
|
||||
ExecuteResult executeResult = dbBaseService.saveProcedure(sourceId, dbName, typeName, procName, procSql);
|
||||
return DocDbResponseJson.ok(executeResult);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.zyplayer.doc.db.controller.param;
|
||||
|
||||
public class ProcedureListParam {
|
||||
private Long sourceId;
|
||||
private String dbName;
|
||||
private Integer pageNum;
|
||||
private Integer pageSize;
|
||||
private Integer offset;
|
||||
private String name;
|
||||
private String type;
|
||||
|
||||
public Long getSourceId() {
|
||||
return sourceId;
|
||||
}
|
||||
|
||||
public void setSourceId(Long sourceId) {
|
||||
this.sourceId = sourceId;
|
||||
}
|
||||
|
||||
public String getDbName() {
|
||||
return dbName;
|
||||
}
|
||||
|
||||
public void setDbName(String dbName) {
|
||||
this.dbName = dbName;
|
||||
}
|
||||
|
||||
public Integer getPageNum() {
|
||||
return pageNum;
|
||||
}
|
||||
|
||||
public void setPageNum(Integer pageNum) {
|
||||
this.pageNum = pageNum;
|
||||
}
|
||||
|
||||
public Integer getPageSize() {
|
||||
return pageSize;
|
||||
}
|
||||
|
||||
public void setPageSize(Integer pageSize) {
|
||||
this.pageSize = pageSize;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Integer getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
public void setOffset(Integer offset) {
|
||||
this.offset = offset;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package com.zyplayer.doc.db.framework.db.dto;
|
||||
|
||||
/**
|
||||
* 存储过程信息
|
||||
*/
|
||||
public class ProcedureDto {
|
||||
private String db;
|
||||
private String name;
|
||||
private String type;
|
||||
private String definer;
|
||||
private String body;
|
||||
private String paramList;
|
||||
private String returns;
|
||||
private String created;
|
||||
|
||||
public String getDb() {
|
||||
return db;
|
||||
}
|
||||
|
||||
public void setDb(String db) {
|
||||
this.db = db;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getDefiner() {
|
||||
return definer;
|
||||
}
|
||||
|
||||
public void setDefiner(String definer) {
|
||||
this.definer = definer;
|
||||
}
|
||||
|
||||
public String getCreated() {
|
||||
return created;
|
||||
}
|
||||
|
||||
public void setCreated(String created) {
|
||||
this.created = created;
|
||||
}
|
||||
|
||||
public String getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
public void setBody(String body) {
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
public String getParamList() {
|
||||
return paramList;
|
||||
}
|
||||
|
||||
public void setParamList(String paramList) {
|
||||
this.paramList = paramList;
|
||||
}
|
||||
|
||||
public String getReturns() {
|
||||
return returns;
|
||||
}
|
||||
|
||||
public void setReturns(String returns) {
|
||||
this.returns = returns;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.zyplayer.doc.db.framework.db.mapper.base;
|
||||
|
||||
import com.zyplayer.doc.db.controller.param.ProcedureListParam;
|
||||
import com.zyplayer.doc.db.controller.vo.TableStatusVo;
|
||||
import com.zyplayer.doc.db.framework.db.dto.*;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
@@ -119,4 +120,44 @@ public interface BaseMapper {
|
||||
* @since 2019年9月1日
|
||||
*/
|
||||
TableStatusVo getTableStatus(@Param("dbName") String dbName, @Param("tableName") String tableName);
|
||||
|
||||
/**
|
||||
* 获取存储过程总条数
|
||||
*
|
||||
* @param procedureParam 参数
|
||||
* @author 暮光:城中城
|
||||
* @since 2020年4月24日
|
||||
*/
|
||||
Long getProcedureCount(@Param("param") ProcedureListParam procedureParam);
|
||||
|
||||
/**
|
||||
* 获取存储过程列表
|
||||
*
|
||||
* @param procedureParam 参数
|
||||
* @author 暮光:城中城
|
||||
* @since 2020年4月24日
|
||||
*/
|
||||
List<ProcedureDto> getProcedureList(@Param("param") ProcedureListParam procedureParam);
|
||||
|
||||
/**
|
||||
* 获取存储过程详情
|
||||
*
|
||||
* @param dbName 数据库名
|
||||
* @param typeName 类型名称 PROCEDURE、FUNCTION
|
||||
* @param procName 过程名称
|
||||
* @author 暮光:城中城
|
||||
* @since 2020年4月24日
|
||||
*/
|
||||
ProcedureDto getProcedureDetail(@Param("dbName") String dbName, @Param("typeName") String typeName, @Param("procName") String procName);
|
||||
|
||||
/**
|
||||
* 删除存储过程
|
||||
*
|
||||
* @param dbName 数据库名
|
||||
* @param typeName 类型名称 PROCEDURE、FUNCTION
|
||||
* @param procName 过程名称
|
||||
* @author 暮光:城中城
|
||||
* @since 2020年4月24日
|
||||
*/
|
||||
void deleteProcedure(@Param("dbName") String dbName, @Param("typeName") String typeName, @Param("procName") String procName);
|
||||
}
|
||||
|
||||
@@ -99,4 +99,29 @@
|
||||
comment #{newDesc}
|
||||
</insert>
|
||||
|
||||
<select id="getProcedureCount" resultType="java.lang.Long">
|
||||
select count(1) from mysql.proc
|
||||
<include refid="ProcedureListCondition"/>
|
||||
</select>
|
||||
|
||||
<select id="getProcedureList" resultType="com.zyplayer.doc.db.framework.db.dto.ProcedureDto">
|
||||
select `db`, `name`, `type`, `definer`, `created` from mysql.proc
|
||||
<include refid="ProcedureListCondition"/>
|
||||
limit #{param.pageSize} offset #{param.offset}
|
||||
</select>
|
||||
|
||||
<select id="getProcedureDetail" resultType="com.zyplayer.doc.db.framework.db.dto.ProcedureDto">
|
||||
select `db`, `name`, `type`, `definer`, `created`, `body`, `param_list` as paramList, `returns` from mysql.proc where db=#{dbName} and `type`=#{typeName} and name=#{procName}
|
||||
</select>
|
||||
|
||||
<delete id="deleteProcedure">
|
||||
DROP ${typeName} IF EXISTS `${dbName}`.`${procName}`
|
||||
</delete>
|
||||
|
||||
<sql id="ProcedureListCondition">
|
||||
where db=#{param.dbName}
|
||||
<if test="param.name != null and param.name != ''">and `name` like #{param.name}</if>
|
||||
<if test="param.type != null and param.type != ''">and `type` = #{param.type}</if>
|
||||
</sql>
|
||||
|
||||
</mapper>
|
||||
|
||||
@@ -3,6 +3,8 @@ package com.zyplayer.doc.db.framework.json;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.serializer.SerializeConfig;
|
||||
import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.zyplayer.doc.core.json.ResponseJson;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
@@ -27,6 +29,8 @@ public class DocDbResponseJson implements ResponseJson {
|
||||
private String errMsg;
|
||||
@ApiModelProperty(value = "返回数据")
|
||||
private Object data;
|
||||
@ApiModelProperty(value = "总数")
|
||||
private Long total;
|
||||
|
||||
public DocDbResponseJson() {
|
||||
this.errCode = 200;
|
||||
@@ -76,7 +80,19 @@ public class DocDbResponseJson implements ResponseJson {
|
||||
}
|
||||
|
||||
public void setData(Object data) {
|
||||
this.data = data;
|
||||
if (null != data) {
|
||||
if (data instanceof PageInfo) {
|
||||
PageInfo<?> pageInfo = (PageInfo<?>) data;
|
||||
this.data = pageInfo.getList();
|
||||
this.total = pageInfo.getTotal();
|
||||
} else if (data instanceof IPage) {
|
||||
IPage<?> iPage = (IPage<?>) data;
|
||||
this.data = iPage.getRecords();
|
||||
this.total = iPage.getTotal();
|
||||
} else {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -146,4 +162,12 @@ public class DocDbResponseJson implements ResponseJson {
|
||||
public String toString() {
|
||||
return "DefaultResponseJson [errCode=" + errCode + ", errMsg=" + errMsg + ", data=" + data + "]";
|
||||
}
|
||||
|
||||
public Long getTotal() {
|
||||
return total;
|
||||
}
|
||||
|
||||
public void setTotal(Long total) {
|
||||
this.total = total;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package com.zyplayer.doc.db.service;
|
||||
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import com.zyplayer.doc.core.exception.ConfirmException;
|
||||
import com.zyplayer.doc.data.config.security.DocUserUtil;
|
||||
import com.zyplayer.doc.data.repository.support.consts.DocAuthConst;
|
||||
import com.zyplayer.doc.db.controller.param.ProcedureListParam;
|
||||
import com.zyplayer.doc.db.controller.vo.TableColumnVo;
|
||||
import com.zyplayer.doc.db.controller.vo.TableDdlVo;
|
||||
import com.zyplayer.doc.db.controller.vo.TableStatusVo;
|
||||
@@ -10,8 +12,11 @@ import com.zyplayer.doc.db.framework.consts.DbAuthType;
|
||||
import com.zyplayer.doc.db.framework.db.bean.DatabaseFactoryBean;
|
||||
import com.zyplayer.doc.db.framework.db.bean.DatabaseRegistrationBean;
|
||||
import com.zyplayer.doc.db.framework.db.dto.*;
|
||||
import com.zyplayer.doc.db.framework.db.mapper.base.BaseMapper;
|
||||
import com.zyplayer.doc.db.framework.db.mapper.base.*;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang.exception.ExceptionUtils;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.*;
|
||||
@@ -25,6 +30,8 @@ import java.util.stream.Collectors;
|
||||
*/
|
||||
public abstract class DbBaseService {
|
||||
|
||||
@Resource
|
||||
SqlExecutor sqlExecutor;
|
||||
@Resource
|
||||
DatabaseRegistrationBean databaseRegistrationBean;
|
||||
|
||||
@@ -56,6 +63,7 @@ public abstract class DbBaseService {
|
||||
|
||||
/**
|
||||
* 获取当前是什么数据源服务
|
||||
*
|
||||
* @return 服务类型
|
||||
*/
|
||||
abstract DatabaseFactoryBean.DatabaseProduct getDatabaseProduct();
|
||||
@@ -215,7 +223,7 @@ public abstract class DbBaseService {
|
||||
* 获取编辑器所需的所有信息,用于自动补全
|
||||
* 此接口会返回所有库表结构,介意的话请自己手动屏蔽调此接口
|
||||
*
|
||||
* @param sourceId sourceId
|
||||
* @param sourceId sourceId
|
||||
* @author 暮光:城中城
|
||||
* @since 2019年9月1日
|
||||
*/
|
||||
@@ -262,4 +270,69 @@ public abstract class DbBaseService {
|
||||
dbResultMap.put("column", tableColumnsMap);
|
||||
return dbResultMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取存储过程列表
|
||||
*
|
||||
* @param procedureParam 参数
|
||||
* @author 暮光:城中城
|
||||
* @since 2020年4月24日
|
||||
*/
|
||||
public Long getProcedureCount(ProcedureListParam procedureParam) {
|
||||
BaseMapper baseMapper = this.getViewAuthBaseMapper(procedureParam.getSourceId());
|
||||
return baseMapper.getProcedureCount(procedureParam);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取存储过程列表
|
||||
*
|
||||
* @param procedureParam 参数
|
||||
* @author 暮光:城中城
|
||||
* @since 2020年4月24日
|
||||
*/
|
||||
public List<ProcedureDto> getProcedureList(ProcedureListParam procedureParam) {
|
||||
BaseMapper baseMapper = this.getViewAuthBaseMapper(procedureParam.getSourceId());
|
||||
// MySQL是加%,其他数据库不一样的话需要改到各自的实现里面去
|
||||
if (StringUtils.isNotBlank(procedureParam.getName())) {
|
||||
procedureParam.setName("%" + procedureParam.getName() + "%");
|
||||
}
|
||||
return baseMapper.getProcedureList(procedureParam);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取存储过程详情
|
||||
*
|
||||
* @param dbName 数据库名
|
||||
* @author 暮光:城中城
|
||||
* @since 2020年4月24日
|
||||
*/
|
||||
public ProcedureDto getProcedureDetail(Long sourceId, String dbName, String typeName, String procName) {
|
||||
BaseMapper baseMapper = this.getViewAuthBaseMapper(sourceId);
|
||||
return baseMapper.getProcedureDetail(dbName, typeName, procName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除存储过程
|
||||
*
|
||||
* @param dbName 数据库名
|
||||
* @author 暮光:城中城
|
||||
* @since 2020年4月24日
|
||||
*/
|
||||
public void deleteProcedure(Long sourceId, String dbName, String typeName, String procName) {
|
||||
BaseMapper baseMapper = this.getViewAuthBaseMapper(sourceId);
|
||||
baseMapper.deleteProcedure(dbName, typeName, procName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存存储过程
|
||||
*
|
||||
* @param procSql 存储过程SQL
|
||||
* @author 暮光:城中城
|
||||
* @since 2020年4月24日
|
||||
* @return
|
||||
*/
|
||||
public ExecuteResult saveProcedure(Long sourceId, String dbName, String typeName, String procName, String procSql) {
|
||||
// 需要各数据服务自己实现,各数据库产品的实现都不一样
|
||||
throw new ConfirmException("暂未支持的数据库类型");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,22 @@
|
||||
package com.zyplayer.doc.db.service;
|
||||
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import com.sun.org.apache.bcel.internal.generic.RETURN;
|
||||
import com.zyplayer.doc.core.exception.ConfirmException;
|
||||
import com.zyplayer.doc.db.controller.vo.TableDdlVo;
|
||||
import com.zyplayer.doc.db.framework.db.bean.DatabaseFactoryBean;
|
||||
import com.zyplayer.doc.db.framework.db.dto.ColumnInfoDto;
|
||||
import com.zyplayer.doc.db.framework.db.dto.ProcedureDto;
|
||||
import com.zyplayer.doc.db.framework.db.mapper.base.BaseMapper;
|
||||
import com.zyplayer.doc.db.framework.db.mapper.base.ExecuteParam;
|
||||
import com.zyplayer.doc.db.framework.db.mapper.base.ExecuteResult;
|
||||
import com.zyplayer.doc.db.framework.db.mapper.base.ExecuteType;
|
||||
import com.zyplayer.doc.db.framework.db.mapper.mysql.MysqlMapper;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
@Service
|
||||
@@ -49,4 +57,73 @@ public class MysqlServiceImpl extends DbBaseService {
|
||||
columnInfo.setExtra(StringUtils.isBlank(extra) ? "" : extra);
|
||||
baseMapper.updateTableColumnDesc(dbName, tableName, columnName, newDesc, columnInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProcedureDto getProcedureDetail(Long sourceId, String dbName, String typeName, String procName) {
|
||||
BaseMapper baseMapper = this.getViewAuthBaseMapper(sourceId);
|
||||
ProcedureDto procedureDetail = baseMapper.getProcedureDetail(dbName, typeName, procName);
|
||||
if (procedureDetail == null) {
|
||||
// 新建的时候
|
||||
ProcedureDto procedureDetailNew = new ProcedureDto();
|
||||
if (Objects.equals(typeName, "FUNCTION")) {
|
||||
procedureDetailNew.setBody("CREATE DEFINER = CURRENT_USER " + typeName + " `" + procName + "`() RETURNS integer\n" +
|
||||
"BEGIN\n" +
|
||||
"\t#Routine body goes here...\n" +
|
||||
"\tRETURN 0;\n" +
|
||||
"END;");
|
||||
} else {
|
||||
procedureDetailNew.setBody("CREATE DEFINER = CURRENT_USER " + typeName + " `" + procName + "`()\n" +
|
||||
"BEGIN\n" +
|
||||
"\t#Routine body goes here...\n" +
|
||||
"END;");
|
||||
}
|
||||
procedureDetailNew.setDb(dbName);
|
||||
procedureDetailNew.setDefiner("CURRENT_USER");
|
||||
procedureDetailNew.setType(typeName);
|
||||
return procedureDetailNew;
|
||||
}
|
||||
// 组装好SQL
|
||||
String type = procedureDetail.getType();
|
||||
String name = procedureDetail.getName();
|
||||
String paramList = StringUtils.defaultIfBlank(procedureDetail.getParamList(), "");
|
||||
String[] definerArr = procedureDetail.getDefiner().split("@");
|
||||
String createStr = String.format("CREATE DEFINER=`%s`@`%s` %s `%s`(%s)", definerArr[0], definerArr[1], type, name, paramList);
|
||||
if (Objects.equals(procedureDetail.getType(), "FUNCTION")) {
|
||||
createStr += " RETURNS " + procedureDetail.getReturns();
|
||||
}
|
||||
procedureDetail.setBody(createStr + "\r\n" + procedureDetail.getBody());
|
||||
return procedureDetail;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecuteResult saveProcedure(Long sourceId, String dbName, String typeName, String procName, String procSql) {
|
||||
String firstLine = procSql.split("\n")[0];
|
||||
// 看函数名是否被修改了,修改会导致函数名的不确定,有认知上的成本,明确的先删再建吧
|
||||
if (!firstLine.contains(" `" + procName + "`(") && !firstLine.contains(" " + procName + "(")) {
|
||||
return ExecuteResult.error("在编辑页面不允许修改函数名,如需新建或修改,请到列表页删除后再新建函数", procSql);
|
||||
}
|
||||
ProcedureDto procedureDetail = this.getProcedureDetail(sourceId, dbName, typeName, procName);
|
||||
// 按MySQL的来是先删除再创建,如果其他数据库不是这个逻辑,需要重写本方法实现自己的逻辑
|
||||
BaseMapper baseMapper = this.getViewAuthBaseMapper(sourceId);
|
||||
baseMapper.deleteProcedure(dbName, typeName, procName);
|
||||
// 执行创建SQL
|
||||
ExecuteParam executeParam = new ExecuteParam();
|
||||
executeParam.setDatasourceId(sourceId);
|
||||
executeParam.setExecuteId(RandomUtil.randomUUID());
|
||||
executeParam.setExecuteType(ExecuteType.ALL);
|
||||
executeParam.setSql(procSql);
|
||||
executeParam.setMaxRows(1000);
|
||||
try {
|
||||
return sqlExecutor.execute(executeParam);
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
// 尝试恢复函数
|
||||
executeParam.setSql(procedureDetail.getBody());
|
||||
sqlExecutor.execute(executeParam);
|
||||
} catch (Exception e1) {
|
||||
return ExecuteResult.error("执行和恢复函数均失败,请先备份您的SQL,以防丢失", procSql);
|
||||
}
|
||||
return ExecuteResult.error(e.getMessage(), procSql);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user