50 Commits

Author SHA1 Message Date
暮光:城中城
862d637075 1.0.9 版本升级 2021-07-25 08:03:42 +08:00
暮光:城中城
7942262eef 控制台跳转优化,关于页面优化 2021-07-22 23:02:37 +08:00
暮光:城中城
783de18e50 控制台跳转优化 2021-07-18 17:03:19 +08:00
暮光:城中城
3e673c14b7 优化关于页面,优化数据源创建失败后的处理 2021-07-17 16:42:44 +08:00
暮光:城中城
1d5c57d516 SQL执行的动态参数保存,数据预览列表头移上去展示列说明 2021-07-17 12:22:51 +08:00
暮光:城中城
eda81c36bc 自动打包至各模块的文件夹内 2021-07-17 12:19:10 +08:00
暮光:城中城
3d774f43bb 编译后的文件同步 2021-07-11 18:59:49 +08:00
暮光:城中城
e509431340 执行器展示和交互优化 2021-07-11 18:57:35 +08:00
暮光:城中城
77ff6722ab 关于页面优化 2021-07-10 19:15:49 +08:00
暮光:城中城
ddbadcd1e8 关于页面优化 2021-07-08 23:10:47 +08:00
暮光:城中城
03dff7620e sql执行增加动态参数功能 2021-06-27 22:45:30 +08:00
暮光:城中城
6da66fac7c 升级sql文件 2021-06-21 23:52:26 +08:00
暮光:城中城
5abe56caad SQL编辑器自动提示库、表、列逻辑优化,更加好用 2021-06-20 17:47:46 +08:00
暮光:城中城
a30d9318da 优化SQL编辑器引入方式,优化自动提示,优化sqlserver表、字段注释获取和更新方式,数据查询时改为需指定数据库,便于库表检索提示 2021-06-20 00:41:28 +08:00
暮光:城中城
da9146f75f sqlserver数据库查询和导出开发测试 2021-06-17 23:34:48 +08:00
暮光:城中城
01ab1d6079 关系图和数据预览优化 2021-06-09 00:05:25 +08:00
暮光:城中城
1d5e0e2bf1 表数据导出优化,增加表关系图功能 2021-06-08 23:04:15 +08:00
暮光:城中城
dcbb2b4ac8 数据表信息查看页面优化,合并数据查看页面 2021-06-06 22:43:16 +08:00
暮光:城中城
b1fefdeba7 数据导出功能完善 2021-06-05 18:58:32 +08:00
暮光:城中城
694f847f1d 表数据导出支持 2021-06-05 16:38:27 +08:00
暮光:城中城
9e3f479b3e 修改一些展示问题 2021-06-01 22:34:21 +08:00
暮光:城中城
40a3db911d 去掉一些感觉没用的插件 2021-05-31 22:57:19 +08:00
暮光:城中城
50a1f794c2 复制语句修改,日志打印优化 2021-05-31 22:44:12 +08:00
暮光:城中城
089fab958d 更新的条件支持选择列 2021-05-29 22:18:15 +08:00
暮光:城中城
c56613bc63 wiki查看页面优化 2021-05-24 22:42:50 +08:00
暮光:城中城
206f410573 数据查看优化,执行器支持复制为insert、update、json格式 2021-05-24 22:42:01 +08:00
暮光:城中城
9992ca9183 #I2BC14 移动端展示适配优化 2021-05-20 00:05:30 +08:00
暮光:城中城
8fa04b9973 数据预览优化,SQL组装移到后端 2021-05-20 00:04:07 +08:00
暮光:城中城
dcf487d55c #I2BC14 手机端查看页面适配 2021-05-14 23:45:12 +08:00
暮光:城中城
477fef11d3 测试vant移动端框架 2021-05-13 22:59:04 +08:00
暮光:城中城
ff5434a173 测试wiki的移动端展示 2021-05-13 22:02:10 +08:00
暮光:城中城
da5e0e5017 轻轻的优化了一下数据库框架 2021-05-13 22:01:41 +08:00
暮光:城中城
09d6ccca57 增加hive和impala数据源支持 2021-05-11 23:14:44 +08:00
暮光:城中城
2fab0d6a80 1.0.8 版本升级 2021-05-01 17:35:39 +08:00
暮光:城中城
4dec5b73f4 update README.md. 2021-05-01 17:04:46 +08:00
暮光:城中城
58976dc829 库函数增加修改日志记录,增加函数修改授权,展示优化 2021-04-27 23:24:21 +08:00
暮光:城中城
744e877309 增加数据库函数和存储过程的增删改查支持,优化数据源管理 2021-04-25 21:56:27 +08:00
暮光:城中城
f270a9bb12 DDL多数据源支持,虽然还没实现 2021-04-23 22:58:16 +08:00
暮光:城中城
e0e59cc82e 变量初始化 2021-04-19 15:06:13 +08:00
暮光:城中城
a153809649 用户支持分组,wiki空间支持按分组授权,细节优化 2021-02-09 22:57:52 +08:00
暮光:城中城
13d6f3ca8b 数据库文档查询优化 2021-02-01 21:50:46 +08:00
暮光:城中城
8a3f40c394 导出库表支持建表语句的导出 2021-01-31 22:04:27 +08:00
暮光:城中城
b252eeb33b 库列表增加刷新功能 2021-01-23 13:30:27 +08:00
暮光:城中城
91e7b0eb33 修改查询权限限制 2021-01-16 16:05:50 +08:00
暮光:城中城
7c8a1e7ebc 修改开放文档样式问题 2021-01-12 20:47:16 +08:00
暮光:城中城
0f72acc973 fix:I2CG72 wiki文档搜索时忽略大小写 2021-01-09 18:25:41 +08:00
暮光:城中城
e66586c765 ddl支持复制和高亮,postgresql支持 2021-01-06 23:53:14 +08:00
暮光:城中城
e949570c1a 数据库增加postgresql支持,展示优化 2021-01-06 22:32:12 +08:00
暮光:城中城
6cb2d76bfb 开放wiki页文档样式修改,支持图片预览 2021-01-06 22:30:04 +08:00
暮光:城中城
2dfb089665 升级说明修改 2021-01-01 21:54:08 +08:00
330 changed files with 10600 additions and 4671 deletions

11
.gitignore vendored
View File

@@ -33,7 +33,7 @@ target/
nbproject/private/
build/*
nbbuild/
dist/
zyplayer-doc-ui/dist/
nbdist/
.nb-gradle/
@@ -59,12 +59,3 @@ rebel.xml
# 忽略office文件打开临时文件 #
[~$]*.*
tmlog.lck
zyplayer-doc-es/src/test/
zyplayer-doc-manage/tmlog.lck
zyplayer-doc-other/src/
zyplayer-doc-other/zyplayer-doc-annotation/src/main/resources/
zyplayer-doc-other/zyplayer-doc-annotation/src/test/
zyplayer-doc-other/zyplayer-doc-dubbo-libs/dependency-reduced-pom.xml
zyplayer-doc-other/zyplayer-doc-dubbo-libs/src/
zyplayer-doc-other/zyplayer-doc-test/src/main/java/com/zyplayer/doc/test/db/
zyplayer-doc-other/zyplayer-doc-test/src/test/

View File

@@ -1,48 +1,59 @@
# zyplayer-doc
#### 项目介绍
## 项目介绍
zyplayer-doc是一款在线文档工具现有swagger 文档、dubbo文档、数据库文档、WIKI文档、ElasticSearch文档等管理端具有人员管理、权限管理功能等功能。项目后端使用spring-boot、mybatis-plus等框架前端使用zui、Vue、element-ui等框架。为开发者服务欢迎有想法的一起来写给个Star鼓励下呗您的一个Star是快速迭代的动力源泉
欢迎加群讨论QQ群号466363173
体验地址:[http://doc.zyplayer.com](http://doc.zyplayer.com/zyplayer-doc-manage/) 需登录 账号zyplayer 密码123456 未运行dubbo服务不能体验dubbo文档调试
体验地址:[http://doc.zyplayer.com](http://doc.zyplayer.com/zyplayer-doc-manage/) 账号zyplayer 密码123456
各模块的详细使用文档地址,部署必看:
[http://doc.zyplayer.com/zyplayer-doc-manage/doc-wiki#/page/share/view?pageId=1&space=23f3f59a60824d21af9f7c3bbc9bc3cb](http://doc.zyplayer.com/zyplayer-doc-manage/doc-wiki#/page/share/view?pageId=1&space=23f3f59a60824d21af9f7c3bbc9bc3cb)
[详细部署文档](http://doc.zyplayer.com/zyplayer-doc-manage/doc-wiki#/page/share/view?pageId=1&space=23f3f59a60824d21af9f7c3bbc9bc3cb)
## 功能介绍
### 一、zyplayer-doc-manage 文档管理后台
1. 具有项目模块导航,人员及权限管理功能,分组管理等功能。
2. 集成了本项目内的各个子模块功能,是各模块的协调管理模块。
#### 模块介绍
##### 一、zyplayer-doc-core
> 一些核心、公用的类
### 二、zyplayer-doc-db 数据库文档
一款在线管理数据库的工具,你可以将所有的数据源统一管理到这里面,团队间的各成员就不必每人在自己电脑上装一个数据库管理软件,
然后再添加数据源,修改账号密码也可以统一进行修改,新员工进入后对他关心的数据源进行授权即可查看。
##### 二、zyplayer-doc-manage 可以单独部署的文档管理后台
> 集成了本项目内的各子模块,具有人员及权限管理功能,是各模块的协调模块
1. 支持MySQL、SQLServer、Oracle、PostgreSQL、Hive、Impala数据源。
2. 支持数据库表、字段文档查看修改表文档导出、建表语句DDL导出、表数据导出。
3. 支持SQL执行、表数据预览、不同数据库之间的数据互导支持多数据源管理。
4. 支持按人员、按数据源对用户授权,可给用户 库表注释查看、注释修改、SQL执行、函数修改等粒度的授权。
5. 支持库函数和存储过程的增删改查,修改记录查询等。
6. 目标是取代Navicat做一个小而精的开源免费的在线数据库管理工具。
##### 三、zyplayer-doc-db 数据库文档
> 支持MySQL、SQLServer、Oracle数据源支持数据库表、字段文档查看修改表文档导出SQL执行、表数据预览、不同数据库之间的数据互导支持多数据源管理。支持按人员、按数据源对用户授权可给用户 库表注释查看、注释修改、SQL执行 粒度的授权。目标是取代Navicat做一个开源免费的在线数据库管理工具。
### 三、zyplayer-doc-wiki wiki文档工具
1. 在线管理公司、项目及任意形式的文档
2. 文档支持按空间划分,按人员分组授权,支持空间收藏和空间内的文档开放访问。
3. 文档支持编辑、查看、评论、上传附件、历史版本查看、页面权限控制、文档搜索等功能。
4. 文档编辑支持html富文本方式编辑和markdown的方式编辑。
5. 本工具使用的开源工具有vue、element-ui、mavon-editor、wangeditor等。
6. 参考学习了Atlassian Confluence文档工具进行开发争取作为该软件的开源免费替代产品同时作为内部文档管理工具最好的存在。
##### 四、zyplayer-doc-wiki wiki文档工具
> 在线管理公司、项目及任意形式的文档文档支持按空间划分在线编辑查看支持附件上传下载支持评论、点赞及权限设置等。参考学习了Atlassian Confluence文档工具进行开发争取作为该软件的开源免费替代产品同时作为内部文档管理工具最好的存在
### 四、zyplayer-doc-swagger swagger的UI及整套解决方案
1. 支持swagger的文档展示接口调试文档导出等解析速度快界面设计走心
2. 支持将所有的swagger文档进行统一管理支持全局参数设置请求参数缓存下次自动填充等。
3. 目标是解决swagger官方文档查看及接口调试不方便的问题。
##### 五、zyplayer-doc-swaggerswagger的UI及整套解决方案
> 支持swagger的文档展示接口调试文档导出等解析速度快界面设计走心。支持将所有的swagger文档进行统一管理支持全局参数设置请求参数缓存下次自动填充等。目标是解决swagger官方文档查看及接口调试不方便的问题。
### 五、zyplayer-doc-dubbo 将dubbo的文档在线化管理
1. 支持zookeeper、nacos的注册中心文档获取支持在线调试接口
##### 六、zyplayer-doc-dubbo 将dubbo的文档在线化管理
> 支持zookeeper、nacos的注册中心文档获取支持在线调试接口
### 六、zyplayer-doc-es ElasticSearch文档工具
1. 支持ElasticSearch的文档查看和执行DSL查询的功能
##### 七、zyplayer-doc-grpc grpc文档工具
> 用比较变态的方式实现了grpc的文档和在线调试功能通过http的方式来请求grpc的接口
### 七、其他
1. zyplayer-doc-ui 前面各模块的前端UI源码
2. zyplayer-doc-core 一些核心、公用的类
3. zyplayer-doc-data 数据库层面的交互
4. zyplayer-doc-grpc grpc文档工具
5. zyplayer-doc-other 一些测试
> 默认未开启此功能如需使用需要在zyplayer-doc-manage项目中开启@EnableDocGrpc注解
## 运行方式
##### 八、zyplayer-doc-es ElasticSearch文档工具
> 支持ElasticSearch的文档查看和执行DSL查询的功能
##### 九、zyplayer-doc-ui
> 前面各模块的前端UI源码
#### 运行方式
1. 创建数据库zyplayer_doc_manage执行脚本[zyplayer_doc_manage.1.0.7.sql](https://gitee.com/zyplayer/zyplayer-doc/blob/master/zyplayer-doc-manage/src/main/resources/sql/zyplayer_doc_manage.1.0.6.sql)
1. 创建数据库:zyplayer_doc_manage执行脚本[全量建表语句.sql](https://gitee.com/zyplayer/zyplayer-doc/blob/master/zyplayer-doc-manage/src/main/resources/sql/全量建表语句.sql)
2. 修改zyplayer-doc-manage项目的application.yml配置文件里面的数据库账号密码
@@ -50,12 +61,6 @@ zyplayer-doc是一款在线文档工具现有swagger 文档、dubbo文档、
更多详细的使用部署文档http://doc.zyplayer.com/zyplayer-doc-manage/doc-wiki#/page/share/view?pageId=1&space=23f3f59a60824d21af9f7c3bbc9bc3cb
虽然在GitHub上也有账号虽然本项目也不是很好但还是内在自发的只在码云上活跃每个人的一次活跃、一次评论、一次PR、一次Issue、一次鼓励的捐赠都能聚集起来聚沙成塔营造一个每个人都希望看到的一个开源文化和氛围引用码云推文的一段话
> 不再习惯性地把国内开源生态的落后归咎于开源文化和氛围,我们应意识到每人都是开源生态中的一员,我们拥有实际行动的力量,良好的开源文化和氛围需要大家的共同努力。
> 不再把开源当作「别人的事」、「大佬们的事」,尽己所能地参与建设,哪怕是一个 Issue、一个 PR健康的开源生态就是由这一个个反馈、一次次协作构建起来的。
#### 界面展示
![主页面](https://images.gitee.com/uploads/images/2020/0516/125840_d6284954_596905.png "主页面.png")
![数据库文档](https://images.gitee.com/uploads/images/2020/0516/130017_254f9559_596905.png "数据库文档.png")

View File

@@ -4,7 +4,7 @@
<groupId>com.zyplayer</groupId>
<artifactId>zyplayer-doc</artifactId>
<version>1.0.7</version>
<version>1.0.9</version>
<packaging>pom</packaging>
<name>zyplayer-doc</name>

View File

@@ -1,15 +1,24 @@
# update
# 本文件用于已部署好的系统检测自己是否需要升级使用,怕有人担心安全一类的问题,所以不提供服务器接口来做
lastVersion=1.0.7
upgradeContent=1、数据库工具增加数据源时支持测试数据源优化展示细节特殊情况下页面卡死等问题\
2、数据库工具改为使用vue-cli打包修改所有的请求方式代码更加规范化\
3、数据库文档增加Word导出支持 #I1QU0R\
4、WIKI文档工具前端重构代码更加规范化优化查看编辑页展示及URL参数无权限时不展示对应操作按钮\
5、WIKI文档工具增加删除评论功能 #I1KMTP\
6、WIKI文档工具开放地址首页展示优化 #I1KQUK\
7、WIKI文档工具重构开放文档页面集成到同一项目内\
8、WIKI文档工具增加Markdown格式编辑方式和查看增加快速打开开放文档地址\
9、WIKI文档工具增加消息提醒功能增强文档互动的感知
upgradeUrl=https://gitee.com/zyplayer/zyplayer-doc/releases
nextStep=1、WIKI文档优化
lastVersion=1.0.9
upgradeContent=数据库模块:\
1、增加hive和impala数据源支持可查看表结构、执行SQL查询数据\
2、框架优化数据查询和层级更合理\
3、数据查看优化执行器支持复制为insert、update、json格式\
4、数据库表数据导出支持支持导出为为insert、update、json格式可使用单个文件导出或zip压缩文件导出\
5、增加表关系图简版找到更好的ER图组件再替换\
6、将表字段、表结构、表关系图、表数据查看页面合并到一个页面更加便于使用\
7、sqlserver数据库查询加强数据查询、库表信息、数据导出等全功能支持\
8、优化SQL编辑器引入方式优化自动提示优化sqlserver表、字段注释获取和更新方式数据查询时改为需指定数据库便于库表检索提示\
9、SQL编辑器自动提示库、表、列逻辑优化更加好用\
10、sql执行增加动态参数功能SQL中可使用${xx}或#{xx}动态参数;\
11、数据预览列表头移上去展示列说明\
12、自动打包至各模块的文件夹内不再拷贝打包后的文件\
13、优化关于页面和项目升级提示\
wiki模块\
1、wiki模块使用vant移动端框架支持手机端文档查看适配 #I2BC14\
2、wiki查看页面优化
upgradeUrl=https://gitee.com/zyplayer/zyplayer-doc/releases
nextStep=

View File

@@ -6,7 +6,7 @@
<groupId>com.zyplayer</groupId>
<artifactId>zyplayer-doc-core</artifactId>
<version>1.0.7</version>
<version>1.0.9</version>
<name>zyplayer-doc-core</name>
<url>http://maven.apache.org</url>
@@ -39,8 +39,8 @@
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-http</artifactId>
<version>4.1.8</version>
<artifactId>hutool-all</artifactId>
<version>5.6.6</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>

View File

@@ -0,0 +1,9 @@
package com.zyplayer.doc.core.util;
/**
* zyplayer-doc版本号
* @since 2021-06-06
*/
public class ZyplayerDocVersion {
public static final String version = "1.0.9";
}

View File

@@ -6,7 +6,7 @@
<groupId>com.zyplayer</groupId>
<artifactId>zyplayer-doc-data</artifactId>
<version>1.0.7</version>
<version>1.0.9</version>
<parent>
<groupId>org.springframework.boot</groupId>
@@ -23,7 +23,7 @@
<velocity.engine.core.version>2.0</velocity.engine.core.version>
<dozer.core.version>6.1.0</dozer.core.version>
<alibaba.druid.version>1.1.9</alibaba.druid.version>
<zyplayer.doc.version>1.0.7</zyplayer.doc.version>
<zyplayer.doc.version>1.0.9</zyplayer.doc.version>
<elasticsearch.version>7.2.0</elasticsearch.version>
</properties>
@@ -67,7 +67,42 @@
<artifactId>ojdbc6</artifactId>
<version>12.1.0.1-atlassian-hosted</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.2</version>
</dependency>
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-jdbc</artifactId>
<version>2.1.1</version>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
<exclusion>
<artifactId>log4j</artifactId>
<groupId>log4j</groupId>
</exclusion>
<exclusion>
<artifactId>log4j-1.2-api</artifactId>
<groupId>org.apache.logging.log4j</groupId>
</exclusion>
<exclusion>
<artifactId>log4j-slf4j-impl</artifactId>
<groupId>org.apache.logging.log4j</groupId>
</exclusion>
<exclusion>
<artifactId>log4j-web</artifactId>
<groupId>org.apache.logging.log4j</groupId>
</exclusion>
<exclusion>
<artifactId>slf4j-log4j12</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.github.dozermapper</groupId>
<artifactId>dozer-core</artifactId>

View File

