Skip to content

Commit

Permalink
[Feature][Connector-V2] Jdbc connector support SAP HANA.
Browse files Browse the repository at this point in the history
  • Loading branch information
FlechazoW committed Nov 8, 2022
1 parent 4fcb3ca commit 6cb0b51
Show file tree
Hide file tree
Showing 11 changed files with 381 additions and 1 deletion.
1 change: 1 addition & 0 deletions docs/en/connector-v2/sink/Jdbc.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ there are some reference value for params above.
| GBase8a | com.gbase.jdbc.Driver | jdbc:gbase://e2e_gbase8aDb:5258/test | / | https://www.gbase8.cn/wp-content/uploads/2020/10/gbase-connector-java-8.3.81.53-build55.5.7-bin_min_mix.jar |
| StarRocks | com.mysql.cj.jdbc.Driver | jdbc:mysql://localhost:3306/test | / | https://mvnrepository.com/artifact/mysql/mysql-connector-java |
| db2 | com.ibm.db2.jcc.DB2Driver | jdbc:db2://localhost:50000/testdb | com.ibm.db2.jcc.DB2XADataSource | https://mvnrepository.com/artifact/com.ibm.db2.jcc/db2jcc/db2jcc4 |
| saphana | com.sap.db.jdbc.Driver | jdbc:sap://localhost:39015 | / | https://mvnrepository.com/artifact/com.sap.cloud.db.jdbc/ngdbc |

## Example

Expand Down
1 change: 1 addition & 0 deletions docs/en/connector-v2/source/Jdbc.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ there are some reference value for params above.
| gbase8a | com.gbase.jdbc.Driver | jdbc:gbase://e2e_gbase8aDb:5258/test | https://www.gbase8.cn/wp-content/uploads/2020/10/gbase-connector-java-8.3.81.53-build55.5.7-bin_min_mix.jar |
| starrocks | com.mysql.cj.jdbc.Driver | jdbc:mysql://localhost:3306/test | https://mvnrepository.com/artifact/mysql/mysql-connector-java |
| db2 | com.ibm.db2.jcc.DB2Driver | jdbc:db2://localhost:50000/testdb | https://mvnrepository.com/artifact/com.ibm.db2.jcc/db2jcc/db2jcc4 |
| saphana | com.sap.db.jdbc.Driver | jdbc:sap://localhost:39015 | https://mvnrepository.com/artifact/com.sap.cloud.db.jdbc/ngdbc |

## Example

Expand Down
13 changes: 13 additions & 0 deletions seatunnel-connectors-v2/connector-jdbc/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
<phoenix.version>5.2.5-HBase-2.x</phoenix.version>
<oracle.version>12.2.0.1</oracle.version>
<db2.version>db2jcc4</db2.version>
<saphana.version>2.14.7</saphana.version>
</properties>

<dependencyManagement>
Expand Down Expand Up @@ -84,6 +85,13 @@
<scope>provided</scope>
</dependency>

