version for 1.6.11 : support SQLite

This commit is contained in:
inrgihc
2022-07-02 17:46:13 +08:00
parent 432a470eba
commit fd312588c7
73 changed files with 716 additions and 165 deletions

View File

@@ -24,19 +24,19 @@
### 3、详细功能
- 源端oracle/SqlServer/MySQL/MariaDB/PostgreSQL/DB2/DM/Kingbase8/HighGo/Hive向目的端为Greenplum/PostgreSQL/HighGo的迁移(**支持绝大多数常规类型字段**)
- 源端oracle/SqlServer/MySQL/MariaDB/PostgreSQL/DB2/DM/Kingbase8/HighGo/Hive/SQLite向目的端为Greenplum/PostgreSQL/HighGo的迁移(**支持绝大多数常规类型字段**)
- 源端oracle/SqlServer/MySQL/MariaDB/PostgreSQL/DB2/DM/Kingbase8/HighGo/Hive向目的端为Oracle的迁移(**支持绝大多数常规类型字段**)
- 源端oracle/SqlServer/MySQL/MariaDB/PostgreSQL/DB2/DM/Kingbase8/HighGo/Hive/SQLite向目的端为Oracle/DM的迁移(**支持绝大多数常规类型字段**)
- 源端oracle/SqlServer/MySQL/MariaDB/PostgreSQL/DB2/DM/Kingbase8/HighGo/Hive向目的端为DM的迁移(**支持绝大多数常规类型字段...**)
- 源端oracle/SqlServer/MySQL/MariaDB/PostgreSQL/DB2/DM/Kingbase8/HighGo/Hive/SQLite向目的端为SQLServer的迁移(**字段类型兼容测试中...**)
- 源端oracle/SqlServer/MySQL/MariaDB/PostgreSQL/DB2/DM/Kingbase8/HighGo/Hive向目的端为SQLServer的迁移(**字段类型兼容测试中...**)
- 源端oracle/SqlServer/MySQL/MariaDB/PostgreSQL/DB2/DM/Kingbase8/HighGo/Hive/SQLite向目的端为MySQL/MariaDB的迁移(**字段类型兼容测试中...**)
- 源端oracle/SqlServer/MySQL/MariaDB/PostgreSQL/DB2/DM/Kingbase8/HighGo/Hive向目的端为MySQL/MariaDB的迁移(**字段类型兼容测试中...**)
- 源端oracle/SqlServer/MySQL/MariaDB/PostgreSQL/DB2/DM/Kingbase8/HighGo/Hive/SQLite向目的端为DB2的迁移(**字段类型兼容测试中...**)
- 源端oracle/SqlServer/MySQL/MariaDB/PostgreSQL/DB2/DM/Kingbase8/HighGo/Hive向目的端为DB2的迁移(**字段类型兼容测试中...**)
- 源端oracle/SqlServer/MySQL/MariaDB/PostgreSQL/DB2/DM/Kingbase8/HighGo/Hive/SQLite向目的端为Kingbase8的迁移(**支持绝大多数常规类型字段...**)
- 源端oracle/SqlServer/MySQL/MariaDB/PostgreSQL/DB2/DM/Kingbase8/HighGo/Hive向目的端为Kingbase8的迁移(**支持绝大多数常规类型字段...**)
- 源端oracle/SqlServer/MySQL/MariaDB/PostgreSQL/DB2/DM/Kingbase8/HighGo/Hive/SQLite向目的端为SQLite的迁移(**支持部分常规类型字段...**)
** 注:** 目前Hive只支持Hive version 3.x的账号密码方式认证。
@@ -112,7 +112,7 @@ sh ./docker-maven-build.sh
(2) 基于docker-compose提供linux联网环境下的**一键安装**,安装命令见 [发行版链接地址](https://gitee.com/inrgihc/dbswitch/releases)
详见文档: [build-docker/install/README.md](build-docker/install)
文档详见: [build-docker/install/README.md](build-docker/install)
## 三、工具使用
@@ -206,21 +206,21 @@ dbswitch:
- 5对于```regex-table-mapper```和```regex-column-mappe```为基于正则表达式替换的表名映射和字段名映射均可以为空代表原名映射即源的表t_a映射到目的端也为t_a
> 提示:如果要将源端所有表名添加前缀,可以配置```"from-pattern": "^","to-value": "T_"```;
> 提示:如果要将源端所有表名(或者字段名)添加前缀,可以配置```"from-pattern": "^","to-value": "T_"```;
- 6各个数据库的JDBC驱动连接示例如下
**mysql/mariadb的驱动配置样例**
```
jdbc连接地址jdbc:mysql://172.17.2.10:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true&tinyInt1isBit=false
jdbc连接地址jdbc:mysql://172.17.2.10:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true&tinyInt1isBit=false&rewriteBatchedStatements=true
jdbc驱动名称 com.mysql.jdbc.Driver
```
与:
```
jdbc连接地址jdbc:mariadb://172.17.2.10:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true&tinyInt1isBit=false
jdbc连接地址jdbc:mariadb://172.17.2.10:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true&tinyInt1isBit=false&rewriteBatchedStatements=true
jdbc驱动名称 org.mariadb.jdbc.Driver
```
@@ -241,7 +241,7 @@ jdbc驱动名称com.microsoft.sqlserver.jdbc.SQLServerDriver
**PostgreSQL/Greenplum的驱动配置样例**
```
jdbc连接地址jdbc:postgresql://172.17.2.10:5432/study
jdbc连接地址jdbc:postgresql://172.17.2.10:5432/test
jdbc驱动名称org.postgresql.Driver
```
@@ -280,6 +280,32 @@ jdbc连接地址jdbc:hive2://172.17.2.12:10000/default
jdbc驱动名称org.apache.hive.jdbc.HiveDriver
```
注意当前只支持hive version 3.x的账号密码认证方式。
**SQLite数据库**
```
jdbc连接地址jdbc:sqlite:/tmp/test.db 或者 jdbc:sqlite::resource:http://172.17.2.12:8080/test.db
jdbc驱动名称org.sqlite.JDBC
```
注意:
> (a) 本地文件方式jdbc:sqlite:/tmp/test.db , 该方式适用于dbswitch为实体机器部署的场景。
>
> (b) 远程文件方式: jdbc:sqlite::resource:http://172.17.2.12:8080/test.db ,该方式适用于容器方式部署的场景, 搭建文件服务器的方法可使
> 用如下docker方式快速部署(/home/sqlites为服务器上存放sqlite数据库文件的目录)
>
> ```docker run -d --name http_file_server -p 8080:8080 -v /home/sqlites:/data inrgihc/http_file_server:latest```
>
> 说明远程服务器文件将会被下载到本地System.getProperty("java.io.tmpdir")所指定的目录下(linux为/tmp/Windows为C:/temp/),并以
> sqlite-jdbc-tmp-{XXX}.db的方式进行文件命名其中{XXX}为文件网络地址(例如上述为http://192.168.31.57:8080/test.db) 的字符串哈希值,
> 如果本地文件已经存在则不会再次进行下载而是直接使用该文件(当已经下载过文件后远程服务器即使关闭了该sqlite的jdbc-url任然可
> 用直至本地的sqlite-jdbc-tmp-XXX.db文件被人为手动删除)
>
> (c) 不支持内存及其他方式;本地文件方式可以作为源端和目的端,而远程服务器方式只能作为源端。
>
> (d) SQLite为单写多读方式禁止人为方式造成多写导致锁表。
#### (2)、启动方法
- linux系统下
@@ -388,15 +414,17 @@ bin/startup.sh
- dbswitch离线同步工具提供各种数据库间表结构转换RESTful在线API接口如下:(详见[接口文档](/INTERFACE.md)
> Swagger在线接口地址 http://127.0.0.1:9088/swagger-ui/
- WEB系统的访问如下
> URL地址: ```http://127.0.0.1:9088``` 登陆账号:```admin``` 登陆密码:```123456```
> Swagger在线接口地址 http://127.0.0.1:9088/swagger-ui/
注意如果为服务器部署时需要将127.0.0.1替换为服务器的IP地址。
- WEB系统的使用流程为
> 建立源端数据库的连接 -> 建立目的断数据库的连接 -> 配置任务 -> 发布任务 -> 手动/系统调度执行任务 -> 查看调度记录
> 建立源端数据库的连接 -> 建立目的断数据库的连接 -> 配置任务 -> 发布任务 -> 手动/系统调度执行任务 -> 查看调度记录 -> 数据目录查看数据结果
- WEB系统的部分截图

View File

@@ -2,7 +2,7 @@
set -e
DBSWITCH_VERSION=1.6.10
DBSWITCH_VERSION=1.6.11
BUILD_DOCKER_DIR="$( cd "$( dirname "$0" )" && pwd )"
PROJECT_ROOT_DIR=$( dirname "$BUILD_DOCKER_DIR")
DOCKER_DBSWITCH_DIR=$BUILD_DOCKER_DIR/dbswitch

View File

@@ -13,12 +13,14 @@ services:
MYSQL_ROOT_HOST: '%'
dbswitch:
container_name: dbswitch_webui
image: inrgihc/dbswitch:1.6.10
image: inrgihc/dbswitch:1.6.11
environment:
MYSQLDB_HOST: dbswitch_mysqldb
MYSQLDB_PORT: 3306
MYSQLDB_USERNAME: tangyibo
MYSQLDB_PASSWORD: 123456
volumes:
- /tmp:/tmp
ports:
- 9088:9088
depends_on:

View File

@@ -24,6 +24,9 @@
<p>
字段类型主键信息建表语句等的转换并生成建表SQL语句
</p>
<p>
支持基于正则表达式转换的表名与字段名映射转换
</p>
<li>数据迁移</li>
<p>
基于JDBC的分批次读取源端数据库数据并基于insert/copy方式将数据分批写入目的数据库
@@ -59,6 +62,8 @@
</li>
<li>PostgreSQL
</li>
<li>Greenplum
</li>
<li>DB2
</li>
<li>达梦数据库DM
@@ -69,6 +74,8 @@
</li>
<li>Apache Hive(只支持为源端)
</li>
<li>SQLite3
</li>
</ul>
</div>
</el-card>
@@ -79,7 +86,7 @@
<div class="content_tag">
<el-tag type="success">SpringBoot</el-tag>
<el-tag type="danger">Quartz</el-tag>
<el-tag type="success">Vue/Element</el-tag>
<el-tag type="success">Vue/ElementUI</el-tag>
</div>
<div class="content_card">
<el-card class="box-card">
@@ -98,7 +105,7 @@
dbswitch-dbsynch // 将dbchange模块计算的变更数据同步入库模块
dbswitch-data // 工具入口模块,读取配置文件中的参数执行异构迁移同步
dbswitch-admin // 在以上模块的基础上采用Quartz提供可视化调度
dbswitch-admin-ui // 基于Vue的前端交互页面
dbswitch-admin-ui // 基于Vue+ElementUI的前端交互页面
package-tool // 基于maven-assembly-plugin插件的项目打包模块
</pre>
</p>

View File

@@ -1,12 +1,14 @@
<template>
<div style="margin-top: 15px">
<el-table v-loading="loading"
:header-cell-style="{background:'#eef1f6',color:'#606266'}"
element-loading-text="拼命加载中"
element-loading-spinner="el-icon-loading"
element-loading-background="rgba(0, 0, 0, 0.8)"
:data="lists"
stripe
style="width:100%" size="small"
style="width:100%"
size="small"
border>
<el-table-column prop="createTime"
label="日志时间"

View File

@@ -1,6 +1,7 @@
<template>
<div style="margin-top: 15px">
<el-table v-loading="loading"
:header-cell-style="{background:'#eef1f6',color:'#606266'}"
element-loading-text="拼命加载中"
element-loading-spinner="el-icon-loading"
element-loading-background="rgba(0, 0, 0, 0.8)"

View File

@@ -56,8 +56,9 @@
<el-input slot="reference"
:disabled=false
v-model="createform.cronExpression"
placeholder="点击选择"
@click="cronPopover=true" />
placeholder="点击选择或手动输入"
@click="cronPopover=true"
size="small" />
</el-popover>
</el-col>
</el-form-item>

View File

@@ -56,8 +56,9 @@
<el-input slot="reference"
:disabled=false
v-model="updateform.cronExpression"
placeholder="点击选择"
@click="cronPopover=true" />
placeholder="点击选择或手动输入"
@click="cronPopover=true"
size="small" />
</el-popover>
</el-col>
</el-form-item>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>com.gitee.dbswitch</groupId>
<artifactId>dbswitch-parent</artifactId>
<version>1.6.10</version>
<version>1.6.11</version>
</parent>
<artifactId>dbswitch-admin</artifactId>

View File

@@ -41,11 +41,8 @@ import java.util.function.Supplier;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.quartz.CronExpression;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.quartz.CronExpression;
@Service
public class AssignmentService {
@@ -75,6 +72,12 @@ public class AssignmentService {
if (SupportDbTypeEnum.HIVE == entity.getType()) {
throw new DbswitchException(ResultCode.ERROR_INVALID_ASSIGNMENT_CONFIG, "不支持目的端数据源为Hive");
}
if (SupportDbTypeEnum.SQLITE3 == entity.getType()) {
if (SupportDbTypeEnum.isUnsupportedTargetSqlite(entity.getUrl())) {
throw new DbswitchException(ResultCode.ERROR_INVALID_ASSIGNMENT_CONFIG,
"不支持目的端数据源为远程服务器上的SQLite或内存方式下的SQLite");
}
}
return ConverterFactory.getConverter(AssignmentInfoConverter.class)
.convert(assignmentTaskDAO.getById(assignment.getId()));
@@ -101,6 +104,18 @@ public class AssignmentService {
.toAssignmentConfig(assignmentTaskEntity.getId());
assignmentConfigDAO.deleteByAssignmentTaskId(assignmentTaskEntity.getId());
assignmentConfigDAO.insert(assignmentConfigEntity);
Long targetConnectionId = assignmentConfigEntity.getTargetConnectionId();
DatabaseConnectionEntity entity = databaseConnectionDAO.getById(targetConnectionId);
if (SupportDbTypeEnum.HIVE == entity.getType()) {
throw new DbswitchException(ResultCode.ERROR_INVALID_ASSIGNMENT_CONFIG, "不支持目的端数据源为Hive");
}
if (SupportDbTypeEnum.SQLITE3 == entity.getType()) {
if (SupportDbTypeEnum.isUnsupportedTargetSqlite(entity.getUrl())) {
throw new DbswitchException(ResultCode.ERROR_INVALID_ASSIGNMENT_CONFIG,
"不支持目的端数据源为远程服务器上的SQLite或内存方式下的SQLite");
}
}
}
public PageResult<AssignmentInfoResponse> listAll(String searchText, Integer page, Integer size) {

View File

@@ -49,6 +49,7 @@ public class DbConnectionService {
public IMetaDataByJdbcService getMetaDataCoreService(DatabaseConnectionEntity dbConn) {
String typeName = dbConn.getType().getName().toUpperCase();
SupportDbTypeEnum supportDbType = SupportDbTypeEnum.valueOf(typeName);
if (supportDbType.hasAddress()) {
for (String pattern : supportDbType.getUrl()) {
final Matcher matcher = JDBCURL.getPattern(pattern).matcher(dbConn.getUrl());
if (!matcher.matches()) {
@@ -69,6 +70,7 @@ public class DbConnectionService {
throw new DbswitchException(ResultCode.ERROR_CANNOT_CONNECT_REMOTE, dbConn.getName());
}
}
}
DatabaseTypeEnum prd = DatabaseTypeEnum.valueOf(dbConn.getType().getName().toUpperCase());
IMetaDataByJdbcService metaDataService = new MetaDataByJdbcServiceImpl(prd);
return metaDataService;
@@ -223,6 +225,10 @@ public class DbConnectionService {
throw new DbswitchException(ResultCode.ERROR_INVALID_JDBC_URL,
"库名没有指定 :" + conn.getUrl());
}
if (supportDbType.hasFilePath() && StringUtils.isBlank(matcher.group("file"))) {
throw new DbswitchException(ResultCode.ERROR_INVALID_JDBC_URL,
"文件路径没有指定 :" + conn.getUrl());
}
break;
}

View File

@@ -9,6 +9,7 @@
/////////////////////////////////////////////////////////////
package com.gitee.dbswitch.admin.type;
import java.util.Arrays;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.util.StringUtils;
@@ -54,6 +55,12 @@ public enum SupportDbTypeEnum {
"SELECT 1",
"jdbc:hive2://",
new String[]{"jdbc:hive2://{host}[:{port}]/[{database}][\\?{params}]"}),
// 参考文章https://blog.csdn.net/wank1259162/article/details/104946744
SQLITE3(1, "sqlite3", "org.sqlite.JDBC", 0,
"SELECT 1",
"jdbc:sqlite:",
new String[]{"jdbc:sqlite:{file}", "jdbc:sqlite::resource:{file}"}),
;
private int id;
@@ -65,7 +72,15 @@ public enum SupportDbTypeEnum {
private String[] url;
public boolean hasDatabaseName() {
return this != DM;
return !Arrays.asList(DM, SQLITE3).contains(this);
}
public boolean hasFilePath() {
return this == SQLITE3;
}
public boolean hasAddress() {
return this != SQLITE3;
}
public static SupportDbTypeEnum of(String name) {
@@ -80,4 +95,10 @@ public enum SupportDbTypeEnum {
throw new IllegalArgumentException("cannot find enum name: " + name);
}
public static boolean isUnsupportedTargetSqlite(String url) {
String prefix1 = "jdbc:sqlite::resource:";
//String prefix2 = "jdbc:sqlite::memory:";
return url.startsWith(prefix1);
}
}

View File

@@ -1 +1 @@
<!DOCTYPE html><html><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>异构数据迁移工具</title><link href=/static/css/app.b3378b34adc1e2ea16f5864d0330a4ea.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=/static/js/manifest.feed98e3dd9fb57fcb68.js></script><script type=text/javascript src=/static/js/vendor.d6c2f50c2f02bf33c8cf.js></script><script type=text/javascript src=/static/js/app.bd883e8c290338935864.js></script></body></html>
<!DOCTYPE html><html><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>异构数据迁移工具</title><link href=/static/css/app.7100812cbfb54537881ccb2f2c33240f.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=/static/js/manifest.4f3e74017de9a770cb02.js></script><script type=text/javascript src=/static/js/vendor.d6c2f50c2f02bf33c8cf.js></script><script type=text/javascript src=/static/js/app.4dca8abefa8e2bff97e5.js></script></body></html>

View File

@@ -0,0 +1,2 @@
webpackJsonp([10],{oQRv:function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n={data:function(){return{loading:!0,lists:[],currentPage:1,pageSize:10,totalCount:0}},methods:{loadData:function(){var t=this;this.$http.get("/dbswitch/admin/api/v1/syslog/list/1/"+this.currentPage+"/"+this.pageSize).then(function(e){t.loading=!1,0===e.data.code?(t.currentPage=e.data.pagination.page,t.pageSize=e.data.pagination.size,t.totalCount=e.data.pagination.total,t.lists=e.data.data):alert("加载数据失败:"+e.data.message)},function(e){t.$message({showClose:!0,message:"数据加载错误",type:"error"})})},handleSizeChange:function(t){this.loading=!0,this.pageSize=t,this.loadData()},handleCurrentChange:function(t){this.loading=!0,this.currentPage=t,this.loadData()}},created:function(){this.loadData()}},i={render:function(){var t=this,e=t.$createElement,a=t._self._c||e;return a("div",{staticStyle:{"margin-top":"15px"}},[a("el-table",{directives:[{name:"loading",rawName:"v-loading",value:t.loading,expression:"loading"}],staticStyle:{width:"100%"},attrs:{"header-cell-style":{background:"#eef1f6",color:"#606266"},"element-loading-text":"拼命加载中","element-loading-spinner":"el-icon-loading","element-loading-background":"rgba(0, 0, 0, 0.8)",data:t.lists,stripe:"",size:"small",border:""}},[a("el-table-column",{attrs:{prop:"createTime",label:"日志时间","min-width":"15%","show-overflow-tooltip":!0}}),t._v(" "),a("el-table-column",{attrs:{prop:"ipAddress",label:"请求IP","min-width":"10%","show-overflow-tooltip":!0}}),t._v(" "),a("el-table-column",{attrs:{prop:"content",label:"操作内容","min-width":"20%","show-overflow-tooltip":!0}}),t._v(" "),a("el-table-column",{attrs:{prop:"userAgent",label:"请求代理","min-width":"50%","show-overflow-tooltip":!0}})],1),t._v(" "),a("div",{staticClass:"page",attrs:{align:"right"}},[a("el-pagination",{attrs:{"current-page":t.currentPage,"page-sizes":[5,10,20,40],"page-size":t.pageSize,layout:"total, sizes, prev, pager, next, jumper",total:t.totalCount},on:{"size-change":t.handleSizeChange,"current-change":t.handleCurrentChange}})],1)],1)},staticRenderFns:[]};var o=a("VU/8")(n,i,!1,function(t){a("rPsM")},"data-v-86686ab2",null);e.default=o.exports},rPsM:function(t,e){}});
//# sourceMappingURL=10.c2e1c087ed8b370c038c.js.map

File diff suppressed because one or more lines are too long

View File

@@ -1,2 +0,0 @@
webpackJsonp([10],{"0eSS":function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var l={data:function(){return{loading:!0,lists:[],currentPage:1,pageSize:10,totalCount:0}},methods:{loadData:function(){var e=this;this.$http.get("/dbswitch/admin/api/v1/syslog/list/2/"+this.currentPage+"/"+this.pageSize).then(function(t){e.loading=!1,0===t.data.code?(e.currentPage=t.data.pagination.page,e.pageSize=t.data.pagination.size,e.totalCount=t.data.pagination.total,e.lists=t.data.data):alert("加载数据失败:"+t.data.message)},function(t){e.$message({showClose:!0,message:"数据加载错误",type:"error"})})},boolFormat:function(e,t){return!0===e.failed?"是":"否"},handleSizeChange:function(e){this.loading=!0,this.pageSize=e,this.loadData()},handleCurrentChange:function(e){this.loading=!0,this.currentPage=e,this.loadData()},handleDetail:function(e,t){this.$message({showClose:!0,message:"查看日志详情"+e+" "+t,type:"info"})}},created:function(){this.loadData()}},o={render:function(){var e=this,t=e.$createElement,a=e._self._c||t;return a("div",{staticStyle:{"margin-top":"15px"}},[a("el-table",{directives:[{name:"loading",rawName:"v-loading",value:e.loading,expression:"loading"}],staticStyle:{width:"100%"},attrs:{"element-loading-text":"拼命加载中","element-loading-spinner":"el-icon-loading","element-loading-background":"rgba(0, 0, 0, 0.8)",data:e.lists,stripe:"",size:"small",border:""}},[a("el-table-column",{attrs:{type:"expand"},scopedSlots:e._u([{key:"default",fn:function(t){return[a("el-form",{staticClass:"demo-table-expand",attrs:{"label-position":"left",inline:""}},[a("el-form-item",{attrs:{label:"日志编号:"}},[a("span",[e._v(e._s(t.row.id))])]),e._v(" "),a("el-form-item",{attrs:{label:"日志时间:"}},[a("span",[e._v(e._s(t.row.createTime))])]),e._v(" "),a("el-form-item",{attrs:{label:"操作用户:"}},[a("span",[e._v(e._s(t.row.username))])]),e._v(" "),a("el-form-item",{attrs:{label:"请求IP地址:"}},[a("span",[e._v(e._s(t.row.ipAddress))])]),e._v(" "),a("el-form-item",{attrs:{label:"操作模块:"}},[a("span",[e._v(e._s(t.row.moduleName))])]),e._v(" "),a("el-form-item",{attrs:{label:"操作描述:"}},[a("span",[e._v(e._s(t.row.content))])]),e._v(" "),a("el-form-item",{attrs:{label:"处理耗时(ms):"}},[a("span",[e._v(e._s(t.row.elapseSeconds))])]),e._v(" "),a("el-form-item",{attrs:{label:"请求路径:"}},[a("span",[e._v(e._s(t.row.urlPath))])]),e._v(" "),a("el-form-item",{attrs:{label:"异常状态:"}},[a("span",[e._v(e._s(t.row.failed))])]),e._v(" "),a("el-form-item",{attrs:{label:""}},[a("span")]),e._v(" "),a("el-form-item",{attrs:{label:"异常日志:"}},[a("el-input",{staticStyle:{"font-size":"12px",width:"700px"},attrs:{type:"textarea",autosize:{minRows:2,maxRows:5}},model:{value:t.row.exception,callback:function(a){e.$set(t.row,"exception",a)},expression:"props.row.exception"}})],1)],1)]}}])}),e._v(" "),a("el-table-column",{attrs:{prop:"createTime",label:"日志时间","min-width":"15%","show-overflow-tooltip":!0}}),e._v(" "),a("el-table-column",{attrs:{prop:"username",label:"操作用户","min-width":"10%","show-overflow-tooltip":!0}}),e._v(" "),a("el-table-column",{attrs:{prop:"ipAddress",label:"请求IP","min-width":"10%","show-overflow-tooltip":!0}}),e._v(" "),a("el-table-column",{attrs:{prop:"moduleName",label:"操作类型","min-width":"10%","show-overflow-tooltip":!0}}),e._v(" "),a("el-table-column",{attrs:{prop:"elapseSeconds",label:"耗时(ms)","min-width":"10%","show-overflow-tooltip":!0}}),e._v(" "),a("el-table-column",{attrs:{prop:"urlPath",label:"请求路径","min-width":"20%","show-overflow-tooltip":!0}}),e._v(" "),a("el-table-column",{attrs:{prop:"failed",label:"异常",formatter:e.boolFormat,"min-width":"10%","show-overflow-tooltip":!0}})],1),e._v(" "),a("div",{staticClass:"page",attrs:{align:"right"}},[a("el-pagination",{attrs:{"current-page":e.currentPage,"page-sizes":[5,10,20,40],"page-size":e.pageSize,layout:"total, sizes, prev, pager, next, jumper",total:e.totalCount},on:{"size-change":e.handleSizeChange,"current-change":e.handleCurrentChange}})],1)],1)},staticRenderFns:[]};var n=a("VU/8")(l,o,!1,function(e){a("sACR")},"data-v-5a0d71c9",null);t.default=n.exports},sACR:function(e,t){}});
//# sourceMappingURL=10.ec3b8253b1c336df3447.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,2 +0,0 @@
webpackJsonp([14],{HH4r:function(t,e){},oQRv:function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n={data:function(){return{loading:!0,lists:[],currentPage:1,pageSize:10,totalCount:0}},methods:{loadData:function(){var t=this;this.$http.get("/dbswitch/admin/api/v1/syslog/list/1/"+this.currentPage+"/"+this.pageSize).then(function(e){t.loading=!1,0===e.data.code?(t.currentPage=e.data.pagination.page,t.pageSize=e.data.pagination.size,t.totalCount=e.data.pagination.total,t.lists=e.data.data):alert("加载数据失败:"+e.data.message)},function(e){t.$message({showClose:!0,message:"数据加载错误",type:"error"})})},handleSizeChange:function(t){this.loading=!0,this.pageSize=t,this.loadData()},handleCurrentChange:function(t){this.loading=!0,this.currentPage=t,this.loadData()}},created:function(){this.loadData()}},i={render:function(){var t=this,e=t.$createElement,a=t._self._c||e;return a("div",{staticStyle:{"margin-top":"15px"}},[a("el-table",{directives:[{name:"loading",rawName:"v-loading",value:t.loading,expression:"loading"}],staticStyle:{width:"100%"},attrs:{"element-loading-text":"拼命加载中","element-loading-spinner":"el-icon-loading","element-loading-background":"rgba(0, 0, 0, 0.8)",data:t.lists,stripe:"",size:"small",border:""}},[a("el-table-column",{attrs:{prop:"createTime",label:"日志时间","min-width":"15%","show-overflow-tooltip":!0}}),t._v(" "),a("el-table-column",{attrs:{prop:"ipAddress",label:"请求IP","min-width":"10%","show-overflow-tooltip":!0}}),t._v(" "),a("el-table-column",{attrs:{prop:"content",label:"操作内容","min-width":"20%","show-overflow-tooltip":!0}}),t._v(" "),a("el-table-column",{attrs:{prop:"userAgent",label:"请求代理","min-width":"50%","show-overflow-tooltip":!0}})],1),t._v(" "),a("div",{staticClass:"page",attrs:{align:"right"}},[a("el-pagination",{attrs:{"current-page":t.currentPage,"page-sizes":[5,10,20,40],"page-size":t.pageSize,layout:"total, sizes, prev, pager, next, jumper",total:t.totalCount},on:{"size-change":t.handleSizeChange,"current-change":t.handleCurrentChange}})],1)],1)},staticRenderFns:[]};var o=a("VU/8")(n,i,!1,function(t){a("HH4r")},"data-v-1bc640ee",null);e.default=o.exports}});
//# sourceMappingURL=14.220c10d64f09655e8973.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,2 @@
webpackJsonp([9],{"0eSS":function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var l={data:function(){return{loading:!0,lists:[],currentPage:1,pageSize:10,totalCount:0}},methods:{loadData:function(){var e=this;this.$http.get("/dbswitch/admin/api/v1/syslog/list/2/"+this.currentPage+"/"+this.pageSize).then(function(t){e.loading=!1,0===t.data.code?(e.currentPage=t.data.pagination.page,e.pageSize=t.data.pagination.size,e.totalCount=t.data.pagination.total,e.lists=t.data.data):alert("加载数据失败:"+t.data.message)},function(t){e.$message({showClose:!0,message:"数据加载错误",type:"error"})})},boolFormat:function(e,t){return!0===e.failed?"是":"否"},handleSizeChange:function(e){this.loading=!0,this.pageSize=e,this.loadData()},handleCurrentChange:function(e){this.loading=!0,this.currentPage=e,this.loadData()},handleDetail:function(e,t){this.$message({showClose:!0,message:"查看日志详情"+e+" "+t,type:"info"})}},created:function(){this.loadData()}},o={render:function(){var e=this,t=e.$createElement,a=e._self._c||t;return a("div",{staticStyle:{"margin-top":"15px"}},[a("el-table",{directives:[{name:"loading",rawName:"v-loading",value:e.loading,expression:"loading"}],staticStyle:{width:"100%"},attrs:{"header-cell-style":{background:"#eef1f6",color:"#606266"},"element-loading-text":"拼命加载中","element-loading-spinner":"el-icon-loading","element-loading-background":"rgba(0, 0, 0, 0.8)",data:e.lists,stripe:"",size:"small",border:""}},[a("el-table-column",{attrs:{type:"expand"},scopedSlots:e._u([{key:"default",fn:function(t){return[a("el-form",{staticClass:"demo-table-expand",attrs:{"label-position":"left",inline:""}},[a("el-form-item",{attrs:{label:"日志编号:"}},[a("span",[e._v(e._s(t.row.id))])]),e._v(" "),a("el-form-item",{attrs:{label:"日志时间:"}},[a("span",[e._v(e._s(t.row.createTime))])]),e._v(" "),a("el-form-item",{attrs:{label:"操作用户:"}},[a("span",[e._v(e._s(t.row.username))])]),e._v(" "),a("el-form-item",{attrs:{label:"请求IP地址:"}},[a("span",[e._v(e._s(t.row.ipAddress))])]),e._v(" "),a("el-form-item",{attrs:{label:"操作模块:"}},[a("span",[e._v(e._s(t.row.moduleName))])]),e._v(" "),a("el-form-item",{attrs:{label:"操作描述:"}},[a("span",[e._v(e._s(t.row.content))])]),e._v(" "),a("el-form-item",{attrs:{label:"处理耗时(ms):"}},[a("span",[e._v(e._s(t.row.elapseSeconds))])]),e._v(" "),a("el-form-item",{attrs:{label:"请求路径:"}},[a("span",[e._v(e._s(t.row.urlPath))])]),e._v(" "),a("el-form-item",{attrs:{label:"异常状态:"}},[a("span",[e._v(e._s(t.row.failed))])]),e._v(" "),a("el-form-item",{attrs:{label:""}},[a("span")]),e._v(" "),a("el-form-item",{attrs:{label:"异常日志:"}},[a("el-input",{staticStyle:{"font-size":"12px",width:"700px"},attrs:{type:"textarea",autosize:{minRows:2,maxRows:5}},model:{value:t.row.exception,callback:function(a){e.$set(t.row,"exception",a)},expression:"props.row.exception"}})],1)],1)]}}])}),e._v(" "),a("el-table-column",{attrs:{prop:"createTime",label:"日志时间","min-width":"15%","show-overflow-tooltip":!0}}),e._v(" "),a("el-table-column",{attrs:{prop:"username",label:"操作用户","min-width":"10%","show-overflow-tooltip":!0}}),e._v(" "),a("el-table-column",{attrs:{prop:"ipAddress",label:"请求IP","min-width":"10%","show-overflow-tooltip":!0}}),e._v(" "),a("el-table-column",{attrs:{prop:"moduleName",label:"操作类型","min-width":"10%","show-overflow-tooltip":!0}}),e._v(" "),a("el-table-column",{attrs:{prop:"elapseSeconds",label:"耗时(ms)","min-width":"10%","show-overflow-tooltip":!0}}),e._v(" "),a("el-table-column",{attrs:{prop:"urlPath",label:"请求路径","min-width":"20%","show-overflow-tooltip":!0}}),e._v(" "),a("el-table-column",{attrs:{prop:"failed",label:"异常",formatter:e.boolFormat,"min-width":"10%","show-overflow-tooltip":!0}})],1),e._v(" "),a("div",{staticClass:"page",attrs:{align:"right"}},[a("el-pagination",{attrs:{"current-page":e.currentPage,"page-sizes":[5,10,20,40],"page-size":e.pageSize,layout:"total, sizes, prev, pager, next, jumper",total:e.totalCount},on:{"size-change":e.handleSizeChange,"current-change":e.handleCurrentChange}})],1)],1)},staticRenderFns:[]};var n=a("VU/8")(l,o,!1,function(e){a("3GnV")},"data-v-aee4e92e",null);t.default=n.exports},"3GnV":function(e,t){}});
//# sourceMappingURL=9.5a8e8f0e586b6f27113c.js.map

File diff suppressed because one or more lines are too long

View File

@@ -1,2 +1,2 @@
webpackJsonp([17],{NHnr:function(n,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=t("//Fk"),r=t.n(o),a=t("7+uW"),u={render:function(){var n=this.$createElement,e=this._self._c||n;return e("div",{staticClass:"body-wrapper"},[e("router-view")],1)},staticRenderFns:[]};var c=t("VU/8")({name:"App"},u,!1,function(n){t("Pibb")},"data-v-a97617c2",null).exports,i=t("/ocq");a.default.use(i.a);var l=new i.a({routes:[{path:"/",name:"首页",component:function(){return t.e(4).then(t.bind(null,"4er+"))},redirect:"/dashboard",children:[{path:"/dashboard",name:"概览",icon:"el-icon-menu",component:function(){return Promise.all([t.e(0),t.e(8)]).then(t.bind(null,"ARoL"))}},{path:"/connection",name:"连接管理",icon:"el-icon-s-order",component:function(){return Promise.all([t.e(0),t.e(11)]).then(t.bind(null,"qdtB"))}},{path:"/metadata",name:"数据目录",icon:"el-icon-coin",component:function(){return t.e(1).then(t.bind(null,"PJ2q"))}},{path:"/task",name:"任务管理",icon:"el-icon-s-tools",component:function(){return t.e(6).then(t.bind(null,"4KEO"))},children:[{path:"/task/assignment",name:"任务安排",icon:"el-icon-eleme",component:function(){return Promise.all([t.e(0),t.e(13)]).then(t.bind(null,"D0I9"))}},{path:"/task/schedule",name:"调度记录",icon:"el-icon-pie-chart",component:function(){return t.e(12).then(t.bind(null,"mKp/"))}}]},{path:"/log",name:"审计日志",icon:"el-icon-platform-eleme",component:function(){return t.e(7).then(t.bind(null,"QWih"))},children:[{path:"/log/access",name:"登录日志",icon:"el-icon-eleme",component:function(){return t.e(14).then(t.bind(null,"oQRv"))}},{path:"/log/action",name:"操作日志",icon:"el-icon-s-check",component:function(){return t.e(10).then(t.bind(null,"0eSS"))}}]},{path:"/about",name:"关于系统",icon:"el-icon-s-custom",component:function(){return t.e(2).then(t.bind(null,"m25N"))}},{path:"/user/personal",name:"个人中心",hidden:!0,component:function(){return t.e(3).then(t.bind(null,"uTKz"))}},{path:"/task/create",name:"创建任务",hidden:!0,component:function(){return Promise.all([t.e(0),t.e(9)]).then(t.bind(null,"/rCC"))}},{path:"/task/update",name:"修改任务",hidden:!0,component:function(){return Promise.all([t.e(0),t.e(15)]).then(t.bind(null,"txod"))}}]},{path:"/login",name:"登录",component:function(){return t.e(5).then(t.bind(null,"T+/8"))}}]}),p=t("mtWM"),s=t.n(p).a.create();s.interceptors.request.use(function(n){return n.url=""+n.url,n});var d=s,m=t("zL8q"),h=t.n(m),f=(t("muQq"),t("tvR6"),t("7Vno")),b=t.n(f),v=t("XLwt"),g=t.n(v);a.default.use(d),a.default.use(h.a),a.default.use(b.a),a.default.prototype.$http=d,a.default.config.productionTip=!1,a.default.prototype.$echarts=g.a,d.interceptors.request.use(function(n){var e=sessionStorage.getItem("token");return e&&(n.headers.Authorization="Bearer "+e),n},function(n){return r.a.reject(n)}),d.interceptors.response.use(function(n){return!n.data||401!==n.data.code&&403!==n.data.code&&404!==n.data.code||l.push({path:"/login"}),n},function(n){return console.log(n),r.a.reject(n.response)}),new a.default({el:"#app",router:l,components:{App:c},template:"<App/>"})},Pibb:function(n,e){},muQq:function(n,e){},tvR6:function(n,e){}},["NHnr"]);
//# sourceMappingURL=app.bd883e8c290338935864.js.map
webpackJsonp([17],{NHnr:function(n,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=t("//Fk"),r=t.n(o),a=t("7+uW"),u={render:function(){var n=this.$createElement,e=this._self._c||n;return e("div",{staticClass:"body-wrapper"},[e("router-view")],1)},staticRenderFns:[]};var c=t("VU/8")({name:"App"},u,!1,function(n){t("Pibb")},"data-v-a97617c2",null).exports,i=t("/ocq");a.default.use(i.a);var l=new i.a({routes:[{path:"/",name:"首页",component:function(){return t.e(4).then(t.bind(null,"4er+"))},redirect:"/dashboard",children:[{path:"/dashboard",name:"概览",icon:"el-icon-menu",component:function(){return Promise.all([t.e(0),t.e(8)]).then(t.bind(null,"ARoL"))}},{path:"/connection",name:"连接管理",icon:"el-icon-s-order",component:function(){return Promise.all([t.e(0),t.e(13)]).then(t.bind(null,"qdtB"))}},{path:"/metadata",name:"数据目录",icon:"el-icon-coin",component:function(){return t.e(1).then(t.bind(null,"PJ2q"))}},{path:"/task",name:"任务管理",icon:"el-icon-s-tools",component:function(){return t.e(6).then(t.bind(null,"4KEO"))},children:[{path:"/task/assignment",name:"任务安排",icon:"el-icon-eleme",component:function(){return Promise.all([t.e(0),t.e(15)]).then(t.bind(null,"D0I9"))}},{path:"/task/schedule",name:"调度记录",icon:"el-icon-pie-chart",component:function(){return t.e(14).then(t.bind(null,"mKp/"))}}]},{path:"/log",name:"审计日志",icon:"el-icon-platform-eleme",component:function(){return t.e(7).then(t.bind(null,"QWih"))},children:[{path:"/log/access",name:"登录日志",icon:"el-icon-eleme",component:function(){return t.e(10).then(t.bind(null,"oQRv"))}},{path:"/log/action",name:"操作日志",icon:"el-icon-s-check",component:function(){return t.e(9).then(t.bind(null,"0eSS"))}}]},{path:"/about",name:"关于系统",icon:"el-icon-s-custom",component:function(){return t.e(2).then(t.bind(null,"m25N"))}},{path:"/user/personal",name:"个人中心",hidden:!0,component:function(){return t.e(3).then(t.bind(null,"uTKz"))}},{path:"/task/create",name:"创建任务",hidden:!0,component:function(){return Promise.all([t.e(0),t.e(11)]).then(t.bind(null,"/rCC"))}},{path:"/task/update",name:"修改任务",hidden:!0,component:function(){return Promise.all([t.e(0),t.e(12)]).then(t.bind(null,"txod"))}}]},{path:"/login",name:"登录",component:function(){return t.e(5).then(t.bind(null,"T+/8"))}}]}),p=t("mtWM"),s=t.n(p).a.create();s.interceptors.request.use(function(n){return n.url=""+n.url,n});var d=s,m=t("zL8q"),h=t.n(m),f=(t("muQq"),t("tvR6"),t("7Vno")),b=t.n(f),v=t("XLwt"),g=t.n(v);a.default.use(d),a.default.use(h.a),a.default.use(b.a),a.default.prototype.$http=d,a.default.config.productionTip=!1,a.default.prototype.$echarts=g.a,d.interceptors.request.use(function(n){var e=sessionStorage.getItem("token");return e&&(n.headers.Authorization="Bearer "+e),n},function(n){return r.a.reject(n)}),d.interceptors.response.use(function(n){return!n.data||401!==n.data.code&&403!==n.data.code&&404!==n.data.code||l.push({path:"/login"}),n},function(n){return console.log(n),r.a.reject(n.response)}),new a.default({el:"#app",router:l,components:{App:c},template:"<App/>"})},Pibb:function(n,e){},muQq:function(n,e){},tvR6:function(n,e){}},["NHnr"]);
//# sourceMappingURL=app.4dca8abefa8e2bff97e5.js.map

View File

@@ -0,0 +1,2 @@
!function(e){var n=window.webpackJsonp;window.webpackJsonp=function(r,c,a){for(var f,d,i,u=0,s=[];u<r.length;u++)d=r[u],t[d]&&s.push(t[d][0]),t[d]=0;for(f in c)Object.prototype.hasOwnProperty.call(c,f)&&(e[f]=c[f]);for(n&&n(r,c,a);s.length;)s.shift()();if(a)for(u=0;u<a.length;u++)i=o(o.s=a[u]);return i};var r={},t={18:0};function o(n){if(r[n])return r[n].exports;var t=r[n]={i:n,l:!1,exports:{}};return e[n].call(t.exports,t,t.exports,o),t.l=!0,t.exports}o.e=function(e){var n=t[e];if(0===n)return new Promise(function(e){e()});if(n)return n[2];var r=new Promise(function(r,o){n=t[e]=[r,o]});n[2]=r;var c=document.getElementsByTagName("head")[0],a=document.createElement("script");a.type="text/javascript",a.charset="utf-8",a.async=!0,a.timeout=12e4,o.nc&&a.setAttribute("nonce",o.nc),a.src=o.p+"static/js/"+e+"."+{0:"ca67e87d8c000a42e592",1:"bd90a7e98064156140b6",2:"f18db4bdf8ae8c90de89",3:"d4c1dc7b68edb49b61d2",4:"c4abd62fbe15189d37a5",5:"837a4a67f1fcf6ee6c6a",6:"7f56c2238fb7e4ee2ecd",7:"d5dc80a855f66a3208ff",8:"2bf951413fb931374230",9:"5a8e8f0e586b6f27113c",10:"c2e1c087ed8b370c038c",11:"095e904476d1f54d76ff",12:"7a16e7ccf65062debc3b",13:"193d0e9c6755a2722219",14:"ed586583e97505228b92",15:"fb483208e2855048c8d0"}[e]+".js";var f=setTimeout(d,12e4);function d(){a.onerror=a.onload=null,clearTimeout(f);var n=t[e];0!==n&&(n&&n[1](new Error("Loading chunk "+e+" failed.")),t[e]=void 0)}return a.onerror=a.onload=d,c.appendChild(a),r},o.m=e,o.c=r,o.d=function(e,n,r){o.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},o.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(n,"a",n),n},o.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},o.p="/",o.oe=function(e){throw console.error(e),e}}([]);
//# sourceMappingURL=manifest.4f3e74017de9a770cb02.js.map

View File

@@ -1,2 +0,0 @@
!function(e){var n=window.webpackJsonp;window.webpackJsonp=function(r,c,f){for(var a,d,i,u=0,b=[];u<r.length;u++)d=r[u],t[d]&&b.push(t[d][0]),t[d]=0;for(a in c)Object.prototype.hasOwnProperty.call(c,a)&&(e[a]=c[a]);for(n&&n(r,c,f);b.length;)b.shift()();if(f)for(u=0;u<f.length;u++)i=o(o.s=f[u]);return i};var r={},t={18:0};function o(n){if(r[n])return r[n].exports;var t=r[n]={i:n,l:!1,exports:{}};return e[n].call(t.exports,t,t.exports,o),t.l=!0,t.exports}o.e=function(e){var n=t[e];if(0===n)return new Promise(function(e){e()});if(n)return n[2];var r=new Promise(function(r,o){n=t[e]=[r,o]});n[2]=r;var c=document.getElementsByTagName("head")[0],f=document.createElement("script");f.type="text/javascript",f.charset="utf-8",f.async=!0,f.timeout=12e4,o.nc&&f.setAttribute("nonce",o.nc),f.src=o.p+"static/js/"+e+"."+{0:"ca67e87d8c000a42e592",1:"bd90a7e98064156140b6",2:"45757fdd22b0c905f12a",3:"d4c1dc7b68edb49b61d2",4:"c4abd62fbe15189d37a5",5:"837a4a67f1fcf6ee6c6a",6:"7f56c2238fb7e4ee2ecd",7:"d5dc80a855f66a3208ff",8:"2bf951413fb931374230",9:"51471fff489d5c840717",10:"ec3b8253b1c336df3447",11:"313c152f4354145af7b5",12:"eb5401eb22c55db52cd0",13:"bdcf7e684437edab125f",14:"220c10d64f09655e8973",15:"60356d680f753f10fcdd"}[e]+".js";var a=setTimeout(d,12e4);function d(){f.onerror=f.onload=null,clearTimeout(a);var n=t[e];0!==n&&(n&&n[1](new Error("Loading chunk "+e+" failed.")),t[e]=void 0)}return f.onerror=f.onload=d,c.appendChild(f),r},o.m=e,o.c=r,o.d=function(e,n,r){o.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},o.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(n,"a",n),n},o.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},o.p="/",o.oe=function(e){throw console.error(e),e}}([]);
//# sourceMappingURL=manifest.feed98e3dd9fb57fcb68.js.map

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>com.gitee.dbswitch</groupId>
<artifactId>dbswitch-parent</artifactId>
<version>1.6.10</version>
<version>1.6.11</version>
</parent>
<artifactId>dbswitch-common</artifactId>

