@@ -3,80 +3,89 @@
|
||||
<mapper namespace="com.zyplayer.doc.db.framework.db.mapper.base.BaseMapper">
|
||||
|
||||
<resultMap id="TableColumnDescDtoMap" type="com.zyplayer.doc.db.framework.db.dto.TableColumnDescDto" >
|
||||
<result column="TABLE_NAME" property="tableName" jdbcType="VARCHAR" />
|
||||
<result column="COLUMN_NAME" property="name" jdbcType="VARCHAR" />
|
||||
<result column="DATA_TYPE" property="type" jdbcType="VARCHAR" />
|
||||
<result column="NULLABLE" property="nullable" jdbcType="VARCHAR" />
|
||||
<result column="COMMENTS" property="description" jdbcType="VARCHAR" />
|
||||
</resultMap>
|
||||
<result column="TABLE_NAME" property="tableName" jdbcType="VARCHAR" />
|
||||
<result column="COLUMN_NAME" property="name" jdbcType="VARCHAR" />
|
||||
<result column="DATA_TYPE" property="type" jdbcType="VARCHAR" />
|
||||
<result column="NULLABLE" property="nullable" jdbcType="VARCHAR" />
|
||||
<result column="COMMENTS" property="description" jdbcType="VARCHAR" />
|
||||
</resultMap>
|
||||
|
||||
<resultMap id="QueryTableColumnDescDtoMap" type="com.zyplayer.doc.db.framework.db.dto.QueryTableColumnDescDto" >
|
||||
<result column="TABLE_NAME" property="tableName" jdbcType="VARCHAR" />
|
||||
<result column="COLUMN_NAME" property="columnName" jdbcType="VARCHAR" />
|
||||
<result column="COMMENTS" property="description" jdbcType="VARCHAR" />
|
||||
</resultMap>
|
||||
<result column="TABLE_NAME" property="tableName" jdbcType="VARCHAR" />
|
||||
<result column="COLUMN_NAME" property="columnName" jdbcType="VARCHAR" />
|
||||
<result column="COMMENTS" property="description" jdbcType="VARCHAR" />
|
||||
</resultMap>
|
||||
|
||||
<!-- 获取用户列表 -->
|
||||
<!-- 获取用户列表 -->
|
||||
<select id="getDatabaseList" resultType="com.zyplayer.doc.db.framework.db.dto.DatabaseInfoDto">
|
||||
select USERNAME dbName from all_users
|
||||
select USERNAME dbName from all_users
|
||||
</select>
|
||||
|
||||
<select id="getTableStatus" resultType="com.zyplayer.doc.db.controller.vo.TableStatusVo">
|
||||
select 1
|
||||
</select>
|
||||
<select id="getTableStatus" resultType="com.zyplayer.doc.db.controller.vo.TableStatusVo">
|
||||
select dt.TABLE_NAME as name,
|
||||
dt.NUM_ROWS as "rows",
|
||||
dt.AVG_ROW_LEN as avgRowLength,
|
||||
do.CREATED as createTime,
|
||||
do.LAST_DDL_TIME as updateTime,
|
||||
dtc.COMMENTS as "comment"
|
||||
from dba_tables dt
|
||||
left join dba_objects do on do.owner = dt.owner and do.object_name = dt.table_name
|
||||
left join dba_tab_comments dtc on dtc.owner = dt.owner and dtc.table_name = dt.table_name
|
||||
where dt.owner = #{dbName} and dt.table_name = #{tableName}
|
||||
</select>
|
||||
|
||||
<!-- 获取表列表 -->
|
||||
<select id="getTableList" resultType="com.zyplayer.doc.db.framework.db.dto.TableInfoDto">
|
||||
select t.OWNER as dbName,t.TABLE_NAME as tableName,c.COMMENTS as tableComment from all_tables t left join user_tab_comments c on t.TABLE_NAME = c.TABLE_NAME
|
||||
<where>
|
||||
<if test="dbName != null">t.owner = #{dbName}</if>
|
||||
</where>
|
||||
</select>
|
||||
<!-- 获取表列表 -->
|
||||
<select id="getTableList" resultType="com.zyplayer.doc.db.framework.db.dto.TableInfoDto">
|
||||
select t.OWNER as dbName,t.TABLE_NAME as tableName,c.COMMENTS as tableComment from all_tables t left join user_tab_comments c on t.TABLE_NAME = c.TABLE_NAME
|
||||
<where>
|
||||
<if test="dbName != null">t.owner = #{dbName}</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<!-- 获取表字段集合 -->
|
||||
<select id="getTableColumnList" resultMap="TableColumnDescDtoMap">
|
||||
select t.TABLE_NAME,t.COLUMN_NAME,t.DATA_TYPE,case t.NULLABLE when 'Y' then '1' when 'N' then '0' end NULLABLE, c.COMMENTS
|
||||
from user_tab_columns t left join user_col_comments c on t.COLUMN_NAME = c.COLUMN_NAME and t.TABLE_NAME = c.TABLE_NAME
|
||||
<where>
|
||||
t.table_name in (select table_name from all_tables where owner = #{dbName} )
|
||||
<if test="tableName != null"> and t.TABLE_NAME = #{tableName}</if>
|
||||
</where>
|
||||
</select>
|
||||
<!-- 获取表字段集合 -->
|
||||
<select id="getTableColumnList" resultMap="TableColumnDescDtoMap">
|
||||
select t.TABLE_NAME,t.COLUMN_NAME,t.DATA_TYPE,case t.NULLABLE when 'Y' then '1' when 'N' then '0' end NULLABLE, c.COMMENTS
|
||||
from user_tab_columns t left join user_col_comments c on t.COLUMN_NAME = c.COLUMN_NAME and t.TABLE_NAME = c.TABLE_NAME
|
||||
<where>
|
||||
t.table_name in (select table_name from all_tables where owner = #{dbName} )
|
||||
<if test="tableName != null"> and t.TABLE_NAME = #{tableName}</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<!-- 条件查询表字段 -->
|
||||
<select id="getTableAndColumnBySearch" resultMap="QueryTableColumnDescDtoMap">
|
||||
select t.TABLE_NAME,t.COLUMN_NAME,t.DATA_TYPE,case t.NULLABLE when 'Y' then 1 when 'N' then 0 end NULLABLE, c.COMMENTS
|
||||
from user_tab_columns t
|
||||
left join user_col_comments c on t.COLUMN_NAME = c.COLUMN_NAME and t.TABLE_NAME = c.TABLE_NAME
|
||||
where t.TABLE_NAME = #{tableName} AND (t.COLUMN_NAME like #{searchText} or c.COMMENTS like #{searchText})
|
||||
</select>
|
||||
<!-- 条件查询表字段 -->
|
||||
<select id="getTableAndColumnBySearch" resultMap="QueryTableColumnDescDtoMap">
|
||||
select t.TABLE_NAME,t.COLUMN_NAME,t.DATA_TYPE,case t.NULLABLE when 'Y' then 1 when 'N' then 0 end NULLABLE, c.COMMENTS
|
||||
from user_tab_columns t
|
||||
left join user_col_comments c on t.COLUMN_NAME = c.COLUMN_NAME and t.TABLE_NAME = c.TABLE_NAME
|
||||
where t.TABLE_NAME = #{tableName} AND (t.COLUMN_NAME like #{searchText} or c.COMMENTS like #{searchText})
|
||||
</select>
|
||||
|
||||
<!-- 条件查询表 -->
|
||||
<select id="getTableDescList" resultType="com.zyplayer.doc.db.framework.db.dto.TableDescDto">
|
||||
select t.OWNER,t.TABLE_NAME as tableName,c.COMMENTS as description
|
||||
from all_tables t
|
||||
left join user_tab_comments c on t.TABLE_NAME = c.TABLE_NAME
|
||||
<where>
|
||||
<if test="dbName != null">and t.owner = #{dbName}</if>
|
||||
<if test="tableName != null">and t.TABLE_NAME = #{tableName}</if>
|
||||
</where>
|
||||
</select>
|
||||
<!-- 条件查询表 -->
|
||||
<select id="getTableDescList" resultType="com.zyplayer.doc.db.framework.db.dto.TableDescDto">
|
||||
select t.OWNER,t.TABLE_NAME as tableName,c.COMMENTS as description
|
||||
from all_tables t
|
||||
left join user_tab_comments c on t.TABLE_NAME = c.TABLE_NAME
|
||||
<where>
|
||||
<if test="dbName != null">and t.owner = #{dbName}</if>
|
||||
<if test="tableName != null">and t.TABLE_NAME = #{tableName}</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<!-- 增加表注释 -->
|
||||
<insert id="updateTableDesc">
|
||||
comment on table ${dbName}.${tableName} is #{new Desc}
|
||||
</insert>
|
||||
<insert id="updateTableDesc">
|
||||
comment on table ${dbName}.${tableName} is #{new Desc}
|
||||
</insert>
|
||||
|
||||
<!-- 增加表字段注释 -->
|
||||
<insert id="updateTableColumnDesc">
|
||||
comment on column ${dbName}.${tableName}.${columnName} is #{new Desc}
|
||||
</insert>
|
||||
<insert id="updateTableColumnDesc">
|
||||
comment on column ${dbName}.${tableName}.${columnName} is #{new Desc}
|
||||
</insert>
|
||||
|
||||
<delete id="deleteTableLineData">
|
||||
delete from ${dbName}.${tableName} where
|
||||
<foreach collection="lineParam.entrySet()" index="key" item="value">
|
||||
${key} = #{value}
|
||||
</foreach>
|
||||
</delete>
|
||||
<delete id="deleteTableLineData">
|
||||
delete from ${dbName}.${tableName} where
|
||||
<foreach collection="lineParam.entrySet()" index="key" item="value">
|
||||
${key} = #{value}
|
||||
</foreach>
|
||||
</delete>
|
||||
|
||||
</mapper>
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.zyplayer.doc.db.service.database;
|
||||
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import com.zyplayer.doc.db.controller.param.DataViewParam;
|
||||
import com.zyplayer.doc.db.controller.vo.TableDdlVo;
|
||||
import com.zyplayer.doc.db.framework.db.dto.ColumnInfoDto;
|
||||
import com.zyplayer.doc.db.framework.db.dto.ProcedureDto;
|
||||
@@ -29,126 +30,180 @@ import java.util.Optional;
|
||||
@Service
|
||||
public class MysqlServiceImpl extends DbBaseService {
|
||||
|
||||
@Override
|
||||
public DatabaseProductEnum getDatabaseProduct() {
|
||||
return DatabaseProductEnum.MYSQL;
|
||||
}
|
||||
@Override
|
||||
public DatabaseProductEnum getDatabaseProduct() {
|
||||
return DatabaseProductEnum.MYSQL;
|
||||
}
|
||||
|
||||
/**
|
||||
* mysql数据库名中含有 - 等特殊字符,需要用反引号包裹
|
||||
*
|
||||
* @author diantu
|
||||
* @since 2023年1月16日
|
||||
*/
|
||||
@Override
|
||||
public String getUseDbSql(String dbName) {
|
||||
if (StringUtils.isNotBlank(dbName)) {
|
||||
return "use " + "`" + dbName + "`";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* mysql数据库名中含有 - 等特殊字符,需要用反引号包裹
|
||||
*
|
||||
* @author diantu
|
||||
* @since 2023年1月16日
|
||||
*/
|
||||
@Override
|
||||
public String getUseDbSql(String dbName) {
|
||||
if (StringUtils.isNotBlank(dbName)) {
|
||||
return "use " + "`" + dbName + "`";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableDdlVo getTableDdl(Long sourceId, String dbName, String tableName) {
|
||||
BaseMapper baseMapper = this.getViewAuthBaseMapper(sourceId);
|
||||
List<Map<String, String>> tableDdlList = baseMapper.getTableDdl(dbName, tableName);
|
||||
TableDdlVo tableDdlVo = new TableDdlVo();
|
||||
tableDdlVo.setCurrent(DatabaseProductEnum.MYSQL.name().toLowerCase());
|
||||
tableDdlVo.setMysql("// 生成失败");
|
||||
tableDdlVo.setOracle("// TODO 等待大佬来实现转换");
|
||||
// TODO 将建表语句转换为其他数据库的,还不知道怎么做,先这样留着,看有没大佬来实现
|
||||
if (CollectionUtils.isNotEmpty(tableDdlList)) {
|
||||
tableDdlVo.setMysql(tableDdlList.get(0).get("Create Table") + ";");
|
||||
}
|
||||
return tableDdlVo;
|
||||
}
|
||||
/**
|
||||
* 获取查询总条数的SQL(mysql数据库名中含有 - 等特殊字符,需要用反引号包裹)
|
||||
*
|
||||
* @author diantu
|
||||
* @since 2023年1月16日
|
||||
*/
|
||||
@Override
|
||||
public String getQueryCountSql(DataViewParam dataViewParam) {
|
||||
StringBuilder sqlSb = new StringBuilder();
|
||||
sqlSb.append(String.format("select count(1) as counts from %s.%s", "`"+dataViewParam.getDbName()+"`", dataViewParam.getTableName()));
|
||||
if (StringUtils.isNotBlank(dataViewParam.getCondition())) {
|
||||
sqlSb.append(String.format(" where %s", dataViewParam.getCondition()));
|
||||
}
|
||||
return sqlSb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTableColumnDesc(Long sourceId, String dbName, String tableName, String columnName, String newDesc) {
|
||||
BaseMapper baseMapper = this.getViewAuthBaseMapper(sourceId);
|
||||
// mysql要同时修改类型默认值等,所以先查出来
|
||||
MysqlMapper mysqlMapper = databaseRegistrationBean.getBaseMapper(sourceId, MysqlMapper.class);
|
||||
ColumnInfoDto columnInfo = mysqlMapper.getColumnInfo(dbName, tableName, columnName);
|
||||
String isNullable = Optional.ofNullable(columnInfo.getIsNullable()).orElse("");
|
||||
columnInfo.setIsNullable("yes".equalsIgnoreCase(isNullable) ? "null" : "not null");
|
||||
String columnDefault = columnInfo.getColumnDefault();
|
||||
if (StringUtils.isNotBlank(columnDefault)) {
|
||||
columnInfo.setColumnDefault("DEFAULT " + columnDefault);
|
||||
} else {
|
||||
columnInfo.setColumnDefault("");
|
||||
}
|
||||
String extra = columnInfo.getExtra();
|
||||
columnInfo.setExtra(StringUtils.isBlank(extra) ? "" : extra);
|
||||
baseMapper.updateTableColumnDesc(dbName, tableName, columnName, newDesc, columnInfo);
|
||||
}
|
||||
/**
|
||||
* 获取全量数据查询的SQL(mysql数据库名中含有 - 等特殊字符,需要用反引号包裹)
|
||||
*
|
||||
* @author diantu
|
||||
* @since 2023年1月17日
|
||||
*/
|
||||
@Override
|
||||
public String getQueryAllSql(DataViewParam dataViewParam) {
|
||||
String queryColumns = StringUtils.defaultIfBlank(dataViewParam.getRetainColumn(), "*");
|
||||
StringBuilder sqlSb = new StringBuilder();
|
||||
sqlSb.append(String.format("select %s from %s.%s", queryColumns, "`" + dataViewParam.getDbName() + "`", dataViewParam.getTableName()));
|
||||
if (StringUtils.isNotBlank(dataViewParam.getCondition())) {
|
||||
sqlSb.append(String.format(" where %s", dataViewParam.getCondition()));
|
||||
}
|
||||
return sqlSb.toString();
|
||||
}
|
||||
|
||||
@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 + " `" + dbName + "`.`" + procName + "`() RETURNS integer\n" +
|
||||
"BEGIN\n" +
|
||||
"\t#Routine body goes here...\n" +
|
||||
"\tRETURN 0;\n" +
|
||||
"END;");
|
||||
} else {
|
||||
procedureDetailNew.setBody("CREATE DEFINER = CURRENT_USER " + typeName + " `" + dbName + "`.`" + 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 db = procedureDetail.getDb();
|
||||
String paramList = StringUtils.defaultIfBlank(procedureDetail.getParamList(), "");
|
||||
String[] definerArr = procedureDetail.getDefiner().split("@");
|
||||
String createStr = String.format("CREATE DEFINER=`%s`@`%s` %s `%s`.`%s`(%s)", definerArr[0], definerArr[1], type, db, name, paramList);
|
||||
if (Objects.equals(procedureDetail.getType(), "FUNCTION")) {
|
||||
createStr += " RETURNS " + procedureDetail.getReturns();
|
||||
}
|
||||
procedureDetail.setBody(createStr + "\r\n" + procedureDetail.getBody());
|
||||
return procedureDetail;
|
||||
}
|
||||
/**
|
||||
* 获取分页查询的SQL(mysql数据库名中含有 - 等特殊字符,需要用反引号包裹)
|
||||
*
|
||||
* @author diantu
|
||||
* @since 2023年1月17日
|
||||
*/
|
||||
@Override
|
||||
public String getQueryPageSql(DataViewParam dataViewParam) {
|
||||
String queryColumns = StringUtils.defaultIfBlank(dataViewParam.getRetainColumn(), "*");
|
||||
StringBuilder sqlSb = new StringBuilder();
|
||||
sqlSb.append(String.format("select %s from %s.%s", queryColumns, "`" + dataViewParam.getDbName() + "`", dataViewParam.getTableName()));
|
||||
if (StringUtils.isNotBlank(dataViewParam.getCondition())) {
|
||||
sqlSb.append(String.format(" where %s", dataViewParam.getCondition()));
|
||||
}
|
||||
if (StringUtils.isNotBlank(dataViewParam.getOrderColumn()) && StringUtils.isNotBlank(dataViewParam.getOrderType())) {
|
||||
sqlSb.append(String.format(" order by %s %s", dataViewParam.getOrderColumn(), dataViewParam.getOrderType()));
|
||||
}
|
||||
sqlSb.append(String.format(" limit %s offset %s", dataViewParam.getPageSize(), dataViewParam.getOffset()));
|
||||
return sqlSb.toString();
|
||||
}
|
||||
|
||||
@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 + "(") && !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(IdUtil.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,以防丢失\n" + e.getMessage(), procSql);
|
||||
}
|
||||
return ExecuteResult.error(e.getMessage(), procSql);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public TableDdlVo getTableDdl(Long sourceId, String dbName, String tableName) {
|
||||
BaseMapper baseMapper = this.getViewAuthBaseMapper(sourceId);
|
||||
List<Map<String, String>> tableDdlList = baseMapper.getTableDdl(dbName, tableName);
|
||||
TableDdlVo tableDdlVo = new TableDdlVo();
|
||||
tableDdlVo.setCurrent(DatabaseProductEnum.MYSQL.name().toLowerCase());
|
||||
tableDdlVo.setMysql("// 生成失败");
|
||||
tableDdlVo.setOracle("// TODO 等待大佬来实现转换");
|
||||
// TODO 将建表语句转换为其他数据库的,还不知道怎么做,先这样留着,看有没大佬来实现
|
||||
if (CollectionUtils.isNotEmpty(tableDdlList)) {
|
||||
tableDdlVo.setMysql(tableDdlList.get(0).get("Create Table") + ";");
|
||||
}
|
||||
return tableDdlVo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTableColumnDesc(Long sourceId, String dbName, String tableName, String columnName, String newDesc) {
|
||||
BaseMapper baseMapper = this.getViewAuthBaseMapper(sourceId);
|
||||
// mysql要同时修改类型默认值等,所以先查出来
|
||||
MysqlMapper mysqlMapper = databaseRegistrationBean.getBaseMapper(sourceId, MysqlMapper.class);
|
||||
ColumnInfoDto columnInfo = mysqlMapper.getColumnInfo(dbName, tableName, columnName);
|
||||
String isNullable = Optional.ofNullable(columnInfo.getIsNullable()).orElse("");
|
||||
columnInfo.setIsNullable("yes".equalsIgnoreCase(isNullable) ? "null" : "not null");
|
||||
String columnDefault = columnInfo.getColumnDefault();
|
||||
if (StringUtils.isNotBlank(columnDefault)) {
|
||||
columnInfo.setColumnDefault("DEFAULT " + columnDefault);
|
||||
} else {
|
||||
columnInfo.setColumnDefault("");
|
||||
}
|
||||
String extra = columnInfo.getExtra();
|
||||
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 + " `" + dbName + "`.`" + procName + "`() RETURNS integer\n" +
|
||||
"BEGIN\n" +
|
||||
"\t#Routine body goes here...\n" +
|
||||
"\tRETURN 0;\n" +
|
||||
"END;");
|
||||
} else {
|
||||
procedureDetailNew.setBody("CREATE DEFINER = CURRENT_USER " + typeName + " `" + dbName + "`.`" + 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 db = procedureDetail.getDb();
|
||||
String paramList = StringUtils.defaultIfBlank(procedureDetail.getParamList(), "");
|
||||
String[] definerArr = procedureDetail.getDefiner().split("@");
|
||||
String createStr = String.format("CREATE DEFINER=`%s`@`%s` %s `%s`.`%s`(%s)", definerArr[0], definerArr[1], type, db, 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 + "(") && !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(IdUtil.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,以防丢失\n" + e.getMessage(), procSql);
|
||||
}
|
||||
return ExecuteResult.error(e.getMessage(), procSql);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.zyplayer.doc.db.service.database;
|
||||
|
||||
import com.zyplayer.doc.db.controller.param.DataViewParam;
|
||||
import com.zyplayer.doc.db.framework.db.enums.DatabaseProductEnum;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
@@ -12,18 +14,42 @@ import org.springframework.stereotype.Service;
|
||||
@Service
|
||||
public class OracleServiceImpl extends DbBaseService {
|
||||
|
||||
@Override
|
||||
public DatabaseProductEnum getDatabaseProduct() {
|
||||
return DatabaseProductEnum.ORACLE;
|
||||
}
|
||||
@Override
|
||||
public DatabaseProductEnum getDatabaseProduct() {
|
||||
return DatabaseProductEnum.ORACLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* oracle数据库中没有也不需要use语句,指定数据库名的情况下直接返回空即可
|
||||
* @author diantu
|
||||
* @since 2023年1月16日
|
||||
*/
|
||||
@Override
|
||||
public String getUseDbSql(String dbName) {
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* oracle数据库中没有也不需要use语句,指定数据库名的情况下直接返回空即可
|
||||
* @author diantu
|
||||
* @since 2023年1月16日
|
||||
*/
|
||||
@Override
|
||||
public String getUseDbSql(String dbName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分页查询的SQL(oracle分页)
|
||||
*
|
||||
* @author diantu
|
||||
* @since 2023年1月17日
|
||||
*/
|
||||
@Override
|
||||
public String getQueryPageSql(DataViewParam dataViewParam) {
|
||||
String queryColumns = StringUtils.defaultIfBlank(dataViewParam.getRetainColumn(), "*");
|
||||
StringBuilder sqlSb = new StringBuilder();
|
||||
sqlSb.append(String.format("select %s from %s.%s", queryColumns, dataViewParam.getDbName(), dataViewParam.getTableName()));
|
||||
if (StringUtils.isNotBlank(dataViewParam.getCondition())) {
|
||||
sqlSb.append(String.format(" where %s", dataViewParam.getCondition()));
|
||||
}
|
||||
if (StringUtils.isNotBlank(dataViewParam.getOrderColumn()) && StringUtils.isNotBlank(dataViewParam.getOrderType())) {
|
||||
sqlSb.append(String.format(" order by %s %s", dataViewParam.getOrderColumn(), dataViewParam.getOrderType()));
|
||||
}
|
||||
StringBuilder sqlSbFinal = new StringBuilder();
|
||||
Integer pageSize = dataViewParam.getPageSize() * dataViewParam.getPageNum();
|
||||
Integer offsetSize = dataViewParam.getPageSize() * (dataViewParam.getPageNum() - 1) + 1;
|
||||
sqlSbFinal.append(String.format("select * from ( select %s from %s", queryColumns + ",rownum rn", "(" + sqlSb + ") where rownum<=" + pageSize + " ) t2 where t2.rn >=" + offsetSize));
|
||||
return sqlSbFinal.toString();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user