diff --git a/src/connector/jdbc/pom.xml b/src/connector/jdbc/pom.xml
index 25a36e3a4822bfbea0c7f07ff3a4a09032d44542..97bcdbb38c08439b88002fb671d79069320e3739 100755
--- a/src/connector/jdbc/pom.xml
+++ b/src/connector/jdbc/pom.xml
@@ -56,6 +56,12 @@
test
+
+ mysql
+ mysql-connector-java
+ 5.1.47
+
+
org.apache.httpcomponents
@@ -74,6 +80,7 @@
+
diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractDatabaseMetaData.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractDatabaseMetaData.java
new file mode 100644
index 0000000000000000000000000000000000000000..1445be18654ff3e73b74484b47e09856ddc94b01
--- /dev/null
+++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractDatabaseMetaData.java
@@ -0,0 +1,808 @@
+/***************************************************************************
+ * Copyright (c) 2019 TAOS Data, Inc.
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *****************************************************************************/
+package com.taosdata.jdbc;
+
+import java.sql.*;
+import java.util.ArrayList;
+import java.util.List;
+
+public abstract class AbstractDatabaseMetaData implements DatabaseMetaData {
+
+ private final static String PRODUCT_NAME = "TDengine";
+ private final static String PRODUCT_VESION = "2.0.x.x";
+ private final static String DRIVER_NAME = "taos-jdbcdriver";
+ private final static String DRIVER_VERSION = "2.0.x";
+ private final static int DRIVER_MAJAR_VERSION = 2;
+ private final static int DRIVER_MINOR_VERSION = 0;
+
+ public boolean allProceduresAreCallable() throws SQLException {
+ return false;
+ }
+
+ public boolean allTablesAreSelectable() throws SQLException {
+ return false;
+ }
+
+ public abstract String getURL() throws SQLException;
+
+ public abstract String getUserName() throws SQLException;
+
+ public boolean isReadOnly() throws SQLException {
+ return false;
+ }
+
+ public boolean nullsAreSortedHigh() throws SQLException {
+ return false;
+ }
+
+ public boolean nullsAreSortedLow() throws SQLException {
+ return !nullsAreSortedHigh();
+ }
+
+ public boolean nullsAreSortedAtStart() throws SQLException {
+ return true;
+ }
+
+ public boolean nullsAreSortedAtEnd() throws SQLException {
+ return !nullsAreSortedAtStart();
+ }
+
+ public String getDatabaseProductName() throws SQLException {
+ return PRODUCT_NAME;
+ }
+
+ public String getDatabaseProductVersion() throws SQLException {
+ return PRODUCT_VESION;
+ }
+
+ public String getDriverName() throws SQLException {
+ return DRIVER_NAME;
+ }
+
+ public String getDriverVersion() throws SQLException {
+ return DRIVER_VERSION;
+ }
+
+ public int getDriverMajorVersion() {
+ return DRIVER_MAJAR_VERSION;
+ }
+
+ public int getDriverMinorVersion() {
+ return DRIVER_MINOR_VERSION;
+ }
+
+ public boolean usesLocalFiles() throws SQLException {
+ return false;
+ }
+
+ public boolean usesLocalFilePerTable() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsMixedCaseIdentifiers() throws SQLException {
+ return false;
+ }
+
+ public boolean storesUpperCaseIdentifiers() throws SQLException {
+ return false;
+ }
+
+ public boolean storesLowerCaseIdentifiers() throws SQLException {
+ return false;
+ }
+
+ public boolean storesMixedCaseIdentifiers() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException {
+ return false;
+ }
+
+ public boolean storesUpperCaseQuotedIdentifiers() throws SQLException {
+ return false;
+ }
+
+ public boolean storesLowerCaseQuotedIdentifiers() throws SQLException {
+ return false;
+ }
+
+ public boolean storesMixedCaseQuotedIdentifiers() throws SQLException {
+ return false;
+ }
+
+ public String getIdentifierQuoteString() throws SQLException {
+ return " ";
+ }
+
+ public String getSQLKeywords() throws SQLException {
+ return null;
+ }
+
+ public String getNumericFunctions() throws SQLException {
+ return null;
+ }
+
+ public String getStringFunctions() throws SQLException {
+ return null;
+ }
+
+ public String getSystemFunctions() throws SQLException {
+ return null;
+ }
+
+ public String getTimeDateFunctions() throws SQLException {
+ return null;
+ }
+
+ public String getSearchStringEscape() throws SQLException {
+ return null;
+ }
+
+ public String getExtraNameCharacters() throws SQLException {
+ return null;
+ }
+
+ public boolean supportsAlterTableWithAddColumn() throws SQLException {
+ return true;
+ }
+
+ public boolean supportsAlterTableWithDropColumn() throws SQLException {
+ return true;
+ }
+
+ public boolean supportsColumnAliasing() throws SQLException {
+ return true;
+ }
+
+ public boolean nullPlusNonNullIsNull() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsConvert() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsConvert(int fromType, int toType) throws SQLException {
+ return false;
+ }
+
+ public boolean supportsTableCorrelationNames() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsDifferentTableCorrelationNames() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsExpressionsInOrderBy() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsOrderByUnrelated() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsGroupBy() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsGroupByUnrelated() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsGroupByBeyondSelect() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsLikeEscapeClause() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsMultipleResultSets() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsMultipleTransactions() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsNonNullableColumns() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsMinimumSQLGrammar() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsCoreSQLGrammar() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsExtendedSQLGrammar() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsANSI92EntryLevelSQL() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsANSI92IntermediateSQL() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsANSI92FullSQL() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsIntegrityEnhancementFacility() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsOuterJoins() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsFullOuterJoins() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsLimitedOuterJoins() throws SQLException {
+ return false;
+ }
+
+ public String getSchemaTerm() throws SQLException {
+ return null;
+ }
+
+ public String getProcedureTerm() throws SQLException {
+ return null;
+ }
+
+ public String getCatalogTerm() throws SQLException {
+ return "database";
+ }
+
+ public boolean isCatalogAtStart() throws SQLException {
+ return true;
+ }
+
+ public String getCatalogSeparator() throws SQLException {
+ return ".";
+ }
+
+ public boolean supportsSchemasInDataManipulation() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsSchemasInProcedureCalls() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsSchemasInTableDefinitions() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsSchemasInIndexDefinitions() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsCatalogsInDataManipulation() throws SQLException {
+ return true;
+ }
+
+ public boolean supportsCatalogsInProcedureCalls() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsCatalogsInTableDefinitions() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsCatalogsInIndexDefinitions() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsPositionedDelete() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsPositionedUpdate() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsSelectForUpdate() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsStoredProcedures() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsSubqueriesInComparisons() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsSubqueriesInExists() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsSubqueriesInIns() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsSubqueriesInQuantifieds() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsCorrelatedSubqueries() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsUnion() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsUnionAll() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsOpenCursorsAcrossCommit() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsOpenCursorsAcrossRollback() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsOpenStatementsAcrossCommit() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsOpenStatementsAcrossRollback() throws SQLException {
+ return false;
+ }
+
+ public int getMaxBinaryLiteralLength() throws SQLException {
+ return 0;
+ }
+
+ public int getMaxCharLiteralLength() throws SQLException {
+ return 0;
+ }
+
+ public int getMaxColumnNameLength() throws SQLException {
+ return 0;
+ }
+
+ public int getMaxColumnsInGroupBy() throws SQLException {
+ return 0;
+ }
+
+ public int getMaxColumnsInIndex() throws SQLException {
+ return 0;
+ }
+
+ public int getMaxColumnsInOrderBy() throws SQLException {
+ return 0;
+ }
+
+ public int getMaxColumnsInSelect() throws SQLException {
+ return 0;
+ }
+
+ public int getMaxColumnsInTable() throws SQLException {
+ return 0;
+ }
+
+ public int getMaxConnections() throws SQLException {
+ return 0;
+ }
+
+ public int getMaxCursorNameLength() throws SQLException {
+ return 0;
+ }
+
+ public int getMaxIndexLength() throws SQLException {
+ return 0;
+ }
+
+ public int getMaxSchemaNameLength() throws SQLException {
+ return 0;
+ }
+
+ public int getMaxProcedureNameLength() throws SQLException {
+ return 0;
+ }
+
+ public int getMaxCatalogNameLength() throws SQLException {
+ return 0;
+ }
+
+ public int getMaxRowSize() throws SQLException {
+ return 0;
+ }
+
+ public boolean doesMaxRowSizeIncludeBlobs() throws SQLException {
+ return false;
+ }
+
+ public int getMaxStatementLength() throws SQLException {
+ return 0;
+ }
+
+ public int getMaxStatements() throws SQLException {
+ return 0;
+ }
+
+ public int getMaxTableNameLength() throws SQLException {
+ return 0;
+ }
+
+ public int getMaxTablesInSelect() throws SQLException {
+ return 0;
+ }
+
+ public int getMaxUserNameLength() throws SQLException {
+ return 0;
+ }
+
+ public int getDefaultTransactionIsolation() throws SQLException {
+ return 0;
+ }
+
+ public boolean supportsTransactions() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsTransactionIsolationLevel(int level) throws SQLException {
+ return false;
+ }
+
+ public boolean supportsDataDefinitionAndDataManipulationTransactions() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsDataManipulationTransactionsOnly() throws SQLException {
+ return false;
+ }
+
+ public boolean dataDefinitionCausesTransactionCommit() throws SQLException {
+ return false;
+ }
+
+ public boolean dataDefinitionIgnoredInTransactions() throws SQLException {
+ return false;
+ }
+
+ public ResultSet getProcedures(String catalog, String schemaPattern, String procedureNamePattern)
+ throws SQLException {
+ throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
+ }
+
+ public ResultSet getProcedureColumns(String catalog, String schemaPattern, String procedureNamePattern,
+ String columnNamePattern) throws SQLException {
+ throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
+ }
+
+ public abstract ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types)
+ throws SQLException;
+
+ public ResultSet getSchemas() throws SQLException {
+ return getEmptyResultSet();
+ }
+
+ public abstract ResultSet getCatalogs() throws SQLException;
+
+ public ResultSet getTableTypes() throws SQLException {
+ DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet();
+
+ // set up ColumnMetaDataList
+ List columnMetaDataList = new ArrayList(1);
+ ColumnMetaData colMetaData = new ColumnMetaData();
+ colMetaData.setColIndex(0);
+ colMetaData.setColName("TABLE_TYPE");
+ colMetaData.setColSize(10);
+ colMetaData.setColType(TSDBConstants.TSDB_DATA_TYPE_BINARY);
+ columnMetaDataList.add(colMetaData);
+
+ // set up rowDataList
+ List rowDataList = new ArrayList(2);
+ TSDBResultSetRowData rowData = new TSDBResultSetRowData();
+ rowData.setString(0, "TABLE");
+ rowDataList.add(rowData);
+ rowData = new TSDBResultSetRowData();
+ rowData.setString(0, "STABLE");
+ rowDataList.add(rowData);
+
+ resultSet.setColumnMetaDataList(columnMetaDataList);
+ resultSet.setRowDataList(rowDataList);
+ return resultSet;
+ }
+
+ public abstract ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException;
+
+ protected int getNullable(int index, String typeName) {
+ if (index == 0 && "TIMESTAMP".equals(typeName))
+ return DatabaseMetaData.columnNoNulls;
+ return DatabaseMetaData.columnNullable;
+ }
+
+ protected int getColumnSize(String typeName, int length) {
+ switch (typeName) {
+ case "TIMESTAMP":
+ return 23;
+
+ default:
+ return 0;
+ }
+ }
+
+ protected int getDecimalDigits(String typeName) {
+ switch (typeName) {
+ case "FLOAT":
+ return 5;
+ case "DOUBLE":
+ return 9;
+ default:
+ return 0;
+ }
+ }
+
+ protected int getDataType(String typeName) {
+ switch (typeName) {
+ case "TIMESTAMP":
+ return Types.TIMESTAMP;
+ case "INT":
+ return Types.INTEGER;
+ case "BIGINT":
+ return Types.BIGINT;
+ case "FLOAT":
+ return Types.FLOAT;
+ case "DOUBLE":
+ return Types.DOUBLE;
+ case "BINARY":
+ return Types.BINARY;
+ case "SMALLINT":
+ return Types.SMALLINT;
+ case "TINYINT":
+ return Types.TINYINT;
+ case "BOOL":
+ return Types.BOOLEAN;
+ case "NCHAR":
+ return Types.NCHAR;
+ default:
+ return Types.NULL;
+ }
+ }
+
+ public ResultSet getColumnPrivileges(String catalog, String schema, String table, String columnNamePattern)
+ throws SQLException {
+ return getEmptyResultSet();
+ }
+
+ public ResultSet getTablePrivileges(String catalog, String schemaPattern, String tableNamePattern)
+ throws SQLException {
+ return getEmptyResultSet();
+ }
+
+ public ResultSet getBestRowIdentifier(String catalog, String schema, String table, int scope, boolean nullable)
+ throws SQLException {
+ return getEmptyResultSet();
+ }
+
+ public ResultSet getVersionColumns(String catalog, String schema, String table) throws SQLException {
+ return getEmptyResultSet();
+ }
+
+ public ResultSet getPrimaryKeys(String catalog, String schema, String table) throws SQLException {
+ return getEmptyResultSet();
+ }
+
+ public ResultSet getImportedKeys(String catalog, String schema, String table) throws SQLException {
+ return getEmptyResultSet();
+ }
+
+ public ResultSet getExportedKeys(String catalog, String schema, String table) throws SQLException {
+ return getEmptyResultSet();
+ }
+
+ public ResultSet getCrossReference(String parentCatalog, String parentSchema, String parentTable,
+ String foreignCatalog, String foreignSchema, String foreignTable) throws SQLException {
+ return getEmptyResultSet();
+ }
+
+ public ResultSet getTypeInfo() throws SQLException {
+ return getEmptyResultSet();
+ }
+
+ public ResultSet getIndexInfo(String catalog, String schema, String table, boolean unique, boolean approximate)
+ throws SQLException {
+ return getEmptyResultSet();
+ }
+
+ public boolean supportsResultSetType(int type) throws SQLException {
+ return false;
+ }
+
+ public boolean supportsResultSetConcurrency(int type, int concurrency) throws SQLException {
+ return false;
+ }
+
+ public boolean ownUpdatesAreVisible(int type) throws SQLException {
+ return false;
+ }
+
+ public boolean ownDeletesAreVisible(int type) throws SQLException {
+ return false;
+ }
+
+ public boolean ownInsertsAreVisible(int type) throws SQLException {
+ return false;
+ }
+
+ public boolean othersUpdatesAreVisible(int type) throws SQLException {
+ return false;
+ }
+
+ public boolean othersDeletesAreVisible(int type) throws SQLException {
+ return false;
+ }
+
+ public boolean othersInsertsAreVisible(int type) throws SQLException {
+ return false;
+ }
+
+ public boolean updatesAreDetected(int type) throws SQLException {
+ return false;
+ }
+
+ public boolean deletesAreDetected(int type) throws SQLException {
+ return false;
+ }
+
+ public boolean insertsAreDetected(int type) throws SQLException {
+ return false;
+ }
+
+ public boolean supportsBatchUpdates() throws SQLException {
+ return false;
+ }
+
+ public ResultSet getUDTs(String catalog, String schemaPattern, String typeNamePattern, int[] types)
+ throws SQLException {
+ return getEmptyResultSet();
+ }
+
+ public Connection getConnection() throws SQLException {
+ return null;
+ }
+
+ public boolean supportsSavepoints() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsNamedParameters() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsMultipleOpenResults() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsGetGeneratedKeys() throws SQLException {
+ return false;
+ }
+
+ public ResultSet getSuperTypes(String catalog, String schemaPattern, String typeNamePattern) throws SQLException {
+ return getEmptyResultSet();
+ }
+
+ public ResultSet getSuperTables(String catalog, String schemaPattern, String tableNamePattern) throws SQLException {
+ return getEmptyResultSet();
+ }
+
+ public ResultSet getAttributes(String catalog, String schemaPattern, String typeNamePattern,
+ String attributeNamePattern) throws SQLException {
+ return getEmptyResultSet();
+ }
+
+ public boolean supportsResultSetHoldability(int holdability) throws SQLException {
+ return false;
+ }
+
+ public int getResultSetHoldability() throws SQLException {
+ return 0;
+ }
+
+ public int getDatabaseMajorVersion() throws SQLException {
+ return 0;
+ }
+
+ public int getDatabaseMinorVersion() throws SQLException {
+ return 0;
+ }
+
+ public int getJDBCMajorVersion() throws SQLException {
+ return 0;
+ }
+
+ public int getJDBCMinorVersion() throws SQLException {
+ return 0;
+ }
+
+ public int getSQLStateType() throws SQLException {
+ return 0;
+ }
+
+ public boolean locatorsUpdateCopy() throws SQLException {
+ return false;
+ }
+
+ public boolean supportsStatementPooling() throws SQLException {
+ return false;
+ }
+
+ public RowIdLifetime getRowIdLifetime() throws SQLException {
+ return null;
+ }
+
+ public ResultSet getSchemas(String catalog, String schemaPattern) throws SQLException {
+ return null;
+ }
+
+ public boolean supportsStoredFunctionsUsingCallSyntax() throws SQLException {
+ return false;
+ }
+
+ public boolean autoCommitFailureClosesAllResultSets() throws SQLException {
+ return false;
+ }
+
+ public ResultSet getClientInfoProperties() throws SQLException {
+ return getEmptyResultSet();
+ }
+
+ public ResultSet getFunctions(String catalog, String schemaPattern, String functionNamePattern)
+ throws SQLException {
+ return getEmptyResultSet();
+ }
+
+ public ResultSet getFunctionColumns(String catalog, String schemaPattern, String functionNamePattern,
+ String columnNamePattern) throws SQLException {
+ return getEmptyResultSet();
+ }
+
+ public ResultSet getPseudoColumns(String catalog, String schemaPattern, String tableNamePattern,
+ String columnNamePattern) throws SQLException {
+ return getEmptyResultSet();
+ }
+
+ public boolean generatedKeyAlwaysReturned() throws SQLException {
+ return false;
+ }
+
+ private ResultSet getEmptyResultSet() {
+ return new EmptyResultSet();
+ }
+}
\ No newline at end of file
diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConstants.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConstants.java
index 3940e809300b7d8e0b6c79038afaa6ff76f81bf0..4f4911aad9c138eb13fffdd698b794a03222160f 100644
--- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConstants.java
+++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConstants.java
@@ -19,68 +19,71 @@ import java.util.Map;
public abstract class TSDBConstants {
- public static final String DEFAULT_PORT = "6200";
- public static final String UNSUPPORT_METHOD_EXCEPTIONZ_MSG = "this operation is NOT supported currently!";
- public static final String INVALID_VARIABLES = "invalid variables";
- public static Map DATATYPE_MAP = null;
+ public static final String DEFAULT_PORT = "6200";
+ public static final String UNSUPPORT_METHOD_EXCEPTIONZ_MSG = "this operation is NOT supported currently!";
+ public static final String INVALID_VARIABLES = "invalid variables";
+ public static Map DATATYPE_MAP = null;
- public static final long JNI_NULL_POINTER = 0L;
+ public static final long JNI_NULL_POINTER = 0L;
- public static final int JNI_SUCCESS = 0;
- public static final int JNI_TDENGINE_ERROR = -1;
- public static final int JNI_CONNECTION_NULL = -2;
- public static final int JNI_RESULT_SET_NULL = -3;
- public static final int JNI_NUM_OF_FIELDS_0 = -4;
- public static final int JNI_SQL_NULL = -5;
- public static final int JNI_FETCH_END = -6;
-
- public static final int TSDB_DATA_TYPE_NULL = 0;
- public static final int TSDB_DATA_TYPE_BOOL = 1;
- public static final int TSDB_DATA_TYPE_TINYINT = 2;
- public static final int TSDB_DATA_TYPE_SMALLINT = 3;
- public static final int TSDB_DATA_TYPE_INT = 4;
- public static final int TSDB_DATA_TYPE_BIGINT = 5;
- public static final int TSDB_DATA_TYPE_FLOAT = 6;
- public static final int TSDB_DATA_TYPE_DOUBLE = 7;
- public static final int TSDB_DATA_TYPE_BINARY = 8;
- public static final int TSDB_DATA_TYPE_TIMESTAMP = 9;
- public static final int TSDB_DATA_TYPE_NCHAR = 10;
-
- public static String WrapErrMsg(String msg) {
- return "TDengine Error: " + msg;
- }
+ public static final int JNI_SUCCESS = 0;
+ public static final int JNI_TDENGINE_ERROR = -1;
+ public static final int JNI_CONNECTION_NULL = -2;
+ public static final int JNI_RESULT_SET_NULL = -3;
+ public static final int JNI_NUM_OF_FIELDS_0 = -4;
+ public static final int JNI_SQL_NULL = -5;
+ public static final int JNI_FETCH_END = -6;
- public static String FixErrMsg(int code) {
- switch (code) {
- case JNI_TDENGINE_ERROR:
- return WrapErrMsg("internal error of database!");
- case JNI_CONNECTION_NULL:
- return WrapErrMsg("invalid tdengine connection!");
- case JNI_RESULT_SET_NULL:
- return WrapErrMsg("invalid resultset pointer!");
- case JNI_NUM_OF_FIELDS_0:
- return WrapErrMsg("invalid num of fields!");
- case JNI_SQL_NULL:
- return WrapErrMsg("can't execute empty sql!");
- case JNI_FETCH_END:
- return WrapErrMsg("fetch to the end of resultset");
- default:
- break;
- }
- return WrapErrMsg("unkown error!");
- }
+ public static final int TSDB_DATA_TYPE_NULL = 0;
+ public static final int TSDB_DATA_TYPE_BOOL = 1;
+ public static final int TSDB_DATA_TYPE_TINYINT = 2;
+ public static final int TSDB_DATA_TYPE_SMALLINT = 3;
+ public static final int TSDB_DATA_TYPE_INT = 4;
+ public static final int TSDB_DATA_TYPE_BIGINT = 5;
+ public static final int TSDB_DATA_TYPE_FLOAT = 6;
+ public static final int TSDB_DATA_TYPE_DOUBLE = 7;
+ public static final int TSDB_DATA_TYPE_BINARY = 8;
+ public static final int TSDB_DATA_TYPE_TIMESTAMP = 9;
+ public static final int TSDB_DATA_TYPE_NCHAR = 10;
- static {
- DATATYPE_MAP = new HashMap();
- DATATYPE_MAP.put(1, "BOOL");
- DATATYPE_MAP.put(2, "TINYINT");
- DATATYPE_MAP.put(3, "SMALLINT");
- DATATYPE_MAP.put(4, "INT");
- DATATYPE_MAP.put(5, "BIGINT");
- DATATYPE_MAP.put(6, "FLOAT");
- DATATYPE_MAP.put(7, "DOUBLE");
- DATATYPE_MAP.put(8, "BINARY");
- DATATYPE_MAP.put(9, "TIMESTAMP");
- DATATYPE_MAP.put(10, "NCHAR");
- }
+ // nchar field's max length
+ public static final int maxFieldSize = 16 * 1024;
+
+ public static String WrapErrMsg(String msg) {
+ return "TDengine Error: " + msg;
+ }
+
+ public static String FixErrMsg(int code) {
+ switch (code) {
+ case JNI_TDENGINE_ERROR:
+ return WrapErrMsg("internal error of database!");
+ case JNI_CONNECTION_NULL:
+ return WrapErrMsg("invalid tdengine connection!");
+ case JNI_RESULT_SET_NULL:
+ return WrapErrMsg("invalid resultset pointer!");
+ case JNI_NUM_OF_FIELDS_0:
+ return WrapErrMsg("invalid num of fields!");
+ case JNI_SQL_NULL:
+ return WrapErrMsg("can't execute empty sql!");
+ case JNI_FETCH_END:
+ return WrapErrMsg("fetch to the end of resultset");
+ default:
+ break;
+ }
+ return WrapErrMsg("unkown error!");
+ }
+
+ static {
+ DATATYPE_MAP = new HashMap();
+ DATATYPE_MAP.put(1, "BOOL");
+ DATATYPE_MAP.put(2, "TINYINT");
+ DATATYPE_MAP.put(3, "SMALLINT");
+ DATATYPE_MAP.put(4, "INT");
+ DATATYPE_MAP.put(5, "BIGINT");
+ DATATYPE_MAP.put(6, "FLOAT");
+ DATATYPE_MAP.put(7, "DOUBLE");
+ DATATYPE_MAP.put(8, "BINARY");
+ DATATYPE_MAP.put(9, "TIMESTAMP");
+ DATATYPE_MAP.put(10, "NCHAR");
+ }
}
diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulConnection.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulConnection.java
index 6b0937a9b7c50c25d03459d18e01b807b5c00c3c..ed77847484cc363cf0fd9ce7a313364d75043d9a 100644
--- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulConnection.java
+++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulConnection.java
@@ -1,19 +1,29 @@
package com.taosdata.jdbc.rs;
import com.taosdata.jdbc.TSDBConstants;
+import com.taosdata.jdbc.TSDBDriver;
import java.sql.*;
+import java.util.Enumeration;
+import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executor;
public class RestfulConnection implements Connection {
+ private static final String CONNECTION_IS_CLOSED = "connection is closed.";
+ private static final String AUTO_COMMIT_IS_TRUE = "auto commit is true";
private final String host;
private final int port;
private final Properties props;
- private final String database;
+ private volatile String database;
private final String url;
+ /******************************************************/
+ private boolean isClosed;
+ private DatabaseMetaData metadata;
+ private Map> typeMap;
+ private Properties clientInfoProps = new Properties();
public RestfulConnection(String host, String port, Properties props, String database, String url) {
this.host = host;
@@ -21,280 +31,425 @@ public class RestfulConnection implements Connection {
this.props = props;
this.database = database;
this.url = url;
+ this.metadata = new RestfulDatabaseMetaData(url, props.getProperty(TSDBDriver.PROPERTY_KEY_USER), this);
}
@Override
public Statement createStatement() throws SQLException {
if (isClosed())
- throw new SQLException(TSDBConstants.WrapErrMsg("restful TDengine connection is closed."));
+ throw new SQLException(CONNECTION_IS_CLOSED);
+
return new RestfulStatement(this, database);
}
@Override
public PreparedStatement prepareStatement(String sql) throws SQLException {
- return null;
+ if (isClosed())
+ throw new SQLException(CONNECTION_IS_CLOSED);
+ //TODO: prepareStatement
+ throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
}
@Override
public CallableStatement prepareCall(String sql) throws SQLException {
- return null;
+ if (isClosed())
+ throw new SQLException(CONNECTION_IS_CLOSED);
+
+ throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
}
@Override
public String nativeSQL(String sql) throws SQLException {
- return null;
+ if (isClosed())
+ throw new SQLException(CONNECTION_IS_CLOSED);
+
+ //nothing did
+ return sql;
}
@Override
public void setAutoCommit(boolean autoCommit) throws SQLException {
-
+ if (isClosed())
+ throw new SQLException(CONNECTION_IS_CLOSED);
+ if (!autoCommit)
+ throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
}
@Override
public boolean getAutoCommit() throws SQLException {
- return false;
+ if (isClosed())
+ throw new SQLException(CONNECTION_IS_CLOSED);
+ return true;
}
@Override
public void commit() throws SQLException {
-
+ if (isClosed())
+ throw new SQLException(CONNECTION_IS_CLOSED);
+ if (getAutoCommit())
+ throw new SQLException(AUTO_COMMIT_IS_TRUE);
+ //nothing to do
}
@Override
public void rollback() throws SQLException {
-
+ if (isClosed())
+ throw new SQLException(CONNECTION_IS_CLOSED);
+ if (getAutoCommit())
+ throw new SQLException(AUTO_COMMIT_IS_TRUE);
+ //nothing to do
}
@Override
public void close() throws SQLException {
-
+ if (isClosed)
+ return;
+ //TODO: release all resources
+ isClosed = true;
}
@Override
public boolean isClosed() throws SQLException {
- return false;
+ return isClosed;
}
@Override
public DatabaseMetaData getMetaData() throws SQLException {
- //TODO: RestfulDatabaseMetaData is not implemented
- return new RestfulDatabaseMetaData();
+ if (isClosed())
+ throw new SQLException(CONNECTION_IS_CLOSED);
+
+ return this.metadata;
}
@Override
public void setReadOnly(boolean readOnly) throws SQLException {
-
+ if (isClosed())
+ throw new SQLException(CONNECTION_IS_CLOSED);
+ // nothing to do
}
@Override
public boolean isReadOnly() throws SQLException {
- return false;
+ if (isClosed())
+ throw new SQLException(CONNECTION_IS_CLOSED);
+ return true;
}
@Override
public void setCatalog(String catalog) throws SQLException {
-
+ if (isClosed())
+ throw new SQLException(CONNECTION_IS_CLOSED);
+ synchronized (RestfulConnection.class) {
+ this.database = catalog;
+ }
}
@Override
public String getCatalog() throws SQLException {
- return null;
+ if (isClosed())
+ throw new SQLException(CONNECTION_IS_CLOSED);
+ return this.database;
}
@Override
public void setTransactionIsolation(int level) throws SQLException {
- //transaction is not supported
- throw new SQLFeatureNotSupportedException("transactions are not supported");
+ if (isClosed())
+ throw new SQLException(CONNECTION_IS_CLOSED);
+ switch (level) {
+ case Connection.TRANSACTION_NONE:
+ break;
+ case Connection.TRANSACTION_READ_UNCOMMITTED:
+ case Connection.TRANSACTION_READ_COMMITTED:
+ case Connection.TRANSACTION_REPEATABLE_READ:
+ case Connection.TRANSACTION_SERIALIZABLE:
+ throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
+ default:
+ throw new SQLException(TSDBConstants.INVALID_VARIABLES);
+ }
}
- /**
- *
- */
@Override
public int getTransactionIsolation() throws SQLException {
+ if (isClosed())
+ throw new SQLException(CONNECTION_IS_CLOSED);
//Connection.TRANSACTION_NONE specifies that transactions are not supported.
return Connection.TRANSACTION_NONE;
}
@Override
public SQLWarning getWarnings() throws SQLException {
- //TODO: getWarnings not implemented
+ if (isClosed())
+ throw new SQLException(CONNECTION_IS_CLOSED);
+
return null;
}
@Override
public void clearWarnings() throws SQLException {
- throw new SQLFeatureNotSupportedException("clearWarnings not supported.");
+ if (isClosed())
+ throw new SQLException(CONNECTION_IS_CLOSED);
+ //nothing to do
}
@Override
public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
- return null;
+ if (isClosed())
+ throw new SQLException(CONNECTION_IS_CLOSED);
+
+ if (resultSetType != ResultSet.TYPE_FORWARD_ONLY) {
+ throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
+ }
+ if (resultSetConcurrency != ResultSet.CONCUR_READ_ONLY)
+ throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
+ return createStatement();
}
@Override
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
- return null;
+ if (isClosed())
+ throw new SQLException(CONNECTION_IS_CLOSED);
+ if (resultSetType != ResultSet.TYPE_FORWARD_ONLY || resultSetConcurrency != ResultSet.CONCUR_READ_ONLY)
+ throw new SQLFeatureNotSupportedException(TSDBConstants.INVALID_VARIABLES);
+
+ return this.prepareStatement(sql);
}
@Override
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
- return null;
+ if (isClosed())
+ throw new SQLException(CONNECTION_IS_CLOSED);
+ if (resultSetType != ResultSet.TYPE_FORWARD_ONLY || resultSetConcurrency != ResultSet.CONCUR_READ_ONLY)
+ throw new SQLFeatureNotSupportedException(TSDBConstants.INVALID_VARIABLES);
+
+ throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
}
@Override
public Map> getTypeMap() throws SQLException {
- return null;
+ if (isClosed())
+ throw new SQLException(CONNECTION_IS_CLOSED);
+
+ synchronized (RestfulConnection.class) {
+ if (this.typeMap == null) {
+ this.typeMap = new HashMap<>();
+ }
+ return this.typeMap;
+ }
}
@Override
public void setTypeMap(Map> map) throws SQLException {
+ if (isClosed())
+ throw new SQLException(CONNECTION_IS_CLOSED);
+ synchronized (RestfulConnection.class) {
+ this.typeMap = map;
+ }
}
@Override
public void setHoldability(int holdability) throws SQLException {
-
+ if (isClosed())
+ throw new SQLException(CONNECTION_IS_CLOSED);
+ if (holdability != ResultSet.HOLD_CURSORS_OVER_COMMIT)
+ throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
}
@Override
public int getHoldability() throws SQLException {
- return 0;
+ if (isClosed())
+ throw new SQLException(CONNECTION_IS_CLOSED);
+ return ResultSet.HOLD_CURSORS_OVER_COMMIT;
}
@Override
public Savepoint setSavepoint() throws SQLException {
- return null;
+ if (isClosed())
+ throw new SQLException(CONNECTION_IS_CLOSED);
+ if (getAutoCommit())
+ throw new SQLException(TSDBConstants.INVALID_VARIABLES);
+ //nothing to do
+ throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
}
@Override
public Savepoint setSavepoint(String name) throws SQLException {
- return null;
+ if (isClosed())
+ throw new SQLException(CONNECTION_IS_CLOSED);
+ if (getAutoCommit())
+ throw new SQLException(TSDBConstants.INVALID_VARIABLES);
+ //nothing to do
+ throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
}
@Override
public void rollback(Savepoint savepoint) throws SQLException {
-
+ if (isClosed())
+ throw new SQLException(CONNECTION_IS_CLOSED);
+ if (getAutoCommit())
+ throw new SQLException(TSDBConstants.INVALID_VARIABLES);
+ //nothing to do
+ throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
}
@Override
public void releaseSavepoint(Savepoint savepoint) throws SQLException {
-
+ if (isClosed())
+ throw new SQLException(CONNECTION_IS_CLOSED);
+ throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
}
@Override
public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
- return null;
+ if (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT)
+ throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
+ return createStatement(resultSetType, resultSetConcurrency);
}
@Override
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
- return null;
+ if (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT)
+ throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
+ return prepareStatement(sql, resultSetType, resultSetConcurrency);
}
@Override
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
- return null;
+ throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
}
@Override
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
- return null;
+ throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
}
@Override
public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
- return null;
+ throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
}
@Override
public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
- return null;
+ throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
}
@Override
public Clob createClob() throws SQLException {
- //TODO: not supported
- throw new SQLFeatureNotSupportedException();
+ throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
}
@Override
public Blob createBlob() throws SQLException {
- //TODO: not supported
- throw new SQLFeatureNotSupportedException();
+ throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
}
@Override
public NClob createNClob() throws SQLException {
- //TODO: not supported
- throw new SQLFeatureNotSupportedException();
+ throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
}
@Override
public SQLXML createSQLXML() throws SQLException {
- //TODO: not supported
- throw new SQLFeatureNotSupportedException();
+ throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
}
@Override
public boolean isValid(int timeout) throws SQLException {
- return false;
+ if (timeout < 0)
+ throw new SQLException(TSDBConstants.INVALID_VARIABLES);
+ // TODO:
+ /* The driver shall submit a query on the connection or use some other mechanism that positively verifies
+ the connection is still valid when this method is called.*/
+ return !isClosed();
}
@Override
public void setClientInfo(String name, String value) throws SQLClientInfoException {
-
+ if (isClosed)
+ throw new SQLClientInfoException();
+ clientInfoProps.setProperty(name, value);
}
@Override
public void setClientInfo(Properties properties) throws SQLClientInfoException {
+ if (isClosed)
+ throw new SQLClientInfoException();
+ for (Enumeration