View File

@@ -9,6 +9,8 @@
/////////////////////////////////////////////////////////////
package com.gitee.dbswitch.common.type;
import java.util.Arrays;
/**
* 数据库类型的枚举定义
*
@@ -74,6 +76,11 @@ public enum DatabaseTypeEnum {
* HIVE数据库
*/
HIVE(11),
/**
* SQLite数据库
*/
SQLITE3(12),
;
private int index;
@@ -82,8 +89,12 @@ public enum DatabaseTypeEnum {
this.index = idx;
}
public int getIndex() {
return index;
public boolean noCommentStatement() {
return Arrays.asList(
DatabaseTypeEnum.MYSQL,
DatabaseTypeEnum.HIVE,
DatabaseTypeEnum.SQLITE3
).contains(this);
}
}

View File

@@ -44,6 +44,7 @@ public final class DatabaseAwareUtils {
productNameMap.put("PostgreSQL", DatabaseTypeEnum.POSTGRESQL);
productNameMap.put("DB2 for Unix/Windows", DatabaseTypeEnum.DB2);
productNameMap.put("Hive", DatabaseTypeEnum.HIVE);
productNameMap.put("SQLite", DatabaseTypeEnum.SQLITE3);
driverNameMap.put("MySQL Connector Java", DatabaseTypeEnum.MYSQL);
driverNameMap.put("MariaDB Connector/J", DatabaseTypeEnum.MARIADB);
@@ -53,6 +54,7 @@ public final class DatabaseAwareUtils {
driverNameMap.put("IBM Data Server Driver for JDBC and SQLJ", DatabaseTypeEnum.DB2);
driverNameMap.put("dm.jdbc.driver.DmDriver", DatabaseTypeEnum.DM);
driverNameMap.put("Hive JDBC", DatabaseTypeEnum.HIVE);
driverNameMap.put("SQLite JDBC", DatabaseTypeEnum.SQLITE3);
}
/**

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>com.gitee.dbswitch</groupId>
<artifactId>dbswitch-parent</artifactId>
<version>1.6.10</version>
<version>1.6.11</version>
</parent>
<artifactId>dbswitch-core</artifactId>
@@ -41,6 +41,11 @@
<artifactId>ojdbc8</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.oracle.ojdbc</groupId>
<artifactId>orai18n</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
@@ -110,6 +115,12 @@
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.31.1</version>
</dependency>
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-jdbc</artifactId>

View File

@@ -19,11 +19,12 @@ import com.gitee.dbswitch.core.database.impl.DatabaseMariaDBImpl;
import com.gitee.dbswitch.core.database.impl.DatabaseMysqlImpl;
import com.gitee.dbswitch.core.database.impl.DatabaseOracleImpl;
import com.gitee.dbswitch.core.database.impl.DatabasePostgresImpl;
import com.gitee.dbswitch.core.database.impl.DatabaseSqliteImpl;
import com.gitee.dbswitch.core.database.impl.DatabaseSqlserver2000Impl;
import com.gitee.dbswitch.core.database.impl.DatabaseSqlserverImpl;
import java.util.HashMap;
import java.util.Map;
import javax.sql.DataSource;
import java.util.concurrent.Callable;
/**
* 数据库实例构建工厂类
@@ -32,30 +33,32 @@ import javax.sql.DataSource;
*/
public final class DatabaseFactory {
private static final Map<DatabaseTypeEnum, String> DATABASE_MAPPER = new HashMap<DatabaseTypeEnum, String>() {
private static final Map<DatabaseTypeEnum, Callable<AbstractDatabase>> DATABASE_MAPPER
= new HashMap<DatabaseTypeEnum, Callable<AbstractDatabase>>() {
private static final long serialVersionUID = 9202705534880971997L;
{
put(DatabaseTypeEnum.MYSQL, DatabaseMysqlImpl.class.getName());
put(DatabaseTypeEnum.ORACLE, DatabaseOracleImpl.class.getName());
put(DatabaseTypeEnum.SQLSERVER2000, DatabaseSqlserver2000Impl.class.getName());
put(DatabaseTypeEnum.SQLSERVER, DatabaseSqlserverImpl.class.getName());
put(DatabaseTypeEnum.POSTGRESQL, DatabasePostgresImpl.class.getName());
put(DatabaseTypeEnum.GREENPLUM, DatabaseGreenplumImpl.class.getName());
put(DatabaseTypeEnum.MARIADB, DatabaseMariaDBImpl.class.getName());
put(DatabaseTypeEnum.DB2, DatabaseDB2Impl.class.getName());
put(DatabaseTypeEnum.DM, DatabaseDmImpl.class.getName());
put(DatabaseTypeEnum.KINGBASE, DatabaseKingbaseImpl.class.getName());
put(DatabaseTypeEnum.HIVE, DatabaseHiveImpl.class.getName());
put(DatabaseTypeEnum.MYSQL, DatabaseMysqlImpl::new);
put(DatabaseTypeEnum.ORACLE, DatabaseOracleImpl::new);
put(DatabaseTypeEnum.SQLSERVER2000, DatabaseSqlserver2000Impl::new);
put(DatabaseTypeEnum.SQLSERVER, DatabaseSqlserverImpl::new);
put(DatabaseTypeEnum.POSTGRESQL, DatabasePostgresImpl::new);
put(DatabaseTypeEnum.GREENPLUM, DatabaseGreenplumImpl::new);
put(DatabaseTypeEnum.MARIADB, DatabaseMariaDBImpl::new);
put(DatabaseTypeEnum.DB2, DatabaseDB2Impl::new);
put(DatabaseTypeEnum.DM, DatabaseDmImpl::new);
put(DatabaseTypeEnum.KINGBASE, DatabaseKingbaseImpl::new);
put(DatabaseTypeEnum.HIVE, DatabaseHiveImpl::new);
put(DatabaseTypeEnum.SQLITE3, DatabaseSqliteImpl::new);
}
};
public static AbstractDatabase getDatabaseInstance(DatabaseTypeEnum type) {
if (DATABASE_MAPPER.containsKey(type)) {
String className = DATABASE_MAPPER.get(type);
Callable<AbstractDatabase> callable = DATABASE_MAPPER.get(type);
if (null != callable) {
try {
return (AbstractDatabase) Class.forName(className).newInstance();
return callable.call();
} catch (Exception e) {
throw new RuntimeException(e);
}
@@ -66,6 +69,7 @@ public final class DatabaseFactory {
}
private DatabaseFactory() {
throw new IllegalStateException();
}
}

View File

@@ -0,0 +1,164 @@
// Copyright tang. All rights reserved.
// https://gitee.com/inrgihc/dbswitch
//
// Use of this source code is governed by a BSD-style license
//
// Author: tang (inrgihc@126.com)
// Date : 2020/1/2
// Location: beijing , china
/////////////////////////////////////////////////////////////
package com.gitee.dbswitch.core.database.impl;
import com.gitee.dbswitch.common.constant.Const;
import com.gitee.dbswitch.common.type.DatabaseTypeEnum;
import com.gitee.dbswitch.core.database.AbstractDatabase;
import com.gitee.dbswitch.core.database.IDatabaseInterface;
import com.gitee.dbswitch.core.model.ColumnDescription;
import com.gitee.dbswitch.core.model.ColumnMetaData;
import com.gitee.dbswitch.core.model.TableDescription;
import com.gitee.dbswitch.core.util.DDLFormatterUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collections;
import java.util.List;
/**
* 支持SQLite数据库的元信息实现
*
* @author tang
*/
public class DatabaseSqliteImpl extends AbstractDatabase implements IDatabaseInterface {
public DatabaseSqliteImpl() {
super("org.sqlite.JDBC");
}
@Override
public DatabaseTypeEnum getDatabaseType() {
return DatabaseTypeEnum.SQLITE3;
}
@Override
public List<String> querySchemaList(Connection connection) {
return Collections.singletonList("main");
}
@Override
public String getTableDDL(Connection connection, String schemaName, String tableName) {
String sql = "SELECT sql FROM \"sqlite_master\" where type='table' and tbl_name=? ";
try (PreparedStatement ps = connection.prepareStatement(sql)) {
ps.setString(1, tableName);
try (ResultSet rs = ps.executeQuery()) {
if (rs != null && rs.next()) {
return DDLFormatterUtils.format(rs.getString(1));
}
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
return "";
}
@Override
public String getViewDDL(Connection connection, String schemaName, String tableName) {
String sql = "SELECT sql FROM \"sqlite_master\" where type='view' and tbl_name=? ";
try (PreparedStatement ps = connection.prepareStatement(sql)) {
ps.setString(1, tableName);
try (ResultSet rs = ps.executeQuery()) {
if (rs != null && rs.next()) {
return DDLFormatterUtils.format(rs.getString(1));
}
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
return "";
}
@Override
public List<ColumnDescription> querySelectSqlColumnMeta(Connection connection, String sql) {
String querySQL = String.format(" %s LIMIT 0 ", sql.replace(";", ""));
return this.getSelectSqlColumnMeta(connection, querySQL);
}
@Override
protected String getTableFieldsQuerySQL(String schemaName, String tableName) {
return String.format("SELECT * FROM \"%s\".\"%s\" ", schemaName, tableName);
}
@Override
protected String getTestQuerySQL(String sql) {
return String.format("explain %s", sql.replace(";", ""));
}
@Override
public String getFieldDefinition(ColumnMetaData v, List<String> pks, boolean useAutoInc,
boolean addCr, boolean withRemarks) {
String fieldname = v.getName();
int length = v.getLength();
int precision = v.getPrecision();
int type = v.getType();
String retval = " \"" + fieldname + "\" ";
switch (type) {
case ColumnMetaData.TYPE_TIMESTAMP:
case ColumnMetaData.TYPE_TIME:
case ColumnMetaData.TYPE_DATE:
// sqlite中没有时间数据类型
retval += "DATETIME";
break;
case ColumnMetaData.TYPE_BOOLEAN:
retval += "CHAR(1)";
break;
case ColumnMetaData.TYPE_NUMBER:
case ColumnMetaData.TYPE_INTEGER:
case ColumnMetaData.TYPE_BIGNUMBER:
if (null != pks && !pks.isEmpty() && pks.contains(fieldname)) {
// 关键字 AUTOINCREMENT 只能⽤于整型INTEGER字段。
if (useAutoInc) {
retval += "INTEGER PRIMARY KEY AUTOINCREMENT";
} else {
retval += "BIGINT ";
}
} else {
if (precision != 0 || length < 0 || length > 18) {
retval += "NUMERIC";
} else {
retval += "INTEGER";
}
}
break;
case ColumnMetaData.TYPE_STRING:
if (length < 1 || length >= AbstractDatabase.CLOB_LENGTH) {
retval += "BLOB";
} else {
retval += "TEXT";
}
break;
case ColumnMetaData.TYPE_BINARY:
retval += "BLOB";
break;
default:
retval += "TEXT";
break;
}
if (addCr) {
retval += Const.CR;
}
return retval;
}
@Override
public List<String> getTableColumnCommentDefinition(TableDescription td,
List<ColumnDescription> cds) {
return Collections.emptyList();
}
}

View File

@@ -26,7 +26,7 @@ import org.apache.commons.lang3.StringUtils;
*
* @author tang
*/
public class GenerateSqlUtils {
public final class GenerateSqlUtils {
public static String getDDLCreateTableSQL(
DatabaseTypeEnum type,
@@ -108,7 +108,7 @@ public class GenerateSqlUtils {
AbstractDatabase db = DatabaseFactory.getDatabaseInstance(type);
String createTableSql = getDDLCreateTableSQL(db, fieldNames, primaryKeys, schemaName,
tableName, true, tableRemarks, autoIncr);
if (DatabaseTypeEnum.MYSQL == type || DatabaseTypeEnum.HIVE == type) {
if (type.noCommentStatement()) {
return Arrays.asList(createTableSql);
}
@@ -122,4 +122,8 @@ public class GenerateSqlUtils {
return results;
}
private GenerateSqlUtils() {
throw new IllegalStateException();
}
}

View File

@@ -126,11 +126,11 @@ public class JdbcUrlUtils {
// + "(CONNECT_DATA=(SERVICE_NAME=%s)))",
/// db.getHost(), db.getPort(), db.getDbname());
//
// (DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=172.17.207.158)(PORT=1521)))(CONNECT_DATA=(SID=orcl)))
// (DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=172.17.20.58)(PORT=1521)))(CONNECT_DATA=(SID=orcl)))
//
// or
//
// (DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=172.17.207.158)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=orcl.ruijie.com.cn)))
// (DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=172.17.20.58)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=orcl.test.com.cn)))
return String.format("jdbc:oracle:thin:@%s", db.getDbname());
} else {
return String.format("jdbc:oracle:thin:@%s:%d:%s",

View File

@@ -18,5 +18,7 @@ public final class PostgresUtils {
}
private PostgresUtils() {
throw new IllegalStateException();
}
}

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>com.gitee.dbswitch</groupId>
<artifactId>dbswitch-parent</artifactId>
<version>1.6.10</version>
<version>1.6.11</version>
</parent>
<artifactId>dbswitch-data</artifactId>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>com.gitee.dbswitch</groupId>
<artifactId>dbswitch-parent</artifactId>
<version>1.6.10</version>
<version>1.6.11</version>
</parent>
<artifactId>dbswitch-dbchange</artifactId>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>com.gitee.dbswitch</groupId>
<artifactId>dbswitch-parent</artifactId>
<version>1.6.10</version>
<version>1.6.11</version>
</parent>
<artifactId>dbswitch-dbcommon</artifactId>

View File

@@ -9,6 +9,7 @@
/////////////////////////////////////////////////////////////
package com.gitee.dbswitch.dbcommon.database;
import com.gitee.dbswitch.common.type.DatabaseTypeEnum;
import com.gitee.dbswitch.common.util.DatabaseAwareUtils;
import com.gitee.dbswitch.dbcommon.database.impl.DB2DatabaseOperator;
import com.gitee.dbswitch.dbcommon.database.impl.DmDatabaseOperator;
@@ -19,6 +20,7 @@ import com.gitee.dbswitch.dbcommon.database.impl.MysqlDatabaseOperator;
import com.gitee.dbswitch.dbcommon.database.impl.OracleDatabaseOperator;
import com.gitee.dbswitch.dbcommon.database.impl.PostgreSqlDatabaseOperator;
import com.gitee.dbswitch.dbcommon.database.impl.SqlServerDatabaseOperator;
import com.gitee.dbswitch.dbcommon.database.impl.SqliteDatabaseOperator;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
@@ -31,22 +33,24 @@ import javax.sql.DataSource;
*/
public final class DatabaseOperatorFactory {
private static final Map<String, Function<DataSource, IDatabaseOperator>> DATABASE_OPERATOR_MAPPER = new HashMap<String, Function<DataSource, IDatabaseOperator>>() {
private static final Map<DatabaseTypeEnum, Function<DataSource, IDatabaseOperator>> DATABASE_OPERATOR_MAPPER
= new HashMap<DatabaseTypeEnum, Function<DataSource, IDatabaseOperator>>() {
private static final long serialVersionUID = -5278835613240515265L;
{
put("MYSQL", MysqlDatabaseOperator::new);
put("MARIADB", MysqlDatabaseOperator::new);
put("ORACLE", OracleDatabaseOperator::new);
put("SQLSERVER", SqlServerDatabaseOperator::new);
put("SQLSERVER2000", SqlServerDatabaseOperator::new);
put("POSTGRESQL", PostgreSqlDatabaseOperator::new);
put("GREENPLUM", GreenplumDatabaseOperator::new);
put("DB2", DB2DatabaseOperator::new);
put("DM", DmDatabaseOperator::new);
put("KINGBASE", KingbaseDatabaseOperator::new);
put("HIVE", HiveDatabaseOperator::new);
put(DatabaseTypeEnum.MYSQL, MysqlDatabaseOperator::new);
put(DatabaseTypeEnum.MYSQL, MysqlDatabaseOperator::new);
put(DatabaseTypeEnum.ORACLE, OracleDatabaseOperator::new);
put(DatabaseTypeEnum.SQLSERVER, SqlServerDatabaseOperator::new);
put(DatabaseTypeEnum.SQLSERVER2000, SqlServerDatabaseOperator::new);
put(DatabaseTypeEnum.POSTGRESQL, PostgreSqlDatabaseOperator::new);
put(DatabaseTypeEnum.GREENPLUM, GreenplumDatabaseOperator::new);
put(DatabaseTypeEnum.DB2, DB2DatabaseOperator::new);
put(DatabaseTypeEnum.DM, DmDatabaseOperator::new);
put(DatabaseTypeEnum.KINGBASE, KingbaseDatabaseOperator::new);
put(DatabaseTypeEnum.HIVE, HiveDatabaseOperator::new);
put(DatabaseTypeEnum.SQLITE3, SqliteDatabaseOperator::new);
}
};
@@ -57,7 +61,7 @@ public final class DatabaseOperatorFactory {
* @return 指定类型的数据库读取器
*/
public static IDatabaseOperator createDatabaseOperator(DataSource dataSource) {
String type = DatabaseAwareUtils.getDatabaseTypeByDataSource(dataSource).name();
DatabaseTypeEnum type = DatabaseAwareUtils.getDatabaseTypeByDataSource(dataSource);
if (!DATABASE_OPERATOR_MAPPER.containsKey(type)) {
throw new RuntimeException(
String.format("[dbcommon] Unsupported database type (%s)", type));

View File

@@ -0,0 +1,72 @@
// Copyright tang. All rights reserved.
// https://gitee.com/inrgihc/dbswitch
//
// Use of this source code is governed by a BSD-style license
//
// Author: tang (inrgihc@126.com)
// Date : 2020/1/2
// Location: beijing , china
/////////////////////////////////////////////////////////////
package com.gitee.dbswitch.dbcommon.database.impl;
import com.gitee.dbswitch.dbcommon.database.AbstractDatabaseOperator;
import com.gitee.dbswitch.dbcommon.database.IDatabaseOperator;
import com.gitee.dbswitch.dbcommon.domain.StatementResultSet;
import java.util.List;
import javax.sql.DataSource;
import org.apache.commons.lang3.StringUtils;
/**
* SQLite数据库实现类
*
* @author tang
*/
public class SqliteDatabaseOperator extends AbstractDatabaseOperator implements IDatabaseOperator {
public SqliteDatabaseOperator(DataSource dataSource) {
super(dataSource);
}
@Override
public String getSelectTableSql(String schemaName, String tableName, List<String> fields) {
return String.format("select \"%s\" from \"%s\".\"%s\" ",
StringUtils.join(fields, "\",\""), schemaName, tableName);
}
@Override
public StatementResultSet queryTableData(String schemaName, String tableName, List<String> fields,
List<String> orders) {
String sql = String.format("select \"%s\" from \"%s\".\"%s\" order by \"%s\" asc ",
StringUtils.join(fields, "\",\""), schemaName, tableName,
StringUtils.join(orders, "\",\""));
return this.selectTableData(sql, this.fetchSize);
}
@Override
public StatementResultSet queryTableData(String schemaName, String tableName,
List<String> fields) {
String sql = String.format("select \"%s\" from \"%s\".\"%s\" ",
StringUtils.join(fields, "\",\""), schemaName, tableName);
return this.selectTableData(sql, this.fetchSize);
}
@Override
public void truncateTableData(String schemaName, String tableName) {
String sql = String.format("DELETE FROM \"%s\".\"%s\" ", schemaName, tableName);
this.executeSql(sql);
try {
sql = String.format("DELETE FROM sqlite_sequence WHERE name = '%s' ", tableName);
this.executeSql(sql);
} catch (Exception e) {
// ignore
}
}
@Override
public void dropTable(String schemaName, String tableName) {
String sql = String.format("DROP TABLE \"%s\".\"%s\" ", schemaName, tableName);
this.executeSql(sql);
}
}

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>com.gitee.dbswitch</groupId>
<artifactId>dbswitch-parent</artifactId>
<version>1.6.10</version>
<version>1.6.11</version>
</parent>
<artifactId>dbswitch-dbsynch</artifactId>

View File

@@ -37,7 +37,6 @@ import org.springframework.transaction.support.DefaultTransactionDefinition;
@Slf4j
public abstract class AbstractDatabaseSynchronize implements IDatabaseSynchronize {
private final DefaultTransactionDefinition defination;
private JdbcTemplate jdbcTemplate;
private PlatformTransactionManager transactionManager;
private Map<String, Integer> columnType;
@@ -51,10 +50,6 @@ public abstract class AbstractDatabaseSynchronize implements IDatabaseSynchroniz
protected int[] deleteArgsType;
public AbstractDatabaseSynchronize(DataSource ds) {
this.defination = new DefaultTransactionDefinition();
this.defination.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
this.defination.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
this.jdbcTemplate = new JdbcTemplate(ds);
this.transactionManager = new DataSourceTransactionManager(ds);
this.columnType = new HashMap<>();
@@ -65,6 +60,13 @@ public abstract class AbstractDatabaseSynchronize implements IDatabaseSynchroniz
return this.jdbcTemplate.getDataSource();
}
protected TransactionDefinition getTransactionDefinition() {
DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
definition.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
return definition;
}
/**
* 获取查询列元信息的SQL语句
*
@@ -178,7 +180,7 @@ public abstract class AbstractDatabaseSynchronize implements IDatabaseSynchroniz
@Override
public long executeInsert(List<Object[]> records) {
TransactionStatus status = transactionManager.getTransaction(defination);
TransactionStatus status = transactionManager.getTransaction(getTransactionDefinition());
if (log.isDebugEnabled()) {
log.debug("Execute Insert SQL : {}", this.insertStatementSql);
}
@@ -227,7 +229,7 @@ public abstract class AbstractDatabaseSynchronize implements IDatabaseSynchroniz
datas.add(nr);
}
TransactionStatus status = transactionManager.getTransaction(defination);
TransactionStatus status = transactionManager.getTransaction(getTransactionDefinition());
if (log.isDebugEnabled()) {
log.debug("Execute Update SQL : {}", this.updateStatementSql);
}
@@ -264,7 +266,7 @@ public abstract class AbstractDatabaseSynchronize implements IDatabaseSynchroniz
datas.add(nr);
}
TransactionStatus status = transactionManager.getTransaction(defination);
TransactionStatus status = transactionManager.getTransaction(getTransactionDefinition());
if (log.isDebugEnabled()) {
log.debug("Execute Delete SQL : {}", this.deleteStatementSql);
}

View File

@@ -9,6 +9,7 @@
/////////////////////////////////////////////////////////////
package com.gitee.dbswitch.dbsynch;
import com.gitee.dbswitch.common.type.DatabaseTypeEnum;
import com.gitee.dbswitch.common.util.DatabaseAwareUtils;
import com.gitee.dbswitch.dbsynch.db2.DB2DatabaseSyncImpl;
import com.gitee.dbswitch.dbsynch.dm.DmDatabaseSyncImpl;
@@ -18,6 +19,7 @@ import com.gitee.dbswitch.dbsynch.mysql.MySqlDatabaseSyncImpl;
import com.gitee.dbswitch.dbsynch.oracle.OracleDatabaseSyncImpl;
import com.gitee.dbswitch.dbsynch.pgsql.GreenplumDatabaseSyncImpl;
import com.gitee.dbswitch.dbsynch.pgsql.PostgresqlDatabaseSyncImpl;
import com.gitee.dbswitch.dbsynch.sqlite.Sqlite3DatabaseSyncImpl;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
@@ -30,20 +32,22 @@ import javax.sql.DataSource;
*/
public final class DatabaseSynchronizeFactory {
private static final Map<String, Function<DataSource, IDatabaseSynchronize>> DATABASE_SYNC_MAPPER = new HashMap<String, Function<DataSource, IDatabaseSynchronize>>() {
private static final Map<DatabaseTypeEnum, Function<DataSource, IDatabaseSynchronize>> DATABASE_SYNC_MAPPER
= new HashMap<DatabaseTypeEnum, Function<DataSource, IDatabaseSynchronize>>() {
private static final long serialVersionUID = -2359773637275934408L;
{
put("MYSQL", MySqlDatabaseSyncImpl::new);
put("ORACLE", OracleDatabaseSyncImpl::new);
put("SQLSERVER", SqlServerDatabaseSyncImpl::new);
put("SQLSERVER2000", SqlServerDatabaseSyncImpl::new);
put("POSTGRESQL", PostgresqlDatabaseSyncImpl::new);
put("GREENPLUM", GreenplumDatabaseSyncImpl::new);
put("DB2", DB2DatabaseSyncImpl::new);
put("DM", DmDatabaseSyncImpl::new);
put("KINGBASE", KingbaseDatabaseSyncImpl::new);
put(DatabaseTypeEnum.MYSQL, MySqlDatabaseSyncImpl::new);
put(DatabaseTypeEnum.ORACLE, OracleDatabaseSyncImpl::new);
put(DatabaseTypeEnum.SQLSERVER, SqlServerDatabaseSyncImpl::new);
put(DatabaseTypeEnum.SQLSERVER2000, SqlServerDatabaseSyncImpl::new);
put(DatabaseTypeEnum.POSTGRESQL, PostgresqlDatabaseSyncImpl::new);
put(DatabaseTypeEnum.GREENPLUM, GreenplumDatabaseSyncImpl::new);
put(DatabaseTypeEnum.DB2, DB2DatabaseSyncImpl::new);
put(DatabaseTypeEnum.DM, DmDatabaseSyncImpl::new);
put(DatabaseTypeEnum.KINGBASE, KingbaseDatabaseSyncImpl::new);
put(DatabaseTypeEnum.SQLITE3, Sqlite3DatabaseSyncImpl::new);
}
};
@@ -54,7 +58,7 @@ public final class DatabaseSynchronizeFactory {
* @return 同步器对象
*/
public static IDatabaseSynchronize createDatabaseWriter(DataSource dataSource) {
String type = DatabaseAwareUtils.getDatabaseTypeByDataSource(dataSource).name();
DatabaseTypeEnum type = DatabaseAwareUtils.getDatabaseTypeByDataSource(dataSource);
if (!DATABASE_SYNC_MAPPER.containsKey(type)) {
throw new RuntimeException(
String.format("[dbsynch] Unsupported database type (%s)", type));

View File

@@ -0,0 +1,115 @@
// Copyright tang. All rights reserved.
// https://gitee.com/inrgihc/dbswitch
//
// Use of this source code is governed by a BSD-style license
//
// Author: tang (inrgihc@126.com)
// Date : 2020/1/2
// Location: beijing , china
/////////////////////////////////////////////////////////////
package com.gitee.dbswitch.dbsynch.sqlite;
import com.gitee.dbswitch.common.util.TypeConvertUtils;
import com.gitee.dbswitch.dbsynch.AbstractDatabaseSynchronize;
import com.gitee.dbswitch.dbsynch.IDatabaseSynchronize;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import javax.sql.DataSource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.support.DefaultTransactionDefinition;
/**
* SQLite数据库DML同步实现类
*
* @author tang
*/
public class Sqlite3DatabaseSyncImpl extends AbstractDatabaseSynchronize implements
IDatabaseSynchronize {
public Sqlite3DatabaseSyncImpl(DataSource ds) {
super(ds);
}
@Override
protected TransactionDefinition getTransactionDefinition() {
DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
definition.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE);
definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
return definition;
}
@Override
public String getColumnMetaDataSql(String schemaName, String tableName) {
return String.format("SELECT * FROM \"%s\".\"%s\" WHERE 1=2", schemaName, tableName);
}
@Override
public String getInsertPrepareStatementSql(String schemaName, String tableName,
List<String> fieldNames) {
List<String> placeHolders = Collections.nCopies(fieldNames.size(), "?");
return String.format("INSERT INTO \"%s\".\"%s\" ( \"%s\" ) VALUES ( %s )",
schemaName, tableName,
StringUtils.join(fieldNames, "\",\""),
StringUtils.join(placeHolders, ","));
}
@Override
public String getUpdatePrepareStatementSql(String schemaName, String tableName,
List<String> fieldNames, List<String> pks) {
List<String> uf = fieldNames.stream()
.filter(field -> !pks.contains(field))
.map(field -> String.format("\"%s\"=?", field))
.collect(Collectors.toList());
List<String> uw = pks.stream()
.map(pk -> String.format("\"%s\"=?", pk))
.collect(Collectors.toList());
return String.format("UPDATE \"%s\".\"%s\" SET %s WHERE %s",
schemaName, tableName, StringUtils.join(uf, " , "),
StringUtils.join(uw, " AND "));
}
@Override
public String getDeletePrepareStatementSql(String schemaName, String tableName,
List<String> pks) {
List<String> uw = pks.stream()
.map(pk -> String.format("\"%s\"=?", pk))
.collect(Collectors.toList());
return String.format("DELETE FROM \"%s\".\"%s\" WHERE %s ",
schemaName, tableName, StringUtils.join(uw, " AND "));
}
@Override
public long executeInsert(List<Object[]> records) {
records.parallelStream().forEach((Object[] row) -> {
for (int i = 0; i < row.length; ++i) {
try {
row[i] = TypeConvertUtils.castByDetermine(row[i]);
} catch (Exception e) {
row[i] = null;
}
}
});
return super.executeInsert(records);
}
@Override
public long executeUpdate(List<Object[]> records) {
records.parallelStream().forEach((Object[] row) -> {
for (int i = 0; i < row.length; ++i) {
try {
row[i] = TypeConvertUtils.castByDetermine(row[i]);
} catch (Exception e) {
row[i] = null;
}
}
});
return super.executeUpdate(records);
}
}

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>com.gitee.dbswitch</groupId>
<artifactId>dbswitch-parent</artifactId>
<version>1.6.10</version>
<version>1.6.11</version>
</parent>
<artifactId>dbswitch-dbwriter</artifactId>

View File

@@ -98,6 +98,13 @@ public abstract class AbstractDatabaseWriter implements IDatabaseWriter {
protected abstract String getDatabaseProductName();
protected TransactionDefinition getTransactionDefinition() {
DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
definition.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
return definition;
}
@Override
public long write(List<String> fieldNames, List<Object[]> recordValues) {
if (recordValues.isEmpty()) {
@@ -115,12 +122,9 @@ public abstract class AbstractDatabaseWriter implements IDatabaseWriter {
argTypes[i] = this.columnType.get(col);
}
DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
definition.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
PlatformTransactionManager transactionManager = new DataSourceTransactionManager(
this.dataSource);
TransactionStatus status = transactionManager.getTransaction(definition);
TransactionStatus status = transactionManager.getTransaction(getTransactionDefinition());
try {
//int[] affects = jdbcTemplate.batchUpdate(sqlInsert, recordValues, argTypes);

View File

@@ -9,7 +9,16 @@
/////////////////////////////////////////////////////////////
package com.gitee.dbswitch.dbwriter;
import com.gitee.dbswitch.common.type.DatabaseTypeEnum;
import com.gitee.dbswitch.common.util.DatabaseAwareUtils;
import com.gitee.dbswitch.dbwriter.db2.DB2WriterImpl;
import com.gitee.dbswitch.dbwriter.dm.DmWriterImpl;
import com.gitee.dbswitch.dbwriter.gpdb.GreenplumCopyWriterImpl;
import com.gitee.dbswitch.dbwriter.kingbase.KingbaseInsertWriterImpl;
import com.gitee.dbswitch.dbwriter.mssql.SqlServerWriterImpl;
import com.gitee.dbswitch.dbwriter.mysql.MySqlWriterImpl;
import com.gitee.dbswitch.dbwriter.oracle.OracleWriterImpl;
import com.gitee.dbswitch.dbwriter.sqlite.Sqlite3WriterImpl;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
@@ -22,22 +31,23 @@ import javax.sql.DataSource;
*/
public class DatabaseWriterFactory {
private static final Map<String, Function<DataSource, IDatabaseWriter>> DATABASE_WRITER_MAPPER
= new HashMap<String, Function<DataSource, IDatabaseWriter>>() {
private static final Map<DatabaseTypeEnum, Function<DataSource, IDatabaseWriter>> DATABASE_WRITER_MAPPER
= new HashMap<DatabaseTypeEnum, Function<DataSource, IDatabaseWriter>>() {
private static final long serialVersionUID = 3365136872693503697L;
{
put("MYSQL", com.gitee.dbswitch.dbwriter.mysql.MySqlWriterImpl::new);
put("ORACLE", com.gitee.dbswitch.dbwriter.oracle.OracleWriterImpl::new);
put("SQLSERVER", com.gitee.dbswitch.dbwriter.mssql.SqlServerWriterImpl::new);
put("SQLSERVER2000", com.gitee.dbswitch.dbwriter.mssql.SqlServerWriterImpl::new);
put("POSTGRESQL", com.gitee.dbswitch.dbwriter.gpdb.GreenplumCopyWriterImpl::new);
put("GREENPLUM", com.gitee.dbswitch.dbwriter.gpdb.GreenplumCopyWriterImpl::new);
put("DB2", com.gitee.dbswitch.dbwriter.db2.DB2WriterImpl::new);
put("DM", com.gitee.dbswitch.dbwriter.dm.DmWriterImpl::new);
put(DatabaseTypeEnum.MYSQL, MySqlWriterImpl::new);
put(DatabaseTypeEnum.ORACLE, OracleWriterImpl::new);
put(DatabaseTypeEnum.SQLSERVER, SqlServerWriterImpl::new);
put(DatabaseTypeEnum.SQLSERVER2000, SqlServerWriterImpl::new);
put(DatabaseTypeEnum.POSTGRESQL, GreenplumCopyWriterImpl::new);
put(DatabaseTypeEnum.GREENPLUM, GreenplumCopyWriterImpl::new);
put(DatabaseTypeEnum.DB2, DB2WriterImpl::new);
put(DatabaseTypeEnum.DM, DmWriterImpl::new);
//对于kingbase当前只能使用insert模式
put("KINGBASE", com.gitee.dbswitch.dbwriter.kingbase.KingbaseInsertWriterImpl::new);
put(DatabaseTypeEnum.KINGBASE, KingbaseInsertWriterImpl::new);
put(DatabaseTypeEnum.SQLITE3, Sqlite3WriterImpl::new);
}
};
@@ -59,9 +69,9 @@ public class DatabaseWriterFactory {
* @return 写入器对象
*/
public static IDatabaseWriter createDatabaseWriter(DataSource dataSource, boolean insert) {
String type = DatabaseAwareUtils.getDatabaseTypeByDataSource(dataSource).name();
DatabaseTypeEnum type = DatabaseAwareUtils.getDatabaseTypeByDataSource(dataSource);
if (insert) {
if ("POSTGRESQL".equalsIgnoreCase(type) || "GREENPLUM".equalsIgnoreCase(type)) {
if (DatabaseTypeEnum.POSTGRESQL.equals(type) || DatabaseTypeEnum.GREENPLUM.equals(type)) {
return new com.gitee.dbswitch.dbwriter.gpdb.GreenplumInsertWriterImpl(dataSource);
}
}
@@ -71,7 +81,7 @@ public class DatabaseWriterFactory {
String.format("[dbwrite] Unsupported database type (%s)", type));
}
return DATABASE_WRITER_MAPPER.get(type.trim()).apply(dataSource);
return DATABASE_WRITER_MAPPER.get(type).apply(dataSource);
}
}

View File

@@ -0,0 +1,58 @@
// Copyright tang. All rights reserved.
// https://gitee.com/inrgihc/dbswitch
//
// Use of this source code is governed by a BSD-style license
//
// Author: tang (inrgihc@126.com)
// Date : 2020/1/2
// Location: beijing , china
/////////////////////////////////////////////////////////////
package com.gitee.dbswitch.dbwriter.sqlite;
import com.gitee.dbswitch.dbwriter.AbstractDatabaseWriter;
import com.gitee.dbswitch.dbwriter.IDatabaseWriter;
import com.gitee.dbswitch.dbwriter.util.ObjectCastUtils;
import java.util.List;
import javax.sql.DataSource;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.support.DefaultTransactionDefinition;
/**
* SQLite数据库写入实现类
*
* @author tang
*/
public class Sqlite3WriterImpl extends AbstractDatabaseWriter implements IDatabaseWriter {
public Sqlite3WriterImpl(DataSource dataSource) {
super(dataSource);
}
@Override
protected String getDatabaseProductName() {
return "SQLite";
}
@Override
protected TransactionDefinition getTransactionDefinition() {
DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
definition.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE);
definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
return definition;
}
@Override
public long write(List<String> fieldNames, List<Object[]> recordValues) {
recordValues.parallelStream().forEach((Object[] row) -> {
for (int i = 0; i < row.length; ++i) {
try {
row[i] = ObjectCastUtils.castByDetermine(row[i]);
} catch (Exception e) {
row[i] = null;
}
}
});
return super.write(fieldNames, recordValues);
}
}

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>com.gitee.dbswitch</groupId>
<artifactId>dbswitch-parent</artifactId>
<version>1.6.10</version>
<version>1.6.11</version>
</parent>
<artifactId>dbswitch-pgwriter</artifactId>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>com.gitee.dbswitch</groupId>
<artifactId>dbswitch-parent</artifactId>
<version>1.6.10</version>
<version>1.6.11</version>
</parent>
<artifactId>dbswitch-sql</artifactId>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>com.gitee.dbswitch</groupId>
<artifactId>dbswitch-parent</artifactId>
<version>1.6.10</version>
<version>1.6.11</version>
</parent>
<artifactId>package-tool</artifactId>

View File

@@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.gitee.dbswitch</groupId>
<artifactId>dbswitch-parent</artifactId>
<version>1.6.10</version>
<version>1.6.11</version>
<packaging>pom</packaging>
<name>dbswitch</name>
<description>database switch project</description>

View File

@@ -1,6 +1,6 @@
@echo off
set APP_VERSION=1.6.10
set APP_VERSION=1.6.11
echo "Clean Project ..."
call mvn clean -f pom.xml