增加数据库函数和存储过程的增删改查支持,优化数据源管理
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
#app,.el-container,.el-menu{height:100%}.el-header{background-color:#1d4e89!important}.database-list-tree{background-color:#fafafa}.database-list-tree .el-tree-node>.el-tree-node__children{overflow:unset}.el-tree-node__content .el-icon-more{margin-left:5px;color:#606266;font-size:12px;display:none;padding:2px 5px}.el-tree-node__content:hover .el-icon-more{display:inline-block}.login-container{border-radius:5px;-moz-border-radius:5px;background-clip:padding-box;margin:0 auto;width:350px;padding:35px 35px 15px 35px;background:#fff;border:1px solid #eaeaea;-webkit-box-shadow:0 0 25px #cac6c6;box-shadow:0 0 25px #cac6c6}.title{margin:0 auto 40px auto;text-align:center;color:#505458}.remember{margin:0 0 35px 0}.my-info-vue .box-card{margin:10px}.table-info-vue .el-dialog__body{padding:0 20px 10px}.table-info-vue .el-form-item{margin-bottom:5px}.table-info-vue .edit-table-desc{cursor:pointer;color:#409eff}.table-info-vue .description{cursor:pointer;min-height:23px}.table-info-vue .el-table td,.table-info-vue .el-table th{padding:5px 0}.table-info-vue .status-info-row{padding:8px 0}.table-info-vue .status-info-row .label{width:80px;display:inline-block;text-align:right;color:#606266}.table-database-vue .el-table td,.table-database-vue .el-table th{padding:5px 0}body,html{margin:0;padding:0;height:100%}.header-right-user-name{color:#fff;padding-right:5px}.el-menu-vertical{border-right:0}.el-menu-vertical,.el-menu-vertical .el-menu{background:#fafafa}.el-header{background-color:#409eff;color:#333;line-height:40px;text-align:right;height:40px!important}.data-transfer-vue .el-button+.el-button{margin-left:4px}.data-executor-vue .ace-monokai .ace_print-margin{display:none}.data-executor-vue .el-card__body{padding:10px}.data-executor-vue .el-table td,.el-table th{padding:6px 0}.data-executor-vue .execute-result-table .el-input__inner{height:25px;line-height:25px;padding:0 5px}.data-executor-vue .execute-result-table .el-textarea__inner{height:27px;min-height:27px;line-height:25px;padding:0 5px;resize:none}.data-executor-vue .execute-use-time{font-size:12px;margin-right:10px}.data-executor-vue-out .el-tabs__nav-scroll{padding-left:20px}.data-executor-vue-out .el-button+.el-button{margin-left:0}.data-executor-vue-out .el-table__body-wrapper{height:calc(100vh - 180px);overflow-y:auto}
|
||||
1
zyplayer-doc-db/src/main/resources/css/app.b6b9fe42.css
Normal file
1
zyplayer-doc-db/src/main/resources/css/app.b6b9fe42.css
Normal file
@@ -0,0 +1 @@
|
||||
#app,.el-container,.el-menu{height:100%}.el-header{background-color:#1d4e89!important}.database-list-tree{background-color:#fafafa}.database-list-tree .el-tree-node>.el-tree-node__children{overflow:unset}.el-tree-node__content .el-icon-more{margin-left:5px;color:#606266;font-size:12px;display:none;padding:2px 5px}.el-tree-node__content:hover .el-icon-more{display:inline-block}.login-container{border-radius:5px;-moz-border-radius:5px;background-clip:padding-box;margin:0 auto;width:350px;padding:35px 35px 15px 35px;background:#fff;border:1px solid #eaeaea;-webkit-box-shadow:0 0 25px #cac6c6;box-shadow:0 0 25px #cac6c6}.title{margin:0 auto 40px auto;text-align:center;color:#505458}.remember{margin:0 0 35px 0}.my-info-vue .box-card{margin:10px}.table-info-vue .el-dialog__body{padding:0 20px 10px}.table-info-vue .el-form-item{margin-bottom:5px}.table-info-vue .edit-table-desc{cursor:pointer;color:#409eff}.table-info-vue .description{cursor:pointer;min-height:23px}.table-info-vue .el-table td,.table-info-vue .el-table th{padding:5px 0}.table-info-vue .status-info-row{padding:8px 0}.table-info-vue .status-info-row .label{width:80px;display:inline-block;text-align:right;color:#606266}.table-database-vue .el-table td,.table-database-vue .el-table th{padding:5px 0}.table-database-vue .label{width:140px;text-align:right}.table-database-vue .el-table th,.table-procedure-edit-vue .el-table td,.table-procedure-vue .el-table td{padding:5px 0}body,html{margin:0;padding:0;height:100%}.header-right-user-name{color:#fff;padding-right:5px}.el-menu-vertical{border-right:0}.el-menu-vertical,.el-menu-vertical .el-menu{background:#fafafa}.el-header{background-color:#409eff;color:#333;line-height:40px;text-align:right;height:40px!important}.data-transfer-vue .el-button+.el-button{margin-left:4px}.data-executor-vue .ace-monokai .ace_print-margin{display:none}.data-executor-vue .el-card__body{padding:10px}.data-executor-vue .el-table td,.el-table th{padding:6px 0}.data-executor-vue .execute-result-table .el-input__inner{height:25px;line-height:25px;padding:0 5px}.data-executor-vue .execute-result-table .el-textarea__inner{height:27px;min-height:27px;line-height:25px;padding:0 5px;resize:none}.data-executor-vue .execute-use-time{font-size:12px;margin-right:10px}.data-executor-vue-out .el-tabs__nav-scroll{padding-left:20px}.data-executor-vue-out .el-button+.el-button{margin-left:0}.data-executor-vue-out .el-table__body-wrapper{height:calc(100vh - 180px);overflow-y:auto}
|
||||
@@ -1 +1 @@
|
||||
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><link rel=icon href=favicon-db.png><title>数据库文档管理</title><link href=css/app.1c916a62.css rel=preload as=style><link href=css/chunk-vendors.8924efc6.css rel=preload as=style><link href=js/app.26e84e5d.js rel=preload as=script><link href=js/chunk-vendors.306ce2df.js rel=preload as=script><link href=css/chunk-vendors.8924efc6.css rel=stylesheet><link href=css/app.1c916a62.css rel=stylesheet></head><body><noscript><strong>We're sorry but zyplayer-db-ui doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app></div><script src=js/chunk-vendors.306ce2df.js></script><script src=js/app.26e84e5d.js></script></body></html>
|
||||
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><link rel=icon href=favicon-db.png><title>数据库文档管理</title><link href=css/app.b6b9fe42.css rel=preload as=style><link href=css/chunk-vendors.8924efc6.css rel=preload as=style><link href=js/app.069b56af.js rel=preload as=script><link href=js/chunk-vendors.d40f789d.js rel=preload as=script><link href=css/chunk-vendors.8924efc6.css rel=stylesheet><link href=css/app.b6b9fe42.css rel=stylesheet></head><body><noscript><strong>We're sorry but zyplayer-db-ui doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app></div><script src=js/chunk-vendors.d40f789d.js></script><script src=js/app.069b56af.js></script></body></html>
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user