<!-- https://mvnrepository.com/artifact/com.sap.cloud.db.jdbc/ngdbc -->
<dependency>
<groupId>com.sap.cloud.db.jdbc</groupId>
<artifactId>ngdbc</artifactId>
<version>${saphana.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
</dependencyManagement>

Expand Down Expand Up @@ -119,6 +127,11 @@
<groupId>com.ibm.db2.jcc</groupId>
<artifactId>db2jcc</artifactId>
</dependency>

<dependency>
<groupId>com.sap.cloud.db.jdbc</groupId>
<artifactId>ngdbc</artifactId>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.seatunnel.connectors.seatunnel.jdbc.internal.dialect.saphana;

import org.apache.seatunnel.connectors.seatunnel.jdbc.internal.converter.JdbcRowConverter;
import org.apache.seatunnel.connectors.seatunnel.jdbc.internal.dialect.JdbcDialect;
import org.apache.seatunnel.connectors.seatunnel.jdbc.internal.dialect.JdbcDialectTypeMapper;

public class SapHanaDialect implements JdbcDialect {
@Override
public String dialectName() {
return "SapHana";
}

@Override
public JdbcRowConverter getRowConverter() {
return new SapHanaJdbcRowConverter();
}

@Override
public JdbcDialectTypeMapper getJdbcDialectTypeMapper() {
return new SapHanaTypeMapper();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.seatunnel.connectors.seatunnel.jdbc.internal.dialect.saphana;

import org.apache.seatunnel.connectors.seatunnel.jdbc.internal.dialect.JdbcDialect;
import org.apache.seatunnel.connectors.seatunnel.jdbc.internal.dialect.JdbcDialectFactory;

import com.google.auto.service.AutoService;

/**
* Dialect Factory of {@link SapHanaDialect}
*/

@AutoService(JdbcDialectFactory.class)
public class SapHanaDialectFactory implements JdbcDialectFactory {
@Override
public boolean acceptsURL(String url) {
return url.startsWith("jdbc:sap://");
}

@Override
public JdbcDialect create() {
return new SapHanaDialect();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.seatunnel.connectors.seatunnel.jdbc.internal.dialect.saphana;

import org.apache.seatunnel.connectors.seatunnel.jdbc.internal.converter.AbstractJdbcRowConverter;

public class SapHanaJdbcRowConverter extends AbstractJdbcRowConverter {
@Override
public String converterName() {
return "SapHana";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.seatunnel.connectors.seatunnel.jdbc.internal.dialect.saphana;

import org.apache.seatunnel.api.table.type.BasicType;
import org.apache.seatunnel.api.table.type.DecimalType;
import org.apache.seatunnel.api.table.type.LocalTimeType;
import org.apache.seatunnel.api.table.type.PrimitiveByteArrayType;
import org.apache.seatunnel.api.table.type.SeaTunnelDataType;
import org.apache.seatunnel.connectors.seatunnel.jdbc.internal.dialect.JdbcDialectTypeMapper;

import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.Locale;

public class SapHanaTypeMapper implements JdbcDialectTypeMapper {

// refer to https://help.sap.com/docs/SAP_BUSINESSOBJECTS_BUSINESS_INTELLIGENCE_PLATFORM/aa4cb9ab429349e49678e146f05d7341/ec3313286fdb101497906a7cb0e91070.html?locale=zh-CN
private static final String SAP_HANA_BLOB = "blob";
private static final String SAP_HANA_VARBINARY = "varbinary";
private static final String SAP_HANA_DATE = "date";
private static final String SAP_HANA_TIME = "time";
private static final String SAP_HANA_LONGDATE = "longtime";
private static final String SAP_HANA_SECONDDATE = "seconddate";
private static final String SAP_HANA_TIMESTAMP = "timestamp";
private static final String SAP_HANA_DECIMAL = "decimal";
private static final String SAP_HANA_REAL = "real";
private static final String SAP_HANA_SMALLDECIMAL = "smalldecimal";
private static final String SAP_HANA_BIGINT = "bigint";
private static final String SAP_HANA_INTEGER = "integer";
private static final String SAP_HANA_SMALLINT = "smallint";
private static final String SAP_HANA_TINYINT = "tinyint";
private static final String SAP_HANA_DOUBLE = "double";
private static final String SAP_HANA_CLOB = "clob";
private static final String SAP_HANA_NCLOB = "nclob";
private static final String SAP_HANA_TEXT = "text";
private static final String SAP_HANA_ALPHANUM = "alphanum";
private static final String SAP_HANA_NVARCHAR = "nvarchar";
private static final String SAP_HANA_SHORTTEXT = "shorttext";
private static final String SAP_HANA_VARCHAR = "varchar";
private static final String SAP_HANA_BINARY = "binary";

@Override
public SeaTunnelDataType<?> mapping(ResultSetMetaData metadata, int colIndex) throws SQLException {
String typeName = metadata.getColumnTypeName(colIndex).toLowerCase(Locale.ROOT);

int precision = metadata.getPrecision(colIndex);
int scale = metadata.getScale(colIndex);

switch (typeName) {
case SAP_HANA_BLOB:
case SAP_HANA_VARBINARY:
case SAP_HANA_BINARY:
return PrimitiveByteArrayType.INSTANCE;
case SAP_HANA_DATE:
return LocalTimeType.LOCAL_DATE_TYPE;
case SAP_HANA_TIME:
return LocalTimeType.LOCAL_TIME_TYPE;
case SAP_HANA_TIMESTAMP:
case SAP_HANA_LONGDATE:
case SAP_HANA_SECONDDATE:
return LocalTimeType.LOCAL_DATE_TIME_TYPE;
case SAP_HANA_DECIMAL:
return new DecimalType(precision, scale);
case SAP_HANA_REAL:
case SAP_HANA_SMALLDECIMAL:
return BasicType.FLOAT_TYPE;
case SAP_HANA_BIGINT:
case SAP_HANA_INTEGER:
case SAP_HANA_SMALLINT:
case SAP_HANA_TINYINT:
return BasicType.INT_TYPE;
case SAP_HANA_DOUBLE:
return BasicType.DOUBLE_TYPE;
case SAP_HANA_CLOB:
case SAP_HANA_NCLOB:
case SAP_HANA_TEXT:
case SAP_HANA_ALPHANUM:
case SAP_HANA_NVARCHAR:
case SAP_HANA_SHORTTEXT:
case SAP_HANA_VARCHAR:
return BasicType.STRING_TYPE;
default:
final String jdbcColumnName = metadata.getColumnName(colIndex);
throw new UnsupportedOperationException(
String.format(
"Doesn't support SapHana type '%s' on column '%s' yet.",
typeName, jdbcColumnName));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@
<artifactId>db2jcc</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.sap.cloud.db.jdbc</groupId>
<artifactId>ngdbc</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.output.Slf4jLogConsumer;
import org.testcontainers.lifecycle.Startables;
import org.testcontainers.utility.DockerLoggerFactory;

import java.io.IOException;
import java.net.MalformedURLException;
Expand Down Expand Up @@ -83,7 +84,7 @@ private void getContainer() throws SQLException, MalformedURLException, ClassNot
.withNetwork(NETWORK)
.withNetworkAliases(jdbcCase.getNetworkAliases())
.withEnv(jdbcCase.getContainerEnv())
.withLogConsumer(new Slf4jLogConsumer(log));
.withLogConsumer(new Slf4jLogConsumer(DockerLoggerFactory.getLogger(jdbcCase.getDockerImage())));
dbServer.setPortBindings(Lists.newArrayList(
String.format("%s:%s", jdbcCase.getPort(), jdbcCase.getPort())));
Startables.deepStart(Stream.of(dbServer)).join();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

sap_hana_table_source = """
-- auto-generated definition
create table E2E_TEST.E2E_TABLE_SOURCE
(
BLOB_VAL BLOB,
VARBINARY_VAL VARBINARY(1),
DATE_VAL DATE(10),
TIME_VAL TIME(8),
LONGDATE_VAL TIMESTAMP(27, 7),
SECONDDATE_VAL SECONDDATE(19),
TIMESTAMP_VAL TIMESTAMP(27,7),
DECIMAL_VAL DECIMAL(34),
REAL_VAL REAL(7),
SMALLDECIMAL_VAL SMALLDECIMAL(16),
BIGINT_VAL BIGINT(19),
INTEGER_VAL INTEGER,
SMALLINT_VAL SMALLINT(5),
TINYINT_VAL TINYINT(3),
DOUBLE_VAL DOUBLE(15),
CLOB_VAL CLOB,
NCLOB_VAL NCLOB(715827882),
TEXT_VAL TEXT(0)
constraint "_SYS_FULLTEXT_166583_#0_#TEXT_VAL"
unique,
ALPHANUM_VAL ALPHANUM(1),
NVARCHAR_VAL NVARCHAR(1),
SHORTTEXT_VAL VARCHAR(1),
VARCHAR_VAL VARCHAR(1)
);
"""

sap_hana_table_sink = """
-- auto-generated definition
create table E2E_TEST.E2E_TABLE_SINK
(
BLOB_VAL BLOB,
VARBINARY_VAL VARBINARY(1),
DATE_VAL DATE(10),
TIME_VAL TIME(8),
LONGDATE_VAL TIMESTAMP(27, 7),
SECONDDATE_VAL SECONDDATE(19),
TIMESTAMP_VAL TIMESTAMP(27,7),
DECIMAL_VAL DECIMAL(34),
REAL_VAL REAL(7),
SMALLDECIMAL_VAL SMALLDECIMAL(16),
BIGINT_VAL BIGINT(19),
INTEGER_VAL INTEGER,
SMALLINT_VAL SMALLINT(5),
TINYINT_VAL TINYINT(3),
DOUBLE_VAL DOUBLE(15),
CLOB_VAL CLOB,
NCLOB_VAL NCLOB(715827882),
TEXT_VAL TEXT(0)
constraint "_SYS_FULLTEXT_166583_#0_#TEXT_VAL"
unique,
ALPHANUM_VAL ALPHANUM(1),
NVARCHAR_VAL NVARCHAR(1),
SHORTTEXT_VAL VARCHAR(1),
VARCHAR_VAL VARCHAR(1)
);
"""

// only for sap_hana_table_source
DML = """
insert into E2E_TEST.E2E_TABLE_SOURCE (BLOB_VAL, VARBINARY_VAL, DATE_VAL, TIME_VAL, LONGDATE_VAL, SECONDDATE_VAL,
TIMESTAMP_VAL, DECIMAL_VAL, REAL_VAL, SMALLDECIMAL_VAL, BIGINT_VAL, INTEGER_VAL,
SMALLINT_VAL, TINYINT_VAL, DOUBLE_VAL, CLOB_VAL, NCLOB_VAL, TEXT_VAL, ALPHANUM_VAL,
NVARCHAR_VAL, SHORTTEXT_VAL, VARCHAR_VAL)
values (TO_BLOB(TO_BINARY('abc')), '1', '2022-10-08', '13:14:00', '2022-10-08', '2022-10-08', '2022-10-08 13:14:00',
13.14, 13.14, 13.14, 11, 22, 33, 1, 13.14, TO_CLOB('xxx'), 'xxx', 'xxx', TO_ALPHANUM(1), 'x', 'x',
TO_VARCHAR('x'));
"""
Loading

0 comments on commit 6cb0b51

Please sign in to comment.