version for 1.6.12

This commit is contained in:
inrgihc
2022-07-16 00:09:15 +08:00
parent 817785fe11
commit ea64d07503
36 changed files with 497 additions and 210 deletions

View File

@@ -24,19 +24,23 @@
### 3、详细功能
- 源端oracle/SqlServer/MySQL/MariaDB/PostgreSQL/DB2/DM/Kingbase8/HighGo/Hive/SQLite向目的端为Greenplum/PostgreSQL/HighGo的迁移(**支持绝大多数常规类型字段**)
- 源端oracle/SqlServer/MySQL/MariaDB/PostgreSQL/DB2/DM/OSCAR/Kingbase8/HighGo/Hive/SQLite向目的端为Greenplum/PostgreSQL/HighGo的迁移(**支持绝大多数常规类型字段**)
- 源端oracle/SqlServer/MySQL/MariaDB/PostgreSQL/DB2/DM/Kingbase8/HighGo/Hive/SQLite向目的端为Oracle/DM的迁移(**支持绝大多数常规类型字段**)
- 源端oracle/SqlServer/MySQL/MariaDB/PostgreSQL/DB2/DM/OSCAR/Kingbase8/HighGo/Hive/SQLite向目的端为Oracle的迁移(**支持绝大多数常规类型字段**)
- 源端oracle/SqlServer/MySQL/MariaDB/PostgreSQL/DB2/DM/Kingbase8/HighGo/Hive/SQLite向目的端为SQLServer的迁移(**字段类型兼容测试中...**)
- 源端oracle/SqlServer/MySQL/MariaDB/PostgreSQL/DB2/DM/OSCAR/Kingbase8/HighGo/Hive/SQLite向目的端为SQLServer的迁移(**字段类型兼容测试中...**)
- 源端oracle/SqlServer/MySQL/MariaDB/PostgreSQL/DB2/DM/Kingbase8/HighGo/Hive/SQLite向目的端为MySQL/MariaDB的迁移(**字段类型兼容测试中...**)
- 源端oracle/SqlServer/MySQL/MariaDB/PostgreSQL/DB2/DM/OSCAR/Kingbase8/HighGo/Hive/SQLite向目的端为MySQL/MariaDB的迁移(**字段类型兼容测试中...**)
- 源端oracle/SqlServer/MySQL/MariaDB/PostgreSQL/DB2/DM/Kingbase8/HighGo/Hive/SQLite向目的端为DB2的迁移(**字段类型兼容测试中...**)
- 源端oracle/SqlServer/MySQL/MariaDB/PostgreSQL/DB2/DM/OSCAR/Kingbase8/HighGo/Hive/SQLite向目的端为DB2的迁移(**字段类型兼容测试中...**)
- 源端oracle/SqlServer/MySQL/MariaDB/PostgreSQL/DB2/DM/Kingbase8/HighGo/Hive/SQLite向目的端为Kingbase8的迁移(**支持绝大多数常规类型字段...**)
- 源端oracle/SqlServer/MySQL/MariaDB/PostgreSQL/DB2/DM/OSCAR/Kingbase8/HighGo/Hive/SQLite向目的端为Kingbase8的迁移(**支持绝大多数常规类型字段...**)
- 源端oracle/SqlServer/MySQL/MariaDB/PostgreSQL/DB2/DM/Kingbase8/HighGo/Hive/SQLite向目的端为SQLite的迁移(**支持部分常规类型字段...**)
- 源端oracle/SqlServer/MySQL/MariaDB/PostgreSQL/DB2/DM/OSCAR/Kingbase8/HighGo/Hive/SQLite向目的端为DM的迁移(**支持绝大多数常规类型字段**)
- 源端oracle/SqlServer/MySQL/MariaDB/PostgreSQL/DB2/DM/OSCAR/Kingbase8/HighGo/Hive/SQLite向目的端为OSCAR的迁移(**支持绝大多数常规类型字段**)
- 源端oracle/SqlServer/MySQL/MariaDB/PostgreSQL/DB2/DM/OSCAR/Kingbase8/HighGo/Hive/SQLite向目的端为SQLite的迁移(**支持部分常规类型字段...**)
** 注:** 目前Hive只支持Hive version 3.x的账号密码方式认证。
@@ -210,7 +214,7 @@ dbswitch:
- 6各个数据库的JDBC驱动连接示例如下
**mysql/mariadb的驱动配置样例**
**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&rewriteBatchedStatements=true
@@ -224,48 +228,55 @@ jdbc连接地址jdbc:mariadb://172.17.2.10:3306/test?useUnicode=true&characte
jdbc驱动名称 org.mariadb.jdbc.Driver
```
**oracle的驱动配置样例**
**Oracle数据库**
```
jdbc连接地址jdbc:oracle:thin:@172.17.2.10:1521:ORCL 或 jdbc:oracle:thin:@//172.17.2.10:1521/ORCL
jdbc驱动名称oracle.jdbc.driver.OracleDriver
```
**SqlServer(>=2005)的驱动配置样例**
**SQL Server(>=2005)数据库**
```
jdbc连接地址jdbc:sqlserver://172.17.2.10:1433;DatabaseName=hqtest
jdbc驱动名称com.microsoft.sqlserver.jdbc.SQLServerDriver
```
**PostgreSQL/Greenplum的驱动配置样例**
**PostgreSQL/Greenplum数据库**
```
jdbc连接地址jdbc:postgresql://172.17.2.10:5432/test
jdbc驱动名称org.postgresql.Driver
```
**DB2的驱动配置样例**
**DB2数据库**
```
jdbc连接地址jdbc:db2://172.17.2.10:50000/testdb:driverType=4;fullyMaterializeLobData=true;fullyMaterializeInputStreams=true;progressiveStreaming=2;progresssiveLocators=2;
jdbc驱动名称com.ibm.db2.jcc.DB2Driver
```
**达梦DM的驱动配置样例**
**达梦DMDB数据库**
```
jdbc连接地址jdbc:dm://172.17.2.10:5236
jdbc驱动名称dm.jdbc.driver.DmDriver
```
**人大金仓Kingbase8的驱动配置样例**
**人大金仓Kingbase8数据库**
```
jdbc连接地址jdbc:kingbase8://172.17.2.10:54321/MYTEST
jdbc驱动名称com.kingbase8.Driver
```
**神通Oscar数据库**
```
jdbc连接地址jdbc:oscar://172.17.2.1:2003/OSRDB
jdbc驱动名称com.oscar.Driver
```
**翰高HighGo数据库(可按PostgreSQL使用)**
```

