diff --git a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/Config.java b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/Config.java index 0b1049330eae7..ebf0baabee283 100644 --- a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/Config.java +++ b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/Config.java @@ -51,6 +51,9 @@ private Config() { static final int RETRY_NUM = 3; static final long RETRY_INTERVAL_MS = 1000; + static final int DRIVER_MAJOR_VERSION = 4; + static final int DRIVER_MINOR_VERSION = 3; + public static final int DEFAULT_FETCH_SIZE = 5000; static final int DEFAULT_CONNECTION_TIMEOUT_MS = 0; diff --git a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBAbstractDatabaseMetadata.java b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBAbstractDatabaseMetadata.java index 0f81bca6069aa..3928657b93372 100644 --- a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBAbstractDatabaseMetadata.java +++ b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBAbstractDatabaseMetadata.java @@ -606,12 +606,12 @@ public String getDriverName() throws SQLException { @Override public int getDriverMajorVersion() { - return 4; + return Config.DRIVER_MAJOR_VERSION; } @Override public int getDriverMinorVersion() { - return 3; + return Config.DRIVER_MINOR_VERSION; } @Override diff --git a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBDriver.java b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBDriver.java index de7065c1c571c..2c0b6d4c7f1a5 100644 --- a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBDriver.java +++ b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBDriver.java @@ -20,8 +20,10 @@ package org.apache.iotdb.jdbc; import org.apache.iotdb.jdbc.i18n.JdbcMessages; +import org.apache.iotdb.rpc.RpcUtils; import org.apache.thrift.transport.TTransportException; +import org.apache.tsfile.common.conf.TSFileConfig; import org.osgi.service.component.annotations.Component; import java.sql.Connection; @@ -30,6 +32,8 @@ import java.sql.DriverPropertyInfo; import java.sql.SQLException; import java.sql.SQLFeatureNotSupportedException; +import java.time.ZoneId; +import java.util.Arrays; import java.util.Properties; import java.util.logging.Logger; import java.util.regex.Pattern; @@ -40,7 +44,12 @@ public class IoTDBDriver implements Driver { org.slf4j.LoggerFactory.getLogger(IoTDBDriver.class); /** Is this driver JDBC compliant. */ - private static final boolean TSFILE_JDBC_COMPLIANT = false; + private static final boolean IOTDB_JDBC_COMPLIANT = false; + + private static final String[] BOOLEAN_CHOICES = {"true", "false"}; + private static final String[] SQL_DIALECT_CHOICES = {Constant.TREE, Constant.TABLE}; + private static final String[] VERSION_CHOICES = + Arrays.stream(Constant.Version.values()).map(Enum::name).toArray(String[]::new); static { try { @@ -58,7 +67,7 @@ public IoTDBDriver() { @Override public boolean acceptsURL(String url) { - return Pattern.matches(TSFILE_URL_PREFIX, url); + return url != null && Pattern.matches(TSFILE_URL_PREFIX, url); } @Override @@ -75,14 +84,12 @@ public Connection connect(String url, Properties info) throws SQLException { @Override public int getMajorVersion() { - // TODO Auto-generated method stub - return 0; + return Config.DRIVER_MAJOR_VERSION; } @Override public int getMinorVersion() { - // TODO Auto-generated method stub - return 0; + return Config.DRIVER_MINOR_VERSION; } @Override @@ -92,12 +99,77 @@ public Logger getParentLogger() throws SQLFeatureNotSupportedException { @Override public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) { - // TODO Auto-generated method stub - return new DriverPropertyInfo[0]; + Properties properties = info == null ? new Properties() : info; + return new DriverPropertyInfo[] { + createProperty( + Config.AUTH_USER, Config.DEFAULT_USER, "User name for authentication.", properties), + createSensitiveProperty(Config.AUTH_PASSWORD, "Password for authentication."), + createProperty( + Config.DEFAULT_BUFFER_CAPACITY, + String.valueOf(RpcUtils.THRIFT_DEFAULT_BUF_CAPACITY), + "Thrift default buffer capacity in bytes.", + properties), + createProperty( + Config.THRIFT_FRAME_MAX_SIZE, + String.valueOf(RpcUtils.THRIFT_FRAME_MAX_SIZE), + "Thrift max frame size in bytes.", + properties), + createProperty( + Config.VERSION, + Config.DEFAULT_VERSION.name(), + VERSION_CHOICES, + "Client compatibility version.", + properties), + createProperty( + Config.NETWORK_TIMEOUT, + String.valueOf(Config.DEFAULT_CONNECTION_TIMEOUT_MS), + "Network timeout in milliseconds.", + properties), + createProperty( + Config.TIME_ZONE, ZoneId.systemDefault().toString(), "Connection time zone.", properties), + createProperty( + Config.CHARSET, TSFileConfig.STRING_CHARSET.name(), "Connection charset.", properties), + createProperty( + Config.USE_SSL, "false", BOOLEAN_CHOICES, "Whether to enable SSL.", properties), + createProperty(Config.TRUST_STORE, null, "SSL trust store path.", properties), + createSensitiveProperty(Config.TRUST_STORE_PWD, "SSL trust store password."), + createProperty( + Config.SQL_DIALECT, + Constant.TREE, + SQL_DIALECT_CHOICES, + "SQL dialect for the connection.", + properties) + }; } @Override public boolean jdbcCompliant() { - return TSFILE_JDBC_COMPLIANT; + return IOTDB_JDBC_COMPLIANT; + } + + private static DriverPropertyInfo createProperty( + String name, String defaultValue, String description, Properties properties) { + return createProperty(name, defaultValue, null, description, properties); + } + + private static DriverPropertyInfo createSensitiveProperty(String name, String description) { + DriverPropertyInfo propertyInfo = new DriverPropertyInfo(name, null); + propertyInfo.required = false; + propertyInfo.description = description; + return propertyInfo; + } + + private static DriverPropertyInfo createProperty( + String name, + String defaultValue, + String[] choices, + String description, + Properties properties) { + DriverPropertyInfo propertyInfo = + new DriverPropertyInfo(name, properties.getProperty(name, defaultValue)); + propertyInfo.required = false; + propertyInfo.choices = choices; + propertyInfo.description = description; + return propertyInfo; } } diff --git a/iotdb-client/jdbc/src/test/java/org/apache/iotdb/jdbc/IoTDBDriverTest.java b/iotdb-client/jdbc/src/test/java/org/apache/iotdb/jdbc/IoTDBDriverTest.java new file mode 100644 index 0000000000000..2dcd873dcd9a7 --- /dev/null +++ b/iotdb-client/jdbc/src/test/java/org/apache/iotdb/jdbc/IoTDBDriverTest.java @@ -0,0 +1,100 @@ +/* + * 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.iotdb.jdbc; + +import org.junit.Test; + +import java.sql.DriverPropertyInfo; +import java.util.Arrays; +import java.util.Properties; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +public class IoTDBDriverTest { + + @Test + public void testAcceptsUrl() { + IoTDBDriver driver = new IoTDBDriver(); + + assertTrue(driver.acceptsURL("jdbc:iotdb://localhost:6667")); + assertFalse(driver.acceptsURL(null)); + assertFalse(driver.acceptsURL("jdbc:mysql://localhost:3306")); + } + + @Test + public void testDriverVersion() { + IoTDBDriver driver = new IoTDBDriver(); + + assertEquals(Config.DRIVER_MAJOR_VERSION, driver.getMajorVersion()); + assertEquals(Config.DRIVER_MINOR_VERSION, driver.getMinorVersion()); + } + + @Test + public void testGetPropertyInfo() { + IoTDBDriver driver = new IoTDBDriver(); + Properties properties = new Properties(); + properties.setProperty(Config.AUTH_USER, "root"); + properties.setProperty(Config.AUTH_PASSWORD, "secret"); + properties.setProperty(Config.USE_SSL, "true"); + properties.setProperty(Config.TRUST_STORE_PWD, "trust-store-secret"); + + DriverPropertyInfo[] propertyInfos = + driver.getPropertyInfo("jdbc:iotdb://localhost:6667", properties); + + assertTrue(propertyInfos.length > 0); + assertEquals("root", findProperty(propertyInfos, Config.AUTH_USER).value); + assertNull(findProperty(propertyInfos, Config.AUTH_PASSWORD).value); + assertNull(findProperty(propertyInfos, Config.TRUST_STORE_PWD).value); + assertEquals("true", findProperty(propertyInfos, Config.USE_SSL).value); + assertEquals( + Arrays.asList("true", "false"), + Arrays.asList(findProperty(propertyInfos, Config.USE_SSL).choices)); + assertEquals( + Arrays.asList(Constant.TREE, Constant.TABLE), + Arrays.asList(findProperty(propertyInfos, Config.SQL_DIALECT).choices)); + assertEquals(Config.DEFAULT_VERSION.name(), findProperty(propertyInfos, Config.VERSION).value); + } + + @Test + public void testGetPropertyInfoAllowsNullProperties() { + IoTDBDriver driver = new IoTDBDriver(); + + DriverPropertyInfo[] propertyInfos = + driver.getPropertyInfo("jdbc:iotdb://localhost:6667", null); + + assertNotNull(propertyInfos); + assertEquals(Config.DEFAULT_USER, findProperty(propertyInfos, Config.AUTH_USER).value); + } + + private static DriverPropertyInfo findProperty(DriverPropertyInfo[] propertyInfos, String name) { + for (DriverPropertyInfo propertyInfo : propertyInfos) { + if (name.equals(propertyInfo.name)) { + return propertyInfo; + } + } + fail("Missing driver property: " + name); + return null; + } +}