@@ -1,7 +1,10 @@
package com.zyplayer.doc.data.config.security;
import com.zyplayer.doc.data.utils.CachePrefix;
import com.zyplayer.doc.data.utils.CacheUtil;
import java.util.Set;
/**
* 用户工具类
* @author 暮光:城中城
@@ -54,6 +57,21 @@ public class DocUserUtil {
public static void setCurrentUser(String accessToken, DocUserDetails docUser) {
DOC_USER_DETAILS.set(docUser);
CacheUtil.put(accessToken, docUser);
CacheUtil.put(CachePrefix.LOGIN_USER_ID_TOKEN + docUser.getUserId(), accessToken);
}
/**
* 设置当前用户权限
*/
public static void setUserAuth(Long userId, Set<String> userAuthSet) {
String userToken = CacheUtil.get(CachePrefix.LOGIN_USER_ID_TOKEN + userId);
if (userToken != null) {
DocUserDetails docUser = CacheUtil.get(userToken);
if (docUser != null) {
docUser.setAuthorities(userAuthSet);
CacheUtil.put(userToken, docUser);
}
}
}
/**

View File

@@ -58,6 +58,11 @@ public class DbFavorite implements Serializable {
* 是否有效 0=无效 1=有效
*/
private Integer yn;
/**
* 执行参数JSON
*/
private String paramJson;
public Long getId() {
return id;
@@ -129,4 +134,12 @@ public class DbFavorite implements Serializable {
public void setDatasourceId(Long datasourceId) {
this.datasourceId = datasourceId;
}
public String getParamJson() {
return paramJson;
}
public void setParamJson(String paramJson) {
this.paramJson = paramJson;
}
}

View File

@@ -7,7 +7,7 @@ import java.io.Serializable;
/**
* <p>
*
*
* </p>
*
* @author 暮光:城中城
@@ -53,6 +53,11 @@ public class DbHistory implements Serializable {
*/
private Integer yn;
/**
* 执行参数JSON
*/
private String paramJson;
public Long getId() {
return id;
}
@@ -115,4 +120,12 @@ public class DbHistory implements Serializable {
public void setDatasourceId(Long datasourceId) {
this.datasourceId = datasourceId;
}
public String getParamJson() {
return paramJson;
}
public void setParamJson(String paramJson) {
this.paramJson = paramJson;
}
}

View File

@@ -0,0 +1,158 @@
package com.zyplayer.doc.data.repository.manage.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
* 数据库函数修改日志
* </p>
*
* @author 暮光:城中城
* @since 2021-04-26
*/
public class DbProcLog implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键自增ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 数据源ID
*/
private Long datasourceId;
/**
* 所属数据库
*/
private String procDb;
/**
* 名字
*/
private String procName;
/**
* 类型
*/
private String procType;
/**
* 函数创建SQL
*/
private String procBody;
/**
* 保存状态 1=成功 2=失败
*/
private Integer status;
/**
* 创建人ID
*/
private Long createUserId;
/**
* 创建人名字
*/
private String createUserName;
/**
* 创建时间
*/
private Date createTime;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getDatasourceId() {
return datasourceId;
}
public void setDatasourceId(Long datasourceId) {
this.datasourceId = datasourceId;
}
public String getProcDb() {
return procDb;
}
public void setProcDb(String procDb) {
this.procDb = procDb;
}
public String getProcName() {
return procName;
}
public void setProcName(String procName) {
this.procName = procName;
}
public String getProcType() {
return procType;
}
public void setProcType(String procType) {
this.procType = procType;
}
public String getProcBody() {
return procBody;
}
public void setProcBody(String procBody) {
this.procBody = procBody;
}
public Long getCreateUserId() {
return createUserId;
}
public void setCreateUserId(Long createUserId) {
this.createUserId = createUserId;
}
public String getCreateUserName() {
return createUserName;
}
public void setCreateUserName(String createUserName) {
this.createUserName = createUserName;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
@Override
public String toString() {
return "DbProcLog{" +
"id=" + id +
", datasourceId=" + datasourceId +
", procDb=" + procDb +
", procName=" + procName +
", procType=" + procType +
", procBody=" + procBody +
", createUserId=" + createUserId +
", createUserName=" + createUserName +
", createTime=" + createTime +
"}";
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
}

View File

@@ -0,0 +1,170 @@
package com.zyplayer.doc.data.repository.manage.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
/**
* <p>
* 表关系
* </p>
*
* @author 暮光:城中城
* @since 2021-06-07
*/
public class DbTableRelation implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键自增ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 数据源ID
*/
private Long datasourceId;
/**
* 源库名
*/
private String startDbName;
/**
* 源表名
*/
private String startTableName;
/**
* 源字段名
*/
private String startColumnName;
/**
* 目标库名
*/
private String endDbName;
/**
* 目标表名
*/
private String endTableName;
/**
* 目标字段名
*/
private String endColumnName;
/**
* 创建人ID
*/
private Long createUserId;
/**
* 创建人名字
*/
private String createUserName;
/**
* 创建时间
*/
private Date createTime;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getDatasourceId() {
return datasourceId;
}
public void setDatasourceId(Long datasourceId) {
this.datasourceId = datasourceId;
}
public String getStartDbName() {
return startDbName;
}
public void setStartDbName(String startDbName) {
this.startDbName = startDbName;
}
public String getStartTableName() {
return startTableName;
}
public void setStartTableName(String startTableName) {
this.startTableName = startTableName;
}
public String getStartColumnName() {
return startColumnName;
}
public void setStartColumnName(String startColumnName) {
this.startColumnName = startColumnName;
}
public String getEndDbName() {
return endDbName;
}
public void setEndDbName(String endDbName) {
this.endDbName = endDbName;
}
public String getEndTableName() {
return endTableName;
}
public void setEndTableName(String endTableName) {
this.endTableName = endTableName;
}
public String getEndColumnName() {
return endColumnName;
}
public void setEndColumnName(String endColumnName) {
this.endColumnName = endColumnName;
}
public Long getCreateUserId() {
return createUserId;
}
public void setCreateUserId(Long createUserId) {
this.createUserId = createUserId;
}
public String getCreateUserName() {
return createUserName;
}
public void setCreateUserName(String createUserName) {
this.createUserName = createUserName;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
@Override
public String toString() {
return "DbTableRelation{" +
"id=" + id +
", datasourceId=" + datasourceId +
", startDbName=" + startDbName +
", startTableName=" + startTableName +
", startColumnName=" + startColumnName +
", endDbName=" + endDbName +
", endTableName=" + endTableName +
", endColumnName=" + endColumnName +
", createUserId=" + createUserId +
", createUserName=" + createUserName +
", createTime=" + createTime +
"}";
}
}

View File

@@ -0,0 +1,106 @@
package com.zyplayer.doc.data.repository.manage.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
* 用户组
* </p>
*
* @author 暮光:城中城
* @since 2021-02-08
*/
public class UserGroup implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键自增ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 分组名
*/
private String name;
/**
* 创建人ID
*/
private Long createUserId;
/**
* 创建人名字
*/
private String createUserName;
/**
* 创建时间
*/
private Date createTime;
/**
* 删除标记 0=正常 1=已删除
*/
private Integer delFlag;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getCreateUserId() {
return createUserId;
}
public void setCreateUserId(Long createUserId) {
this.createUserId = createUserId;
}
public String getCreateUserName() {
return createUserName;
}
public void setCreateUserName(String createUserName) {
this.createUserName = createUserName;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Integer getDelFlag() {
return delFlag;
}
public void setDelFlag(Integer delFlag) {
this.delFlag = delFlag;
}
@Override
public String toString() {
return "UserGroup{" +
"id=" + id +
", name=" + name +
", createUserId=" + createUserId +
", createUserName=" + createUserName +
", createTime=" + createTime +
", delFlag=" + delFlag +
"}";
}
}

View File

@@ -0,0 +1,145 @@
package com.zyplayer.doc.data.repository.manage.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
* 用户组在各项目内的授权关系
* </p>
*
* @author 暮光:城中城
* @since 2021-02-09
*/
public class UserGroupAuth implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键自增ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 群ID
*/
private Long groupId;
/**
* 授权数据的ID
*/
private Long dataId;
/**
* 授权类型,依据各项目自己定义
*/
private Integer authType;
/**
* 项目类型 1=WIKI模块 2=数据库模块
*/
private Integer projectType;
/**
* 创建人ID
*/
private Long createUserId;
/**
* 创建人名字
*/
private String createUserName;
/**
* 创建时间
*/
private Date createTime;
/**
* 删除标记 0=正常 1=已删除
*/
private Integer delFlag;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getGroupId() {
return groupId;
}
public void setGroupId(Long groupId) {
this.groupId = groupId;
}
public Long getDataId() {
return dataId;
}
public void setDataId(Long dataId) {
this.dataId = dataId;
}
public Integer getProjectType() {
return projectType;
}
public void setProjectType(Integer projectType) {
this.projectType = projectType;
}
public Long getCreateUserId() {
return createUserId;
}
public void setCreateUserId(Long createUserId) {
this.createUserId = createUserId;
}
public String getCreateUserName() {
return createUserName;
}
public void setCreateUserName(String createUserName) {
this.createUserName = createUserName;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Integer getDelFlag() {
return delFlag;
}
public void setDelFlag(Integer delFlag) {
this.delFlag = delFlag;
}
@Override
public String toString() {
return "UserGroupAuth{" +
"id=" + id +
", groupId=" + groupId +
", dataId=" + dataId +
", projectType=" + projectType +
", createUserId=" + createUserId +
", createUserName=" + createUserName +
", createTime=" + createTime +
", delFlag=" + delFlag +
"}";
}
public Integer getAuthType() {
return authType;
}
public void setAuthType(Integer authType) {
this.authType = authType;
}
}

View File

@@ -0,0 +1,118 @@
package com.zyplayer.doc.data.repository.manage.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
/**
* <p>
* 用户和用户组关系表
* </p>
*
* @author 暮光:城中城
* @since 2021-02-08
*/
public class UserGroupRelation implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键自增ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 群ID
*/
private Long groupId;
/**
* 用户ID
*/
private Long userId;
/**
* 创建人ID
*/
private Long createUserId;
/**
* 创建人名字
*/
private String createUserName;
/**
* 创建时间
*/
private Date createTime;
/**
* 删除标记 0=正常 1=已删除
*/
private Integer delFlag;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getGroupId() {
return groupId;
}
public void setGroupId(Long groupId) {
this.groupId = groupId;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public Long getCreateUserId() {
return createUserId;
}
public void setCreateUserId(Long createUserId) {
this.createUserId = createUserId;
}
public String getCreateUserName() {
return createUserName;
}
public void setCreateUserName(String createUserName) {
this.createUserName = createUserName;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Integer getDelFlag() {
return delFlag;
}
public void setDelFlag(Integer delFlag) {
this.delFlag = delFlag;
}
@Override
public String toString() {
return "UserGroupRelation{" +
"id=" + id +
", groupId=" + groupId +
", userId=" + userId +
", createUserId=" + createUserId +
", createUserName=" + createUserName +
", createTime=" + createTime +
", delFlag=" + delFlag +
"}";
}
}

View File

@@ -0,0 +1,105 @@
package com.zyplayer.doc.data.repository.manage.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
/**
* <p>
* 用户设置表
* </p>
*
* @author 暮光:城中城
* @since 2021-02-09
*/
public class UserSetting implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键自增ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 用户ID
*/
private Long userId;
/**
* 设置的名字
*/
private String name;
/**
* 设置的值
*/
private String value;
/**
* 创建时间
*/
private Date createTime;
/**
* 删除标记 0=正常 1=已删除
*/
private Integer delFlag;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Integer getDelFlag() {
return delFlag;
}
public void setDelFlag(Integer delFlag) {
this.delFlag = delFlag;
}
@Override
public String toString() {
return "UserSetting{" +
"id=" + id +
", userId=" + userId +
", name=" + name +
", value=" + value +
", createTime=" + createTime +
", delFlag=" + delFlag +
"}";
}
}

View File

@@ -0,0 +1,92 @@
package com.zyplayer.doc.data.repository.manage.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
/**
* <p>
* 用户空间收藏记录表
* </p>
*
* @author 暮光:城中城
* @since 2021-02-09
*/
public class WikiSpaceFavorite implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键自增ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 空间ID
*/
private Long spaceId;
/**
* 用户ID
*/
private Long userId;
/**
* 创建时间
*/
private Date createTime;
/**
* 删除标记 0=正常 1=已删除
*/
private Integer delFlag;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getSpaceId() {
return spaceId;
}
public void setSpaceId(Long spaceId) {
this.spaceId = spaceId;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Integer getDelFlag() {
return delFlag;
}
public void setDelFlag(Integer delFlag) {
this.delFlag = delFlag;
}
@Override
public String toString() {
return "WikiSpaceFavorite{" +
"id=" + id +
", spaceId=" + spaceId +
", userId=" + userId +
", createTime=" + createTime +
", delFlag=" + delFlag +
"}";
}
}

View File

@@ -0,0 +1,16 @@
package com.zyplayer.doc.data.repository.manage.mapper;
import com.zyplayer.doc.data.repository.manage.entity.DbProcLog;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 数据库函数修改日志 Mapper 接口
* </p>
*
* @author 暮光:城中城
* @since 2021-04-26
*/
public interface DbProcLogMapper extends BaseMapper<DbProcLog> {
}

View File

@@ -0,0 +1,16 @@
package com.zyplayer.doc.data.repository.manage.mapper;
import com.zyplayer.doc.data.repository.manage.entity.DbTableRelation;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 表关系 Mapper 接口
* </p>
*
* @author 暮光:城中城
* @since 2021-06-07
*/
public interface DbTableRelationMapper extends BaseMapper<DbTableRelation> {
}

View File

@@ -0,0 +1,20 @@
package com.zyplayer.doc.data.repository.manage.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zyplayer.doc.data.repository.manage.entity.UserGroupAuth;
import org.apache.ibatis.annotations.Select;
/**
* <p>
* 用户组在各项目内的授权关系 Mapper 接口
* </p>
*
* @author 暮光:城中城
* @since 2021-02-09
*/
public interface UserGroupAuthMapper extends BaseMapper<UserGroupAuth> {
@Select("select a.id from user_group_auth a join user_group_relation b on a.group_id=b.group_id and b.user_id=#{userId} " +
"where a.project_type=#{projectType} and a.auth_type=#{authType} and a.data_id=#{spaceId} and b.del_flag=0")
Long haveAuth(Long spaceId, Integer projectType, Integer authType, Long userId);
}

View File

@@ -0,0 +1,23 @@
package com.zyplayer.doc.data.repository.manage.mapper;
import com.zyplayer.doc.data.repository.manage.entity.UserGroup;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zyplayer.doc.data.repository.manage.entity.UserInfo;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* <p>
* 用户组 Mapper 接口
* </p>
*
* @author 暮光:城中城
* @since 2021-02-08
*/
public interface UserGroupMapper extends BaseMapper<UserGroup> {
@Select("select b.id, b.user_no, b.email, b.phone, b.sex, b.user_name, b.avatar from user_group_relation a join user_info b on b.id=a.user_id where a.group_id=#{groupId} and a.del_flag=0 and b.del_flag=0")
List<UserInfo> groupUserList(@Param("groupId") Long groupId);
}

View File

@@ -0,0 +1,16 @@
package com.zyplayer.doc.data.repository.manage.mapper;
import com.zyplayer.doc.data.repository.manage.entity.UserGroupRelation;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 用户和用户组关系表 Mapper 接口
* </p>
*
* @author 暮光:城中城
* @since 2021-02-08
*/
public interface UserGroupRelationMapper extends BaseMapper<UserGroupRelation> {
}

View File

@@ -0,0 +1,16 @@
package com.zyplayer.doc.data.repository.manage.mapper;
import com.zyplayer.doc.data.repository.manage.entity.UserSetting;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 用户设置表 Mapper 接口
* </p>
*
* @author 暮光:城中城
* @since 2021-02-09
*/
public interface UserSettingMapper extends BaseMapper<UserSetting> {
}

View File

@@ -0,0 +1,16 @@
package com.zyplayer.doc.data.repository.manage.mapper;
import com.zyplayer.doc.data.repository.manage.entity.WikiSpaceFavorite;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 用户空间收藏记录表 Mapper 接口
* </p>
*
* @author 暮光:城中城
* @since 2021-02-09
*/
public interface WikiSpaceFavoriteMapper extends BaseMapper<WikiSpaceFavorite> {
}

View File

@@ -0,0 +1,55 @@
package com.zyplayer.doc.data.repository.manage.param;
/**
* 表关系请求参数
* @author 暮光:城中城
* @since 2021-06-07
*/
public class TableRelationParam {
private Long sourceId;
private String dbName;
private String tableName;
private String columnName;
// 关系JSON大概是[{dbName: 'xxx', tableName: 'xxx', columnName: 'xxx'}]
private String relation;
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 String getTableName() {
return tableName;
}
public void setTableName(String tableName) {
this.tableName = tableName;
}
public String getRelation() {
return relation;
}
public void setRelation(String relation) {
this.relation = relation;
}
public String getColumnName() {
return columnName;
}
public void setColumnName(String columnName) {
this.columnName = columnName;
}
}

View File

@@ -0,0 +1,66 @@
package com.zyplayer.doc.data.repository.manage.vo;
import java.util.List;
/**
* 表关系结构
* @author 暮光:城中城
* @since 2021-06-07
*/
public class TableRelationVo {
private String dbName;
private String tableName;
// name和columnName是一个name给前端使用的
private String name;
private String columnName;
private Integer nodeType;
private List<TableRelationVo> children;
public String getDbName() {
return dbName;
}
public void setDbName(String dbName) {
this.dbName = dbName;
}
public String getTableName() {
return tableName;
}
public void setTableName(String tableName) {
this.tableName = tableName;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getColumnName() {
return columnName;
}
public void setColumnName(String columnName) {
this.columnName = columnName;
}
public List<TableRelationVo> getChildren() {
return children;
}
public void setChildren(List<TableRelationVo> children) {
this.children = children;
}
public Integer getNodeType() {
return nodeType;
}
public void setNodeType(Integer nodeType) {
this.nodeType = nodeType;
}
}

View File

@@ -0,0 +1,5 @@
package com.zyplayer.doc.data.repository.support.consts;
public class UserSettingConst {
public static final String WIKI_ONLY_SHOW_FAVORITE = "wiki_only_show_favorite";
}

View File

@@ -13,15 +13,15 @@ import java.util.ArrayList;
import java.util.List;
public class CodeGenerator {
public static void main(String[] args) {
final String moduleName = "manage";
// final String[] tableName = { "zyplayer_storage", "auth_info", "user_auth", "user_info", "db_datasource" };
// final String[] tableName = { "wiki_space", "wiki_page", "wiki_page_content", "wiki_page_file", "wiki_page_comment", "wiki_page_zan" };
// final String[] tableName = { "db_datasource", "es_datasource", "db_favorite" };
final String[] tableName = { "wiki_page_history" };
final String[] tableName = {"db_table_relation"};
// 代码生成器
AutoGenerator mpg = new AutoGenerator();
// 全局配置
@@ -35,7 +35,7 @@ public class CodeGenerator {
gc.setServiceName("%sService");
gc.setControllerName("Generator%sController");
mpg.setGlobalConfig(gc);
// 数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://127.0.0.1:3306/zyplayer_doc_manage?useUnicode=true&useSSL=false&characterEncoding=utf8");
@@ -44,7 +44,7 @@ public class CodeGenerator {
dsc.setUsername("root");
dsc.setPassword("root");
mpg.setDataSource(dsc);
// 包配置
final PackageConfig pc = new PackageConfig();
pc.setModuleName(null);
@@ -55,7 +55,7 @@ public class CodeGenerator {
pc.setService("service.manage");
pc.setServiceImpl("service.manage.impl");
mpg.setPackageInfo(pc);
// 自定义配置
InjectionConfig cfg = new InjectionConfig() {
@Override
@@ -73,7 +73,7 @@ public class CodeGenerator {
cfg.setFileOutConfigList(focList);
mpg.setCfg(cfg);
mpg.setTemplate(new TemplateConfig().setXml(null));
// 策略配置
StrategyConfig strategy = new StrategyConfig();
strategy.setNaming(NamingStrategy.underline_to_camel);
@@ -90,5 +90,5 @@ public class CodeGenerator {
mpg.setTemplateEngine(new FreemarkerTemplateEngine());
mpg.execute();
}
}

View File

@@ -13,6 +13,6 @@ import com.baomidou.mybatisplus.extension.service.IService;
*/
public interface DbHistoryService extends IService<DbHistory> {
void saveHistory(String content, Long datasourceId);
void saveHistory(String content, String paramJson, Long datasourceId);
}

View File

@@ -0,0 +1,16 @@
package com.zyplayer.doc.data.service.manage;
import com.zyplayer.doc.data.repository.manage.entity.DbProcLog;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 数据库函数修改日志 服务类
* </p>
*
* @author 暮光:城中城
* @since 2021-04-26
*/
public interface DbProcLogService extends IService<DbProcLog> {
}

View File

@@ -0,0 +1,20 @@
package com.zyplayer.doc.data.service.manage;
import com.zyplayer.doc.data.repository.manage.entity.DbTableRelation;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zyplayer.doc.data.repository.manage.param.TableRelationParam;
import com.zyplayer.doc.data.repository.manage.vo.TableRelationVo;
/**
* <p>
* 表关系 服务类
* </p>
*
* @author 暮光:城中城
* @since 2021-06-07
*/
public interface DbTableRelationService extends IService<DbTableRelation> {
void update(TableRelationParam param);
}

View File

@@ -3,6 +3,8 @@ package com.zyplayer.doc.data.service.manage;
import com.zyplayer.doc.data.repository.manage.entity.UserAuth;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.Set;
/**
* <p>
* 用户权限表 服务类
@@ -12,5 +14,6 @@ import com.baomidou.mybatisplus.extension.service.IService;
* @since 2019-05-31
*/
public interface UserAuthService extends IService<UserAuth> {
Set<String> getUserAuthSet(Long id);
}

View File

@@ -0,0 +1,16 @@
package com.zyplayer.doc.data.service.manage;
import com.zyplayer.doc.data.repository.manage.entity.UserGroupAuth;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 用户组在各项目内的授权关系 服务类
* </p>
*
* @author 暮光:城中城
* @since 2021-02-09
*/
public interface UserGroupAuthService extends IService<UserGroupAuth> {
}

View File

@@ -0,0 +1,16 @@
package com.zyplayer.doc.data.service.manage;
import com.zyplayer.doc.data.repository.manage.entity.UserGroupRelation;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 用户和用户组关系表 服务类
* </p>
*
* @author 暮光:城中城
* @since 2021-02-08
*/
public interface UserGroupRelationService extends IService<UserGroupRelation> {
}

View File

@@ -0,0 +1,16 @@
package com.zyplayer.doc.data.service.manage;
import com.zyplayer.doc.data.repository.manage.entity.UserGroup;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 用户组 服务类
* </p>
*
* @author 暮光:城中城
* @since 2021-02-08
*/
public interface UserGroupService extends IService<UserGroup> {
}

View File

@@ -0,0 +1,16 @@
package com.zyplayer.doc.data.service.manage;
import com.zyplayer.doc.data.repository.manage.entity.UserSetting;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 用户设置表 服务类
* </p>
*
* @author 暮光:城中城
* @since 2021-02-09
*/
public interface UserSettingService extends IService<UserSetting> {
}

View File

@@ -0,0 +1,16 @@
package com.zyplayer.doc.data.service.manage;
import com.zyplayer.doc.data.repository.manage.entity.WikiSpaceFavorite;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 用户空间收藏记录表 服务类
* </p>
*
* @author 暮光:城中城
* @since 2021-02-09
*/
public interface WikiSpaceFavoriteService extends IService<WikiSpaceFavorite> {
}

View File

@@ -26,11 +26,12 @@ public class DbHistoryServiceImpl extends ServiceImpl<DbHistoryMapper, DbHistory
DbHistoryMapper dbHistoryMapper;
@Override
public void saveHistory(String content, Long datasourceId) {
public void saveHistory(String content, String paramJson, Long datasourceId) {
DocUserDetails currentUser = DocUserUtil.getCurrentUser();
DbHistory dbHistory = new DbHistory();
dbHistory.setDatasourceId(datasourceId);
dbHistory.setContent(content);
dbHistory.setParamJson(paramJson);
dbHistory.setCreateTime(new Date());
dbHistory.setCreateUserId(currentUser.getUserId());
dbHistory.setCreateUserName(currentUser.getUsername());

View File

@@ -0,0 +1,20 @@
package com.zyplayer.doc.data.service.manage.impl;
import com.zyplayer.doc.data.repository.manage.entity.DbProcLog;
import com.zyplayer.doc.data.repository.manage.mapper.DbProcLogMapper;
import com.zyplayer.doc.data.service.manage.DbProcLogService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* <p>
* 数据库函数修改日志 服务实现类
* </p>
*
* @author 暮光:城中城
* @since 2021-04-26
*/
@Service
public class DbProcLogServiceImpl extends ServiceImpl<DbProcLogMapper, DbProcLog> implements DbProcLogService {
}

View File

@@ -0,0 +1,72 @@
package com.zyplayer.doc.data.service.manage.impl;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.sun.jersey.server.impl.wadl.WadlResource;
import com.zyplayer.doc.data.config.security.DocUserDetails;
import com.zyplayer.doc.data.config.security.DocUserUtil;
import com.zyplayer.doc.data.repository.manage.entity.DbTableRelation;
import com.zyplayer.doc.data.repository.manage.mapper.DbTableRelationMapper;
import com.zyplayer.doc.data.repository.manage.param.TableRelationParam;
import com.zyplayer.doc.data.repository.manage.vo.TableRelationVo;
import com.zyplayer.doc.data.service.manage.DbTableRelationService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.*;
/**
* <p>
* 表关系 服务实现类
* </p>
*
* @author 暮光:城中城
* @since 2021-06-07
*/
@Service
public class DbTableRelationServiceImpl extends ServiceImpl<DbTableRelationMapper, DbTableRelation> implements DbTableRelationService {
@Override
@Transactional
public void update(TableRelationParam param) {
UpdateWrapper<DbTableRelation> removeWrapper = new UpdateWrapper<>();
removeWrapper.eq("datasource_id", param.getSourceId());
removeWrapper.and(wrapper -> wrapper.or(or -> or.eq("start_db_name", param.getDbName())
.eq("start_table_name", param.getTableName())
.eq("start_column_name", param.getColumnName())
).or(or -> or.eq("end_db_name", param.getDbName())
.eq("end_table_name", param.getTableName())
.eq("end_column_name", param.getColumnName())
));
this.remove(removeWrapper);
if(StringUtils.isEmpty(param.getRelation())) {
return;
}
DocUserDetails currentUser = DocUserUtil.getCurrentUser();
List<TableRelationParam> tableRelationList = JSON.parseArray(param.getRelation(), TableRelationParam.class);
for (TableRelationParam relation : tableRelationList) {
if (StringUtils.isBlank(relation.getDbName())
|| StringUtils.isBlank(relation.getTableName())
|| StringUtils.isBlank(relation.getColumnName())) {
continue;
}
DbTableRelation tableRelation = new DbTableRelation();
tableRelation.setDatasourceId(param.getSourceId());
tableRelation.setStartDbName(param.getDbName());
tableRelation.setStartTableName(param.getTableName());
tableRelation.setStartColumnName(param.getColumnName());
tableRelation.setEndDbName(relation.getDbName());
tableRelation.setEndTableName(relation.getTableName());
tableRelation.setEndColumnName(relation.getColumnName());
tableRelation.setCreateTime(new Date());
tableRelation.setCreateUserId(currentUser.getUserId());
tableRelation.setCreateUserName(currentUser.getUsername());
this.save(tableRelation);
}
}
}

View File

@@ -1,11 +1,18 @@
package com.zyplayer.doc.data.service.manage.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zyplayer.doc.data.repository.manage.entity.AuthInfo;
import com.zyplayer.doc.data.repository.manage.entity.UserAuth;
import com.zyplayer.doc.data.repository.manage.mapper.UserAuthMapper;
import com.zyplayer.doc.data.service.manage.AuthInfoService;
import com.zyplayer.doc.data.service.manage.UserAuthService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
/**
* <p>
* 用户权限表 服务实现类
@@ -16,5 +23,25 @@ import org.springframework.stereotype.Service;
*/
@Service
public class UserAuthServiceImpl extends ServiceImpl<UserAuthMapper, UserAuth> implements UserAuthService {
@Resource
AuthInfoService authInfoService;
@Override
public Set<String> getUserAuthSet(Long id) {
QueryWrapper<UserAuth> authWrapper = new QueryWrapper<>();
authWrapper.eq("user_id", id).eq("del_flag", "0");
List<UserAuth> userAuthList = this.list(authWrapper);
Set<String> userAuthSet = Collections.emptySet();
if (userAuthList != null && userAuthList.size() > 0) {
List<Long> authIdList = userAuthList.stream().map(UserAuth::getAuthId).collect(Collectors.toList());
Collection<AuthInfo> authInfoList = authInfoService.listByIds(authIdList);
Map<Long, String> authNameMap = authInfoList.stream().collect(Collectors.toMap(AuthInfo::getId, AuthInfo::getAuthName));
userAuthSet = userAuthList.stream().map(val -> {
String authName = Optional.ofNullable(authNameMap.get(val.getAuthId())).orElse("");
return authName + Optional.ofNullable(val.getAuthCustomSuffix()).orElse("");
}).collect(Collectors.toSet());
}
return userAuthSet;
}
}

View File

@@ -0,0 +1,20 @@
package com.zyplayer.doc.data.service.manage.impl;
import com.zyplayer.doc.data.repository.manage.entity.UserGroupAuth;
import com.zyplayer.doc.data.repository.manage.mapper.UserGroupAuthMapper;
import com.zyplayer.doc.data.service.manage.UserGroupAuthService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* <p>
* 用户组在各项目内的授权关系 服务实现类
* </p>
*
* @author 暮光:城中城
* @since 2021-02-09
*/
@Service
public class UserGroupAuthServiceImpl extends ServiceImpl<UserGroupAuthMapper, UserGroupAuth> implements UserGroupAuthService {
}

View File

@@ -0,0 +1,20 @@
package com.zyplayer.doc.data.service.manage.impl;
import com.zyplayer.doc.data.repository.manage.entity.UserGroupRelation;
import com.zyplayer.doc.data.repository.manage.mapper.UserGroupRelationMapper;
import com.zyplayer.doc.data.service.manage.UserGroupRelationService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* <p>
* 用户和用户组关系表 服务实现类
* </p>
*
* @author 暮光:城中城
* @since 2021-02-08
*/
@Service
public class UserGroupRelationServiceImpl extends ServiceImpl<UserGroupRelationMapper, UserGroupRelation> implements UserGroupRelationService {
}

View File

@@ -0,0 +1,20 @@
package com.zyplayer.doc.data.service.manage.impl;
import com.zyplayer.doc.data.repository.manage.entity.UserGroup;
import com.zyplayer.doc.data.repository.manage.mapper.UserGroupMapper;
import com.zyplayer.doc.data.service.manage.UserGroupService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* <p>
* 用户组 服务实现类
* </p>
*
* @author 暮光:城中城
* @since 2021-02-08
*/
@Service
public class UserGroupServiceImpl extends ServiceImpl<UserGroupMapper, UserGroup> implements UserGroupService {
}

View File

@@ -0,0 +1,20 @@
package com.zyplayer.doc.data.service.manage.impl;
import com.zyplayer.doc.data.repository.manage.entity.UserSetting;
import com.zyplayer.doc.data.repository.manage.mapper.UserSettingMapper;
import com.zyplayer.doc.data.service.manage.UserSettingService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* <p>
* 用户设置表 服务实现类
* </p>
*
* @author 暮光:城中城
* @since 2021-02-09
*/
@Service
public class UserSettingServiceImpl extends ServiceImpl<UserSettingMapper, UserSetting> implements UserSettingService {
}

View File

@@ -0,0 +1,20 @@
package com.zyplayer.doc.data.service.manage.impl;
import com.zyplayer.doc.data.repository.manage.entity.WikiSpaceFavorite;
import com.zyplayer.doc.data.repository.manage.mapper.WikiSpaceFavoriteMapper;
import com.zyplayer.doc.data.service.manage.WikiSpaceFavoriteService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* <p>
* 用户空间收藏记录表 服务实现类
* </p>
*
* @author 暮光:城中城
* @since 2021-02-09
*/
@Service
public class WikiSpaceFavoriteServiceImpl extends ServiceImpl<WikiSpaceFavoriteMapper, WikiSpaceFavorite> implements WikiSpaceFavoriteService {
}

View File

@@ -3,4 +3,5 @@ package com.zyplayer.doc.data.utils;
public class CachePrefix {
public static final String WIKI_LOCK_PAGE = "WIKI_LOCK_PAGE_";
public static final String DB_EDITOR_DATA_CACHE = "DB_EDITOR_DATA_CACHE_";
public static final String LOGIN_USER_ID_TOKEN = "LOGIN_USER_ID_TOKEN_";
}

View File

@@ -4,6 +4,7 @@ import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidPooledConnection;
import com.zyplayer.doc.core.exception.ConfirmException;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicLong;
public class DruidDataSourceUtil {
@@ -33,7 +34,7 @@ public class DruidDataSourceUtil {
dataSource.setBreakAfterAcquireFailure(breakAfterAcquireFailure);// false连接出错后不退出等待下个定时周期重试true失败不再重试
dataSource.setTimeBetweenConnectErrorMillis(180000);// 连接出错后重试时间间隔3分钟
dataSource.setName("zyplayer-doc-db-" + nameId.incrementAndGet());
if (url.contains("oracle")) {
if (Objects.equals("oracle.jdbc.driver.OracleDriver", driverClassName)) {
dataSource.setValidationQuery("select 1 from dual");
}
DruidPooledConnection connection = dataSource.getConnection(3000);

View File

@@ -1,20 +0,0 @@
package com.zyplayer.doc.data.web.generator;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* <p>
* 用户消息表 前端控制器
* </p>
*
* @author 暮光:城中城
* @since 2020-06-23
*/
@RestController
@RequestMapping("/user-message")
public class GeneratorUserMessageController {
}

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zyplayer.doc.data.repository.manage.mapper.DbProcLogMapper">
</mapper>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zyplayer.doc.data.repository.manage.mapper.DbTableRelationMapper">
</mapper>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zyplayer.doc.data.repository.manage.mapper.UserGroupAuthMapper">
</mapper>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zyplayer.doc.data.repository.manage.mapper.UserGroupMapper">
</mapper>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zyplayer.doc.data.repository.manage.mapper.UserGroupRelationMapper">
</mapper>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zyplayer.doc.data.repository.manage.mapper.UserSettingMapper">
</mapper>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zyplayer.doc.data.repository.manage.mapper.WikiSpaceFavoriteMapper">
</mapper>

View File

@@ -5,7 +5,7 @@
<groupId>com.zyplayer</groupId>
<artifactId>zyplayer-doc-db</artifactId>
<version>1.0.7</version>
<version>1.0.9</version>
<packaging>jar</packaging>
<name>zyplayer-doc-db</name>
<description>数据库文档工具</description>
@@ -67,13 +67,18 @@
<artifactId>easyexcel</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<zyplayer.doc.version>1.0.7</zyplayer.doc.version>
<zyplayer.doc.version>1.0.9</zyplayer.doc.version>
<!-- 打包跳过单元测试 -->
<skipTests>true</skipTests>
<elasticsearch.version>7.2.0</elasticsearch.version>
@@ -104,6 +109,10 @@
<build>
<resources>
<resource>
<directory>src/main/resources/dist</directory>
<targetPath>META-INF/resources/</targetPath>
</resource>
<resource>
<directory>src/main/resources</directory>
<targetPath>META-INF/resources/</targetPath>
@@ -126,103 +135,5 @@
<filtering>false</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.2</version>
<configuration>
<aggregate>true</aggregate>
</configuration>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<skipTests>${skipTests}</skipTests>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>release</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.2</version>
<configuration>
<aggregate>true</aggregate>
</configuration>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@@ -1,6 +1,5 @@
package com.zyplayer.doc.db.controller;
import cn.hutool.core.util.ZipUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zyplayer.doc.core.annotation.AuthMan;
import com.zyplayer.doc.core.exception.ConfirmException;
@@ -17,30 +16,28 @@ import com.zyplayer.doc.data.utils.CacheUtil;
import com.zyplayer.doc.db.controller.vo.DatabaseExportVo;
import com.zyplayer.doc.db.controller.vo.TableColumnVo;
import com.zyplayer.doc.db.controller.vo.TableColumnVo.TableInfoVo;
import com.zyplayer.doc.db.controller.vo.TableDdlVo;
import com.zyplayer.doc.db.controller.vo.TableStatusVo;
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.DatabaseFactoryBean.DatabaseProduct;
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.mysql.MysqlMapper;
import com.zyplayer.doc.db.framework.db.enums.DatabaseProductEnum;
import com.zyplayer.doc.db.framework.json.DocDbResponseJson;
import com.zyplayer.doc.db.framework.utils.PoiUtil;
import org.apache.commons.collections.CollectionUtils;
import com.zyplayer.doc.db.service.DatabaseServiceFactory;
import com.zyplayer.doc.db.service.DbBaseService;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.web.bind.annotation.GetMapping;
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 javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* 文档控制器
@@ -59,6 +56,8 @@ public class DatabaseDocController {
DbDatasourceService dbDatasourceService;
@Resource
UserAuthService userAuthService;
@Resource
DatabaseServiceFactory databaseServiceFactory;
@PostMapping(value = "/getDataSourceList")
public ResponseJson getDataSourceList() {
@@ -84,206 +83,111 @@ public class DatabaseDocController {
}
/**
* 获取编辑器所需的所有信息,用于自动补全
* 此接口会返回所有库表结构,介意的话请自己手动屏蔽调此接口
*
* @param sourceId
* @return
* 获取数据源基本信息
* @param sourceId 数据源ID
* @return 基本信息
*/
@PostMapping(value = "/getEditorData")
public ResponseJson getEditorData(Long sourceId) {
// 没权限,返回空
if (!DocUserUtil.haveAuth(DocAuthConst.DB_DATASOURCE_MANAGE)
&& !DocUserUtil.haveCustomAuth(DbAuthType.VIEW.getName(), DocAuthConst.DB + sourceId)) {
return DocDbResponseJson.ok();
}
String cacheKey = CachePrefix.DB_EDITOR_DATA_CACHE + sourceId;
Object resultObj = CacheUtil.get(cacheKey);
if (resultObj != null) {
return DocDbResponseJson.ok(resultObj);
}
BaseMapper baseMapper = this.getBaseMapper(sourceId);
DatabaseFactoryBean databaseFactoryBean = databaseRegistrationBean.getOrCreateFactoryById(sourceId);
List<DatabaseInfoDto> dbNameDtoList = baseMapper.getDatabaseList();
Map<String, List<TableInfoDto>> dbTableMap = new HashMap<>();
Map<String, List<TableColumnDescDto>> tableColumnsMap = new HashMap<>();
Map<String, List<TableInfoDto>> tableMapList = new HashMap<>();
// MYSQL可以一次性查询所有库表
if (databaseFactoryBean.getDatabaseProduct() == DatabaseProduct.MYSQL) {
List<TableInfoDto> dbTableList = baseMapper.getTableList(null);
tableMapList = dbTableList.stream().collect(Collectors.groupingBy(TableInfoDto::getDbName));
}
for (DatabaseInfoDto infoDto : dbNameDtoList) {
List<TableInfoDto> tableInfoDtoList = tableMapList.get(infoDto.getDbName());
// SQLSERVER必须要库才能查
if (databaseFactoryBean.getDatabaseProduct() == DatabaseProduct.SQLSERVER) {
tableInfoDtoList = baseMapper.getTableList(infoDto.getDbName());
}
if (CollectionUtils.isEmpty(tableInfoDtoList)) {
continue;
}
dbTableMap.put(infoDto.getDbName(), tableInfoDtoList);
// 小于10个库查所有库否则只查询当前链接的库防止库表太多数据量太大
// 如果觉得没必要就自己改吧!
Map<String, List<TableColumnDescDto>> columnDescDtoMap = new HashMap<>();
if (dbNameDtoList.size() <= 10 || Objects.equals(databaseFactoryBean.getDbName(), infoDto.getDbName())) {
List<TableColumnDescDto> columnDescDto = baseMapper.getTableColumnList(infoDto.getDbName(), null);
columnDescDtoMap = columnDescDto.stream().collect(Collectors.groupingBy(TableColumnDescDto::getTableName));
}
for (TableInfoDto tableInfoDto : tableInfoDtoList) {
List<TableColumnDescDto> descDtoList = columnDescDtoMap.get(tableInfoDto.getTableName());
if (CollectionUtils.isNotEmpty(descDtoList)) {
tableColumnsMap.put(tableInfoDto.getTableName(), descDtoList);
}
}
}
@PostMapping(value = "/getSourceBaseInfo")
public ResponseJson getSourceBaseInfo(Long sourceId) {
DbBaseService dbBaseService = databaseServiceFactory.getDbBaseService(sourceId);
Map<String, Object> dbResultMap = new HashMap<>();
dbResultMap.put("db", dbNameDtoList);
dbResultMap.put("table", dbTableMap);
dbResultMap.put("column", tableColumnsMap);
// 缓存10分钟如果10分钟内库里面增删改了表或字段则提示不出来
CacheUtil.put(cacheKey, dbResultMap, 6000);
dbResultMap.put("product", dbBaseService.getDatabaseProduct().name().toLowerCase());
return DocDbResponseJson.ok(dbResultMap);
}
@PostMapping(value = "/getTableDdl")
public ResponseJson getTableDdl(Long sourceId, String dbName, String tableName) {
BaseMapper baseMapper = this.getViewAuthBaseMapper(sourceId);
Map<String, String> dataMap = baseMapper.getTableDdl(dbName, tableName);
DatabaseFactoryBean databaseFactoryBean = databaseRegistrationBean.getOrCreateFactoryById(sourceId);
// 不同数据源类型获取方式不一致
if (Objects.equals(DatabaseProduct.MYSQL, databaseFactoryBean.getDatabaseProduct())) {
return DocDbResponseJson.ok(dataMap.get("Create Table"));
}
return DocDbResponseJson.ok("暂未支持的数据库类型");
DbBaseService dbBaseService = databaseServiceFactory.getDbBaseService(sourceId);
TableDdlVo tableDdlVo = dbBaseService.getTableDdl(sourceId, dbName, tableName);
return DocDbResponseJson.ok(tableDdlVo);
}
@PostMapping(value = "/getDatabaseList")
public ResponseJson getDatabaseList(Long sourceId) {
BaseMapper baseMapper = this.getViewAuthBaseMapper(sourceId);
List<DatabaseInfoDto> dbNameDtoList = baseMapper.getDatabaseList();
return DocDbResponseJson.ok(dbNameDtoList);
DbBaseService dbBaseService = databaseServiceFactory.getDbBaseService(sourceId);
List<DatabaseInfoDto> databaseList = dbBaseService.getDatabaseList(sourceId);
return DocDbResponseJson.ok(databaseList);
}
@PostMapping(value = "/getTableStatus")
public ResponseJson getTableStatus(Long sourceId, String dbName, String tableName) {
BaseMapper baseMapper = this.getViewAuthBaseMapper(sourceId);
TableStatusVo tableStatusVo = baseMapper.getTableStatus(dbName, tableName);
DatabaseFactoryBean factoryBean = databaseRegistrationBean.getOrCreateFactoryById(sourceId);
tableStatusVo.setDbType(factoryBean.getDatabaseProduct().name().toLowerCase());
DbBaseService dbBaseService = databaseServiceFactory.getDbBaseService(sourceId);
TableStatusVo tableStatusVo = dbBaseService.getTableStatus(sourceId, dbName, tableName);
return DocDbResponseJson.ok(tableStatusVo);
}
@PostMapping(value = "/getTableList")
public ResponseJson getTableList(Long sourceId, String dbName) {
BaseMapper baseMapper = this.getBaseMapper(sourceId);
List<TableInfoDto> dbTableList = baseMapper.getTableList(dbName);
return DocDbResponseJson.ok(dbTableList);
DbBaseService dbBaseService = databaseServiceFactory.getDbBaseService(sourceId);
List<TableInfoDto> tableList = dbBaseService.getTableList(sourceId, dbName);
return DocDbResponseJson.ok(tableList);
}
@PostMapping(value = "/getTableColumnList")
public ResponseJson getTableColumnList(Long sourceId, String dbName, String tableName) {
this.judgeAuth(sourceId, DbAuthType.VIEW.getName(), "没有查看该库表信息的权限");
DatabaseFactoryBean databaseFactoryBean = databaseRegistrationBean.getOrCreateFactoryById(sourceId);
if (databaseFactoryBean == null) {
return DocDbResponseJson.warn("未找到对应的数据库连接");
}
TableColumnVo tableColumnVo = this.getTableColumnVo(databaseFactoryBean, dbName, tableName);
DbBaseService dbBaseService = databaseServiceFactory.getDbBaseService(sourceId);
TableColumnVo tableColumnVo = dbBaseService.getTableColumnList(sourceId, dbName, tableName);
return DocDbResponseJson.ok(tableColumnVo);
}
@PostMapping(value = "/getTableColumnDescList")
public ResponseJson getTableColumnDescList(Long sourceId, String tableName) {
BaseMapper baseMapper = this.getViewAuthBaseMapper(sourceId);
List<TableColumnDescDto> columnDescDto = baseMapper.getTableColumnDescList(tableName);
return DocDbResponseJson.ok(columnDescDto);
}
@PostMapping(value = "/getTableAndColumnBySearch")
public ResponseJson getTableAndColumnBySearch(Long sourceId, String dbName, String searchText) {
BaseMapper baseMapper = this.getViewAuthBaseMapper(sourceId);
if (StringUtils.isBlank(searchText)) {
return DocDbResponseJson.ok();
}
searchText = "%" + searchText + "%";
List<QueryTableColumnDescDto> columnDescDto = baseMapper.getTableAndColumnBySearch(dbName, searchText);
DbBaseService dbBaseService = databaseServiceFactory.getDbBaseService(sourceId);
List<QueryTableColumnDescDto> columnDescDto = dbBaseService.getTableAndColumnBySearch(sourceId, dbName, searchText);
return DocDbResponseJson.ok(columnDescDto);
}
@PostMapping(value = "/getTableDescList")
public ResponseJson getTableDescList(Long sourceId, String dbName, String tableName) {
BaseMapper baseMapper = this.getViewAuthBaseMapper(sourceId);
List<TableDescDto> columnDescDto = baseMapper.getTableDescList(dbName, tableName);
return DocDbResponseJson.ok(columnDescDto);
DbBaseService dbBaseService = databaseServiceFactory.getDbBaseService(sourceId);
List<TableDescDto> tableDescList = dbBaseService.getTableDescList(sourceId, dbName, tableName);
return DocDbResponseJson.ok(tableDescList);
}
@PostMapping(value = "/updateTableDesc")
public ResponseJson updateTableDesc(Long sourceId, String dbName, String tableName, String newDesc) {
this.judgeAuth(sourceId, DbAuthType.DESC_EDIT.getName(), "没有修改该表注释的权限");
BaseMapper baseMapper = this.getBaseMapper(sourceId);
baseMapper.updateTableDesc(dbName, tableName, newDesc);
DbBaseService dbBaseService = databaseServiceFactory.getDbBaseService(sourceId);
dbBaseService.updateTableDesc(sourceId, dbName, tableName, newDesc);
return DocDbResponseJson.ok();
}
@PostMapping(value = "/updateTableColumnDesc")
public ResponseJson updateTableColumnDesc(Long sourceId, String dbName, String tableName, String columnName, String newDesc) {
this.judgeAuth(sourceId, DbAuthType.DESC_EDIT.getName(), "没有修改该表字段注释的权限");
BaseMapper baseMapper = this.getBaseMapper(sourceId);
ColumnInfoDto columnInfo = null;
// mysql要同时修改类型默认值等所以先查出来
MysqlMapper mysqlMapper = databaseRegistrationBean.getBaseMapper(sourceId, MysqlMapper.class);
if (mysqlMapper != null) {
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);
DbBaseService dbBaseService = databaseServiceFactory.getDbBaseService(sourceId);
dbBaseService.updateTableColumnDesc(sourceId, dbName, tableName, columnName, newDesc);
return DocDbResponseJson.ok();
}
@PostMapping(value = "/exportDatabase")
public ResponseJson exportDatabase(HttpServletResponse response, Long sourceId, String dbName, String tableNames, Integer exportType) {
this.judgeAuth(sourceId, DbAuthType.VIEW.getName(), "没有查看该库表信息的权限");
public ResponseJson exportDatabase(HttpServletResponse response, Long sourceId, String dbName, String tableNames, Integer exportType, Integer exportFormat) {
if (StringUtils.isBlank(tableNames)) {
return DocDbResponseJson.warn("请选择需要导出的表");
}
DatabaseFactoryBean databaseFactoryBean = databaseRegistrationBean.getOrCreateFactoryById(sourceId);
if (databaseFactoryBean == null) {
return DocDbResponseJson.warn("未找到对应的数据库连接");
List<String> tableNameList = Stream.of(tableNames.split(",")).filter(StringUtils::isNotBlank).collect(Collectors.toList());
if (Objects.equals(exportType, 1)) {
return this.exportForTableDoc(response, sourceId, dbName, tableNameList, exportFormat);
} else if (Objects.equals(exportType, 2)) {
return this.exportForTableDdl(response, sourceId, dbName, tableNameList, exportFormat);
}
List<TableInfoVo> tableList = new LinkedList<>();
Map<String, List<TableColumnDescDto>> columnList = new HashMap<>();
String[] tableNameArr = tableNames.split(",");
for (String tableName : tableNameArr) {
if (StringUtils.isBlank(tableName)) {
continue;
}
TableColumnVo tableColumnVo = this.getTableColumnVo(databaseFactoryBean, dbName, tableName);
columnList.put(tableName, tableColumnVo.getColumnList());
tableList.add(tableColumnVo.getTableInfo());
return DocDbResponseJson.ok();
}
private DocDbResponseJson exportForTableDdl(HttpServletResponse response, Long sourceId, String dbName, List<String> tableNameList, Integer exportFormat) {
DbBaseService dbBaseService = databaseServiceFactory.getDbBaseService(sourceId);
Map<String, String> ddlSqlMap = new HashMap<>();
for (String tableName : tableNameList) {
TableDdlVo tableDdlVo = dbBaseService.getTableDdl(sourceId, dbName, tableName);
ddlSqlMap.put(tableName, tableDdlVo.getTableDDLByType());
}
DatabaseExportVo exportVo = new DatabaseExportVo();
exportVo.setColumnList(columnList);
exportVo.setTableList(tableList);
try {
if (Objects.equals(exportType, 1)) {
PoiUtil.exportByText(exportVo, response);
} else if (Objects.equals(exportType, 2)) {
PoiUtil.exportByXlsx(exportVo, response);
} else if (Objects.equals(exportType, 3)) {
PoiUtil.exportByDocx(dbName, exportVo, response);
} else {
return DocDbResponseJson.error("导出失败:请先选择导出类型");
}
DatabaseFactoryBean databaseFactoryBean = databaseRegistrationBean.getOrCreateFactoryById(sourceId);
DatabaseProductEnum databaseProduct = databaseFactoryBean.getDatabaseProduct();
PoiUtil.exportByDdl(ddlSqlMap, dbName, databaseProduct.name(), response);
} catch (Exception e) {
e.printStackTrace();
return DocDbResponseJson.error("导出失败:" + e.getMessage());
@@ -291,37 +195,30 @@ public class DatabaseDocController {
return DocDbResponseJson.ok();
}
private TableColumnVo getTableColumnVo(DatabaseFactoryBean databaseFactoryBean, String dbName, String tableName) {
SqlSessionTemplate sessionTemplate = databaseFactoryBean.getSqlSessionTemplate();
BaseMapper baseMapper = sessionTemplate.getMapper(BaseMapper.class);
List<TableColumnDescDto> columnDescDto = baseMapper.getTableColumnList(dbName, tableName);
// SQLSERVER要单独查字段注释
if (databaseFactoryBean.getDatabaseProduct() == DatabaseProduct.SQLSERVER) {
List<TableColumnDescDto> columnDescList = baseMapper.getTableColumnDescList(tableName);
Map<String, TableColumnDescDto> columnMap = columnDescDto.stream().collect(Collectors.toMap(TableColumnDescDto::getName, val -> val));
// 字段注释
for (TableColumnDescDto descDto : columnDescList) {
TableColumnDescDto tempDesc = columnMap.get(descDto.getName());
if (tempDesc != null) {
tempDesc.setDescription(descDto.getDescription());
}
private DocDbResponseJson exportForTableDoc(HttpServletResponse response, Long sourceId, String dbName, List<String> tableNameList, Integer exportFormat) {
DbBaseService dbBaseService = databaseServiceFactory.getDbBaseService(sourceId);
// 数据组装
List<TableInfoVo> tableList = new LinkedList<>();
Map<String, List<TableColumnDescDto>> columnList = new HashMap<>();
for (String tableName : tableNameList) {
TableColumnVo tableColumnVo = dbBaseService.getTableColumnList(sourceId, dbName, tableName);
columnList.put(tableName, tableColumnVo.getColumnList());
tableList.add(tableColumnVo.getTableInfo());
}
try {
DatabaseExportVo exportVo = new DatabaseExportVo(columnList, tableList);
if (Objects.equals(exportFormat, 1)) {
PoiUtil.exportByText(exportVo, response);
} else if (Objects.equals(exportFormat, 2)) {
PoiUtil.exportByXlsx(exportVo, response);
} else if (Objects.equals(exportFormat, 3)) {
PoiUtil.exportByDocx(dbName, exportVo, response);
}
return DocDbResponseJson.error("导出失败:请先选择导出类型");
} catch (Exception e) {
e.printStackTrace();
return DocDbResponseJson.error("导出失败:" + e.getMessage());
}
TableColumnVo tableColumnVo = new TableColumnVo();
tableColumnVo.setColumnList(columnDescDto);
// 表注释
TableInfoVo tableInfoVo = new TableInfoVo();
List<TableDescDto> tableDescList = baseMapper.getTableDescList(dbName, tableName);
String description = null;
if (tableDescList.size() > 0) {
TableDescDto descDto = tableDescList.get(0);
description = descDto.getDescription();
}
description = Optional.ofNullable(description).orElse("");
tableInfoVo.setDescription(description);
tableInfoVo.setTableName(tableName);
tableColumnVo.setTableInfo(tableInfoVo);
return tableColumnVo;
}
/**
@@ -335,35 +232,5 @@ public class DatabaseDocController {
throw new ConfirmException(noAuthInfo);
}
}
/**
* 获取BaseMapper
*
* @author 暮光:城中城
*/
private BaseMapper getBaseMapper(Long sourceId) {
BaseMapper baseMapper = databaseRegistrationBean.getBaseMapperById(sourceId);
if (baseMapper == null) {
throw new ConfirmException("未找到对应的数据库连接");
}
return baseMapper;
}
/**
* 判断查看权和获取BaseMapper
*
* @author 暮光:城中城
*/
private BaseMapper getViewAuthBaseMapper(Long sourceId) {
this.judgeAuth(sourceId, DbAuthType.VIEW.getName(), "没有查看该库表信息的权限");
return this.getBaseMapper(sourceId);
}
public static void main(String[] args) {
//File zipFile = ZipUtil.zip("d:/aaa");
File zipFile = new File("d:/111.zip");
ZipUtil.zip(zipFile, true, new File("d:/111.txt"),
new File("d:/222.txt"), new File("d:/aaa"));
}
}

View File

@@ -91,6 +91,11 @@ public class DbDataSourceAuthController {
UserAuth userAuth = this.createUserAuth(sourceId, currentUser.getUserId(), authVo.getUserId(), authId);
userAuthList.add(userAuth);
}
if (Objects.equals(authVo.getProcEditAuth(), 1)) {
Long authId = authInfoMap.get(DbAuthType.PROC_EDIT.getName());
UserAuth userAuth = this.createUserAuth(sourceId, currentUser.getUserId(), authVo.getUserId(), authId);
userAuthList.add(userAuth);
}
if (userAuthList.size() <= 0) {
continue;
}
@@ -121,7 +126,6 @@ public class DbDataSourceAuthController {
userAuthGroup.forEach((key, value) -> {
Set<String> authNameSet = value.stream().map(auth -> authInfoMap.get(auth.getAuthId())).collect(Collectors.toSet());
UserDbAuthVo authVo = new UserDbAuthVo();
authVo.setExecuteAuth(0);
if (this.haveAuth(authNameSet, DbAuthType.UPDATE) == 1) {
authVo.setExecuteAuth(3);
} else if (this.haveAuth(authNameSet, DbAuthType.SELECT) == 1) {
@@ -130,6 +134,7 @@ public class DbDataSourceAuthController {
authVo.setExecuteAuth(1);
}
authVo.setDescEditAuth(this.haveAuth(authNameSet, DbAuthType.DESC_EDIT));
authVo.setProcEditAuth(this.haveAuth(authNameSet, DbAuthType.PROC_EDIT));
authVo.setUserId(key);
authVo.setUserName(userInfoMap.get(key));
authVoList.add(authVo);

View File

@@ -0,0 +1,251 @@
package com.zyplayer.doc.db.controller;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.util.TypeUtils;
import com.zyplayer.doc.core.annotation.AuthMan;
import com.zyplayer.doc.core.exception.ConfirmException;
import com.zyplayer.doc.core.json.ResponseJson;
import com.zyplayer.doc.core.util.StringUtil;
import com.zyplayer.doc.core.util.ZyplayerDocVersion;
import com.zyplayer.doc.data.config.security.DocUserUtil;
import com.zyplayer.doc.data.repository.support.consts.DocAuthConst;
import com.zyplayer.doc.db.controller.param.DataViewParam;
import com.zyplayer.doc.db.controller.vo.TableColumnVo;
import com.zyplayer.doc.db.framework.consts.DbAuthType;
import com.zyplayer.doc.db.framework.db.dto.TableColumnDescDto;
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.base.SqlExecutor;
import com.zyplayer.doc.db.framework.json.DocDbResponseJson;
import com.zyplayer.doc.db.framework.utils.JSONUtil;
import com.zyplayer.doc.db.service.DatabaseServiceFactory;
import com.zyplayer.doc.db.service.DbBaseService;
import com.zyplayer.doc.db.service.download.BaseDownloadService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
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 javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* 表数据查看控制器
*
* @author 暮光:城中城
* @since 2021年5月16日
*/
@AuthMan
@RestController
@RequestMapping("/zyplayer-doc-db/data-view")
public class DbDataViewController {
private static Logger logger = LoggerFactory.getLogger(DbDataViewController.class);
@Resource
SqlExecutor sqlExecutor;
@Resource
DatabaseServiceFactory databaseServiceFactory;
@Resource
BaseDownloadService baseDownloadService;
// 最大允许导出的行数设置的过大有可能会导致内存溢出默认10W条
@Value("${zyplayer.doc.db.download-max-row:100000}")
Integer downloadMaxRow;
@PostMapping(value = "/query")
public ResponseJson query(DataViewParam param) {
// 数据查询
ExecuteType executeType = this.getExecuteType(param.getSourceId());
DbBaseService dbBaseService = databaseServiceFactory.getDbBaseService(param.getSourceId());
String queryPageSql = dbBaseService.getQueryPageSql(param);
ExecuteResult executeResult = this.query(param.getSourceId(), param.getExecuteId(), executeType, queryPageSql);
// 数据组装
List<String> resultList = new LinkedList<>();
resultList.add(JSON.toJSONString(executeResult, JSONUtil.serializeConfig, SerializerFeature.WriteMapNullValue));
DocDbResponseJson responseJson = DocDbResponseJson.ok(resultList);
// 计算总条数,第一页才查询总条数
if (CollectionUtils.isNotEmpty(executeResult.getResult()) && Objects.equals(param.getPageNum(), 1)) {
responseJson.setTotal((long) executeResult.getResult().size());
if (executeResult.getResult().size() >= param.getPageSize()) {
responseJson.setTotal(this.getDataCount(param, executeType));
}
}
return responseJson;
}
/**
* 单表数据下载
*
* @param response
* @param param
* @return
*/
@PostMapping(value = "/download")
public ResponseJson download(HttpServletResponse response, DataViewParam param) {
param.setExecuteId(RandomUtil.simpleUUID());
ExecuteType executeType = this.getExecuteType(param.getSourceId());
DbBaseService dbBaseService = databaseServiceFactory.getDbBaseService(param.getSourceId());
if (this.getDataCount(param, executeType) > downloadMaxRow) {
return DocDbResponseJson.error(String.format("导出失败,表:%s 数据行数超过最大导出配置 %s请联系管理员修改", param.getTableName(), downloadMaxRow));
}
// 获取列信息等
TableColumnVo tableColumnVo = dbBaseService.getTableColumnList(param.getSourceId(), param.getDbName(), param.getTableName());
Set<String> conditionSet = StringUtils.isBlank(param.getConditionColumn()) ? Collections.emptySet() : Stream.of(param.getConditionColumn().split(",")).collect(Collectors.toSet());
Set<String> retainColumnSet = StringUtils.isBlank(param.getRetainColumn()) ? Collections.emptySet() : Stream.of(param.getRetainColumn().split(",")).collect(Collectors.toSet());
List<TableColumnDescDto> columnList = tableColumnVo.getColumnList().stream().filter(item -> retainColumnSet.isEmpty() || retainColumnSet.contains(item.getName())).collect(Collectors.toList());
// 数据查询
String queryAllSql = dbBaseService.getQueryAllSql(param);
ExecuteParam executeParam = new ExecuteParam();
executeParam.setDatasourceId(param.getSourceId());
executeParam.setExecuteId(param.getExecuteId());
executeParam.setExecuteType(executeType);
executeParam.setSql(queryAllSql);
try {
dbBaseService.downloadSingleTableData(response, param, executeParam, columnList, conditionSet);
} catch (Exception e) {
return DocDbResponseJson.error("导出失败:" + e.getMessage());
}
return DocDbResponseJson.ok();
}
/**
* 多表下载
*
* @param response
* @param param
* @return
*/
@PostMapping(value = "/downloadMultiple")
public ResponseJson downloadMultiple(HttpServletResponse response, DataViewParam param) {
DbBaseService dbBaseService = databaseServiceFactory.getDbBaseService(param.getSourceId());
if (StringUtils.isBlank(param.getTableNames())) {
return DocDbResponseJson.warn("请选择导出的表");
}
param.setExecuteId(IdUtil.simpleUUID());
String tempDir = System.getProperty("java.io.tmpdir");
boolean multipleFile = Objects.equals(param.getDownloadFileType(), 2);
boolean isJson = Objects.equals(param.getDownloadType(), "json");
StringBuilder resultSb = new StringBuilder("/*\n" +
" zyplayer-doc 表数据导出\n" +
"\n" +
" 数据库 : " + param.getDbName() + "\n" +
" 数据库类型 : " + dbBaseService.getDatabaseProduct().name() + "\n" +
" 导出时间 : " + DateTime.now().toString() + "\n" +
" 软件版本 : " + ZyplayerDocVersion.version + "\n" +
"*/\n\n");
String[] tableNameArr = param.getTableNames().split(",");
String tempDirName = tempDir + "zyplayer-doc-" + IdUtil.fastSimpleUUID();
try {
// 先校验总条数是否超过限制
for (String tableName : tableNameArr) {
param.setTableName(tableName);
ExecuteType executeType = this.getExecuteType(param.getSourceId());
if (this.getDataCount(param, executeType) > downloadMaxRow) {
return DocDbResponseJson.error(String.format("导出失败,表:%s 数据行数超过最大导出配置 %s请联系管理员修改", tableName, downloadMaxRow));
}
}
// 创建临时文件夹
FileUtil.mkdir(tempDirName);
// 再分表查数据
String suffix = isJson ? ".json" : ".sql";
for (String tableName : tableNameArr) {
param.setTableName(tableName);
ExecuteType executeType = this.getExecuteType(param.getSourceId());
// 获取列信息等
TableColumnVo tableColumnVo = dbBaseService.getTableColumnList(param.getSourceId(), param.getDbName(), tableName);
List<TableColumnDescDto> columnList = tableColumnVo.getColumnList();
// 找主键作为更新条件
Set<String> conditionSet = columnList.stream().filter(item -> Objects.equals(item.getPrimaryKey(), "1")).map(TableColumnDescDto::getName).collect(Collectors.toSet());
// 数据查询
String queryAllSql = dbBaseService.getQueryAllSql(param);
ExecuteParam executeParam = new ExecuteParam();
executeParam.setDatasourceId(param.getSourceId());
executeParam.setExecuteId(param.getExecuteId());
executeParam.setExecuteType(executeType);
executeParam.setSql(queryAllSql);
String downloadTableData = dbBaseService.getDownloadTableData(param, executeParam, columnList, conditionSet);
// 写入临时文件
if (multipleFile) {
File tempFile = FileUtil.file(tempDirName + "/" + tableName + suffix);
String tableDataSb = isJson ? downloadTableData : String.format("-- 导出数据表:`%s`.`%s` --\n", param.getDbName(), tableName) + downloadTableData;
FileUtil.writeUtf8String(tableDataSb, tempFile);
} else {
resultSb.append(String.format("-- 导出数据表:`%s`.`%s` --\n", param.getDbName(), tableName));
resultSb.append(downloadTableData).append("\n");
}
}
if (multipleFile) {
baseDownloadService.sendResponse(response, param.getDbName(), tempDirName);
} else {
baseDownloadService.sendResponse(response, param.getDbName(), suffix, resultSb.toString());
}
} catch (Exception e) {
e.printStackTrace();
return DocDbResponseJson.error("导出失败:" + e.getMessage());
} finally {
FileUtil.del(tempDirName);
}
return DocDbResponseJson.ok();
}
private Long getDataCount(DataViewParam param, ExecuteType executeType) {
DbBaseService dbBaseService = databaseServiceFactory.getDbBaseService(param.getSourceId());
String queryCountSql = dbBaseService.getQueryCountSql(param);
ExecuteResult countResult = this.query(param.getSourceId(), param.getExecuteId(), executeType, queryCountSql);
if (CollectionUtils.isNotEmpty(countResult.getResult()) && MapUtils.isNotEmpty(countResult.getResult().get(0))) {
Map<String, Object> countMap = countResult.getResult().get(0);
Optional<Object> countAny = countMap.values().stream().findAny();
return TypeUtils.castToLong(countAny.orElse(0));
}
return 0L;
}
/**
* 执行数据查询
*
* @param sourceId
* @param executeId
* @param executeType
* @param executeSql
* @return
*/
private ExecuteResult query(Long sourceId, String executeId, ExecuteType executeType, String executeSql) {
try {
ExecuteParam executeParam = new ExecuteParam();
executeParam.setDatasourceId(sourceId);
executeParam.setExecuteId(executeId);
executeParam.setExecuteType(executeType);
executeParam.setSql(executeSql);
executeParam.setMaxRows(1000);
return sqlExecutor.execute(executeParam);
} catch (Exception e) {
logger.error("执行出错", e);
return ExecuteResult.error(StringUtil.getException(e), executeSql);
}
}
private ExecuteType getExecuteType(Long sourceId) {
boolean manageAuth = DocUserUtil.haveAuth(DocAuthConst.DB_DATASOURCE_MANAGE);
boolean select = DocUserUtil.haveCustomAuth(DbAuthType.SELECT.getName(), DocAuthConst.DB + sourceId);
boolean update = DocUserUtil.haveCustomAuth(DbAuthType.UPDATE.getName(), DocAuthConst.DB + sourceId);
if (!manageAuth && !select && !update) {
throw new ConfirmException("没有该数据源的执行权限");
}
return (manageAuth || update) ? ExecuteType.ALL : ExecuteType.SELECT;
}
}

View File

@@ -1,17 +1,22 @@
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.exception.ConfirmException;
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;
import com.zyplayer.doc.db.framework.db.bean.DatabaseFactoryBean;
import com.zyplayer.doc.db.framework.db.bean.DatabaseRegistrationBean;
import com.zyplayer.doc.db.framework.json.DocDbResponseJson;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.springframework.web.bind.annotation.PostMapping;
@@ -20,6 +25,7 @@ import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
/**
* 数据源控制器
@@ -38,16 +44,34 @@ 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.isNotNull("group_name");
wrapper.select("group_name");
wrapper.groupBy("group_name");
List<DbDatasource> datasourceList = dbDatasourceService.list(wrapper);
if (CollectionUtils.isEmpty(datasourceList)) {
return DocDbResponseJson.ok();
}
Set<String> groupNameSet = datasourceList.stream().map(DbDatasource::getGroupName).filter(StringUtils::isNotBlank).collect(Collectors.toSet());
return DocDbResponseJson.ok(groupNameSet);
}
@PostMapping(value = "/test")
public ResponseJson test(DbDatasource dbDatasource) {
// 验证新的数据源
@@ -60,10 +84,9 @@ public class DbDatasourceController {
}
}
DatabaseFactoryBean databaseFactoryBean = DatasourceUtil.createDatabaseFactoryBean(dbDatasource, true);
if (databaseFactoryBean == null) {
return DocDbResponseJson.warn("获取数据源失败,请检查配置是否正确");
}
databaseFactoryBean.getDataSource().close();
} catch (ConfirmException e) {
return DocDbResponseJson.warn(e.getMessage());
} catch (Exception e) {
e.printStackTrace();
return DocDbResponseJson.warn(ExceptionUtils.getFullStackTrace(e));

View File

@@ -0,0 +1,220 @@
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.exception.ConfirmException;
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.DbProcLog;
import com.zyplayer.doc.data.repository.support.consts.DocAuthConst;
import com.zyplayer.doc.data.service.manage.DbProcLogService;
import com.zyplayer.doc.db.controller.param.ProcedureListParam;
import com.zyplayer.doc.db.framework.consts.DbAuthType;
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.DatabaseServiceFactory;
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.Date;
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
DatabaseServiceFactory databaseServiceFactory;
@Resource
DbProcLogService dbProcLogService;
/**
* 存储过程列表
*
* @param procedureParam 参数
* @return 列表
*/
@PostMapping(value = "/list")
public ResponseJson list(ProcedureListParam procedureParam) {
try {
DbBaseService dbBaseService = databaseServiceFactory.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;
} catch (Exception e) {
// 一般是数据库的帐号没权限查存储过程
return DocDbResponseJson.error(e.getMessage());
}
}
/**
* 获取函数详情
*
* @param sourceId 数据源ID
* @param dbName 数据库名
* @param typeName 类型名
* @param procName 函数名
* @return 详情
*/
@PostMapping(value = "/detail")
public ResponseJson detail(Long sourceId, String dbName, String typeName, String procName) {
DbBaseService dbBaseService = databaseServiceFactory.getDbBaseService(sourceId);
try {
ProcedureDto procedureDto = dbBaseService.getProcedureDetail(sourceId, dbName, typeName, procName);
return DocDbResponseJson.ok(procedureDto);
} catch (Exception e) {
// 一般是数据库的帐号没权限查存储过程
return DocDbResponseJson.error(e.getMessage());
}
}
/**
* 删除函数
*
* @param sourceId 数据源ID
* @param dbName 数据库名
* @param typeName 类型名
* @param procName 函数名
* @return 结果
*/
@PostMapping(value = "/delete")
public ResponseJson delete(Long sourceId, String dbName, String typeName, String procName) {
this.judgeAuth(sourceId, DbAuthType.PROC_EDIT.getName(), "没有修改该库函数的权限");
DbProcLog dbProcLog = this.createDbProcLog(sourceId, dbName, typeName, procName, "删除函数操作");
try {
DbBaseService dbBaseService = databaseServiceFactory.getDbBaseService(sourceId);
dbBaseService.deleteProcedure(sourceId, dbName, typeName, procName);
return DocDbResponseJson.ok();
} catch (Exception e) {
dbProcLog.setStatus(2);
// 一般是数据库的帐号没权限查存储过程
return DocDbResponseJson.error(e.getMessage());
} finally {
dbProcLogService.save(dbProcLog);
}
}
/**
* 保存函数
*
* @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) {
this.judgeAuth(sourceId, DbAuthType.PROC_EDIT.getName(), "没有修改该库函数的权限");
DbProcLog dbProcLog = this.createDbProcLog(sourceId, dbName, typeName, procName, procSql);
try {
DbBaseService dbBaseService = databaseServiceFactory.getDbBaseService(sourceId);
ExecuteResult executeResult = dbBaseService.saveProcedure(sourceId, dbName, typeName, procName, procSql);
if (StringUtils.isNotBlank(executeResult.getErrMsg())) {
dbProcLog.setStatus(2);
}
return DocDbResponseJson.ok(executeResult);
} catch (Exception e) {
dbProcLog.setStatus(2);
// 一般是数据库的帐号没权限查存储过程
return DocDbResponseJson.error(e.getMessage());
} finally {
dbProcLogService.save(dbProcLog);
}
}
/**
* 存储过程修改日志列表
*
* @param sourceId 数据源ID
* @param dbName 数据库名
* @param typeName 类型名
* @param procName 函数名
* @return 列表
*/
@PostMapping(value = "/log/list")
public ResponseJson logList(Integer pageNum, Integer pageSize, Long sourceId, String dbName, String typeName, String procName) {
QueryWrapper<DbProcLog> wrapper = new QueryWrapper<>();
wrapper.eq("datasource_id", sourceId);
wrapper.eq("proc_db", dbName);
wrapper.eq("proc_name", procName);
wrapper.eq("proc_type", typeName);
wrapper.orderByDesc("id");
wrapper.select("id", "proc_body", "create_user_name", "create_time", "status");
IPage<DbProcLog> page = new Page<>(pageNum, pageSize, pageNum == 1);
dbProcLogService.page(page, wrapper);
return DocDbResponseJson.ok(page);
}
/**
* 存储过程修改日志详情
*
* @param logId 日志ID
* @return 详情
*/
@PostMapping(value = "/log/detail")
public ResponseJson logDetail(Long logId) {
DbProcLog dbProcLog = dbProcLogService.getById(logId);
return DocDbResponseJson.ok(dbProcLog);
}
/**
* 权限判断
*
* @author 暮光:城中城
*/
private void judgeAuth(Long sourceId, String authName, String noAuthInfo) {
if (!DocUserUtil.haveAuth(DocAuthConst.DB_DATASOURCE_MANAGE)
&& !DocUserUtil.haveCustomAuth(authName, DocAuthConst.DB + sourceId)) {
throw new ConfirmException(noAuthInfo);
}
}
/**
* 创建日志对象
* @param sourceId
* @param dbName
* @param typeName
* @param procName
* @param procSql
* @return
*/
public DbProcLog createDbProcLog(Long sourceId, String dbName, String typeName, String procName, String procSql) {
DocUserDetails currentUser = DocUserUtil.getCurrentUser();
DbProcLog dbProcLog = new DbProcLog();
dbProcLog.setDatasourceId(sourceId);
dbProcLog.setCreateTime(new Date());
dbProcLog.setCreateUserId(currentUser.getUserId());
dbProcLog.setCreateUserName(currentUser.getUsername());
dbProcLog.setProcDb(dbName);
dbProcLog.setProcName(procName);
dbProcLog.setProcType(typeName);
dbProcLog.setProcBody(procSql);
dbProcLog.setStatus(1);
return dbProcLog;
}
}

View File

@@ -1,9 +1,8 @@
package com.zyplayer.doc.db.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.zyplayer.doc.core.annotation.AuthMan;
import com.zyplayer.doc.core.json.ResponseJson;
@@ -20,7 +19,12 @@ 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.base.SqlExecutor;
import com.zyplayer.doc.db.framework.db.transfer.SqlParseUtil;
import com.zyplayer.doc.db.framework.json.DocDbResponseJson;
import com.zyplayer.doc.db.framework.utils.JSONUtil;
import com.zyplayer.doc.db.framework.utils.SqlLogUtil;
import com.zyplayer.doc.db.service.DatabaseServiceFactory;
import com.zyplayer.doc.db.service.DbBaseService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -29,11 +33,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.sql.Timestamp;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.*;
/**
* sql执行器
@@ -53,9 +53,11 @@ public class DbSqlExecutorController {
DbHistoryService dbHistoryService;
@Resource
DbFavoriteService dbFavoriteService;
@Resource
DatabaseServiceFactory databaseServiceFactory;
@PostMapping(value = "/execute")
public ResponseJson execute(Long sourceId, String executeId, String sql, String params) {
public ResponseJson execute(Long sourceId, String executeId, String dbName, String sql, String params) {
if (StringUtils.isBlank(sql)) {
return DocDbResponseJson.warn("执行的SQL不能为空");
}
@@ -65,35 +67,43 @@ public class DbSqlExecutorController {
if (!manageAuth && !select && !update) {
return DocDbResponseJson.warn("没有该数据源的执行权限");
}
DbBaseService dbBaseService = databaseServiceFactory.getDbBaseService(sourceId);
String useDbSql = dbBaseService.getUseDbSql(dbName);
// 保留历史记录
dbHistoryService.saveHistory(sql.trim(), sourceId);
dbHistoryService.saveHistory(sql.trim(), params, sourceId);
// 参数处理
Map<String, Object> paramMap = JSON.parseObject(params);
List<String> resultList = new LinkedList<>();
// 支持;分割的多个sql执行
String[] sqlArr = sql.split(";");
// 执行条数太多,反应慢,展示结果栏太多,也不应该在这一次执行很多条语句,应该使用导入
if (sqlArr.length > 20) {
return DocDbResponseJson.warn("单次执行最多支持20条语句同时执行当前语句条数" + sqlArr.length);
}
for (String sqlItem : sqlArr) {
if (StringUtils.isBlank(sqlItem)) {
continue;
}
sqlItem = sqlItem.trim();
ExecuteResult executeResult;
ExecuteParam executeParam = new ExecuteParam();
try {
ExecuteType executeType = (!manageAuth && select) ? ExecuteType.SELECT : ExecuteType.ALL;
ExecuteParam executeParam = new ExecuteParam();
ExecuteType executeType = (manageAuth || update) ? ExecuteType.ALL : ExecuteType.SELECT;
executeParam = SqlParseUtil.getSingleExecuteParam(sqlItem, paramMap);
executeParam.setDatasourceId(sourceId);
executeParam.setExecuteId(executeId);
executeParam.setExecuteType(executeType);
executeParam.setSql(sqlItem);
executeParam.setPrefixSql(useDbSql);
executeParam.setMaxRows(1000);
ExecuteResult executeResult = sqlExecutor.execute(executeParam);
SerializeConfig mapping = new SerializeConfig();
mapping.put(Date.class, new SimpleDateFormatSerializer("yyyy-MM-dd HH:mm:ss"));
mapping.put(Timestamp.class, new SimpleDateFormatSerializer("yyyy-MM-dd HH:mm:ss"));
String resultJsonStr = JSON.toJSONString(executeResult, mapping, SerializerFeature.WriteMapNullValue);
resultList.add(resultJsonStr);
executeResult = sqlExecutor.execute(executeParam);
} catch (Exception e) {
logger.error("执行出错", e);
ExecuteResult executeResult = ExecuteResult.error(StringUtil.getException(e), sqlItem);
resultList.add(JSON.toJSONString(executeResult));
executeResult = ExecuteResult.error(e.getMessage(), sqlItem);
}
// 执行的sql处理
String executeSqlLog = SqlLogUtil.parseLogSql(executeParam.getSql(), executeParam.getParameterMappings(), executeParam.getParamList());
executeResult.setSql(executeSqlLog);
resultList.add(JSON.toJSONString(executeResult, JSONUtil.serializeConfig, SerializerFeature.WriteMapNullValue));
}
return DocDbResponseJson.ok(resultList);
}
@@ -146,5 +156,6 @@ public class DbSqlExecutorController {
}
return DocDbResponseJson.ok();
}
}

View File

@@ -0,0 +1,140 @@
package com.zyplayer.doc.db.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zyplayer.doc.core.annotation.AuthMan;
import com.zyplayer.doc.core.json.ResponseJson;
import com.zyplayer.doc.data.repository.manage.entity.DbTableRelation;
import com.zyplayer.doc.data.repository.manage.param.TableRelationParam;
import com.zyplayer.doc.data.repository.manage.vo.TableRelationVo;
import com.zyplayer.doc.data.service.manage.DbTableRelationService;
import com.zyplayer.doc.db.controller.vo.TableColumnVo;
import com.zyplayer.doc.db.framework.consts.DbAuthType;
import com.zyplayer.doc.db.framework.db.dto.TableColumnDescDto;
import com.zyplayer.doc.db.framework.json.DocDbResponseJson;
import com.zyplayer.doc.db.service.DatabaseServiceFactory;
import com.zyplayer.doc.db.service.DbBaseService;
import org.apache.commons.collections.CollectionUtils;
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.*;
/**
* 表关系控制器
*
* @author 暮光:城中城
* @since 2021年6月6日
*/
@AuthMan
@RestController
@RequestMapping("/zyplayer-doc-db/table-relation")
public class DbTableRelationController {
private static Logger logger = LoggerFactory.getLogger(DbTableRelationController.class);
@Resource
DatabaseServiceFactory databaseServiceFactory;
@Resource
DbTableRelationService dbTableRelationService;
@PostMapping(value = "/update")
public ResponseJson update(TableRelationParam param) {
DbBaseService dbBaseService = databaseServiceFactory.getDbBaseService(param.getSourceId());
dbBaseService.judgeAuth(param.getSourceId(), DbAuthType.UPDATE.getName(), "没有该库的执行权限");
dbTableRelationService.update(param);
return DocDbResponseJson.ok();
}
@PostMapping(value = "/getRelation")
public ResponseJson getRelation(TableRelationParam param) {
TableRelationVo relationVo = new TableRelationVo();
relationVo.setDbName(param.getDbName());
relationVo.setName(param.getTableName());
DbBaseService dbBaseService = databaseServiceFactory.getDbBaseService(param.getSourceId());
TableColumnVo tableColumn = dbBaseService.getTableColumnList(param.getSourceId(), param.getDbName(), param.getTableName());
if (CollectionUtils.isNotEmpty(tableColumn.getColumnList())) {
Set<String> drillPath = new HashSet<>();
List<TableRelationVo> childrenRelationList = new LinkedList<>();
for (TableColumnDescDto columnDto : tableColumn.getColumnList()) {
drillPath.add(param.getDbName() + "." + param.getTableName() + "." + columnDto.getName());
TableRelationVo relationVoChildren = new TableRelationVo();
relationVoChildren.setNodeType(1);
relationVoChildren.setDbName(param.getDbName());
relationVoChildren.setTableName(param.getTableName());
relationVoChildren.setName(columnDto.getName());
relationVoChildren.setColumnName(columnDto.getName());
relationVoChildren.setChildren(this.getRelation(param.getSourceId(), param.getDbName(), param.getTableName(), columnDto.getName(), drillPath,1));
childrenRelationList.add(relationVoChildren);
}
relationVo.setChildren(childrenRelationList);
}
return DocDbResponseJson.ok(relationVo);
}
public List<TableRelationVo> getRelation(Long sourceId, String dbName, String tableName, String columnName, Set<String> drillPath, int recursion) {
// 最大支持5层关系链展示
if (recursion >= 5) {
return Collections.emptyList();
}
QueryWrapper<DbTableRelation> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("datasource_id", sourceId);
queryWrapper.and(wrapper -> wrapper.or(or -> or.eq("start_db_name", dbName)
.eq("start_table_name", tableName)
.eq("start_column_name", columnName)
).or(or -> or.eq("end_db_name", dbName)
.eq("end_table_name", tableName)
.eq("end_column_name", columnName)
));
List<TableRelationVo> resultRelationList = new LinkedList<>();
List<DbTableRelation> relationList = dbTableRelationService.list(queryWrapper);
if (CollectionUtils.isEmpty(relationList)) {
return resultRelationList;
}
DbBaseService dbBaseService = databaseServiceFactory.getDbBaseService(sourceId);
for (DbTableRelation tableRelation : relationList) {
String endDbName = tableRelation.getStartDbName();
String endTableName = tableRelation.getStartTableName();
String endColumnName = tableRelation.getStartColumnName();
if (Objects.equals(tableRelation.getStartDbName(), dbName)
&& Objects.equals(tableRelation.getStartTableName(), tableName)
&& Objects.equals(tableRelation.getStartColumnName(), columnName)) {
endDbName = tableRelation.getEndDbName();
endTableName = tableRelation.getEndTableName();
endColumnName = tableRelation.getEndColumnName();
}
if (drillPath.contains(endDbName + "." + endTableName + "." + endColumnName)) {
continue;
}
TableRelationVo relationVo = new TableRelationVo();
relationVo.setDbName(endDbName);
relationVo.setTableName(endTableName);
relationVo.setName("表:" + endTableName + "\n列" + endColumnName);
relationVo.setColumnName(endColumnName);
TableColumnVo tableColumn = dbBaseService.getTableColumnList(sourceId, endDbName, endTableName);
if (CollectionUtils.isNotEmpty(tableColumn.getColumnList())) {
List<TableRelationVo> childrenRelationList = new LinkedList<>();
for (TableColumnDescDto columnDto : tableColumn.getColumnList()) {
boolean contains = drillPath.contains(endDbName + "." + endTableName + "." + columnDto.getName());
drillPath.add(endDbName + "." + endTableName + "." + columnDto.getName());
TableRelationVo relationVoChildren = new TableRelationVo();
relationVoChildren.setNodeType(1);
relationVoChildren.setDbName(endDbName);
relationVoChildren.setTableName(endTableName);
relationVoChildren.setName(columnDto.getName());
relationVoChildren.setColumnName(columnDto.getName());
if (!contains) {
relationVoChildren.setChildren(this.getRelation(sourceId, endDbName, endTableName, columnDto.getName(), drillPath, recursion + 1));
}
childrenRelationList.add(relationVoChildren);
}
relationVo.setChildren(childrenRelationList);
}
resultRelationList.add(relationVo);
}
return resultRelationList;
}
}

View File

@@ -15,6 +15,10 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Date;
import java.util.List;
@@ -92,5 +96,4 @@ public class DbTransferDataController {
List<String> selectNames = SqlParseUtil.getSelectNames(sql);
return DocDbResponseJson.ok(selectNames);
}
}

View File

@@ -0,0 +1,49 @@
package com.zyplayer.doc.db.controller.param;
public class DataDownloadParam {
private Long sourceId;
private String dbName;
private String tableName;
private String downloadType;
private String conditionColumn;
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 String getTableName() {
return tableName;
}
public void setTableName(String tableName) {
this.tableName = tableName;
}
public String getDownloadType() {
return downloadType;
}
public void setDownloadType(String downloadType) {
this.downloadType = downloadType;
}
public String getConditionColumn() {
return conditionColumn;
}
public void setConditionColumn(String conditionColumn) {
this.conditionColumn = conditionColumn;
}
}

View File

@@ -0,0 +1,153 @@
package com.zyplayer.doc.db.controller.param;
public class DataViewParam {
private Long sourceId;
private String executeId;
private Integer pageSize;
private Integer pageNum;
private String dbName;
private String tableName;
// 下载多张数据表
private String tableNames;
private String orderColumn;
private String orderType;
private String condition;
private String downloadType;
private String retainColumn;
private String conditionColumn;
private Integer dropTableFlag;
private Integer createTableFlag;
private Integer downloadFileType;
public Integer getOffset() {
return ((this.pageNum - 1) * this.pageSize);
}
public Long getSourceId() {
return sourceId;
}
public void setSourceId(Long sourceId) {
this.sourceId = sourceId;
}
public String getExecuteId() {
return executeId;
}
public void setExecuteId(String executeId) {
this.executeId = executeId;
}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
public Integer getPageNum() {
return pageNum;
}
public void setPageNum(Integer pageNum) {
this.pageNum = pageNum;
}
public String getDbName() {
return dbName;
}
public void setDbName(String dbName) {
this.dbName = dbName;
}
public String getTableName() {
return tableName;
}
public void setTableName(String tableName) {
this.tableName = tableName;
}
public String getOrderColumn() {
return orderColumn;
}
public void setOrderColumn(String orderColumn) {
this.orderColumn = orderColumn;
}
public String getOrderType() {
return orderType;
}
public void setOrderType(String orderType) {
this.orderType = orderType;
}
public String getCondition() {
return condition;
}
public void setCondition(String condition) {
this.condition = condition;
}
public String getDownloadType() {
return downloadType;
}
public void setDownloadType(String downloadType) {
this.downloadType = downloadType;
}
public String getConditionColumn() {
return conditionColumn;
}
public void setConditionColumn(String conditionColumn) {
this.conditionColumn = conditionColumn;
}
public Integer getDropTableFlag() {
return dropTableFlag;
}
public void setDropTableFlag(Integer dropTableFlag) {
this.dropTableFlag = dropTableFlag;
}
public Integer getCreateTableFlag() {
return createTableFlag;
}
public void setCreateTableFlag(Integer createTableFlag) {
this.createTableFlag = createTableFlag;
}
public String getRetainColumn() {
return retainColumn;
}
public void setRetainColumn(String retainColumn) {
this.retainColumn = retainColumn;
}
public String getTableNames() {
return tableNames;
}
public void setTableNames(String tableNames) {
this.tableNames = tableNames;
}
public Integer getDownloadFileType() {
return downloadFileType;
}
public void setDownloadFileType(Integer downloadFileType) {
this.downloadFileType = downloadFileType;
}
}

View File

@@ -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;
}
}

View File

@@ -11,7 +11,12 @@ public class DatabaseExportVo {
private Map<String, List<TableColumnDescDto>> columnList;
private List<TableInfoVo> tableList;
public DatabaseExportVo(Map<String, List<TableColumnDescDto>> columnList, List<TableInfoVo> tableList) {
this.columnList = columnList;
this.tableList = tableList;
}
public Map<String, List<TableColumnDescDto>> getColumnList() {
return columnList;
}

View File

@@ -0,0 +1,71 @@
package com.zyplayer.doc.db.controller.vo;
import com.zyplayer.doc.db.framework.db.enums.DatabaseProductEnum;
import java.util.Objects;
public class TableDdlVo {
private String current;
private String mysql;
private String sqlserver;
private String oracle;
private String postgresql;
private String hive;
public String getTableDDLByType() {
if (Objects.equals(current, DatabaseProductEnum.MYSQL.name().toLowerCase())) return mysql;
if (Objects.equals(current, DatabaseProductEnum.SQLSERVER.name().toLowerCase())) return sqlserver;
if (Objects.equals(current, DatabaseProductEnum.ORACLE.name().toLowerCase())) return oracle;
if (Objects.equals(current, DatabaseProductEnum.POSTGRESQL.name().toLowerCase())) return postgresql;
if (Objects.equals(current, DatabaseProductEnum.HIVE.name().toLowerCase())) return hive;
return null;
}
public String getHive() {
return hive;
}
public void setHive(String hive) {
this.hive = hive;
}
public String getCurrent() {
return current;
}
public void setCurrent(String current) {
this.current = current;
}
public String getMysql() {
return mysql;
}
public void setMysql(String mysql) {
this.mysql = mysql;
}
public String getSqlserver() {
return sqlserver;
}
public void setSqlserver(String sqlserver) {
this.sqlserver = sqlserver;
}
public String getOracle() {
return oracle;
}
public void setOracle(String oracle) {
this.oracle = oracle;
}
public String getPostgresql() {
return postgresql;
}
public void setPostgresql(String postgresql) {
this.postgresql = postgresql;
}
}

View File

@@ -5,6 +5,7 @@ public class UserDbAuthVo {
private Long userId;
private Integer executeAuth;
private Integer descEditAuth;
private Integer procEditAuth;
public String getUserName() {
return userName;
@@ -37,4 +38,12 @@ public class UserDbAuthVo {
public void setDescEditAuth(Integer descEditAuth) {
this.descEditAuth = descEditAuth;
}
public Integer getProcEditAuth() {
return procEditAuth;
}
public void setProcEditAuth(Integer procEditAuth) {
this.procEditAuth = procEditAuth;
}
}

View File

@@ -1,66 +1,49 @@
package com.zyplayer.doc.db.framework.configuration;
import com.alibaba.druid.pool.DruidDataSource;
import com.zyplayer.doc.core.exception.ConfirmException;
import com.zyplayer.doc.data.repository.manage.entity.DbDatasource;
import com.zyplayer.doc.data.utils.DruidDataSourceUtil;
import com.zyplayer.doc.db.framework.configuration.analysis.*;
import com.zyplayer.doc.db.framework.db.bean.DatabaseFactoryBean;
import com.zyplayer.doc.db.framework.db.enums.DatabaseProductEnum;
import com.zyplayer.doc.db.framework.db.interceptor.SqlLogInterceptor;
import org.apache.ibatis.plugin.Interceptor;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import java.util.HashMap;
import java.util.Map;
public class DatasourceUtil {
private static SqlLogInterceptor sqlLogInterceptor = new SqlLogInterceptor();
private static final SqlLogInterceptor sqlLogInterceptor = new SqlLogInterceptor();
// url解析
private static final Map<String, AnalysisApi> analysisApiMap = new HashMap<String, AnalysisApi>() {{
put(DatabaseProductEnum.MYSQL.getDriverClassName(), new MysqlAnalysis());
put(DatabaseProductEnum.HIVE.getDriverClassName(), new HiveAnalysis());
put(DatabaseProductEnum.ORACLE.getDriverClassName(), new OracleAnalysis());
put(DatabaseProductEnum.POSTGRESQL.getDriverClassName(), new PostgresqlAnalysis());
put(DatabaseProductEnum.SQLSERVER.getDriverClassName(), new SqlserverAnalysis());
}};
public static DatabaseFactoryBean createDatabaseFactoryBean(DbDatasource dbDatasource, boolean breakAfterAcquireFailure) throws Exception {
Resource[] resources = null;
// 描述连接信息的对象
DatabaseFactoryBean databaseFactoryBean = new DatabaseFactoryBean();
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
String dbUrl = dbDatasource.getSourceUrl();
if (dbUrl.contains("mysql")) {
// jdbc:mysql://192.168.0.1:3306/user_info?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&autoReconnect=true
String[] urlParamArr = dbUrl.split("\\?");
String[] urlDbNameArr = urlParamArr[0].split("/");
if (urlDbNameArr.length >= 2) {
databaseFactoryBean.setDbName(urlDbNameArr[urlDbNameArr.length - 1]);
//databaseFactoryBean.setHost(urlDbNameArr[urlDbNameArr.length - 2]);
}
databaseFactoryBean.setDatabaseProduct(DatabaseFactoryBean.DatabaseProduct.MYSQL);
resources = resolver.getResources("classpath:com/zyplayer/doc/db/framework/db/mapper/mysql/*.xml");
} else if (dbUrl.contains("sqlserver")) {
// jdbc:jtds:sqlserver://192.168.0.1:33434;socketTimeout=60;DatabaseName=user_info;
String[] urlParamArr = dbUrl.split(";");
//String[] urlDbNameArr = urlParamArr[0].split("/");
//databaseFactoryBean.setHost(urlDbNameArr[urlDbNameArr.length - 1]);
for (String urlParam : urlParamArr) {
String[] keyValArr = urlParam.split("=");
if (keyValArr.length >= 2 && keyValArr[0].equalsIgnoreCase("DatabaseName")) {
databaseFactoryBean.setDbName(keyValArr[1]);
}
}
databaseFactoryBean.setDatabaseProduct(DatabaseFactoryBean.DatabaseProduct.SQLSERVER);
resources = resolver.getResources("classpath:com/zyplayer/doc/db/framework/db/mapper/sqlserver/*.xml");
} else if (dbUrl.contains("oracle")) {
// jdbc:oracle:thin:@127.0.0.1:1521:user_info
// jdbc:oracle:thin:@127.0.0.1:1521/user_info
// 代码是写好的但还没有oracle的库让我测试过~
String[] urlParamArr = dbUrl.split("\\?")[0].split("@");
String[] urlDbNameArr = urlParamArr[0].split("/");
if (urlDbNameArr.length <= 1) {
urlDbNameArr = urlParamArr[0].split(":");
}
databaseFactoryBean.setDbName(urlDbNameArr[urlDbNameArr.length - 1]);
databaseFactoryBean.setDatabaseProduct(DatabaseFactoryBean.DatabaseProduct.ORACLE);
resources = resolver.getResources("classpath:com/zyplayer/doc/db/framework/db/mapper/oracle/*.xml");
}
if (resources == null) {
return null;
String driverClassName = dbDatasource.getDriverClassName();
AnalysisApi analysisApi = analysisApiMap.get(driverClassName);
if (analysisApi == null) {
throw new ConfirmException("暂未支持的数据源类型");
}
Resource[] resources = analysisApi.process(dbUrl, databaseFactoryBean);
// 数据源配置
DruidDataSource dataSource = DruidDataSourceUtil.createDataSource(dbDatasource.getDriverClassName(), dbDatasource.getSourceUrl(), dbDatasource.getSourceName(), dbDatasource.getSourcePassword(), breakAfterAcquireFailure);
DruidDataSource dataSource = DruidDataSourceUtil.createDataSource(dbDatasource.getDriverClassName(), dbDatasource.getSourceUrl(), dbDatasource.getSourceName(), dbDatasource.getSourcePassword(), false);
if (breakAfterAcquireFailure) {
dataSource.close();
// 先关闭会自动关闭的数据源,再创建一个会重连的
dataSource = DruidDataSourceUtil.createDataSource(dbDatasource.getDriverClassName(), dbDatasource.getSourceUrl(), dbDatasource.getSourceName(), dbDatasource.getSourcePassword(), true);
}
// 创建sqlSessionTemplate
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);

View File

@@ -0,0 +1,10 @@
package com.zyplayer.doc.db.framework.configuration.analysis;
import com.zyplayer.doc.db.framework.db.bean.DatabaseFactoryBean;
import org.springframework.core.io.Resource;
public interface AnalysisApi {
Resource[] process(String dbUrl, DatabaseFactoryBean databaseFactoryBean) throws Exception;
}

View File

@@ -0,0 +1,23 @@
package com.zyplayer.doc.db.framework.configuration.analysis;
import com.zyplayer.doc.db.framework.db.bean.DatabaseFactoryBean;
import com.zyplayer.doc.db.framework.db.enums.DatabaseProductEnum;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
public class HiveAnalysis implements AnalysisApi {
@Override
public Resource[] process(String dbUrl, DatabaseFactoryBean databaseFactoryBean) throws Exception {
// jdbc:hive2://127.0.0.1:21050/ads_data;auth=noSasl
String[] urlParamArr = dbUrl.split(";");
String[] urlDbNameArr = urlParamArr[0].split("/");
if (urlDbNameArr.length >= 2) {
databaseFactoryBean.setDbName(urlDbNameArr[urlDbNameArr.length - 1]);
}
databaseFactoryBean.setDatabaseProduct(DatabaseProductEnum.HIVE);
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
return resolver.getResources("classpath:com/zyplayer/doc/db/framework/db/mapper/hive/*.xml");
}
}

View File

@@ -0,0 +1,24 @@
package com.zyplayer.doc.db.framework.configuration.analysis;
import com.zyplayer.doc.db.framework.db.bean.DatabaseFactoryBean;
import com.zyplayer.doc.db.framework.db.enums.DatabaseProductEnum;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
public class MysqlAnalysis implements AnalysisApi {
@Override
public Resource[] process(String dbUrl, DatabaseFactoryBean databaseFactoryBean) throws Exception {
// jdbc:mysql://192.168.0.1:3306/user_info?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&autoReconnect=true
String[] urlParamArr = dbUrl.split("\\?");
String[] urlDbNameArr = urlParamArr[0].split("/");
if (urlDbNameArr.length >= 2) {
databaseFactoryBean.setDbName(urlDbNameArr[urlDbNameArr.length - 1]);
//databaseFactoryBean.setHost(urlDbNameArr[urlDbNameArr.length - 2]);
}
databaseFactoryBean.setDatabaseProduct(DatabaseProductEnum.MYSQL);
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
return resolver.getResources("classpath:com/zyplayer/doc/db/framework/db/mapper/mysql/*.xml");
}
}

View File

@@ -0,0 +1,25 @@
package com.zyplayer.doc.db.framework.configuration.analysis;
import com.zyplayer.doc.db.framework.db.bean.DatabaseFactoryBean;
import com.zyplayer.doc.db.framework.db.enums.DatabaseProductEnum;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
public class OracleAnalysis implements AnalysisApi {
@Override
public Resource[] process(String dbUrl, DatabaseFactoryBean databaseFactoryBean) throws Exception {
// jdbc:oracle:thin:@127.0.0.1:1521:user_info
// 代码是写好的但还没有oracle的库让我测试过~
String[] urlParamArr = dbUrl.split("\\?")[0].split("@");
String[] urlDbNameArr = urlParamArr[0].split("/");
if (urlDbNameArr.length <= 1) {
urlDbNameArr = urlParamArr[0].split(":");
}
databaseFactoryBean.setDbName(urlDbNameArr[urlDbNameArr.length - 1]);
databaseFactoryBean.setDatabaseProduct(DatabaseProductEnum.ORACLE);
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
return resolver.getResources("classpath:com/zyplayer/doc/db/framework/db/mapper/oracle/*.xml");
}
}

View File

@@ -0,0 +1,24 @@
package com.zyplayer.doc.db.framework.configuration.analysis;
import com.zyplayer.doc.db.framework.db.bean.DatabaseFactoryBean;
import com.zyplayer.doc.db.framework.db.enums.DatabaseProductEnum;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
public class PostgresqlAnalysis implements AnalysisApi {
@Override
public Resource[] process(String dbUrl, DatabaseFactoryBean databaseFactoryBean) throws Exception {
// jdbc:mysql://192.168.0.1:3306/user_info?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&autoReconnect=true
String[] urlParamArr = dbUrl.split("\\?");
String[] urlDbNameArr = urlParamArr[0].split("/");
if (urlDbNameArr.length >= 2) {
databaseFactoryBean.setDbName(urlDbNameArr[urlDbNameArr.length - 1]);
//databaseFactoryBean.setHost(urlDbNameArr[urlDbNameArr.length - 2]);
}
databaseFactoryBean.setDatabaseProduct(DatabaseProductEnum.POSTGRESQL);
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
return resolver.getResources("classpath:com/zyplayer/doc/db/framework/db/mapper/postgresql/*.xml");
}
}

View File

@@ -0,0 +1,27 @@
package com.zyplayer.doc.db.framework.configuration.analysis;
import com.zyplayer.doc.db.framework.db.bean.DatabaseFactoryBean;
import com.zyplayer.doc.db.framework.db.enums.DatabaseProductEnum;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
public class SqlserverAnalysis implements AnalysisApi {
@Override
public Resource[] process(String dbUrl, DatabaseFactoryBean databaseFactoryBean) throws Exception {
// jdbc:jtds:sqlserver://192.168.0.1:33434;socketTimeout=60;DatabaseName=user_info;
String[] urlParamArr = dbUrl.split(";");
//String[] urlDbNameArr = urlParamArr[0].split("/");
//databaseFactoryBean.setHost(urlDbNameArr[urlDbNameArr.length - 1]);
for (String urlParam : urlParamArr) {
String[] keyValArr = urlParam.split("=");
if (keyValArr.length >= 2 && keyValArr[0].equalsIgnoreCase("DatabaseName")) {
databaseFactoryBean.setDbName(keyValArr[1]);
}
}
databaseFactoryBean.setDatabaseProduct(DatabaseProductEnum.SQLSERVER);
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
return resolver.getResources("classpath:com/zyplayer/doc/db/framework/db/mapper/sqlserver/*.xml");
}
}

View File

@@ -5,7 +5,8 @@ public enum DbAuthType {
VIEW(1, "DB_VIEW_"),
SELECT(2, "DB_SELECT_"),
UPDATE(3, "DB_UPDATE_"),
DESC_EDIT(3, "DB_DESC_EDIT_"),
DESC_EDIT(4, "DB_DESC_EDIT_"),
PROC_EDIT(5, "DB_PROC_EDIT_"),
;
private Integer type;
private String name;

View File

@@ -1,10 +1,12 @@
package com.zyplayer.doc.db.framework.db.bean;
import com.alibaba.druid.pool.DruidDataSource;
import com.zyplayer.doc.db.framework.db.enums.DatabaseProductEnum;
import org.mybatis.spring.SqlSessionTemplate;
/**
* 描述连接信息的对象
*
* @author 暮光:城中城
* @since 2018年8月8日
*/
@@ -16,7 +18,7 @@ public class DatabaseFactoryBean {
private String dbName;
private String cnName;
private String groupName;
private DatabaseProduct databaseProduct;
private DatabaseProductEnum databaseProduct;
public Long getId() {
return id;
@@ -42,48 +44,44 @@ public class DatabaseFactoryBean {
this.groupName = groupName;
}
public static enum DatabaseProduct {
MYSQL, SQLSERVER, ORACLE
}
public DruidDataSource getDataSource() {
return dataSource;
}
public void setDataSource(DruidDataSource dataSource) {
this.dataSource = dataSource;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getDbName() {
return dbName;
}
public void setDbName(String dbName) {
this.dbName = dbName;
}
public DatabaseProduct getDatabaseProduct() {
public DatabaseProductEnum getDatabaseProduct() {
return databaseProduct;
}
public void setDatabaseProduct(DatabaseProduct databaseProduct) {
public void setDatabaseProduct(DatabaseProductEnum databaseProduct) {
this.databaseProduct = databaseProduct;
}
public SqlSessionTemplate getSqlSessionTemplate() {
return sqlSessionTemplate;
}
public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {
this.sqlSessionTemplate = sqlSessionTemplate;
}
}

View File

@@ -25,7 +25,7 @@ public class DatabaseRegistrationBean {
DbDatasourceService dbDatasourceService;
// 描述连接信息的对象列表
private Map<Long, DatabaseFactoryBean> databaseFactoryBeanMap = new ConcurrentHashMap<>();
private final Map<Long, DatabaseFactoryBean> databaseFactoryBeanMap = new ConcurrentHashMap<>();
/**
* 获取BaseMapper
@@ -113,9 +113,6 @@ public class DatabaseRegistrationBean {
}
try {
DatabaseFactoryBean databaseFactoryBean = DatasourceUtil.createDatabaseFactoryBean(dbDatasource, false);
if (databaseFactoryBean == null) {
throw new ConfirmException("获取数据源失败");
}
databaseFactoryBeanMap.put(sourceId, databaseFactoryBean);
return databaseFactoryBean;
} catch (Exception e) {

View File

@@ -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;
}
}

View File

@@ -14,23 +14,27 @@ public class TableColumnDescDto {
@ColumnWidth(15)
@ExcelProperty("是否自增")
private String isidenity;
private String selfIncrement;
@ColumnWidth(20)
@ExcelProperty("类型")
private String type;
@ColumnWidth(10)
@ExcelProperty("NULL")
@ExcelProperty("空值")
private String nullable;
@ColumnWidth(10)
@ExcelProperty("长度")
private String length;
@ColumnWidth(10)
@ExcelProperty("小数点")
private String numericScale;
@ColumnWidth(10)
@ExcelProperty("主键")
private String ispramary;
private String primaryKey;
@ColumnWidth(80)
@ExcelProperty("注释")
@@ -44,14 +48,6 @@ public class TableColumnDescDto {
this.name = name;
}
public String getIsidenity() {
return isidenity;
}
public void setIsidenity(String isidenity) {
this.isidenity = isidenity;
}
public String getType() {
return type;
}
@@ -76,14 +72,6 @@ public class TableColumnDescDto {
this.length = length;
}
public String getIspramary() {
return ispramary;
}
public void setIspramary(String ispramary) {
this.ispramary = ispramary;
}
public String getDescription() {
return description;
}
@@ -99,4 +87,28 @@ public class TableColumnDescDto {
public void setTableName(String tableName) {
this.tableName = tableName;
}
public String getNumericScale() {
return numericScale;
}
public void setNumericScale(String numericScale) {
this.numericScale = numericScale;
}
public String getSelfIncrement() {
return selfIncrement;
}
public void setSelfIncrement(String selfIncrement) {
this.selfIncrement = selfIncrement;
}
public String getPrimaryKey() {
return primaryKey;
}
public void setPrimaryKey(String primaryKey) {
this.primaryKey = primaryKey;
}
}

View File

@@ -0,0 +1,27 @@
package com.zyplayer.doc.db.framework.db.enums;
/**
* 数据库类型枚举
*/
public enum DatabaseProductEnum {
MYSQL("com.mysql.jdbc.Driver"),
SQLSERVER("net.sourceforge.jtds.jdbc.Driver"),
ORACLE("oracle.jdbc.driver.OracleDriver"),
POSTGRESQL("org.postgresql.Driver"),
HIVE("org.apache.hive.jdbc.HiveDriver"),
;
private String driverClassName;
DatabaseProductEnum(String driverClassName) {
this.driverClassName = driverClassName;
}
public String getDriverClassName() {
return driverClassName;
}
public void setDriverClassName(String driverClassName) {
this.driverClassName = driverClassName;
}
}

View File

@@ -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;
@@ -22,7 +23,7 @@ public interface BaseMapper {
* @author 暮光:城中城
* @since 2018年8月8日
*/
Map<String, String> getTableDdl(@Param("dbName") String dbName, @Param("tableName") String tableName);
List<Map<String, String>> getTableDdl(@Param("dbName") String dbName, @Param("tableName") String tableName);
/**
* 获取库列表
@@ -54,16 +55,6 @@ public interface BaseMapper {
*/
List<TableColumnDescDto> getTableColumnList(@Param("dbName") String dbName, @Param("tableName") String tableName);
/**
* 获取字段注释
*
* @param tableName 表名
* @return 表字段注释
* @author 暮光:城中城
* @since 2018年8月8日
*/
List<TableColumnDescDto> getTableColumnDescList(@Param("tableName") String tableName);
/**
* 模糊搜索表和字段
*
@@ -119,4 +110,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);
}

View File

@@ -17,8 +17,12 @@ public class ExecuteParam {
private Long datasourceId;
private Integer maxRows;
private String executeId;
private String prefixSql;
private ExecuteType executeType;
public ExecuteParam() {
}
public Long getDatasourceId() {
return datasourceId;
}
@@ -74,4 +78,12 @@ public class ExecuteParam {
public void setMaxRows(Integer maxRows) {
this.maxRows = maxRows;
}
public String getPrefixSql() {
return prefixSql;
}
public void setPrefixSql(String prefixSql) {
this.prefixSql = prefixSql;
}
}

View File

@@ -2,10 +2,12 @@ package com.zyplayer.doc.db.framework.db.mapper.base;
import com.alibaba.druid.pool.DruidPooledConnection;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.zyplayer.doc.core.util.StringUtil;
import com.zyplayer.doc.data.service.manage.DbHistoryService;
import com.zyplayer.doc.db.framework.db.bean.DatabaseFactoryBean;
import com.zyplayer.doc.db.framework.db.bean.DatabaseRegistrationBean;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.ibatis.builder.SqlSourceBuilder;
import org.apache.ibatis.builder.StaticSqlSource;
import org.apache.ibatis.mapping.BoundSql;
@@ -69,6 +71,16 @@ public class SqlExecutor {
return this.execute(factoryBean, param, null);
}
/**
* 执行sql返回结果
* @author 暮光:城中城
* @since 2019年8月18日
*/
public ExecuteResult execute(ExecuteParam param, ResultHandler handler) {
DatabaseFactoryBean factoryBean = databaseRegistrationBean.getOrCreateFactoryById(param.getDatasourceId());
return this.execute(factoryBean, param, handler);
}
/**
* 执行sql可通过handler回调每一行的结果
* @author 暮光:城中城
@@ -83,16 +95,23 @@ public class SqlExecutor {
// String sqlStr = SqlLogUtil.getSqlString(paramMap, boundSql);
// 有参数的时候不输出日志,暂时只有导数据才有参数
if (CollectionUtils.isEmpty(executeParam.getParamList())) {
if (StringUtils.isNotBlank(executeParam.getPrefixSql())) {
logger.info("prefix sql ==> {}", executeParam.getPrefixSql());
}
logger.info("sql ==> {}", executeParam.getSql());
}
// List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
PreparedStatement preparedStatement = null;
PreparedStatement prefixStatement = null;
DruidPooledConnection connection = null;
// 执行查询
try {
long startTime = System.currentTimeMillis();
connection = factoryBean.getDataSource().getConnection();
if (StringUtils.isNotBlank(executeParam.getPrefixSql())) {
prefixStatement = connection.prepareStatement(executeParam.getPrefixSql());
prefixStatement.execute();
}
preparedStatement = connection.prepareStatement(executeParam.getSql());
// 设置当前的PreparedStatement
statementMap.put(executeParam.getExecuteId(), preparedStatement);
@@ -103,15 +122,17 @@ public class SqlExecutor {
preparedStatement.setObject(i + 1, paramDataList.get(i));
}
}
// 最大限制1分钟
preparedStatement.setQueryTimeout(60);
// 限制下最大数量
if (executeParam.getMaxRows() != null) {
preparedStatement.setMaxRows(executeParam.getMaxRows());
}
if (ExecuteType.SELECT.equals(executeParam.getExecuteType())) {
preparedStatement.executeQuery();
} else {
preparedStatement.execute();
}
// 限制下最大数量
if (executeParam.getMaxRows() != null) {
preparedStatement.setMaxRows(executeParam.getMaxRows());
}
// 查询的结果集
ResultSet resultSet = preparedStatement.getResultSet();
List<Map<String, Object>> resultList = new LinkedList<>();
@@ -138,6 +159,13 @@ public class SqlExecutor {
throw new RuntimeException(e);
} finally {
statementMap.remove(executeParam.getExecuteId());
try {
if (prefixStatement != null && !prefixStatement.isClosed()) {
prefixStatement.close();
}
} catch (Exception e) {
logger.error("关闭Statement失败");
}
try {
if (preparedStatement != null && !preparedStatement.isClosed()) {
preparedStatement.close();

View File

@@ -0,0 +1,89 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<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="name" property="name" jdbcType="VARCHAR" />
<result column="col_name" property="name" jdbcType="VARCHAR" />
<result column="data_type" property="type" jdbcType="VARCHAR" />
<result column="comment" 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="DESCRIPTION" property="description" jdbcType="VARCHAR" />
</resultMap>
<resultMap id="TableStatusDtoMap" type="com.zyplayer.doc.db.controller.vo.TableStatusVo">
<result column="Name" property="name"/>
<result column="Engine" property="engine"/>
<result column="Version" property="version"/>
<result column="Row_format" property="rowFormat"/>
<result column="Rows" property="rows"/>
<result column="Avg_row_length" property="avgRowLength"/>
<result column="Data_length" property="dataLength"/>
<result column="Max_data_length" property="maxDataLength"/>
<result column="Index_length" property="indexLength"/>
<result column="Data_free" property="dataFree"/>
<result column="Auto_increment" property="autoIncrement"/>
<result column="Create_time" property="createTime"/>
<result column="Update_time" property="updateTime"/>
<result column="Check_time" property="checkTime"/>
<result column="Collation" property="collation"/>
<result column="Checksum" property="checksum"/>
<result column="Create_options" property="createOptions"/>
<result column="Comment" property="comment"/>
</resultMap>
<resultMap id="DatabasesDtoMap" type="com.zyplayer.doc.db.framework.db.dto.DatabaseInfoDto" >
<result column="name" property="dbName" jdbcType="VARCHAR" />
<result column="database_name" property="dbName" jdbcType="VARCHAR" />
</resultMap>
<select id="getDatabaseList" resultMap="DatabasesDtoMap">
show databases
</select>
<select id="getTableDdl" resultType="java.util.Map">
show create table `${dbName}`.${tableName}
</select>
<resultMap id="TablesDtoMap" type="com.zyplayer.doc.db.framework.db.dto.TableInfoDto" >
<result column="name" property="tableName" jdbcType="VARCHAR" />
<result column="tab_name" property="tableName" jdbcType="VARCHAR" />
</resultMap>
<select id="getTableList" resultMap="TablesDtoMap">
show tables in ${dbName}
</select>
<select id="getTableColumnList" resultMap="TableColumnDescDtoMap">
describe ${dbName}.${tableName}
</select>
<select id="getTableStatus" resultMap="TableStatusDtoMap">
select #{tableName} as Name
</select>
<select id="getTableColumnDescList" resultMap="TableColumnDescDtoMap">
select 1 from ${dbName}.${tableName} where 0 = 1
</select>
<select id="getTableAndColumnBySearch" resultMap="QueryTableColumnDescDtoMap">
select 1
</select>
<select id="getTableDescList" resultType="com.zyplayer.doc.db.framework.db.dto.TableDescDto">
select 1 from ${dbName}.${tableName} where 0 = 1
</select>
<insert id="updateTableDesc">
select 1 from ${dbName}.${tableName} where 0 = 1
</insert>
<insert id="updateTableColumnDesc">
select 1 from ${dbName}.${tableName} where 0 = 1
</insert>
</mapper>

View File

@@ -0,0 +1,15 @@
package com.zyplayer.doc.db.framework.db.mapper.hive;
import com.zyplayer.doc.db.framework.db.dto.ColumnInfoDto;
import org.apache.ibatis.annotations.Param;
/**
* mysql数据库的mapper持有对象
*
* @author 暮光:城中城
* @since 2018年8月8日
*/
public interface HiveMapper {
ColumnInfoDto getColumnInfo(@Param("dbName") String dbName, @Param("tableName") String tableName, @Param("columnName") String columnName);
}

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zyplayer.doc.db.framework.db.mapper.mysql.HiveMapper">
</mapper>

View File

@@ -2,87 +2,56 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<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="NAME" property="name" jdbcType="VARCHAR" />
<result column="ISIDENITY" property="isidenity" jdbcType="VARCHAR" />
<result column="TYPE" property="type" jdbcType="VARCHAR" />
<result column="NULLABLE" property="nullable" jdbcType="VARCHAR" />
<result column="LENGTH" property="length" jdbcType="VARCHAR" />
<result column="ISPRAMARY" property="ispramary" jdbcType="VARCHAR" />
<result column="DESCRIPTION" 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="DESCRIPTION" property="description" jdbcType="VARCHAR" />
</resultMap>
<resultMap id="TableStatusDtoMap" type="com.zyplayer.doc.db.controller.vo.TableStatusVo">
<result column="Name" property="name"/>
<result column="Engine" property="engine"/>
<result column="Version" property="version"/>
<result column="Row_format" property="rowFormat"/>
<result column="Rows" property="rows"/>
<result column="Avg_row_length" property="avgRowLength"/>
<result column="Data_length" property="dataLength"/>
<result column="Max_data_length" property="maxDataLength"/>
<result column="Index_length" property="indexLength"/>
<result column="Data_free" property="dataFree"/>
<result column="Auto_increment" property="autoIncrement"/>
<result column="Create_time" property="createTime"/>
<result column="Update_time" property="updateTime"/>
<result column="Check_time" property="checkTime"/>
<result column="Collation" property="collation"/>
<result column="Checksum" property="checksum"/>
<result column="Create_options" property="createOptions"/>
<result column="Comment" property="comment"/>
</resultMap>
<select id="getDatabaseList" resultType="com.zyplayer.doc.db.framework.db.dto.DatabaseInfoDto">
select TABLE_SCHEMA dbName
from information_schema.tables
<!--排除系统库-->
where TABLE_SCHEMA != 'information_schema'
group by TABLE_SCHEMA
select SCHEMA_NAME dbName from `information_schema`.SCHEMATA
</select>
<select id="getTableDdl" resultType="java.util.Map">
show create table ${dbName}.${tableName}
show create table `${dbName}`.${tableName}
</select>
<select id="getTableList" resultType="com.zyplayer.doc.db.framework.db.dto.TableInfoDto">
select table_schema dbName,table_name tableName, table_comment as tableComment
from information_schema.tables
from `information_schema`.tables
<if test="dbName != null">where table_schema=#{dbName}</if>
</select>
<select id="getTableColumnList" resultMap="TableColumnDescDtoMap">
SELECT table_name as TABLE_NAME,COLUMN_NAME NAME,column_comment DESCRIPTION,column_type TYPE,if(is_nullable='YES',1,0) NULLABLE
FROM INFORMATION_SCHEMA.Columns
<select id="getTableColumnList" resultType="com.zyplayer.doc.db.framework.db.dto.TableColumnDescDto">
SELECT table_name as tableName,COLUMN_NAME as name,column_comment description,data_type type,
COALESCE(CHARACTER_MAXIMUM_LENGTH,NUMERIC_PRECISION) as `length`,NUMERIC_SCALE as numericScale,
if(COLUMN_KEY='PRI','1','0') as primaryKey,
if(is_nullable='YES','1','0') nullable
FROM `INFORMATION_SCHEMA`.Columns
WHERE table_schema=#{dbName}
<if test="tableName != null">and table_name=#{tableName}</if>
ORDER BY ordinal_position
</select>
<select id="getTableStatus" resultMap="TableStatusDtoMap">
show table status from ${dbName} like #{tableName}
<select id="getTableStatus" resultType="com.zyplayer.doc.db.controller.vo.TableStatusVo">
<!-- show table status from `${dbName}` like #{tableName} -->
select TABLE_NAME as name, ENGINE as engine, VERSION as version, ROW_FORMAT as rowFormat,
TABLE_ROWS as `rows`, AVG_ROW_LENGTH as avgRowLength, DATA_LENGTH as dataLength,
MAX_DATA_LENGTH as maxDataLength, INDEX_LENGTH as indexLength, DATA_FREE as dataFree,
AUTO_INCREMENT as autoIncrement, CREATE_TIME as createTime, UPDATE_TIME as updateTime,
CHECK_TIME as checkTime, TABLE_COLLATION as `collation`, CHECKSUM as checksum,
CREATE_OPTIONS as createOptions, TABLE_COMMENT as comment
from `information_schema`.tables
where table_schema=#{dbName} and table_name=#{tableName}
</select>
<select id="getTableColumnDescList" resultMap="TableColumnDescDtoMap">
<select id="getTableColumnDescList" resultType="com.zyplayer.doc.db.framework.db.dto.TableColumnDescDto">
select 1
</select>
<select id="getTableAndColumnBySearch" resultMap="QueryTableColumnDescDtoMap">
SELECT TABLE_NAME, COLUMN_NAME, column_comment DESCRIPTION
FROM INFORMATION_SCHEMA.Columns
<select id="getTableAndColumnBySearch" resultType="com.zyplayer.doc.db.framework.db.dto.QueryTableColumnDescDto">
SELECT TABLE_NAME as tableName, column_name as columnName, column_comment as description
FROM `INFORMATION_SCHEMA`.Columns
WHERE table_schema=#{dbName} AND (COLUMN_NAME like #{searchText} or column_comment like #{searchText})
</select>
<select id="getTableDescList" resultType="com.zyplayer.doc.db.framework.db.dto.TableDescDto">
select table_name tableName, table_comment as description
from information_schema.tables
from `information_schema`.tables
<where>
<if test="dbName != null">and table_schema=#{dbName}</if>
<if test="tableName != null">and table_name=#{tableName}</if>
@@ -90,13 +59,38 @@
</select>
<insert id="updateTableDesc">
alter table ${dbName}.${tableName} comment #{newDesc}
alter table `${dbName}`.${tableName} comment #{newDesc}
</insert>
<insert id="updateTableColumnDesc">
alter table ${dbName}.${tableName} modify column ${columnName}
alter table `${dbName}`.${tableName} modify column ${columnName}
${columnInfo.columnType} ${columnInfo.isNullable} ${columnInfo.columnDefault} ${columnInfo.extra}
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>

View File

@@ -21,6 +21,10 @@
select USERNAME dbName from all_users
</select>
<select id="getTableStatus" resultType="com.zyplayer.doc.db.controller.vo.TableStatusVo">
select 1
</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
@@ -31,7 +35,7 @@
<!-- 获取表字段集合 -->
<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
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} )

View File

@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<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="NAME" property="name" jdbcType="VARCHAR"/>
<result column="ISIDENITY" property="selfIncrement" jdbcType="VARCHAR"/>
<result column="TYPE" property="type" jdbcType="VARCHAR"/>
<result column="NULLABLE" property="nullable" jdbcType="VARCHAR"/>
<result column="LENGTH" property="length" jdbcType="VARCHAR"/>
<result column="ISPRAMARY" property="primaryKey" jdbcType="VARCHAR"/>
<result column="DESCRIPTION" 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="DESCRIPTION" property="description" jdbcType="VARCHAR"/>
</resultMap>
<select id="getDatabaseList" resultType="com.zyplayer.doc.db.framework.db.dto.DatabaseInfoDto">
SELECT distinct table_schema as dbName
FROM information_schema.tables ORDER BY 1
</select>
<select id="getTableStatus" resultType="com.zyplayer.doc.db.controller.vo.TableStatusVo">
SELECT relname as name, reltuples as rows
FROM pg_class r JOIN pg_namespace n
ON (relnamespace = n.oid)
WHERE relkind = 'r' AND n.nspname = #{dbName} and relname = #{tableName}
</select>
<select id="getTableList" resultType="com.zyplayer.doc.db.framework.db.dto.TableInfoDto">
select relname as tableName,cast(obj_description(relfilenode,'pg_class') as varchar) as tableComment from pg_class c
where relname in (select tablename from pg_tables where schemaname=#{dbName} and position('_2' in tablename)=0)
order by 1
</select>
<select id="getTableColumnList" resultMap="TableColumnDescDtoMap">
SELECT table_name as TABLE_NAME,a.COLUMN_NAME as NAME,b.DESCRIPTION as DESCRIPTION,udt_name as TYPE,case when is_nullable ='YES' then '1' else '0' end as NULLABLE , case when character_maximum_length>0 then character_maximum_length else numeric_precision end LENGTH
FROM information_schema.columns a
left join (SELECT a.attname as COLUMN_NAME,col_description(a.attrelid,a.attnum) as DESCRIPTION
FROM pg_class as c,pg_attribute as a, pg_namespace as n
where a.attrelid = c.oid and a.attnum>0
and c.relnamespace = n.oid AND n.nspname = #{dbName} and c.relname = #{tableName}) b on a.COLUMN_NAME= b.COLUMN_NAME
WHERE table_schema=#{dbName} and table_name=#{tableName}
ORDER BY ordinal_position
</select>
<select id="getTableColumnDescList" resultMap="TableColumnDescDtoMap">
SELECT
col_description (A .attrelid, A .attnum) AS COMMENT,
format_type (A .atttypid, A .atttypmod) AS TYPE,
A .attname AS NAME,
A .attnotnull AS NOTNULL
FROM
pg_class AS C,
pg_attribute AS A
WHERE
C .relname =#{tableName}
AND A .attrelid = C .oid
AND A .attnum > 0
</select>
<select id="getTableAndColumnBySearch" resultMap="QueryTableColumnDescDtoMap">
SELECT
col_description (A .attrelid, A .attnum) AS COMMENT,
format_type (A .atttypid, A .atttypmod) AS TYPE,
A .attname AS NAME,
A .attnotnull AS NOTNULL
FROM
pg_class AS C,
pg_attribute AS A
WHERE
C .relnamelike #{searchText}
AND A .attrelid = C .oid
AND A .attnum > 0
</select>
<select id="getTableDescList" resultType="com.zyplayer.doc.db.framework.db.dto.TableDescDto">
select t.relname as tableName ,description as description
from pg_description d,pg_class c,pg_stat_all_tables t
where d.objoid=c.oid and objsubid=0 and t.relname=c.relname and t.schemaname=#{dbName}
<if test="tableName != null">
and t.relname=#{tableName}
</if>
</select>
</mapper>

View File

@@ -0,0 +1,17 @@
package com.zyplayer.doc.db.framework.db.mapper.postgresql;
import org.apache.ibatis.annotations.Param;
import com.zyplayer.doc.db.framework.db.dto.ColumnInfoDto;
/**
* postgresql数据库的mapper持有对象
*
* @author 辽宁-天平
* @since 2021年1月5日
*/
public interface PostgresqlMapper {
ColumnInfoDto getColumnInfo(@Param("dbName") String dbName, @Param("tableName") String tableName, @Param("columnName") String columnName);
}

View File

@@ -4,11 +4,11 @@
<resultMap id="TableColumnDescDtoMap" type="com.zyplayer.doc.db.framework.db.dto.TableColumnDescDto" >
<result column="NAME" property="name" jdbcType="VARCHAR" />
<result column="ISIDENITY" property="isidenity" jdbcType="VARCHAR" />
<result column="ISIDENITY" property="selfIncrement" jdbcType="VARCHAR" />
<result column="TYPE" property="type" jdbcType="VARCHAR" />
<result column="NULLABLE" property="nullable" jdbcType="VARCHAR" />
<result column="LENGTH" property="length" jdbcType="VARCHAR" />
<result column="ISPRAMARY" property="ispramary" jdbcType="VARCHAR" />
<result column="ISPRAMARY" property="primaryKey" jdbcType="VARCHAR" />
<result column="DESCRIPTION" property="description" jdbcType="VARCHAR" />
</resultMap>
@@ -23,7 +23,7 @@
</select>
<select id="getTableStatus" resultType="com.zyplayer.doc.db.controller.vo.TableStatusVo">
select 1
select #{tableName} as name
</select>
<select id="getTableList" resultType="com.zyplayer.doc.db.framework.db.dto.TableInfoDto">
@@ -31,48 +31,41 @@
FROM ${dbName}..SysObjects Where XType='U' ORDER BY NAME
</select>
<select id="getTableColumnList" resultMap="TableColumnDescDtoMap">
<select id="getTableColumnList" resultType="com.zyplayer.doc.db.framework.db.dto.TableColumnDescDto">
WITH PRIMARYINFO( COLUMNNAME ,ISPRAMARY) AS
(
SELECT C.NAME,'true' AS COLUMNNAME
FROM SYSINDEXES I
JOIN SYSINDEXKEYS K ON I.ID = K.ID AND I.INDID = K.INDID
JOIN SYSOBJECTS O ON I.ID = O.ID
JOIN SYSCOLUMNS C ON I.ID=C.ID AND K.COLID = C.COLID
FROM ${dbName}..SYSINDEXES I
JOIN ${dbName}..SYSINDEXKEYS K ON I.ID = K.ID AND I.INDID = K.INDID
JOIN ${dbName}..SYSOBJECTS O ON I.ID = O.ID
JOIN ${dbName}..SYSCOLUMNS C ON I.ID=C.ID AND K.COLID = C.COLID
WHERE O.XTYPE = 'U'
AND EXISTS(SELECT 1 FROM SYSOBJECTS WHERE XTYPE = 'PK' AND NAME = I.NAME)
AND EXISTS(SELECT 1 FROM ${dbName}..SYSOBJECTS WHERE XTYPE = 'PK' AND NAME = I.NAME)
AND O.NAME=#{tableName}
)
SELECT (
SELECT IS_IDENTITY FROM SYS.ALL_COLUMNS
WHERE SYS.ALL_COLUMNS.NAME=SYSCOLUMNS.NAME AND OBJECT_ID = OBJECT_ID(#{tableName})
) ISIDENTITY,SYSCOLUMNS.NAME NAME,SYSTYPES.NAME TYPE,SYSCOLUMNS.ISNULLABLE NULLABLE,SYSCOLUMNS.LENGTH LENGTH,PRIMARYINFO.ISPRAMARY
FROM SYSCOLUMNS
SELECT IS_IDENTITY FROM ${dbName}.SYS.ALL_COLUMNS
WHERE ${dbName}.SYS.ALL_COLUMNS.NAME=SYSCOLUMNS.NAME AND OBJECT_ID = OBJECT_ID('${dbName}..${tableName}')
) selfIncrement, SYSCOLUMNS.NAME name,SYSTYPES.NAME type,Iif(SYSCOLUMNS.ISNULLABLE=1,'1','0') nullable,
SYSCOLUMNS.LENGTH length,PRIMARYINFO.ISPRAMARY primaryKey
FROM ${dbName}..SYSCOLUMNS
LEFT JOIN PRIMARYINFO ON PRIMARYINFO.COLUMNNAME=NAME
LEFT JOIN SYSTYPES ON SYSCOLUMNS.XUSERTYPE = SYSTYPES.XUSERTYPE
WHERE SYSCOLUMNS.ID = OBJECT_ID(#{tableName})
</select>
<select id="getTableColumnDescList" resultMap="TableColumnDescDtoMap">
SELECT B.name AS NAME,C.value AS DESCRIPTION
FROM sys.tables A
INNER JOIN sys.columns B ON B.object_id = A.object_id
LEFT JOIN sys.extended_properties C ON C.major_id = B.object_id AND C.minor_id = B.column_id
WHERE A.name = #{tableName}
LEFT JOIN ${dbName}..SYSTYPES ON SYSCOLUMNS.XUSERTYPE = SYSTYPES.XUSERTYPE
WHERE SYSCOLUMNS.ID = OBJECT_ID('${dbName}..${tableName}')
</select>
<select id="getTableAndColumnBySearch" resultMap="QueryTableColumnDescDtoMap">
SELECT top 500
A.name AS TABLE_NAME,B.name AS COLUMN_NAME,C.value AS DESCRIPTION
FROM sys.tables A
INNER JOIN sys.columns B ON B.object_id = A.object_id
LEFT JOIN sys.extended_properties C ON C.major_id = B.object_id AND C.minor_id = B.column_id
FROM ${dbName}.sys.tables A
INNER JOIN ${dbName}.sys.columns B ON B.object_id = A.object_id
LEFT JOIN ${dbName}.sys.extended_properties C ON C.major_id = B.object_id AND C.minor_id = B.column_id
WHERE convert(nvarchar(max),C.value) like #{searchText} OR B.name like #{searchText}
</select>
<select id="getTableDescList" resultType="com.zyplayer.doc.db.framework.db.dto.TableDescDto">
select 'TABLEDESC_SYS' as tableName, value as description, major_id as majorId
from sys.extended_properties
from ${dbName}.sys.extended_properties
WHERE minor_id=0
<if test="tableName != null">
and major_id=object_id(#{tableName})
@@ -80,24 +73,24 @@
</select>
<insert id="updateTableDesc">
IF ((SELECT COUNT(*) from fn_listextendedproperty('MS_Description', 'SCHEMA', 'dbo', 'TABLE', #{tableName}, NULL, NULL)) > 0)
EXEC sp_updateextendedproperty @name = 'MS_Description', @value = #{newDesc}
IF ((SELECT COUNT(*) from ${dbName}..fn_listextendedproperty('MS_Description', 'SCHEMA', 'dbo', 'TABLE', #{tableName}, NULL, NULL)) > 0)
EXEC ${dbName}..sp_updateextendedproperty @name = 'MS_Description', @value = #{newDesc}
, @level0type = 'SCHEMA', @level0name = 'dbo'
, @level1type = 'TABLE', @level1name = #{tableName}
ELSE
EXEC sp_addextendedproperty @name = 'MS_Description', @value = #{newDesc}
EXEC ${dbName}..sp_addextendedproperty @name = 'MS_Description', @value = #{newDesc}
, @level0type = 'SCHEMA', @level0name = 'dbo'
, @level1type = 'TABLE', @level1name = #{tableName}
</insert>
<insert id="updateTableColumnDesc">
IF ((SELECT COUNT(*) from fn_listextendedproperty('MS_Description', 'SCHEMA', 'dbo', 'TABLE', #{tableName}, 'COLUMN', #{columnName})) > 0)
EXEC sp_updateextendedproperty @name = 'MS_Description', @value = #{newDesc}
IF ((SELECT COUNT(*) from ${dbName}..fn_listextendedproperty('MS_Description', 'SCHEMA', 'dbo', 'TABLE', #{tableName}, 'COLUMN', #{columnName})) > 0)
EXEC ${dbName}..sp_updateextendedproperty @name = 'MS_Description', @value = #{newDesc}
, @level0type = 'SCHEMA', @level0name = 'dbo'
, @level1type = 'TABLE', @level1name = #{tableName}
, @level2type = 'COLUMN', @level2name = #{columnName}
ELSE
EXEC sp_addextendedproperty @name = 'MS_Description', @value = #{newDesc}
EXEC ${dbName}..sp_addextendedproperty @name = 'MS_Description', @value = #{newDesc}
, @level0type = 'SCHEMA', @level0name = 'dbo'
, @level1type = 'TABLE', @level1name = #{tableName}
, @level2type = 'COLUMN', @level2name = #{columnName}

View File

@@ -1,11 +1,26 @@
package com.zyplayer.doc.db.framework.db.mapper.sqlserver;
import com.zyplayer.doc.db.framework.db.dto.TableColumnDescDto;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* sqlserver数据库的mapper持有对象
*
*
* @author 暮光:城中城
* @since 2018年8月8日
*/
public interface SqlServerMapper {
/**
* 获取字段注释
*
* @param tableName 表名
* @return 表字段注释
* @author 暮光:城中城
* @since 2018年8月8日
*/
List<TableColumnDescDto> getTableColumnDescList(@Param("tableName") String tableName);
}

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zyplayer.doc.db.framework.db.mapper.sqlserver.SqlServerMapper">
<select id="getTableColumnDescList" resultType="com.zyplayer.doc.db.framework.db.dto.TableColumnDescDto">
SELECT B.name AS name,C.value AS description
FROM sys.tables A
INNER JOIN sys.columns B ON B.object_id = A.object_id
LEFT JOIN sys.extended_properties C ON C.major_id = B.object_id AND C.minor_id = B.column_id
WHERE A.name = #{tableName}
</select>
</mapper>

View File

@@ -0,0 +1,17 @@
package com.zyplayer.doc.db.framework.db.parser;
import cn.hutool.core.date.DateTime;
public interface FillParamParser {
/**
* 执行时间处理
*
* @param dateTime 时间
* @param paramOne 第一个参数
* @param paramThree 第三个参数
* @return 时间格式化
*/
String parser(DateTime dateTime, String paramOne, String paramTwo, String paramThree);
}

View File

@@ -0,0 +1,128 @@
package com.zyplayer.doc.db.framework.db.parser;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
* 参数填充帮助类
*
* @author 暮光:城中城
* @since 2019-10-10
*/
public class FillParamUtil {
// 填充时参数map里传入的当前时间的key
public static final String PARAM_NOW = "_now";
public static String fillSqlParam(String sql, Map<String, Object> paramMap) {
return FillParamUtil.fillSqlParam(sql, paramMap, (dateTime, paramOne, format, paramThree) -> {
int addInt = NumberUtils.toInt(paramThree);
if (Objects.equals("now", paramOne)) {
dateTime.offset(DateField.DAY_OF_MONTH, addInt);
format = (format == null) ? "yyyy-MM-dd HH:mm:ss" : format;
} else if (Objects.equals("dt", paramOne)) {
dateTime.offset(DateField.DAY_OF_MONTH, addInt);
format = (format == null) ? "yyyyMMdd" : format;
} else if (Objects.equals("now_d", paramOne)) {
dateTime.offset(DateField.DAY_OF_MONTH, addInt);
format = (format == null) ? "yyyyMMdd" : format;
} else if (Objects.equals("now_m", paramOne)) {
dateTime.offset(DateField.MONTH, addInt);
format = (format == null) ? "yyyyMM" : format;
}
return format;
});
}
/**
* 解析${column}预处理的参数,支持内置参数和动态参数
* 内置参数格式:
* ${now}
* ${now, yyyy-MM-dd 00:00:00}
* ${now, yyyy-MM-dd 00:00:00, 1}
* 内置参数说明:
* 参数1、now当前时间 now_d当前天 now_m当前月
* 参数2、加减天数负数为减。参数1为 now/now_d 时,按天加减,为 now_m 时按月加减
* 参数3、日期格式yyyy-MM-dd HH:mm:ss
*
* @param sql
* @param paramMap
* @return
* @author 暮光:城中城
* @since 2019-10-10
*/
public static String fillSqlParam(String sql, Map<String, Object> paramMap, FillParamParser paramParser) {
// 组装参数
GenericTokenParser parser = new GenericTokenParser("${", "}", content -> {
Object o = paramMap.get(content);
if (o == null) {
Object nowDate = paramMap.get(FillParamUtil.PARAM_NOW);
String[] keyArr = content.split(",");
if (keyArr.length == 1) {
o = getFillParam(paramParser, nowDate, keyArr[0].trim(), null, null);
} else if (keyArr.length == 2) {
o = getFillParam(paramParser, nowDate, keyArr[0].trim(), keyArr[1].trim(), null);
} else if (keyArr.length == 3) {
o = getFillParam(paramParser, nowDate, keyArr[0].trim(), keyArr[1].trim(), keyArr[2].trim());
}
}
return (o == null) ? null : String.valueOf(o);
});
return parser.parse(sql);
}
/**
* 内置参数填充
* ${now, 'yyyy-MM-dd 00:00:00', 1}
*
* @param name
* @param format
* @param add
* @return
* @author 暮光:城中城
* @since 2019-10-10
*/
private static String getFillParam(FillParamParser parser, Object nowDate, String name, String format, String add) {
DateTime dateTime;
// 格式化加不加单引号都支持
if (format != null && format.startsWith("'") && format.endsWith("'")) {
format = format.substring(1, format.length() - 1);
}
// 使用系统时间还是传入的时间作为初始值
if (nowDate instanceof Date) {
dateTime = DateTime.of((Date) nowDate);
} else {
dateTime = DateTime.now();
}
format = (format == null) ? null : format.trim();
if (parser != null) {
format = parser.parser(dateTime, name, format, add);
}
if (StringUtils.isNotBlank(format)) {
return dateTime.toString(format);
}
return null;
// 内置参数格式:
// ${now}
// ${now, yyyy-MM-dd 00:00:00}
// ${now, yyyy-MM-dd 00:00:00, 1}
// 内置参数说明:
// 参数1、now当前时间 now_d当前天 now_m当前月 dt当前年月日默认yyyyMMdd格式
// 参数2、加减天数负数为减。参数1为 now/now_d 时,按天加减,为 now_m 时按月加减
// 参数3、日期格式yyyy-MM-dd HH:mm:ss
}
public static void main(String[] args) {
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("day", 4);
String s = fillSqlParam("${now, yyyy-MM-dd 00:00:00, 2}\n dasda", paramMap);
System.out.println(s);
}
}

View File

@@ -0,0 +1,89 @@
/**
* Copyright 2009-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.zyplayer.doc.db.framework.db.parser;
import org.apache.ibatis.parsing.TokenHandler;
/**
* 参数预处理类
* @author Clinton Begin
* @author 暮光:城中城
* @since 2019-10-10
*/
public class GenericTokenParser {
private final String openToken;
private final String closeToken;
private final TokenHandler handler;
public GenericTokenParser(String openToken, String closeToken, TokenHandler handler) {
this.openToken = openToken;
this.closeToken = closeToken;
this.handler = handler;
}
public String parse(String text) {
if (text == null || text.isEmpty()) {
return "";
}
int start = text.indexOf(openToken, 0);
if (start == -1) {
return text;
}
char[] src = text.toCharArray();
int offset = 0;
final StringBuilder builder = new StringBuilder();
StringBuilder expression = null;
while (start > -1) {
if (start > 0 && src[start - 1] == '\\') {
builder.append(src, offset, start - offset - 1).append(openToken);
offset = start + openToken.length();
} else {
if (expression == null) {
expression = new StringBuilder();
} else {
expression.setLength(0);
}
builder.append(src, offset, start - offset);
offset = start + openToken.length();
int end = text.indexOf(closeToken, offset);
while (end > -1) {
if (end > offset && src[end - 1] == '\\') {
expression.append(src, offset, end - offset - 1).append(closeToken);
offset = end + closeToken.length();
end = text.indexOf(closeToken, offset);
} else {
expression.append(src, offset, end - offset);
offset = end + closeToken.length();
break;
}
}
if (end == -1) {
builder.append(src, start, src.length - start);
offset = src.length;
} else {
builder.append(handler.handleToken(expression.toString()));
offset = end + closeToken.length();
}
}
start = text.indexOf(openToken, offset);
}
if (offset < src.length) {
builder.append(src, offset, src.length - offset);
}
return builder.toString();
}
}

Some files were not shown because too many files have changed in this diff Show More