View File

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

View File

@@ -13,7 +13,7 @@ services:
MYSQL_ROOT_HOST: '%'
dbswitch:
container_name: dbswitch_webui
image: inrgihc/dbswitch:1.6.11
image: inrgihc/dbswitch:1.6.12
environment:
MYSQLDB_HOST: dbswitch_mysqldb
MYSQLDB_PORT: 3306

View File

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

View File

@@ -51,13 +51,17 @@ public enum SupportDbTypeEnum {
"SELECT 1",
"jdbc:kingbase8://",
new String[]{"jdbc:kingbase8://{host}[:{port}]/[{database}][\\?{params}]"}),
HIVE(1, "hive", "org.apache.hive.jdbc.HiveDriver", 10000,
OSCAR(9, "oscar", "com.oscar.Driver", 2003,
"SELECT 1",
"jdbc:oscar://",
new String[]{"jdbc:oscar://{host}[:{port}]/[{database}][\\?{params}]"}),
HIVE(10, "hive", "org.apache.hive.jdbc.HiveDriver", 10000,
"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,
SQLITE3(11, "sqlite3", "org.sqlite.JDBC", 0,
"SELECT 1",
"jdbc:sqlite:",
new String[]{"jdbc:sqlite:{file}", "jdbc:sqlite::resource:{file}"}),

View File

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

View File

@@ -63,24 +63,29 @@ public enum DatabaseTypeEnum {
DB2(8),
/**
* DM数据库类型
* [国产]达梦数据库类型
*/
DM(9),
/**
* Kingbase数据库类型
* [国产]人大金仓数据库类型
*/
KINGBASE(10),
/**
* [国产]神通数据库
*/
OSCAR(11),
/**
* HIVE数据库
*/
HIVE(11),
HIVE(12),
/**
* SQLite数据库
*/
SQLITE3(12),
SQLITE3(13),
;
private int index;

View File

@@ -45,6 +45,7 @@ public final class DatabaseAwareUtils {
productNameMap.put("DB2 for Unix/Windows", DatabaseTypeEnum.DB2);
productNameMap.put("Hive", DatabaseTypeEnum.HIVE);
productNameMap.put("SQLite", DatabaseTypeEnum.SQLITE3);
productNameMap.put("OSCAR", DatabaseTypeEnum.OSCAR);
driverNameMap.put("MySQL Connector Java", DatabaseTypeEnum.MYSQL);
driverNameMap.put("MariaDB Connector/J", DatabaseTypeEnum.MARIADB);
@@ -55,6 +56,7 @@ public final class DatabaseAwareUtils {
driverNameMap.put("dm.jdbc.driver.DmDriver", DatabaseTypeEnum.DM);
driverNameMap.put("Hive JDBC", DatabaseTypeEnum.HIVE);
driverNameMap.put("SQLite JDBC", DatabaseTypeEnum.SQLITE3);
driverNameMap.put("OSCAR JDBC DRIVER", DatabaseTypeEnum.OSCAR);
}
/**

View File

@@ -3,12 +3,18 @@ package com.gitee.dbswitch.common.util;
import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.SQLException;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public final class TypeConvertUtils {
private TypeConvertUtils() {
throw new IllegalStateException("Utility class can not create instance!");
}
public static String castToString(final Object in) {
if (in instanceof java.lang.Character) {
return in.toString();
@@ -123,7 +129,15 @@ public final class TypeConvertUtils {
return null;
}
if (in instanceof java.sql.Clob) {
if (in instanceof BigInteger) {
return ((BigInteger) in).longValue();
} else if (in instanceof BigDecimal) {
BigDecimal decimal = (BigDecimal) in;
if (decimal.doubleValue() > 2.147483647E9D || decimal.doubleValue() < -2.147483648E9D) {
return 0D;
}
return decimal.doubleValue();
} else if (in instanceof java.sql.Clob) {
return clob2Str((java.sql.Clob) in);
} else if (in instanceof java.sql.Array
|| in instanceof java.sql.SQLXML) {
@@ -148,7 +162,7 @@ public final class TypeConvertUtils {
return in;
}
private static byte[] blob2Bytes(java.sql.Blob blob) {
public static byte[] blob2Bytes(java.sql.Blob blob) {
try (java.io.InputStream inputStream = blob.getBinaryStream()) {
try (java.io.BufferedInputStream is = new java.io.BufferedInputStream(inputStream)) {
byte[] bytes = new byte[(int) blob.length()];
@@ -165,7 +179,7 @@ public final class TypeConvertUtils {
}
}
private static String clob2Str(java.sql.Clob clob) {
public static String clob2Str(java.sql.Clob clob) {
try (java.io.Reader is = clob.getCharacterStream()) {
java.io.BufferedReader reader = new java.io.BufferedReader(is);
String line = reader.readLine();

Binary file not shown.

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>com.gitee.dbswitch</groupId>
<artifactId>dbswitch-parent</artifactId>
<version>1.6.11</version>
<version>1.6.12</version>
</parent>
<artifactId>dbswitch-core</artifactId>
@@ -78,14 +78,6 @@
<systemPath>${project.basedir}/lib/mssqlserver.jar</systemPath>
</dependency>
<dependency>
<groupId>com.pivotal</groupId>
<artifactId>greenplum-jdbc</artifactId>
<version>5.1.4</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/greenplum-jdbc-5.1.4.jar</systemPath>
</dependency>
<dependency>
<groupId>com.dameng</groupId>
<artifactId>dm-jdbc</artifactId>
@@ -102,6 +94,14 @@
<systemPath>${project.basedir}/lib/kingbase8-8.2.0.jar</systemPath>
</dependency>
<dependency>
<groupId>com.oscar</groupId>
<artifactId>oscar-jdbc</artifactId>
<version>7.0.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/oscarJDBC8.jar</systemPath>
</dependency>
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>

View File

@@ -18,6 +18,7 @@ import com.gitee.dbswitch.core.database.impl.DatabaseKingbaseImpl;
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.DatabaseOscarImpl;
import com.gitee.dbswitch.core.database.impl.DatabasePostgresImpl;
import com.gitee.dbswitch.core.database.impl.DatabaseSqliteImpl;
import com.gitee.dbswitch.core.database.impl.DatabaseSqlserver2000Impl;
@@ -49,6 +50,7 @@ public final class DatabaseFactory {
put(DatabaseTypeEnum.DB2, DatabaseDB2Impl::new);
put(DatabaseTypeEnum.DM, DatabaseDmImpl::new);
put(DatabaseTypeEnum.KINGBASE, DatabaseKingbaseImpl::new);
put(DatabaseTypeEnum.OSCAR, DatabaseOscarImpl::new);
put(DatabaseTypeEnum.HIVE, DatabaseHiveImpl::new);
put(DatabaseTypeEnum.SQLITE3, DatabaseSqliteImpl::new);
}

View File

@@ -0,0 +1,207 @@
// 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 java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
/**
* 支持神通数据库的元信息实现
*
* @author tang
*/
public class DatabaseOscarImpl extends AbstractDatabase implements IDatabaseInterface {
private static final String SHOW_CREATE_TABLE_SQL =
"SELECT \"SYS_GET_TABLEDEF\" FROM \"V_SYS_TABLE\" WHERE \"SCHEMANAME\"= ? AND \"TABLENAME\"= ? ";
private static final String SHOW_CREATE_VIEW_SQL =
"SELECT \"DEFINITION\" FROM \"V_SYS_VIEWS\" WHERE \"SCHEMANAME\"= ? AND \"VIEWNAME\"= ?";
public DatabaseOscarImpl() {
super("com.oscar.Driver");
}
@Override
public DatabaseTypeEnum getDatabaseType() {
return DatabaseTypeEnum.OSCAR;
}
@Override
public String getTableDDL(Connection connection, String schemaName, String tableName) {
String sql = String.format(SHOW_CREATE_TABLE_SQL, tableName, schemaName);
try (PreparedStatement ps = connection.prepareStatement(sql)) {
ps.setString(1, schemaName);
ps.setString(2, tableName);
try (ResultSet rs = ps.executeQuery()) {
if (rs != null && rs.next()) {
return rs.getString(1);
}
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
return null;
}
@Override
public String getViewDDL(Connection connection, String schemaName, String tableName) {
String sql = String.format(SHOW_CREATE_VIEW_SQL, tableName, schemaName);
try (PreparedStatement ps = connection.prepareStatement(sql)) {
ps.setString(1, schemaName);
ps.setString(2, tableName);
try (ResultSet rs = ps.executeQuery()) {
if (rs != null && rs.next()) {
return rs.getString(1);
}
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
return null;
}
@Override
public List<ColumnDescription> querySelectSqlColumnMeta(Connection connection, String sql) {
String querySQL = String.format(
"SELECT * from (%s) tmp 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();
StringBuilder retval = new StringBuilder(128);
retval.append(" \"").append(fieldname).append("\" ");
int type = v.getType();
switch (type) {
case ColumnMetaData.TYPE_TIMESTAMP:
case ColumnMetaData.TYPE_TIME:
retval.append("TIMESTAMP");
break;
case ColumnMetaData.TYPE_DATE:
retval.append("DATE");
break;
case ColumnMetaData.TYPE_BOOLEAN:
retval.append("BIT");
break;
case ColumnMetaData.TYPE_BIGNUMBER:
case ColumnMetaData.TYPE_INTEGER:
retval.append("BIGINT");
break;
case ColumnMetaData.TYPE_NUMBER:
if (null != pks && !pks.isEmpty() && pks.contains(fieldname)) {
retval.append("BIGINT");
} else {
if (length > 0) {
if (precision > 0 || length > 18) {
if ((length + precision) > 0 && precision > 0) {
// Numeric(Precision, Scale): Precision = total length; Scale = decimal places
retval.append("NUMERIC(" + (length + precision) + ", " + precision + ")");
} else {
retval.append("DOUBLE PRECISION");
}
} else {
if (length > 9) {
retval.append("BIGINT");
} else {
if (length < 5) {
retval.append("SMALLINT");
} else {
retval.append("INTEGER");
}
}
}
} else {
retval.append("DOUBLE PRECISION");
}
}
break;
case ColumnMetaData.TYPE_STRING:
if (2 * length >= AbstractDatabase.CLOB_LENGTH) {
retval.append("TEXT");
} else {
if (length == 1) {
retval.append("VARCHAR(2)");
} else if (length > 0 && length < 2048) {
retval.append("VARCHAR(").append(2 * length).append(')');
} else {
retval.append("TEXT");
}
}
break;
case ColumnMetaData.TYPE_BINARY:
retval.append("BLOB");
break;
default:
retval.append("TEXT");
break;
}
if (addCr) {
retval.append(Const.CR);
}
return retval.toString();
}
@Override
public List<String> getTableColumnCommentDefinition(TableDescription td,
List<ColumnDescription> cds) {
List<String> results = new ArrayList<>();
if (StringUtils.isNotBlank(td.getRemarks())) {
results.add(String
.format("COMMENT ON TABLE \"%s\".\"%s\" IS '%s' ",
td.getSchemaName(), td.getTableName(),
td.getRemarks().replace("\"", "\\\"")));
}
for (ColumnDescription cd : cds) {
if (StringUtils.isNotBlank(cd.getRemarks())) {
results.add(String
.format("COMMENT ON COLUMN \"%s\".\"%s\".\"%s\" IS '%s' ",
td.getSchemaName(), td.getTableName(), cd.getFieldName(),
cd.getRemarks().replace("\"", "\\\"")));
}
}
return results;
}
}

View File

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

View File

@@ -302,7 +302,7 @@ public class MigrationHandler implements Supplier<Long> {
Object[] record = new Object[sourceFields.size()];
for (int i = 1; i <= sourceFields.size(); ++i) {
try {
record[i - 1] = writer.format(rs.getObject(i));
record[i - 1] = rs.getObject(i);
} catch (Exception e) {
log.warn("!!! Read data from table [ {} ] use function ResultSet.getObject() error",
tableNameMapString, e);

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>com.gitee.dbswitch</groupId>
<artifactId>dbswitch-parent</artifactId>
<version>1.6.11</version>
<version>1.6.12</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.11</version>
<version>1.6.12</version>
</parent>
<artifactId>dbswitch-dbcommon</artifactId>

View File

@@ -18,6 +18,7 @@ import com.gitee.dbswitch.dbcommon.database.impl.HiveDatabaseOperator;
import com.gitee.dbswitch.dbcommon.database.impl.KingbaseDatabaseOperator;
import com.gitee.dbswitch.dbcommon.database.impl.MysqlDatabaseOperator;
import com.gitee.dbswitch.dbcommon.database.impl.OracleDatabaseOperator;
import com.gitee.dbswitch.dbcommon.database.impl.OscarDatabaseOperator;
import com.gitee.dbswitch.dbcommon.database.impl.PostgreSqlDatabaseOperator;
import com.gitee.dbswitch.dbcommon.database.impl.SqlServerDatabaseOperator;
import com.gitee.dbswitch.dbcommon.database.impl.SqliteDatabaseOperator;
@@ -49,6 +50,7 @@ public final class DatabaseOperatorFactory {
put(DatabaseTypeEnum.DB2, DB2DatabaseOperator::new);
put(DatabaseTypeEnum.DM, DmDatabaseOperator::new);
put(DatabaseTypeEnum.KINGBASE, KingbaseDatabaseOperator::new);
put(DatabaseTypeEnum.OSCAR, OscarDatabaseOperator::new);
put(DatabaseTypeEnum.HIVE, HiveDatabaseOperator::new);
put(DatabaseTypeEnum.SQLITE3, SqliteDatabaseOperator::new);
}

View File

@@ -0,0 +1,25 @@
// 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 javax.sql.DataSource;
public class OscarDatabaseOperator extends OracleDatabaseOperator {
public OscarDatabaseOperator(DataSource dataSource) {
super(dataSource);
}
@Override
public void dropTable(String schemaName, String tableName) {
String sql = String.format("DROP TABLE \"%s\".\"%s\" CASCADE ", schemaName, tableName);
this.executeSql(sql);
}
}

View File

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

View File

@@ -17,6 +17,7 @@ import com.gitee.dbswitch.dbsynch.kingbase.KingbaseDatabaseSyncImpl;
import com.gitee.dbswitch.dbsynch.mssql.SqlServerDatabaseSyncImpl;
import com.gitee.dbswitch.dbsynch.mysql.MySqlDatabaseSyncImpl;
import com.gitee.dbswitch.dbsynch.oracle.OracleDatabaseSyncImpl;
import com.gitee.dbswitch.dbsynch.oscar.OscarDatabaseSyncImpl;
import com.gitee.dbswitch.dbsynch.pgsql.GreenplumDatabaseSyncImpl;
import com.gitee.dbswitch.dbsynch.pgsql.PostgresqlDatabaseSyncImpl;
import com.gitee.dbswitch.dbsynch.sqlite.Sqlite3DatabaseSyncImpl;
@@ -47,6 +48,7 @@ public final class DatabaseSynchronizeFactory {
put(DatabaseTypeEnum.DB2, DB2DatabaseSyncImpl::new);
put(DatabaseTypeEnum.DM, DmDatabaseSyncImpl::new);
put(DatabaseTypeEnum.KINGBASE, KingbaseDatabaseSyncImpl::new);
put(DatabaseTypeEnum.OSCAR, OscarDatabaseSyncImpl::new);
put(DatabaseTypeEnum.SQLITE3, Sqlite3DatabaseSyncImpl::new);
}
};

View File

@@ -19,7 +19,7 @@ import javax.sql.DataSource;
import org.apache.commons.lang3.StringUtils;
/**
* DM数据库DML同步实现类
* 达梦数据库DML同步实现类
*
* @author tang
*/

View File

@@ -0,0 +1,105 @@
// 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.oscar;
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;
/**
* 神通数据库DML同步实现类
*
* @author tang
*/
public class OscarDatabaseSyncImpl extends AbstractDatabaseSynchronize implements
IDatabaseSynchronize {
public OscarDatabaseSyncImpl(DataSource ds) {
super(ds);
}
@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.11</version>
<version>1.6.12</version>
</parent>
<artifactId>dbswitch-dbwriter</artifactId>

View File

@@ -18,6 +18,7 @@ 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.oscar.OscarWriterImpl;
import com.gitee.dbswitch.dbwriter.sqlite.Sqlite3WriterImpl;
import java.util.HashMap;
import java.util.Map;
@@ -47,6 +48,7 @@ public class DatabaseWriterFactory {
put(DatabaseTypeEnum.DM, DmWriterImpl::new);
//对于kingbase当前只能使用insert模式
put(DatabaseTypeEnum.KINGBASE, KingbaseInsertWriterImpl::new);
put(DatabaseTypeEnum.OSCAR, OscarWriterImpl::new);
put(DatabaseTypeEnum.SQLITE3, Sqlite3WriterImpl::new);
}
};

View File

@@ -42,14 +42,4 @@ public interface IDatabaseWriter {
* @return 返回实际写入的数据记录条数
*/
long write(List<String> fieldNames, List<Object[]> recordValues);
/**
* 值字段转换主要用于处理某些数据库不兼容java值类型例如sqlserver驱动sqljdbc4-4.0不支持BigInteger
*
* @param columnValue 列字段值
* @return 转换后的值
*/
default Object format(Object columnValue) {
return columnValue;
}
}

View File

@@ -16,7 +16,7 @@ import java.util.List;
import javax.sql.DataSource;
/**
* DM数据库写入实现类
* 达梦数据库写入实现类
*
* @author tang
*/

View File

@@ -12,8 +12,6 @@ package com.gitee.dbswitch.dbwriter.mssql;
import com.gitee.dbswitch.dbwriter.AbstractDatabaseWriter;
import com.gitee.dbswitch.dbwriter.IDatabaseWriter;
import com.gitee.dbswitch.dbwriter.util.ObjectCastUtils;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -110,12 +108,4 @@ public class SqlServerWriterImpl extends AbstractDatabaseWriter implements IData
}
@Override
public Object format(Object columnValue) {
if (columnValue instanceof BigInteger) {
return ((BigInteger) columnValue).longValue();
}
return columnValue;
}
}

View File

@@ -0,0 +1,48 @@
// 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.oscar;
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;
/**
* 神通数据库写入实现类
*
* @author tang
*/
public class OscarWriterImpl extends AbstractDatabaseWriter implements IDatabaseWriter {
public OscarWriterImpl(DataSource dataSource) {
super(dataSource);
}
@Override
protected String getDatabaseProductName() {
return "Oscar";
}
@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

@@ -1,9 +1,9 @@
package com.gitee.dbswitch.dbwriter.util;
import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import com.gitee.dbswitch.common.util.TypeConvertUtils;
import java.lang.reflect.Method;
import java.sql.SQLException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
@@ -16,6 +16,7 @@ import org.apache.commons.lang3.StringUtils;
public final class ObjectCastUtils {
private ObjectCastUtils() {
throw new IllegalStateException("Utility class can not create instance!");
}
/**
@@ -25,23 +26,7 @@ public final class ObjectCastUtils {
* @return java.lang.String类型数据
*/
public static String clob2Str(java.sql.Clob clob) {
if (null == clob) {
return null;
}
try (java.io.Reader is = clob.getCharacterStream()) {
java.io.BufferedReader reader = new java.io.BufferedReader(is);
String line = reader.readLine();
StringBuilder sb = new StringBuilder();
while (line != null) {
sb.append(line);
line = reader.readLine();
}
return sb.toString();
} catch (SQLException | java.io.IOException e) {
log.warn("Field Value convert from java.sql.Clob to java.lang.String failed:", e);
return null;
}
return TypeConvertUtils.clob2Str(clob);
}
/**
@@ -51,45 +36,17 @@ public final class ObjectCastUtils {
* @return byte数组
*/
public static byte[] blob2Bytes(java.sql.Blob blob) {
if (null == blob) {
return null;
}
try (java.io.InputStream inputStream = blob.getBinaryStream();) {
try (java.io.BufferedInputStream is = new java.io.BufferedInputStream(inputStream)) {
byte[] bytes = new byte[(int) blob.length()];
int len = bytes.length;
int offset = 0;
int read = 0;
while (offset < len && (read = is.read(bytes, offset, len - offset)) >= 0) {
offset += read;
}
return bytes;
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return TypeConvertUtils.blob2Bytes(blob);
}
/**
* 将Object对象转换为字节数组
*
* @param obj 对象
* @param in 对象
* @return 字节数组
*/
public static byte[] toByteArray(Object obj) {
if (null == obj) {
return null;
}
try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos)) {
oos.writeObject(obj);
oos.flush();
return bos.toByteArray();
} catch (Exception e) {
throw new RuntimeException(e);
}
public static byte[] toByteArray(Object in) {
return TypeConvertUtils.castToByteArray(in);
}
/**
@@ -99,94 +56,7 @@ public final class ObjectCastUtils {
* @return java.lang.String类型
*/
public static String castToString(final Object in) {
if (in instanceof java.lang.Character) {
return in.toString();
} else if (in instanceof java.lang.String) {
return in.toString();
} else if (in instanceof java.lang.Character) {
return in.toString();
} else if (in instanceof java.sql.Clob) {
return clob2Str((java.sql.Clob) in);
} else if (in instanceof java.lang.Number) {
return in.toString();
} else if (in instanceof java.sql.RowId) {
return in.toString();
} else if (in instanceof java.lang.Boolean) {
return in.toString();
} else if (in instanceof java.util.Date) {
return in.toString();
} else if (in instanceof java.time.LocalDate) {
return in.toString();
} else if (in instanceof java.time.LocalTime) {
return in.toString();
} else if (in instanceof java.time.LocalDateTime) {
return in.toString();
} else if (in instanceof java.time.OffsetDateTime) {
return in.toString();
} else if (in instanceof java.util.UUID) {
return in.toString();
} else if (in instanceof org.postgresql.util.PGobject) {
return in.toString();
} else if (in instanceof org.postgresql.jdbc.PgSQLXML) {
try {
return ((org.postgresql.jdbc.PgSQLXML) in).getString();
} catch (Exception e) {
return "";
}
} else if (in instanceof java.sql.SQLXML) {
return in.toString();
} else if (in instanceof java.sql.Array) {
return in.toString();
} else if (in.getClass().getName().equals("oracle.sql.INTERVALDS")) {
return in.toString();
} else if (in.getClass().getName().equals("oracle.sql.INTERVALYM")) {
return in.toString();
} else if (in.getClass().getName().equals("oracle.sql.TIMESTAMPLTZ")) {
return in.toString();
} else if (in.getClass().getName().equals("oracle.sql.TIMESTAMPTZ")) {
return in.toString();
} else if (in.getClass().getName().equals("oracle.sql.BFILE")) {
Class<?> clz = in.getClass();
try {
Method methodFileExists = clz.getMethod("fileExists");
boolean exists = (boolean) methodFileExists.invoke(in);
if (!exists) {
return "";
}
Method methodOpenFile = clz.getMethod("openFile");
methodOpenFile.invoke(in);
try {
Method methodCharacterStreamValue = clz.getMethod("getBinaryStream");
java.io.InputStream is = (java.io.InputStream) methodCharacterStreamValue.invoke(in);
String line;
StringBuilder sb = new StringBuilder();
java.io.BufferedReader br = new java.io.BufferedReader(new java.io.InputStreamReader(is));
while ((line = br.readLine()) != null) {
sb.append(line);
}
return sb.toString();
} finally {
Method methodCloseFile = clz.getMethod("closeFile");
methodCloseFile.invoke(in);
}
} catch (java.lang.reflect.InvocationTargetException ex) {
log.warn("Error for handle oracle.sql.BFILE: ", ex);
return "";
} catch (Exception e) {
throw new RuntimeException(e);
}
} else if (in.getClass().getName().equals("microsoft.sql.DateTimeOffset")) {
return in.toString();
} else if (in instanceof byte[]) {
return new String((byte[]) in);
}
return null;
return TypeConvertUtils.castToString(in);
}
/**
@@ -867,7 +737,15 @@ public final class ObjectCastUtils {
return null;
}
if (in instanceof java.sql.Clob) {
if (in instanceof BigInteger) {
return ((BigInteger) in).longValue();
} else if (in instanceof BigDecimal) {
BigDecimal decimal = (BigDecimal) in;
if (decimal.doubleValue() > 2.147483647E9D || decimal.doubleValue() < -2.147483648E9D) {
return 0D;
}
return decimal.doubleValue();
} else if (in instanceof java.sql.Clob) {
return clob2Str((java.sql.Clob) in);
} else if (in instanceof java.sql.Array
|| in instanceof java.sql.SQLXML) {

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>com.gitee.dbswitch</groupId>
<artifactId>dbswitch-parent</artifactId>
<version>1.6.11</version>
<version>1.6.12</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.11</version>
<version>1.6.12</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.11</version>
<version>1.6.12</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.11</version>
<version>1.6.12</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.11
set APP_VERSION=1.6.12
echo "Clean Project ..."
call mvn clean -f pom.xml